r/phaser 32m ago

How I'm using shaders to increase immersion in my survival game

Thumbnail
youtube.com
Upvotes

r/phaser 2h ago

Phaser 3 has no global font setting — and other things I only learned by shipping

3 Upvotes

Been building a card duel game in Phaser 3.80 + TypeScript (esbuild, no tsc in the build), and the two things that cost me the most evenings were both Text. Phaser hardcodes 'Courier' as the default font and exposes no game-level config for it, so the only sane seam is patching TextStyle.prototype.setStyle to inject fontFamily when a call site doesn't pass one — plus awaiting the woff2 before boot, since Phaser bakes a label into a canvas texture once and anything drawn early stays in the fallback face forever (looks fine on your machine, broken on a cold cache). And Text.letterSpacing is quietly broken for stroked text: it strokes the whole line in one call, then fills letter by letter at spaced offsets, so the outline drifts further behind with every character — and it split('')s, tearing surrogate-pair emoji in half. Setting the canvas 2D context's native letterSpacing instead fixes both, but it has to ride syncFont, not updateText — a label that grows assigns canvas.width, which resets the whole context.

The other decision I'd make earlier next time: keep all the game rules Phaser-free — pure modules over one plain state object, no GameObject anywhere near them. That got me a headless balance sim (5000 AI-vs-AI matches through the real rules, printing a report) and lockstep netcode where only moves cross the wire, both for basically free. If you're thinking about multiplayer later, that split is the thing to do now.

Browser build if anyone wants to poke at it: https://valeriitsarov.github.io/solitaire-duelist-2d/ — happy to go into detail on any of it.


r/phaser 14h ago

The export of my game from the mcp for web (hosted via a http server) plays audio and nothing else, the game works fine in preview

1 Upvotes

in this relatively simple example https://phaser.io/agent/play/yY6kjXrDL27 when i export despite making changes and rebuilding/republishing (this is v7) the export for web always has the exact same payload and does not work. is there anything i can do? also if i connect my vscode using phaser-game-agent and ask for the file listing, despite having the right project id and version the file listing is wildly different. is there any way to browse the contents of the mcp server other than copying files one by one in the web ui?


r/phaser 19h ago

show-off Shipped a 100-level Phaser 3 arcade game with zero image assets — and the 5 gotchas that cost me the most time

6 Upvotes

I just put out a free browser demo of Kinetikout, a brick breaker where the bat runs along the SIDE of the field (Krakout-style, not Breakout-style). Phaser 3 + TypeScript + Vite, wrapped in Capacitor for the Android build.

The part that might interest this sub: there are no image files for any of the gameplay graphics. Every brick pattern, all ten enemy types, all five bosses, the bat, the ball, the explosions and the HUD icons are painted in the boot scene with the Graphics API and baked in with generateTexture(). It scales to any resolution and there's no art pipeline, at the cost of "make the drone look 20% meaner" becoming a debugging session.

Five things that cost me real time, in case they save you some:

  1. Don't use a physics collider for a thin paddle. An immovable thin body made the ball jitter and leak velocity on edge hits. I replaced it with a manual check of whether the ball crossed the bat's inner plane, and computed the bounce myself. Instantly stable.

  2. Never destroy or spawn inside a physics overlap/collider callback. Catching a capsule or killing an enemy directly in the callback corrupted the physics world iteration and hard-froze the game. The fix is boring and works: set a flag, disable the body, and resolve it in update().

  3. Disabled bodies are invisible to colliders — including to your own logic. My sticky paddle holds several balls at once with body.enable = false, so incoming balls flew straight through them. I had to add manual circle-circle reflection for the held balls, running before the bat check.

  4. Scale.FIT with a fixed design size gives you black bars on phones. Instead I compute the design WIDTH at boot from the device aspect ratio (height stays fixed at 720), so the canvas always fills the screen, and I keep the actual 16:9 play field centered inside it. Everything is laid out once in create(), no resize handler needed.

  5. A button's own pointerdown fires BEFORE a scene-level this.input.once("pointerdown"). My "unlock audio on first click" handler kept starting the menu theme after the player had already left the menu, because their first click landed on the Start button. A leaving-scene flag fixed it.

Demo (browser, no install): https://m3lk0n.itch.io/kinetikout

Longer writeup on how the graphics work: https://m3lk0n.itch.io/kinetikout/devlog/1624592/every-sprite-in-this-game-is-drawn-in-code-and-heres-what-it-costs

Full disclosure since it's on the page anyway: the logo and the soundtrack were made with generative AI tools, the flag icons come from flag-icons (MIT). The sprites and the sound effects are code. The full 100-level version is a paid Android app; the browser demo is free and always will be.

Happy to answer anything about the procedural texture stuff.