Inspiration

I keep replaying tower-defense waves to see what happens if one tile moves by one square. That habit became Lastlight Bastion. I wanted practice to be generous, the final decision to matter, and the damage to remain visible after the timer resets. Reddit supplied the missing piece: everyone inherits the same fort.

What it does

Lastlight Bastion is played on one persistent 7-by-7 fort. Every thirty minutes, a deterministic storm attacks from one of four gates.

Players can forecast that exact storm as often as they like. During a forecast, they can place or replace up to three defenses within the current supply budget. The five defense types are Conductors, Mirrors, Braces, Lures, and Dynamos.

The result shows the exact beacon, stopped-contact, salvage, and supply arithmetic behind its score, explains what the defenses did, and suggests one useful change. An expired forecast leads back to a fresh copy of the current pulse instead of leaving stale tactical state on screen.

Each signed-in player can seal one official plan per pulse. At impact, the server adopts the highest-scoring valid plan. Damage, surviving defenses, scars, supplies, and recent reconstruction records carry into the next pulse. The command budget starts at six points and can rise to eight as the fort gathers supplies.

If nobody submits a plan, a built-in curator plan keeps the campaign moving. A failed defense restores the beacon to at least 25 health, grants salvage, and reduces pressure on the next storm, so one bad pulse cannot end the game. Detailed plans appear after six planners take part, but account names are never exposed.

How we built it

React and TypeScript power the command screen and its keyboard-operable 49-cell grid. Phaser renders the forecast replay. A Hono server on Devvit Web creates forecast sessions, validates plans, scores them, and resolves each pulse. Redis stores the fort, submissions, journals, and reconstruction archive. Devvit Scheduler calls the resolution route every thirty minutes.

On mobile, the tile tray sits above the board so the bottom row stays reachable. Phaser accepts placements only from its own canvas, preventing a tile-rack tap from bubbling into a hidden board placement.

The same simulation is used for practice and official resolution, so the browser cannot award itself a better result.

Challenges

Practice had to stay unlimited while the official choice stayed scarce. I also had to handle the scheduler and a moderator repair action reaching the same pulse without resolving it twice.

The other hard problem was failure. Keeping damage makes the fort feel real, but permanent defeat would make the game useless for the next visitor. The recovery rule came from testing long runs of bad pulses rather than resetting the campaign.

Accomplishments

I am happiest with the history the fort develops. A defense can survive, wear down, or disappear. Supplies earned in one pulse change the budget available later, and the archive shows how the current fort got here.

The game also has a useful first-player state. Forecasts work immediately, and the curator can carry a quiet community until more planners arrive.

What we learned

Exact replay simplified much more than the animation. One simulation now drives practice, server validation, the Phaser replay, accessible text, pulse repair, and tests.

I also learned that an empty multiplayer game needs an actual fallback plan, not just a message asking people to come back later.

What's next

I would add storm families with visibly different behavior, campaign-era milestones, and shared engineering projects that spend accumulated supplies. I would also improve reconstruction summaries and add optional reminders shortly before impact.

Built with

Devvit Web, Reddit custom posts, React 19, TypeScript, Phaser 3, Hono, Redis, Devvit Scheduler, Reddit API, Vite, Vitest, Testing Library, Playwright, ESLint, and Prettier.

The war-table background was generated specifically for Lastlight Bastion with OpenAI image generation on July 14, 2026. The command grid, tile symbols, battle effects, and interface are original CSS, React, and Phaser work.

Significant hackathon updates

During the hackathon I built five defense types, unlimited forecasts, one official plan per pulse, persistent fort damage, supply-budget progression, curator recovery, mobile onboarding, private planner labels, journals, and reconstruction history. The final polish pass added exact score explanations, stale-forecast recovery, canvas-only placement, an unobscured mobile board, and explicit six-planner privacy guidance.

Built With

Share this project:

Updates