melsom.dev

A browser-based incremental tower defence + factory game. Build a refining chain, automate ammo production with conveyor belts, and defend your HQ from escalating waves of enemies. Works on desktop and mobile.

orbit-fd

PixiJS Version

Orbit — Unreleased Version Notes

Orbit is a browser-based tower-factory defence game built on PixiJS 8. Below is how the current (unreleased) build plays and how the pieces fit together.

Changes from original

Instead of basic JS rendering, the game has been migrated to PixiJS - The HTML5 Creation Engine.

Optimized for large waves and more particles.

Fully customizable with retexturing, animations, VFX, particles and more.

Alternative textures and animations
Example of custom textures and animations

Loop

  1. Prep phase (30s countdown, labelled First wave in / Next wave in). Final 5s show a large center-screen countdown with rising beeps and a heavier "GO" tone at 1.
  2. Wave: enemies spawn from the map edge and push toward HQ. Round 1 gets a grace pass — enemies move at 40% speed so new players can bootstrap.
  3. Wave clear: a modifier picker appears with 3 cards. Each card is a trade-off (buff + opposing debuff) shown as a qualitative description. Stacking the same modifier upgrades its tier; every 5 stars merge into a larger tier star on the HUD badge row.
  4. Map radius grows each round up to 250 tiles (was 20 — effectively unbounded past round ~100).

Economy

You start with 50 ◆ ore and nothing else. The plate/power counters are gone from the HUD — only ore is shown, with a bigger standalone read.

Chain: ore node → Harvester → conveyor → HQ (refines ore → plates) → conveyor → Plants → conveyor → Turrets.

  • Harvesters (5◆) sit on 2×2 ore-node footprints and run a 96-frame drill loop that freezes when the node depletes. Ore nodes hold 400 units.
  • Refinery (12◆) converts ore → plates.
  • Bullet Plant (10◆) / Missile Plant (20◆) consume plates and emit ammo.
  • Turrets (Gun 15◆, Missile 30◆, Laser 40◆) hold 10 ammo max (Gun base 20 rounds — each delivered bullet counts as 2 shots).
  • Power Plant (15◆) covers a Chebyshev square: 2-tile base range, up to ~4 tiles fully upgraded. Lasers within range draw power; multiple plants stack their coverage.
  • Resource-node seeding happens every 5th round only, so nodes are scarcer than before.
  • Ore pickups appear when you demolish a belt/splitter carrying cargo — drag them to salvage.
  • Manual harvesting: drag an ore node onto HQ to bootstrap (plays pickup/deposit SFX).

Belts & routing

  • Conveyors (1◆) can start as a corner directly off a building, and must align with the tile they receive from.
  • A building's output requires the belt to flow directly away (straight or corner), and only into transport tiles (conveyor / splitter) — no direct building-to-building.
  • Splitters are conversions on the upgrade FAB when a conveyor is selected. Input is from below, splits left/right. Producers with multiple outputs round-robin clockwise.
  • Belt textures scroll at conveyor speed; items ride upright on top; corners wrap the straight texture via slice-sampling; junctions, T's and crosses use the textured belt too.

Turrets

  • Gun is now a minigun: 12.5 shots/sec, 2 dmg, thin tracers, per-turret looping fire SFX (individually pan-localized), muzzle-flash gated on the aim state (not target-acquired).
  • Missile turret has a sprite base + rotating head, exhaust FX, sprite-based explosions, and mid-flight retargeting if the original target dies.
  • Laser turret shares one continuous hum across all lasers (no stacking pulses) with a smaller, tighter muzzle flash.
  • Turret turn rate is capped, and a new Greased Gears modifier raises it.
  • Gun and missile turrets pick one of three exclusive upgrade paths on first upgrade.
  • All factory & turret buildings have a floating upgrade FAB that docks next to the current selection; buttons are icon-only (no tier stars or cost text). Upgrades are gated behind a lock until unlocked.

HUD & UX

  • Wave modifiers show as a badge row under the HUD; HQ speed / storage moved out of the upgrade tree and became opposing wave-clear modifier pairs.
  • Pause overlay is opaque; hosts music + SFX sliders (drag to 0 to mute) and the leaderboard.
  • Intro always shows at session start and keeps the game paused until dismissed.
  • Mobile: build menu is 5-per-row, sits above browser bottom UI overlays, and uses visualViewport.height → --vh for Vivaldi/Firefox. Info panel is a bottom-sheet.
  • Reset-view (⌖) button auto-fits the camera.

Audio

  • Sampled SFX for laser, missile launch, and explosion (laser/missile/explosion volumes are halved from earlier builds).
  • Stereo-panned by world position relative to the camera viewport.
  • Theme music (resources/music/orbit-theme.mp3) loops at a default 2% volume; file is gitignored and uploaded to the server manually — game works silently if missing.

Scoreboard

  • Postgres-backed API behind nginx + systemd. On game-over you can submit a name; leaderboard renders in game-over and on the pause screen.

Dev mode

  • Konami code toggles HQ invincibility + infinite resources. Any run touched by dev mode is tainted (no scoreboard entry); a second Konami ends the run.

File layout

  • index.html — DOM shell (HUD, menus, overlays), cache-busted ?v=160 script tags.
  • js/config.js — all balance numbers.
  • js/state.js — game state, modifier registry.
  • js/world.js — grid, tile logic, building/belt placement rules.
  • js/entities.js — enemies, projectiles, turret behavior.
  • js/render.js + js/textures.js — PixiJS pipelines: tiled terrain, muzzle flash, laser beam, sprite atlases.
  • js/input.js — pointer/keyboard, drag, upgrade FAB positioning.
  • js/sound.js — sample cache, pan/volume, per-turret loops.
  • js/scoreboard.js — leaderboard API client.
  • js/main.js — boot + game loop.