Inspiration
I grew up playing platformers where a simple jump, a hidden coin, or a familiar sound could create a memorable moment. I wanted to build my own version of that feeling while pushing the idea beyond a traditional Mario-style platformer.
SuperMario is my attempt to combine nostalgic 2D platforming with modern engineering: different playable characters, changing world physics, secrets, bosses, and levels that are programmatically validated before they ship.
What it does
SuperMario is an 8-world, 32-level 2D platformer with 10 playable characters, each designed with different abilities and play styles.
Players run, jump, attack, explore secrets, collect coins and stars, defeat enemies, discover checkpoints, and fight bosses at the end of worlds.
Each world introduces its own gameplay identity and physics changes — from slippery movement and altered gravity to environmental forces such as wind and underwater currents.
The goal isn't just to reach the end of a level — it's to explore, master the mechanics, and discover what each world is hiding.
How we built it
SuperMario is built with:
Phaser 4 — game engine, rendering, physics, collisions, scenes and gameplay React 19 — surrounding application/UI layer TypeScript — core game architecture and type safety Vite — development and production build tooling Bun — development, testing and tooling
The interesting part is the custom TypeScript level-builder DSL.
Instead of manually creating every level as raw tile coordinates, levels can be authored using higher-level primitives such as:
ground() ledge() shaft() islands() patrol() checkpoint() blockRow() zigzag() finish()
Those level definitions are then converted into playable Phaser worlds.
I also built automated level-validation and traversal tests so that level geometry can be checked programmatically instead of relying entirely on manually playing every stage.
The project currently contains a structured gameplay architecture for characters, enemies, bosses, collectibles, projectiles, objectives, checkpoints, audio, physics and level progression.
Challenges we ran into
Some of the biggest challenges were:
- Making levels actually completable
A platform can look reachable to a developer but still be impossible because of jump height, horizontal velocity, collision boxes or platform spacing. This led to the custom level validation system.
- World-specific physics
Changing physics between worlds creates unexpected interactions. Ice, gravity, wind, water and normal movement all have to work without breaking the underlying player controller.
- Boss encounters
Bosses required their own health, phases, attacks, projectiles, hit detection, health bars and defeat states. Making sure one projectile equals exactly one boss hit while preventing duplicate collision events was surprisingly tricky.
- Level progression
Bosses, objectives, checkpoints, coins and goal flags all interact with the level-completion system. A player shouldn't accidentally complete a boss level without defeating its boss.
- Designing levels through code
Procedural or DSL-based level construction is powerful, but a small coordinate change can completely change how a player experiences a level. Making the generated geometry feel intentionally designed required continuous iteration
Accomplishments that we're proud of
Built the game solo from scratch Created 8 worlds and 32 levels Implemented 10 playable characters Built a custom TypeScript level-builder DSL Added different physics/gameplay identities across worlds Implemented enemies, projectiles, collectibles, checkpoints and boss encounters Built automated level geometry/traversal validation Created a reusable architecture for characters, enemies and bosses Built the game around original gameplay systems and assets rather than simply reproducing an existing level Turned a large game concept into a structured, testable codebase
Most importantly, I'm proud that this became more than a collection of levels — it became a small game-engineering system for building and validating levels.
What we learned
The biggest lesson was that game development is much more about systems interacting than individual features working independently.
A jump system can work perfectly by itself and still fail when combined with a platform layout. A boss can have correct health logic but still break because of collision callbacks. A level can pass a geometry check but still feel bad to play.
I learned to think about:
Gameplay as interacting state machines Physics and level geometry together Deterministic collision handling Reusable game architecture Data-driven level design Automated gameplay validation Designing for both the player experience and the underlying system
Building SuperMario also taught me that testing a game isn't just checking whether the code compiles — you have to validate whether the player can actually play it.
What's next for SuperMario
The next step is to push SuperMario from a large prototype into a fully polished playable game.
Planned improvements include:
Polish all 32 levels Improve boss designs and boss encounters Add richer character animations Expand character-specific abilities Improve sound design and nostalgic atmosphere Add more secrets and bonus areas Improve level-generation validation with stronger traversal simulation Add better progression and save-state systems Improve UI/UX and accessibility Optimize performance
Built With
- bun
- phaser.js
- react
- typescript
- vite



Log in or sign up for Devpost to join the conversation.