Period: October 26, 2025 Total Commits: 52
Hey — here’s what we’ve been working on. Today’s update pulls the single‑player campaign experience together with sequential progression, a roads system that constrains pathing, a redesigned level browser, and a lot of fixes around placement, pathfinding, and UI. It’s playable, it’s cleaner, and it’s getting there.
What’s New
-
Campaign progression
- We added a proper campaign flow: levels are grouped, you play them in order, and progress is tracked between missions. Victory screens now show a Next Level button (final level shows a clear completion state). Defeat gives you a straight Restart option.
- Campaign cards now summarize difficulty and tags, and expanded views list included levels with estimated time.
-
Level browser redesign
- The browser moved to a split‑pane layout: scrollable list on the left, details on the right. It auto‑selects the first entry and uses a compact difficulty dropdown.
- You can import custom maps directly from files. Validated maps launch immediately into a “custom” play route.
- We also cleaned up main menu visuals and added small square icon buttons for Discord, Twitter, Bluesky, and Reddit for quick hops to community spaces.
[screenshot: split‑pane level browser with campaign details at c06e1fd]
-
TowerStorm Map files (.tsm)
- Maps now use the .tsm extension (TowerStorm Map). The format is the same JSON structure, just a clearer, game‑specific extension.
- The browser, loader, and file pickers prefer .tsm. The manifest remains JSON since it’s the index.
-
Roads and constrained pathing
- Campaign maps can include roads. When roads exist, minions are restricted to them (plus spawns and enemy castles). This gives level designers tight control over route design and pacing.
- Roads auto‑connect and render with correct sprites based on neighbors. They also connect cleanly to castles and spawn areas.
- Towers can’t be placed on roads.
[screenshot: minions following connected road tiles into a castle at 3b5534a]
-
Variable map sizes (centered on the fixed background)
- Campaign maps can be smaller than the full board. We center them on the fixed 31x17 background and mask unused areas so the active playfield is clear.
- Spawns, castles, roads, and grid lines all respect the offset and bounds.
-
Unit selection per mission
- Campaign levels can present a unit selection modal. Maps specify which towers/minions are available; the modal respects “none”, “some”, or “all” as intended.
- This supports mission‑specific loadouts and early‑game teaching moments.
-
Visual feedback upgrades
- The tower placement preview now shows the actual tower icon, tinted for validity (green/yellow/orange/red) instead of a simple box. It’s cached and grid‑snapped for clarity.
[screenshot: tinted tower icon placement preview near a road at 3de8c1e]
-
New VFX for droid deaths
- Added an orange/red death explosion effect to droid‑type minions with a synced 0.5s fade. Health bars hide immediately on death to reduce clutter.
[screenshot: droid death explosion effect in combat at 98a1076]
-
Level editor quality‑of‑life
- New top toolbar for select/force/delete tools; right‑click deselect to jump back to wave settings.
- Auto‑save/auto‑load via localStorage; Open from file with modal errors; Save/Test Map flows with validation; filenames use the map name and .tsm extension.
- Adjustable map dimensions and spawn area width with an accurate, centered grid view.
- Optional per‑castle health (1–1000) for mission tuning.
What Got Fixed
-
Placement, bounds, and gold checks
- Placement previews now reflect the live simulation gold instead of a cached value; indicators correctly show yellow for low gold and red on roads.
- Campaign bounds are enforced, so you can’t place outside the actual map area.
- Fixed a missing player team init that suppressed all placement previews in campaign.
- Adjacency and spawn indicators now query the grid (not static data), so custom castle positions and variable map sizes behave correctly.
-
Pathing and roads
- Roads properly connect to castles and update sprites; a bug from converting already‑integer castle positions was removed.
- We corrected init order so castles update before roads, avoiding spawn blocks and ensuring complete flow fields.
- Towers pre‑placed from waves now update the grid and trigger path recalculation so minions don’t walk through occupied tiles.
- Path‑blocking validation uses campaign‑specific castles/spawn centers, fixing edge cases on offset maps.
-
Offsets, spawns, and visuals
- Map offset rounding switched to whole tiles to avoid half‑tile drift; extra tiles bias to bottom/right consistently.
- Spawn areas position correctly on smaller maps with offsets.
- The tower preview replaces the old box sprite entirely and tints correctly across all validity states.
-
Audio and UI polish
- Victory/defeat sounds no longer double‑play; they hand off cleanly to music and respect volume settings.
- Campaign HUD hides the opposing team panel and focuses the layout for single‑side play.
Under the Hood
-
Campaign map schema and validation
- We built a robust validation layer: strict typing, resource limits, sanitization, and bounds checks. It’s used consistently for browser imports, editor saves, and test mode.
- Metadata moved into individual level files; the manifest now indexes campaigns and difficulty theme info. This removes duplication and creates a single source of truth.
-
Serialization and editor pipeline
- One serializer path feeds localStorage, file saves, and test mode. Wave 0 cleanly separates economy (initial state) from entities.
- The file picker prefers .tsm and validation runs before import/play. Errors surface in a modal instead of alerts.
-
Game loop and pathfinding
- Campaign runs on a requestAnimationFrame loop with delta time for smooth updates and clearer timing. Wave countdowns are visible in the HUD.
- Pathfinding APIs now consume unified castle info, reducing inconsistencies between systems and making recalculations more reliable.
Known rough edges we’ve been watching
- Custom maps mixing tight road corridors and unusual spawn widths can still expose odd path choices. If you see minions bail off a road, send us the .tsm.
- Placement color states depend on live sim gold; if you spot a mismatch, include a clip and your map so we can reproduce.
Thanks to everyone poking at campaign maps and sharing screenshots. The roads system + unit selection has already surfaced some fun mission designs. Keep the feedback coming, especially on placement edge cases and road layouts.