DEV Community

Cover image for The Starwarden — browser platformer: collect starlights, fight murklings, beat the darkness
Dang Tran
Dang Tran

Posted on • Edited on

The Starwarden — browser platformer: collect starlights, fight murklings, beat the darkness

June Solstice Game Jam Submission

This is a submission for the June Solstice Game Jam

What I Built

The Starwarden is a browser-based 2D side-scrolling platformer. You are the last Starwarden — a wizard carrying embers of the old light — in a world where a creeping shadow called the Murk has swallowed half the sky.
Each run takes you through four seasons (Spring → Summer → Fall → Winter):

  • The sky starts every season at 50% darkness
  • Darkness rises passively over time (~90 seconds to total night if you do nothing)
  • Collect starlights to push the meter back down
  • Murklings patrol the platforms; touch one and the sky gets darker
  • From Summer onward, purple Striker murklings shoot shadow bolts at range
  • Fireballs (Space) destroy enemies but briefly lock your movement during the attack animation
  • Clear all four seasons to win; hit 100% darkness and you lose The world is procedurally generated each season — floating platform staircases, parallax backgrounds that change with the season, and starlight spawns guaranteed to be reachable (a BFS reachability pass prunes impossible placements).
  • Please turn on the sound when you're playing :-)

Screenshots

The game tale

Victory screen

Site

https://wizard-game-pi.vercel.app/

Code

The Starwarden

A 2D side-scrolling platformer built with Phaser 4, React 19, TypeScript, and Vite. Play as a wizard crossing a procedurally generated world through four seasons — collect starlights to push back the darkness, dodge or defeat murklings, and clear Spring through Winter to win.

AI / contributor reference: See AGENTS.md for architecture, game logic, world generation, assets, and conventions. Start there instead of reading the full codebase.

Quick start

npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:8080. The game loads StoryInstructionsGame (MainMenu is registered but skipped on cold start).

Command Description
npm install Install dependencies
npm run dev Development server with hot reload
npm run build Production build in dist/

How to play

Each season starts with the sky at 50% darkness. Darkness rises passively over time (~90 seconds to reach 100% if you collect nothing). Collect starlights to…

How I Built It

Stack

Layer Choice
Game engine Phaser 4
UI shell React 19
Language TypeScript
Bundler Vite 6
Viewport 1280 × 960
World 6480 px wide procedural tile grid

Phaser handles gameplay, physics, and rendering; React mounts the canvas via a thin PhaserGame wrapper. Scenes emit current-scene-ready on an EventBus so React can track the active scene.

Architecture highlights

Procedural world (worldMap.ts)

Platforms are generated as connected climbable staircases separated by gaps, then pruned with a conservative walk/jump BFS so every remaining starlight spawn is actually collectible. The platforms are generated differently for every season for every play turn.

Season system (seasonConfig.ts)

Four seasons share the same passive darkness fill rate but ramp difficulty through Murkling speed, spawn rate, contact damage, and Striker presence (0 → 3 initial Strikers by Winter).

Depth sorting (elementsConfig.ts)

World entities sort by feet Y + layer offset so characters on lower platforms render in front — important for a stacked platform world.

What I built on

This project started from the official Phaser React TypeScript template (MIT). During the jam period (June 3–21, 2026) I replaced the template demo with original gameplay:

  • Story and Instructions scenes with narrative copy and animated previews
  • Full platformer movement, combat, and enemy AI (patrol + Striker ranged attacks)
  • Darkness/starlight HUD and full-screen overlay system
  • Four-season progression with seasonal parallax backgrounds and tree art
  • Procedural world generation with reachability guarantees
  • Run/lifetime stats persisted in localStorage

Top comments (0)