+ Publish
Pixel Strike #08

Make It Right, Then Make It Fast — and Ship It

By @cccrayfish Part 8 of 8

The game plays. Do not rush into "optimise everything", and do not rush the launch either. Two sentences carry this part: make it right before you make it fast, and test it the way it will actually be served.

Tier optimisations by return on effort

Have the AI sort the work into P0 / P1 / P2, and only do P0:

  • Object pooling — high-frequency effects (tracers, sparks) should not be allocated and destroyed per shot. Recycle a fixed pool. The difference shows up immediately on high rate-of-fire weapons.
  • Distance culling on hit tests — filter raycast targets by distance first and skip anything beyond weapon range.
  • Dirty-flag the HUD — health and ammo write to the DOM only when the value changes, not every frame.
  • Delete dead code — unused branches, values computed and never read. Gone.
// Object pool: recycle in a ring instead of new/dispose (GC pressure gone)
const pool = []; let idx = 0;
function spawnTracer(a, b) {
  const t = pool[idx]; idx = (idx + 1) % pool.length;   // take the next slot
  t.setPoints(a, b); t.visible = true; t.life = 0.08;   // reset, never allocate
}

And leave P1 and P2 alone

Log P1 (hitbox refinement, state management — medium-sized changes) as a to-do. P2 (swapping out the whole collision system, that class of rebuild) stays untouched unless you genuinely need it — say, if you want sloped terrain. Refactoring for its own sake only introduces bugs.

// Dirty-flag the HUD: don't touch the DOM when the value hasn't changed
function setTxt(id, v) { if (cache[id] !== v) { cache[id] = v; el(id).textContent = v; } }

Getting it online was one command

I had braced myself for this part and it turned out to be nothing. Pogglo just takes plain static files — I pointed one command at my folder and got back a link I could send to people:

npx pogglo publish --title "Your Game" --slug your-game \
  --orientation landscape --category shooting --platforms both

So test it as static files, not through a dev server

Because it is static hosting, your pre-launch test should use the same shape. Serve the game as plain static files (npx serve .) instead of only running it through npm run dev. Check that:

  • every path is relative — no ../ escapes, no paths starting with /;
  • dependencies come from an importmap or are copied in, with no node_modules references;
  • every file you reference is actually inside the bundle.

This is exactly why Part 2 pinned down "pure static single file" as a red line so early — it turns launch into one command instead of a refactor.

You do not have to memorise the packaging rules either. The packaging section of the guide is that checklist, and if something is off, what comes back is a plain fix you can paste straight into your AI.

Launches break. That is fine.

My first publish went live and would not open at all. The cause was mundane: Pogglo injects a global pogglo object (for saves and leaderboard scores) and it is read-only. My code had a line like pogglo = pogglo || fallback. Assigning to a read-only property throws in strict mode, and the whole script died with it.

The fix: install the fallback only when there is not a real one, and skip it entirely on the platform.

I found that one by walking into it. It and the rest of the error codes are listed in the last section of the guide — two minutes of skimming would have saved me an evening.

// Install a fallback ONLY when there isn't a real one (i.e. local dev).
// On Pogglo the injected `pogglo` object is read-only — assigning to it
// throws in strict mode and kills the whole script.
if (typeof globalThis.pogglo === 'undefined') {
  try { globalThis.pogglo = fallback; } catch (e) {}
}

The one thing I would wire up differently: saves

I kept progress — coins, levels, unlocked weapons — in localStorage. It works, it costs nothing, and it survives a reload. But it is tied to that one device: play on your phone, come back on a laptop, and you start from zero.

Pogglo has its own answer, and it is a single pogglo.save call. Same one line, except the platform keeps it per game and syncs it across the player's devices once they are logged in — guests stay device-local, exactly what I already had. I only found that afterwards, in the saves section of the guide.

The part that actually stung is one section further down: a single prompt that packs the entire platform spec — saves, scores, packaging, all of it. You paste it into your AI before you start, and what it writes is publish-ready from the first line. Had I pasted that on day one, the read-only bug above would never have happened.

Now go put it in front of people

Locate, fix, republish. Done. Errors are not the scary part — feed the symptom to the AI and work through them one at a time.

By this point you are holding a game that is playable, shareable and live. Do not let it rot in a folder. Publish it, take the link, and send it to people. Watch a real person get stuck in something you made.

That moment when someone asks "you made this?" is the whole reason to start.

In one line

Make it right, then make it fast. And always test the way it will actually be served.

The prompts I used

The original
Moving into optimisation and launch.
Tier the optimisations by return on effort and only do P0: pool high-frequency effects,
distance-cull hit tests, refresh the HUD only when values change, delete dead code.
Record P1 as a to-do; leave P2 alone.
Before launch: test the game as plain static files (not through the dev server) —
check relative paths, the importmap, that nothing references node_modules, and that every
referenced file is inside the bundle.
Then publish to Pogglo with pogglo publish and give me the play link.
If publishing errors, work through the messages one at a time (for example: the injected
read-only pogglo object cannot be assigned to — change it to "install only if absent").
Reusable
Make it work before you optimise it. Give me an optimisation list tiered by ROI (P0/P1/P2),
do only P0 for now, and explain the payoff of each item. Before launch, test end to end using
the real runtime shape of the target platform and give me a release checklist. When you hit
platform-specific errors, locate and fix them one at a time.

The game I built

This is what came out the other end of all of it. It opens in the browser, nothing to download — go and break it.

Pixel Strike — free online shooting game on Pogglo

Pixel Strike

@cccrayfish · ♥ 6