Skip to content
mdr
All work
live2024·personal

Neon Phaser: Cyberwave Assault

Neon cyberpunk shooter with wave-based combat. Phaser + Express, now playable on-site.

Screenshot of Neon Phaser: Cyberwave Assault

TL;DR

  • 100% client-side — Express only served statics, dropped for this site.
  • Seven Phaser scenes, modular classes/managers.
  • Canvas + CSS background composition behind the game canvas.
  • Wave-based enemy spawning + collision data tables.
  • Pause / game-over / settings as proper scene transitions.

Architecture

Flow
CLIENTHOSTPHASER RUNTIMEASSETSPlayerbrowserStatic hostpublic/ onlymain.jsPhaser configPhaser 37 scenesmenu → game → overGame classesPlayer · Enemy · PowerUpCanvas + CSS bggrid · cubes · particlesSprites + audiopublic/assets/

Vanilla Phaser, no framework wrapping. Static host, no API.

sync · HTTP / RPCdata · read / write

Screens

  • Menu — neon city background

    The title screen runs three composed layers: Phaser canvas in front, a regular HTML5 canvas behind it drawing the perspective grid + rotating neon cubes, and a particle layer on top of that. Compositing in CSS instead of Phaser keeps the game canvas focused on gameplay.

  • Story scene — animated dialog frames

    After the menu the game cuts to a narrative scene with hand-drawn cyberpunk frames. Skip/Next live on the canvas. This is one of seven Phaser scenes — preload, menu, story, game, pause, game-over, settings — each in its own file.

Problem

I wanted a side-scrolling cyberpunk shooter with the look of an arcade cabinet — fast, neon-glow, with a hand-built parallax background and an honest 60fps Phaser game loop. No engine framework around it, no build step. Just Phaser, vanilla JS modules, and a static server.

Approach

Phaser 3 client served by a one-file Express static host (no API). Seven Phaser scenes — preload / menu / story / game / pause / game-over / settings — each in its own file. Class-based game objects (Player, Enemy, PowerUp), separated managers, data files for enemy patterns. The background is its own thing: a Canvas-rendered perspective grid + rotating 3D neon cubes + a CSS particle layer, all behind the gameplay.

Deep dive

Background composition without the engine

The Phaser canvas runs the gameplay. Behind it sits a regular HTML5 canvas (`#cityCanvas`) rendering a rotated perspective grid + animated neon cubes in pure 2D context math, and an absolutely-positioned `#particlesContainer` with CSS-animated DOM nodes. Compositing three layers in CSS is cheaper than asking Phaser to also render the city.

Why vanilla JS — and what that cost

No bundler, no TS, no React. The whole game is ES modules loaded as `<script type='module'>`. Build is instant, dev is just refresh. Cost: no type safety, no tree-shaking, no per-route splitting. For a game-canvas app that's a fair trade. The trade-off doesn't hold once you add real UI chrome — that's why Aether Drift (next-gen of this) pulled in Next + React for the shell.

Outcome

Feature-complete demo. Now embedded on this site as a static workspace package — the Express server was replaced by serving the public/ folder directly, since it had zero backend logic.

Related

More in games.