asteroid-logistics
A procedually generated asteroid mining and logistics simulation game built with PixiJS · play asteroid-logistics · devlog
-
v0.34.1 - split building stories
Split the monolithic
BuildingShowcaseStorybook component into individual stories per building type — Habitat, Mine, LandingPad, ProbeFactory, ShipFactory, Spaceport, and Production buildings. Each story lives insrc/components/buildings/with a sharedBuildingDecorator,BuildingShell, anduseBuildingCanvashook for consistent rendering. Renamed “showcase” to “buildings” throughout. -
v0.34 - freighter polish and log indicator
Polished the freighter system with per-spaceport countdown timers and a branded
BuildingIdtype for type-safe building references. Fixed a countdown bypass bug where freighters could skip their departure timer. Added debug controls for freighter transition speed and a dynamic speed multiplier.Added a log count indicator in the top bar with a debounced counter and pulse animation, plus log buffer clearing on page reload with a fix for the clear race condition. Unified entity selection into a single
selectionAtom, dropping the per-domaingetSelectedmethods.Fixed spaceport click area hit detection and added typed showcase component props with branded type Storybook stories.
-
v0.33 - freighters and spaceport
Added spaceport buildings that spawn freighter ships for hauling cargo between asteroids. Freighters have their own behavior system — a state machine that drives ship actions like docking, loading, transiting, and unloading. The ships modal now shows freighters with a find button that pans the camera to the selected ship.
Replaced GSAP with a custom tween engine to eliminate the dependency and gain more control over animation timing. Rewrote the game CLI from a plain JS script to TypeScript with Commander, adding proper error handling and throwing on silent no-ops instead of swallowing them.
Fixed a cascade of issues:
MineMaskdestroy order crash on load, freighter HUD/landing/thrust/pathing bugs, localStorage quota overflow, and PixiJS deprecation warnings. Unified building selection throughBuildingManagerand added a ship scuttle command. Auth errors and debug state now persist in saves. -
v0.32 - CLI expansion and ship fixes
Expanded the game CLI with traversable query methods — you can now browse command groups and drill into entity state interactively. Added the full HTTP bridge between the CLI and the running game.
Ships now persist across asteroid regeneration instead of being lost. Fixed a stale orbit center bug where ships would orbit the wrong point after an asteroid moved, and fixed an orphaned ramp-down animation that was killing landing thrust prematurely. Added
ShipOrbittests to cover the orbit calculation edge cases. -
v0.31 - game CLI and ships modal
Built the
asteroidsgame CLI — a command-line interface that exposes theGame.tsfacade over HTTP via a Vite plugin. The CLI uses agameApiRegistryto map method names to game operations, withresolveParamhandling entity ID resolution andserializeResultformatting responses. This lets me (or an AI agent) inspect and control the running game from the terminal.Added a ships modal accessible from a new icon-based top bar, replacing the old menu button. The modal lists all ships with their current status and location. Blocked keyboard hotkeys while typing in form inputs so ship names and other text fields don’t trigger game actions.
-
v0.30 - production progress and polish
Added a production progress bar to the building HUD showing real-time recipe completion. Selecting a mine now reveals its resource regions on the asteroid surface, making it easy to see what a mine is extracting.
Fixed a mine region rendering artifact when regions were hidden, and fixed the oval hover effect on the menu close button. Made the save menu handle loading states gracefully during save and delete operations.
-
v0.29 - ship jobs and cloud saves
Big day. Added a ship delivery job system — ships can now be assigned jobs to haul resources between asteroids. Moved the ship build button into the factory HUD for a cleaner flow.
Implemented Firebase authentication and cloud saves so game state persists across devices. Fixed several persistence bugs: landing pad reservations lost on reload, landed ship renderers not recreated, buildings lost on cross-machine save/load, and thrust disappearing on return leg transitions.
Migrated the UI from custom styles to Tailwind + Base UI, then further to MUI with the Exo 2 font. Added a curl-able world dump endpoint for inspecting game state from the terminal. The HUD now shows load progress, and the dump output includes resource buffers and ship jobs.
-
v0.28 - session persistence
Added game persistence — asteroids, buildings, and ships now survive across browser sessions via
GamePersistence. Buildings and ships serialize their state on save and restore it on load, so you can close the tab and pick up where you left off.Added
ChemLabandBioReactorproduction buildings. TheProductionManagernow uses proportional resource allocation when multiple buildings compete for the same inputs, preventing starvation.Fixed region labels rendering incorrectly on concave polygons by extracting a proper
calculateLabelPositionutility. Fixed ship selection not working on landing pads, and fixed angled liftoff after a reload where ships were restoring stale rotation state. -
v0.27 - meat production path
Added the meat production path —
CultureVatandSlabCutterbuildings that process raw resources into food. Each has its own visual style and production recipe. The building HUD now shows the active recipe with input and output resources.Fixed the mine resource percentage calculation which was reporting incorrect values, and added boundary rejection so mines can’t be placed where they’d pierce the asteroid edge. Added tests for both mine boundary checks and resource percentage calculations. Fixed regressions in the production and mine HUD displays.
-
v0.26.1 - complexity reduction
Focused on reducing complexity across managers. The biggest win was breaking
ShipManagerapart — extractedlandShipOnPad,spawnShipAtFactory, andtransitionToAsteroidinto their own modules. Each handles a specific ship lifecycle operation that was previously buried in the monolithic manager.Simplified
MouseManager,FogOfWarManager,BuildingManager, andAsteroidManagerby breaking up long methods and reducing nesting. Cleaned upshipAnimationsandAsteroidShaperendering. Extracted alocalToWorldcoordinate transform utility shared across ship operations. -
v0.26 - grouped facade and bug fixes
Refactored
Game.tsinto a proper grouped facade pattern — slimmed it down from a monolithic class to a thin delegation layer that organizes methods into domain groups. ExtractedBuildingManagerfrom the game operations, which took a big chunk of building-related logic out ofGame.ts.Fixed a phantom ship bug caused by a reconcile race condition in
ShipManager, and fixed habitats piercing the asteroid boundary when building basements. Added a dump world data debug button for inspecting the full game state. RenamedGameOperationstoGamethroughout. -
v0.25 - Game.ts facade
Introduced the
Game.tsfacade — a single entry point that exposes the entire game API as organized domain groups (game.asteroids,game.buildings,game.ships,game.buildMode). This replaces the previousGameOperationsapproach with a cleaner grouped API. AddeduseGameas the React hook for accessing it.Separated asteroid rotation into its own atom to fix an FPS regression where rotation updates were triggering unnecessary re-renders. Cleaned up all the migration planning docs (
PLAN.md,RULES.md,STATE-UPDATE.md, etc.) now that the refactor is complete. UpdatedARCHITECTURE.mdto document the new structure. -
v0.24 - atom iteration
Continued iterating on the atom-based state architecture. Refactored
GameOperationsto streamline the API surface and simplifiedAsteroidShaperendering significantly. ExpandedAsteroidManagerto handle more lifecycle responsibilities and addedShipManagertests.Removed the old
generateLandingPadsutility in favour of inline generation within the manager. Slowed down asteroid rotation for a more relaxed feel. Renamed the sync method for clarity across the codebase. -
v0.23 - state migration phases 6-7
Continued the state migration through phases 6 and 7. Extracted all ship animations into a dedicated
shipAnimations.tsmodule and addedanimateDrillDepthfor mine drilling transitions. TheGameOperationsfacade grew substantially — it now handles ship routing, landing toggles, probe queuing and launching, and production management.Simplified entity classes significantly by moving logic up into managers and operations.
Ship,Habitat,Mine,ProbeFactory, and other entities shed their imperative methods in favour of being driven by the operations layer. RemovedAsteroidInventoryandInventoryfrom entities in favour of the newAsteroidStateandShipStatedata types. Added ashipsAtomand expandedbuildingsAtomwith richer building state serialization. -
v0.22 - state migration step 1
Started migrating game state to a proper data layer. Added
BuildingStatetypes that serialize building state into plain objects for the React layer, with abuildingsAtomthat bridges the game engine and UI. IntroduceduseGameOperationsas a React hook to access the game operations facade.Updated all HUD components to consume state through the new atoms instead of reaching into game objects directly. Buildings now expose serialization methods to produce their state snapshots. This is the first step toward fully decoupling the rendering engine from the React UI.
-
v0.21 - architecture refactor
Big restructuring day. Moved all game entities and managers under
src/game/core/and introduced aGameOperationsfacade that provides a clean CQRS-style API for the React layer to interact with game state through Jotai atoms. This separates selection state management from the game engine — atoms now derive fromGameOperationsrather than reaching into managers directly.Slimmed down
GameManagersignificantly by delegating responsibilities to the new operations layer. Removed the old E2E tests and callback bridge in favour of the new architecture. Added unit tests forHabitatandMineentities with test helpers for creating game and asteroid instances.Fixed mine hole cleanup when a mine is destroyed. Merged the separate vitest config into the main vite config and suppressed PixiJS deprecation warnings.
-
v0.20 - production system
Built the production system. A
ProductionManagerruns recipes that transform input resources into outputs over time, with progress bars on buildings. Added three new production building types —AlgaeTank,BlockFormer, andCentrifuge— each with their own visual style. Buildings that produce resources now track anInventoryand feed into anAsteroidInventorythat aggregates everything per asteroid.Refactored the monolithic
Hud.tsxinto separate components:AsteroidHud,BuildingHud,ShipHud, andLevelControls. Added a confirmation modal for destructive actions like the new destroy button on the building HUD.Region labels now render at zoom-independent sizes so they’re always readable. Made the mine mask translucent in region view mode. Added an
AsteroidDebugpane with a dump button for inspecting asteroid state, and extracteddrawDrillShapeinto a shared utility. -
v0.19 - habitat controls and polish
Added habitat level controls — build up and down to grow or shrink habitat towers, plus demolish controls to tear levels back down. Landing pads are now toggleable so you can enable or disable them. Both are controlled through the HUD when the building is selected.
Made the asteroid field circular instead of the previous rectangular distribution, which looks much more natural. Added a toggleable FPS counter widget and a pointer debug pane for tuning glow settings on selected entities. Fixed the selection glow animation and click feedback. Added a ships debug toggle to the debug panel.
-
v0.18 - probes and drilling
Christmas day coding session. Added probe factory buildings that queue and launch probes to explore the asteroid surface, expanding the fog of war. The
ProbeManagerhandles probe lifecycle from launch to landing, with a debug panel for tuning probe parameters.Mines now have drill depth controls displayed in the HUD — you can drill deeper or shallower, and a
MineMaskoverlay shows the resource percentage being extracted at the current depth. The intersection area calculation figures out how much of each Voronoi resource region falls within the mine’s drill radius.Limited camera zoom-out to the revealed fog area so you can’t zoom past the explored regions. Extracted shared button and menu styles into their own modules and refactored
BuildMenuto use them. -
v0.17 - building selection
Added building selection — clicking a building now selects it and shows its details in the HUD. Extracted a shared
SelectionBehaviorto handle the selection logic across all building types (habitats, mines, landing pads, ship factories). Each building’s draw function now renders a selection highlight when active.Fixed a bug where asteroids would disappear on hover due to a rendering issue in
AsteroidShape. Also improved theMouseManagerto properly handle click targets across buildings and other entities. -
v0.16 - mine buildings and voronoi regions
Added mine buildings to the build menu. Mines reveal the resource regions beneath them using a
MineMaskwith a darkened fill overlay that masks the fog-of-war over the mined area. The region reveal creates a nice exploration feel where you discover what resources are under each segment.Switched the region generation algorithm to use Voronoi tessellation, which produces much more natural-looking resource distributions. Borders between adjacent regions of the same resource type are now hidden so contiguous deposits read as a single area. Extracted shared utilities like
drawPolygonPathandregionEdgesinto their own modules. -
v0.15 - resource regions
Started building the mineral discovery and extraction system. I added resource types and two region generation algorithms — a basic one that creates simple contiguous regions and a more sophisticated generator that produces organic, overlapping resource distributions across asteroid surfaces. A
RegionsOverlayrenders the regions visually and aResourcesDebugpanel controls the generation parameters across all asteroids.Set up Playwright for e2e testing with an asteroid screenshot test that captures the rendered asteroid for visual regression. Added
.nvmrcfor consistent Node versions.Fixed build mode breaking after zoom-to-asteroid and added auto-zoom to the first asteroid on startup. Extracted
selectAsteroidByNameinto its own state module. -
v0.14 - ship factory
Added a README to the project. Set up the browser to open automatically on dev server launch.
Fixed ship visibility when fog is disabled and fixed fog resize when the window resizes. Added ship factory buildings with orbit exit debugging - buildings that produce new ships!
Improved the orbit system: buildings now show their exit points, ship orbits update when clearance changes, and the orbit entry calculation is shared for pad takeoff. Tuned thrust behavior - reduced thrust during liftoff rotation and added thrust ramp-down on orbit entry.
Fixed a janky issue with multi-ship transitions. Split WorldDebug into separate panels for better organization. The ship factory now has a proper build queue system, and ships reinitialize correctly when asteroids regenerate.
-
v0.13 - building placement
Set up VS Code launch configuration for debugging.
Zoom now centers on the current selection or cursor position rather than the viewport center - much more intuitive. Fixed selection box strokes to render correctly at all zoom levels.
The big feature was the building placement system! You can now place structures on asteroids.
-
v0.12 - fog of war and HUD
Implemented fog of war! Used a smoke effect with soft noisy edges that looks great. Added a debug tool for revealing fog and an animation that reveals from the edges. The fog panel has a reset button for testing.
Added a HUD system using Jotai for state management. Asteroids now display their names, and selected ships show in the HUD. Fixed ship selection stroke rendering gaps and clamped keyboard zoom to stay within limits.
Did some deployment fixes - trailing slash redirects, renamed the page title, and switched to relative base paths for assets.
-
v0.11 - controls and visual polish
Added full keyboard support - arrow keys and WASD for panning, Q/E for zooming.
Visual improvements were the star of the show today. Added a parallax starfield with subtle glow effects in the background - really sells the space vibe. Added hover glow for selectable items so it’s clear what you can interact with.
Ships got a lot of love: they now rotate toward their target on liftoff, have thrust particle effects during flight, ramp down thrust when arriving at orbit, and the orbit-to-path transition is smoother. Also optimized the orbit path to landing pad routing.
-
v0.10 - CI/CD and landing pads
Cleaned up unused methods and tweaked member accessibility modifiers in the code. Set up Netlify for CI/CD deployment - the game is now live on the web!
The main feature was the ship landing pad system. Ships now have designated spots to land on asteroids, with proper entry point calculations for approach. This makes the docking feel much more intentional.
-
v0.9 - selection fix
Fixed ship click behavior - clicking a ship now properly deselects others instead of adding to the selection.
-
v0.8 - MouseManager and multi-selection
Created a
MouseManagerto centralize all mouse handling - selection, panning, zooming, and clicking are now in one place. Moved path interaction into it as well. Right-click on an asteroid now moves selected ships there.Did a bunch of renaming for clarity:
SavedPairsManagerbecameSavedRoutes,GameViewportbecameGameManager. Replaced all hardcoded colors with the open-color palette for consistency.Fixed several bugs: multi-ship movement on right-click, ship snap-back at end of path, and clamped zoom/pan to world bounds so you can’t scroll into the void.
Refactored Asteroid into its own directory, extracted path animation and geometry helpers, and added jscpd for detecting duplicate code. Made ship pathfinding async with a cached graph for better performance.
-
v0.7 - architecture improvements
Added style linter rules to Biome for consistent code formatting. Refactored the pathfinding code into proper modules and renamed files to match their export names.
The big user-facing feature today was ship selection and click-to-navigate. You can now click a ship to select it, then click on another asteroid to send it there. Also made it so each asteroid spawns with its own ship.
-
v0.6 - cleanup
Cleanup day. Removed the refactor checks that were getting in the way, deleted old unused scripts, and reorganized the debug systems. Moved PathDebug into a dedicated path directory and WorldDebug into a world directory.
Cleaned up dependencies and quieted down the test output. Much tidier codebase now.
-
v0.5 - arc tangent pathfinding
Continued the pathfinding work. Implemented
arcTangentPathFinderfor smoother curved paths. Added persistence for path debug points and save/restore functionality for debug pairs.The big improvements were internal tangents support, precomputing the tangent graph for performance, and making pathfinding async so it doesn’t block the main thread.
Simplified the orbit system by replacing elliptical orbits with circular ones - less realistic but much easier to reason about for pathfinding. Removed the Dubins path approach in favor of the arc tangent system.
Added ship transitions between asteroids with GSAP easing for smooth animations. The transition now has a pre-tween to the path start, smooth orbit-to-path transitions, and ships can be interrupted mid-flight. Also added a station visibility toggle for debugging.
-
v0.4 - pathfinding deep dive
Massive session today. Fixed a blank screen bug that was preventing asteroids from generating on init, then dove deep into the pathfinding system.
Added debug visualization for paths which was essential for debugging. The path finding went through several iterations - fixed external tangent line calculations, corrected arc directions, improved the algorithm with proper tangent points. I extracted a dedicated
tangentPathFindermodule to keep things clean.Also added persistence for debug pane values (finally!), set up a commit message validation script, and created slash commands for the dev workflow. Added test cases for the pathfinding edge cases I discovered.
Ships can now transition between asteroids which is a huge milestone!
-
v0.3 - stations and orbits
Big day! I added landing stations on asteroids and implemented an orbit system so objects can circle around asteroids. This is the foundation for how ships will approach and dock.
Also set up the verify script for code quality checks and added the first ship entity. Left things in a work-in-progress state with some rough edges to polish later.
-
v0.2 - zoom fix
Quick fix today - the zoom functionality was broken and needed some attention. Not glamorous work but necessary.
-
v0.1 - project genesis
Today I kicked off the Asteroid Logistics project. Started with the basic scaffolding - got the initial project structure in place, added a viewport system for handling the game canvas, and integrated Tweakpane for debugging controls.
The main focus was getting asteroids rendering properly. I implemented the core asteroid entity with configurable radius and rotation. Added interactivity so you can click on them, and then expanded to support multiple asteroids in the world. Feels good to have something tangible on screen already!