Platformer bundle
The Platformer bundle is a 30-second 2D side-scroller. The Smith mascot runs across Forge Canyon, jumps three platforms, stomps an Ember Spirit, collects three coins, and reaches the end-of-level flag. Boot lands on a main menu (New Game / Continue / Settings / Controls / Credits). ESC pauses gameplay; falling or taking damage opens a game-over screen with Respawn or Quit to Main Menu.
Use this bundle when you want side-scrolling gameplay with real platformer feel and a complete game shell to extend.
What ships
Section titled “What ships”- 24 TypeScript files including a
GameManagerspine, 8 composed system components, the full Phaser shell (main-menu / pause / settings / credits / controls / game-over scenes plus shared menu helpers), and a hand-built JSON level format. - 29-frame Phaser atlas for the player covering idle / walk / run / jump / fall / land / turn / hurt.
- Enemies, pickups, parallax: per-kind enemy sprites with idle / move / attack / hit, pickups (coin / heart / key), a 4-layer parallax backdrop (sky / cliffs / forge / rocks).
- Music + SFX kits: an ambient music loop on the Music bus, generated SFX (jump, land, coin, stomp) on the SFX bus, AudioManager ducking already wired.
- QA scenarios under
.forge/qa/covering boot and jump movement, runnable from the QA tab.
Systems wired in
Section titled “Systems wired in”The Platformer bundle ships with 9 systems registered in .forge/gamemanager.toml:
- ProjectConfig holds the player feel constants (coyote time, jump buffer, variable jump factor, max fall speed).
- EventBus carries gameplay events between scenes.
- StateMachine drives the boot / menu / play / pause / complete flow.
- SaveSystem persists progression to localStorage.
- AudioManager owns the bus tree, ducking rules, and music crossfades.
- InputManager maps keyboard and gamepad actions.
- SettingsManager renders the in-game settings menu.
- ThemeManager swaps the UI palette via CSS variables.
- CharacterController ships the 2D platformer variant with all the polish constants tuned to Celeste / SMW defaults.
Controls
Section titled “Controls”| Input | Action |
|---|---|
A / D or arrow keys | Run left / right |
Space / W / Up | Jump (hold for higher arc) |
Shift | Run (held) |
J / Z | Attack swing |
E | Interact |
Esc | Pause menu |
| Land on top of an enemy | Stomp it |
| Touch an enemy from the side | Game over |
| Fall off the bottom | Game over |
| Walk into the flag | Level complete |
R (after completion) | Restart |
Player feel constants
Section titled “Player feel constants”The polish constants live in src/systems/entries.json and read through ProjectConfig. You can edit them in the ProjectConfig editor (Inspector → Systems → ProjectConfig → Open) and the values round-trip immediately.
| Key | Default | What it does |
|---|---|---|
player.moveSpeed | 220 | Walk velocity in px/s |
player.runSpeed | 320 | Sprint velocity with Shift held |
player.jumpVelocity | 480 | Initial upward velocity on a jump |
player.maxFallSpeed | 720 | Terminal fall velocity |
player.coyoteMs | 100 | Window after leaving a platform where a jump still counts |
player.jumpBufferMs | 120 | Window before landing where a queued jump auto-fires |
player.variableJumpReleaseFactor | 0.5 | Multiplier on upward velocity when jump is released mid-rise |
Editing levels
Section titled “Editing levels”src/data/level-1.platformer-scene.json is the level definition: platforms, pickups, enemy spawns, and the flag. Open it in Forge and it routes to the PlatformerScene tab, where you can edit the geometry visually (platforms, spawns, exit) and save back to JSON.
To add a level, copy the file, edit it, and register it in src/data/levels.ts:
import level2 from './level-2.platformer-scene.json';export const LEVELS: readonly LevelDef[] = [level1 as LevelDef, level2 as LevelDef];If you have the agent on, forge.generate_platformer_scene (see Forge MCP tools) outputs JSON matching the LevelDef shape directly. Drop the result into src/data/<name>.json and register it.
Extending
Section titled “Extending”The bundle’s README inside the project root has the full extension recipes. The short version:
- Add a level: copy a
level-N.platformer-scene.json, edit in the Forge tab, register inlevels.ts. Or callforge.generate_platformer_scene. - Add an enemy kind: drop a 4-pose sprite set under
public/enemies/<kind>/, append tosrc/entities/enemies.ts. - Add a pickup: drop a sprite under
public/pickups/, append tosrc/entities/pickups.ts, branch the overlap handler inlevel-scene.tsfor new behaviors (heart restores HP, key opens gates). - Tune player feel: edit values in the ProjectConfig editor.
- Edit parallax layers: open
src/data/level-1.parallax.jsonin the Parallax tab.
What’s intentionally not here
Section titled “What’s intentionally not here”- No HP system. Player goes straight to game over on enemy contact. The game-over scene’s Respawn button calls
level.respawnPlayer(), which is public for exactly this reason. Adding HP, invulnerability frames, and a hearts UI is an extension exercise. - No combat beyond stomp. Add a hammer-strike hitbox in
level-scene.ts:update()and bind a key when you want active attacks. - No tilemap import. The hand-built JSON level format keeps the bundle dependency-free. Tiled import is a documented extension.
- No checkpoint flag visuals. The
checkpoints[]array in level JSON is read but not rendered. Add a flag sprite inbuildCheckpointsfor visibility.