Skip to content

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.

  • 24 TypeScript files including a GameManager spine, 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.

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.
InputAction
A / D or arrow keysRun left / right
Space / W / UpJump (hold for higher arc)
ShiftRun (held)
J / ZAttack swing
EInteract
EscPause menu
Land on top of an enemyStomp it
Touch an enemy from the sideGame over
Fall off the bottomGame over
Walk into the flagLevel complete
R (after completion)Restart

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.

KeyDefaultWhat it does
player.moveSpeed220Walk velocity in px/s
player.runSpeed320Sprint velocity with Shift held
player.jumpVelocity480Initial upward velocity on a jump
player.maxFallSpeed720Terminal fall velocity
player.coyoteMs100Window after leaving a platform where a jump still counts
player.jumpBufferMs120Window before landing where a queued jump auto-fires
player.variableJumpReleaseFactor0.5Multiplier on upward velocity when jump is released mid-rise

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.

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 in levels.ts. Or call forge.generate_platformer_scene.
  • Add an enemy kind: drop a 4-pose sprite set under public/enemies/<kind>/, append to src/entities/enemies.ts.
  • Add a pickup: drop a sprite under public/pickups/, append to src/entities/pickups.ts, branch the overlap handler in level-scene.ts for 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.json in the Parallax tab.
  • 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 in buildCheckpoints for visibility.