Files
anekdotin d3bed34c6c Add game mode categories, character creation, on-foot ship/hub mode, RAM currency, and in-ship navigation
Bundles several sessions' worth of previously uncommitted work: map
categories with Domination/Conquest/King of the Hill mode stubs and a
server-list mode filter; a procedurally-drawn character-creation screen
replacing the old callsign-only PROFILE overlay; the on-foot groundwork
(walkable station hub, ship interior, character controller) plus the RAM
currency backend; and today's addition, an in-ship Helldivers-2-style
navigation table that QUICK PLAY's queue/connect flow and the Belters/
Military hub travel now live behind, with hub-and-ship return paths and a
context-aware pause menu usable both in-match and inside the ship.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 12:30:22 -04:00

28 KiB
Raw Permalink Blame History

On-Foot / Ship & Solar System Layer

Planning doc for the Stardew-Valley-style on-foot mode: a walkable layer (your ship, solar-system locations, 2 multiplayer hubs) alongside the existing ship-combat game. This is the working doc for turning the item 29 groundwork (see CLAUDE.md) into something actually playable. Sections below are meant to get filled in / checked off as decisions land — not a finished spec yet, and the vision itself has already changed shape more than once, so treat this as a living document rather than a locked design.

Vision

Two intertwined layers (current thinking, as of this doc's last edit):

  1. Space combat (multiplayer, existing/live) — the ship-vs-ship battles already built (world/world.tscn, GameMode subclasses, matchmaking). This is the money-earning loop: winning/playing matches pays out RAM, the in-game currency (named after EVE Online's ISK — 100% separate from overview/money.md's real-world monetization strategy, confirmed, that doc is about pricing the game itself). Balance is server-authoritative, tracked in matchmaking-api alongside the existing Player.kills/deaths/wins stats rather than trusted client-side.
  2. The Stardew side (new, this doc's scope) — spending RAM and time in a walkable, on-foot layer:
    • Your ship, walked around inside — this is the Stardew farm equivalent, and also the home base (see "Where does it fit in the flow" below — space combat and hub travel both launch from here). Maintenance is broad, not just crops: growing crops (the hydroponics plant-rack furniture already cropped for station_hub.tscn is a natural seed for this), cosmetic decoration, room-based upgrades that matter in combat (see "Ship upgrades = new rooms" below — ties the two layers together mechanically, not just economically), and repairing/ restocking hull, guns, fuel, oxygen, and ammo after combat wear (see "Ship wear, supplies & repair" below). That's 4 systems, not 1 — see the phased plan below for suggested sequencing rather than building all 4 at once.
    • 2 main hubs — Belters (ORC) and Military (ISN). Multiplayer: other players' chosen character sprites (from character creation) are visible walking around, same as the ship-combat side. Also where you buy the supplies that repair ship wear (see below) — this is what ties hub visits into the ship-maintenance loop mechanically, not just thematically.
    • Solar system locations — additional single-player/instanced places to explore beyond the 2 hubs. This is v2, not v1 — see Version Scope below.

Version scope

  • V1 — ship interiors + the 2 main hubs (Belters, Military). Nothing else on foot. This is the whole on-foot surface area for v1: no solar system exploration locations.
  • V2 — additional single-player "cool places to explore" solar-system locations, reachable from the in-ship nav table alongside the 2 hubs (see "Where does it fit in the flow" below). Not scoped further than that yet — revisit once v1 is actually playable.

Multiplayer scope, by location

Location Multiplayer?
Ship combat (existing) Yes — already networked
Your ship interior No — private, single-player/instanced
Belters hub (station_hub.tscn, ORC) Yes — networked, other players' sprites visible
Military hub (military_hub.tscn, ISN art pending — see phased-plan step 3/4) Yes — same as above
Solar system locations (v2, not built) No — single-player/instanced

This means on_foot_character.gd needs to grow two separate modes rather than one: a simple local-only controller (ship interior — what exists today, basically) and a properly networked one for the 2 hub locations (MultiplayerSpawner, position replication, the same predict/reconcile shape ship_movement.gd already has for combat). Worth building the local-only path first regardless (ship interior), then reusing whatever interaction/movement code it establishes for the networked hub pass.

Resolved: station_hub.tscn is the first of the 2 main hubs — the Belters hub (Outer Rim Collective's home turf, see overview/racesclasses.md's ISN-military/ORC-belters split). Its gritty, industrial, patchwork-metal art direction (see Asset Inventory below) fits ORC's established visual identity directly. A second hub for the military (ISN) will be built later — likely wants its own, cleaner/more disciplined tileset+furniture pass to match ISN's gunmetal-gray aesthetic rather than reusing the Belters hub's art wholesale, though the underlying room-building/collider/furniture-placement code (station_hub.gd's approach) should carry over directly.

The ship interior (the Stardew-farm equivalent) is a separate, new, single-player scene — not station_hub.tscn, and not built yet.

Where does it fit in the flow?

Resolved: the ship is the home base, and the specific interaction is settled too. main_menu.gd gets a new entry point (name TBD, e.g. "MY SHIP") that drops the player into their ship interior. Inside, there's a navigation table — Helldivers 2 style: walk up to it, it shows a graph of the solar system, and picking a node is how you travel. For v1 that graph has 3 destinations: space combat (queue/connect, today's QUICK PLAY/SERVER SELECT behavior moves here), the Belters hub, and the Military hub. V2's additional explorable locations (see Version Scope above) are just more nodes on the same graph later — the table doesn't need to change shape, only grow more destinations.

This is a real restructure of the existing menu flow, not an addition alongside it — QUICK PLAY/SERVER SELECT's current straight-into-a-match behavior becomes something reached via the nav table, not a main-menu button. main_menu.gd's QUICK PLAY/SERVER SELECT code itself likely stays close to as-is functionally (still queues/connects the same way); what changes is what calls it — a nav-table node interaction instead of a nav button.

Current implementation state

Everything below predates the "ship interior + solar system + 2 hubs" framing above — it was built as a generic "station hub" proof of concept (item 29) and then given a real character-creation entry point in a later session, before station_hub.tscn was pinned down as specifically the Belters hub (see Vision above). What's actually built and working today (verified via headless screenshot):

  • Character creation (menu/character_preview.gd, menu/character_presets.gd) — 7 pre-composed archetype sprites (Soldier, Marine, Engineer, Laborer, Scavenger, Officer, Heavy Trooper), each with idle + walk frames, picked on the main-menu PROFILE overlay with a live idle/walk preview loop. Stored in GameConfig.player_character_index. This is the only piece with a real menu entry point today.
  • world/levels/station_hub.tscn — one hand-built 12×9 room (station_hub.gd, class_name StationHub), procedurally tiled floor + wall ring with a door gap, 4 static furniture pieces (locker, cabinet, hydroponics plant rack, server console), wall colliders auto-built from whatever's painted on the Walls TileMapLayer.
  • world/levels/on_foot_character.gd (CharacterBody2D) — 4-directional top-down walker, idle/walk sprite swap + flip_h, camera follow. Not networked — single local CharacterBody2D, no MultiplayerSpawner, no server authority. Loads whichever archetype was chosen at character creation via CharacterPresets.get_preset(GameConfig.player_character_index).
  • Not reachable from any menu. The only way to see this scene today is launching station_hub.tscn directly (editor Play, or the --hub-test throwaway autopilot used to verify it — deleted after use, not in the repo).
  • No NPCs, no interaction, no dialogue, no second room/transition.
  • Ship interior (phased-plan step 2 — done)world/levels/ship_interior.tscn
    • ship_interior.gd (class_name ShipInterior), a new single-player/ local-only scene distinct from station_hub.tscn (which stays spoken for as the Belters hub, see Vision above). Reuses on_foot_character.gd as-is for the player controller and station_hub.gd's wall-collider pattern, but not that scene's assets wholesale — no dedicated ship-interior art exists yet, so it's built from the same ORC station tileset/furniture as a placeholder (locker, cabinet, server rack; the plant/hydroponics furniture was deliberately left out, since hydroponics is a purchasable room per the decisions log below, not present on the starter ship). A smaller 8×6 room (vs. the hub's 12×9) to read as a personal ship rather than a public hub. Built procedurally in _ready() (floor/wall TileMapLayer.set_cell() calls, one door gap in the wall ring) rather than hand-authored into the .tscn's tile_map_data, since station_hub.tscn's own layout was originally produced the same code-generated way (see item 29) rather than painted in an interactive editor session. Verified via a throwaway autopilot + headless Xvfb screenshot (same technique as item 29): floor tile variety, the wall ring's door gap, all 3 furniture pieces, and wall-collision (player stops cleanly at the east wall instead of clipping through) all confirmed rendering/working correctly; autopilot and its temporary project.godot autoload entry were removed after. Now reachable from the main menu — see the CONTINUE/NEW entry point below (originally slated for step 3, landed early alongside this step in practice).
  • In-ship navigation table (phased-plan step 3 — done)world/levels/nav_table.gd (class_name NavTable, an Area2D placed in ship_interior.tscn) is a Helldivers-2-style interactable: walking into its range shows a "PRESS E" prompt (new interact input action, E key), and pressing it opens world/levels/nav_table_ui.gd (class_name NavTableUI, CanvasLayer, layer = 20 — same layering convention as TeamSelect/SettingsPanel) — a graph of 3 nodes (SPACE COMBAT, BELTERS HUB, MILITARY HUB) radiating from a center "YOUR SHIP" marker, connected by Line2D routes. A new GameConfig.nav_table_focused flag (same pattern as chat_focused/team_select_focused/ settings_focused) gates OnFootCharacter movement while it's open. SPACE COMBAT is QUICK PLAY's old queue/connect flow, moved here verbatim from main_menu.gd (which lost its QUICK PLAY nav button entirely — NAV_ITEMS is now just ["OPTIONS", "PROFILE", "QUIT"]): NavTableUI owns the NetworkManager.connection_succeeded/failed and MatchmakingClient.match_found/search_failed signal wiring and shows queueing/connecting status inline in the graph panel, then swaps to world.tscn on success. BELTERS HUB/MILITARY HUB are straight change_scene_to_file calls to station_hub.tscn/military_hub.tscn. Caught and fixed one real bug via the autopilot verification below: nav_table_focused was only ever cleared by close(), so picking a destination (which changes scene without closing the panel) left it stuck true forever, silently freezing player movement in every future ship visit — all 3 destination handlers now clear the flag before changing scene.
    • Military hub is a functional placeholder, not a stub (see Decisions below) — world/levels/military_hub.tscn reuses station_hub.gd (class_name StationHub, generic — no ORC-specific logic) and the same ORC tileset/furniture art as station_hub.tscn outright, as its own distinct scene/instance rather than literally reopening the Belters hub. A real ISN art pass (phased-plan step 4) swaps the art later without touching the nav-table wiring.
    • Return paths: a new reusable world/levels/exit_zone.gd (class_name ExitZone, Area2D, exported target_scene) triggers a scene change the instant the player's body enters it — unlike NavTable, which needs an explicit interact press, this matches walking through a doorway. Both hub scenes got one positioned at their existing door sprite, routing back to ship_interior.tscn. menu/pause_menu.gd's "QUIT TO MENU" became "QUIT TO SHIP", changing scene to ship_interior.tscn instead of main_menu.tscn (still disconnects via NetworkManager.disconnect_from_game() first) — the ship is now the only way out of a match, matching its status as home base.
    • Verified end-to-end with a throwaway --navtest-gated autopilot autoload (removed after use, same technique as this doc's other verification notes): a real headless server was hosted and registered with matchmaking-api (confirmed status: "available" via GET /servers), then a windowed client under Xvfb was driven through the full loop — main menu → ship → open nav table (screenshotted, see below) → Belters hub → back to ship → Military hub → back to ship → Space Combat → real matchmaking + connect → in world.tscn → pause menu's quit-to-ship → back in the ship interior — with no errors and the nav_table_focused fix confirmed (focused=false after each hub return, where it previously stuck true).
  • RAM currency backend (phased-plan step 1 — done)Player.ram_kb (BigInteger) in matchmaking-api, credited on POST /matches/report via a tunable participation/per-kill/win-bonus formula (app/config.py, currently 50/15/200 KB — placeholder numbers), returned by GET /stats/{callsign}. Client side: autoload/currency.gd (class_name Currency) formats KB up into KB/MB/GB/TB for display (1000 per step), MatchmakingClient.get_stats() fetches a callsign's balance, and the main-menu profile badge shows it live next to rank/level as a working end-to-end proof (verified via real match-report calls + a headless screenshot — a fresh callsign correctly shows nothing until it has a stats row, an existing one rolls over KB→MB→GB correctly at the 1000 boundary). No spend path yet — nothing to spend it on until the ship interior/hubs below exist. See matchmaking-api/README.md's "RAM (in-game currency)" section for the backend details.

Ship wear, supplies & repair

Combat leaves your ship visibly broken when you're back in the interior — not just a hidden stat. Two related but distinct systems:

  • Repairable damage — things that break and need fixing:
    • Hull — takes damage in combat, needs repair.
    • Guns/weapons — also take damage in combat, repaired separately from the hull.
  • Consumable supplies — things that deplete through play and need restocking, not "broken" so much as "used up":
    • Fuel
    • Oxygen
    • Ammo

Both repairs and supplies are bought at the hubs with RAM — no separate "supplies" currency, it's a RAM purchase like anything else there. This is the mechanic that makes hub visits load-bearing rather than optional: you fight → come home with a damaged hull/guns and depleted fuel/oxygen/ammo → go to a hub and spend RAM → return and repair/restock. Repairing and restocking both take time — not instant on purchase (consistent with crops also being a wait → harvest loop, see Vision above; the ship interior's whole maintenance layer runs on "spend, then wait" pacing, not "spend, get instantly").

Damage formula (resolved): every death in combat randomly drains either the hull or damages the weapons (one or the other per death, picked randomly — not both every time). This accumulates across matches; 50 deaths' worth of accumulated damage fully depletes that system, at which point RAM has to be spent at a hub to repair it. Purely deaths-driven, not tied to damage-taken or match outcome.

Still needs, before it can be built:

  • How fast fuel/oxygen/ammo deplete (a separate formula from the deaths-based hull/gun one above — not yet specified), and what happens if they run out (blocked from queueing another match? a gameplay penalty mid-match?)

This depends on combat generating some persistent-across-matches wear/ consumption state, which does not exist today — ship_movement.gd currently resets health/state fully on every respawn and between matches, nothing survives to be "broken" or "depleted" afterward, and there's no existing fuel/oxygen/ammo concept in combat at all (weapons currently cost energy, which already regenerates freely mid-match per CLAUDE.md item 23 — that's a separate system from this new persistent ammo-supply concept, not to be conflated). That plumbing has to be built as part of this, not assumed already there.

Ship upgrades = new rooms

Upgrades aren't menu-purchased stat tweaks — they're new rooms added onto your ship, walked into like everything else. This is a meatier build than a flat stat upgrade: it means the ship interior can't be one fixed station_hub.tscn-style single room — it needs to support growing its own floor plan as rooms get added, which is a real architectural difference from every other on-foot space in this doc (the 2 hubs and any v2 solar-system stops are all still just fixed single rooms/scenes).

Resolved:

  • A room's only function is granting access to the system it houses — it's a gate, not also a stacking stat/capacity bonus on top of granting access.
  • Hydroponics (crops) is not a starter feature. It's a purchasable room like every other upgrade — the plant-rack furniture already cropped for station_hub.tscn (see Asset Inventory below) is useful reference art for it, but the starter ship doesn't have it until bought.

Still open:

  • What a room being "added" looks like mechanically — a new connected room revealed/unlocked in a pre-built larger ship shell (simpler: author the full possible floor plan up front, gate rooms behind a locked-door-until-purchased flag), vs. actually procedurally attaching/generating new room geometry at purchase time (much harder, and nothing in the codebase does anything like this today — closest analog is station_hub.gd's procedural single-room tile painting, which doesn't generalize to "graft a new room onto an existing layout").

Asset inventory

Source: world/levels/spritesheet.png (a single AI-generated reference sheet — has a source/ jpeg convention like the race art, see CLAUDE.md item 17). Cropped into assets/images/worldsprites/character/, assets/images/worldtiles/, assets/images/worldsprites/furniture/.

Category Used Still on the sheet, uncropped
Characters 7 archetypes × (idle+walk) — appears to be the full set the sheet has — (all 5 character rows are used)
Floor tiles 11 variants → padded/cycled to the 14-slot atlas — (Flooring block fully used)
Wall tiles 6 clean panel variants → cycled to 14 rock/asteroid-wall chunks, 2 blend-mask swatches (not directly usable as tiles as-is)
Doors 1 (plain sliding door) 2 more door variants (open, blast-door), several branded panel doors
Furniture 4 (locker, cabinet, plant rack, server console) bunks (3 variants), desks + chairs, monitor stations, weapon/gear lockers (cage shelving), crates, workbenches, gas canisters, more potted plants, a fish-tank-style prop
Lighting fixtures 0 ~10 wall/ceiling light variants, fully uncropped

Furniture/lighting has a lot of unused headroom for filling out a bigger or second room later — this is not a blocker for anything above, just noting it's there.

Rough phased plan (v1 = ship interior + 2 hubs, nothing else — see Version Scope)

  1. Currency: server-authoritative RAM hookupdone, see "Current implementation state" above and matchmaking-api/README.md. Payout happens via the existing POST /matches/report call (MatchManager's POST_MATCH phase, CLAUDE.md item 26) rather than a new endpoint. Note this landed ahead of step 2 (ship interior) in practice — reasonable since it has no dependency on the ship existing, just needed a balance to exist before anything can spend it later.

  2. Ship interior as its own new scenedone, see world/levels/ship_interior.tscn/ship_interior.gd and "Current implementation state" above. Single-player, local-only, no networking — reused on_foot_character.gd and station_hub.gd's room-building/ collider approach as the starting pattern (not the station_hub.tscn instance itself, which is spoken for as the Belters hub — see Vision above).

    Main-menu entry point into the ship (part of step 3, landed early, same "no dependency" reasoning as step 1 landing ahead of step 2) — done. main_menu.gd's nav gained a dynamic top item, CONTINUE (a callsign/character already exists) or NEW (none yet), replacing the old static NAV_ITEMS first slot; both drop the player straight into ship_interior.tscn (_enter_ship()). NEW reuses the existing PROFILE overlay (_open_profile()'s pending_action param generalized from the old pending_quick_play bool to also carry "enter_ship", alongside the pre-existing "quick_play" case) so a fresh player creates their pilot first, then lands in the ship on Save — same forced-open pattern QUICK PLAY already used for a missing callsign, just a second pending action instead of a second overlay. SERVER SELECT was removed from the main-menu nav entirely (menu/server_select.gd/.tscn left on disk unreferenced, same precedent as the orphaned terran/mech/vorg/ apex asset folders from items 17/19) — no replacement entry point for it yet, since server browsing doesn't have a home on the nav table either until that's built next. QUICK PLAY/OPTIONS/PROFILE/QUIT are otherwise unchanged. Verified via a throwaway autopilot driving main_menu.gd's own _on_continue_pressed()/_on_profile_save() methods directly (same legitimate _-prefixed-access technique as prior sessions) plus headless Xvfb screenshots: NEW label + profile overlay opening with an "enter_ship"-specific hint text, landing in the ship on Save, and the label correctly flipping to CONTINUE back on the menu once a callsign exists.

  3. Navigation table inside the shipdone, see "Current implementation state" above (world/levels/nav_table.gd/ nav_table_ui.gd). QUICK PLAY's queue/connect logic now lives behind the SPACE COMBAT node; Belters/Military hub nodes are the other two. A real server-browsing entry point to replace the removed SERVER SELECT is still not built — no node claims that slot yet, it just isn't reachable from anywhere right now.

  4. Military (ISN) hub — placeholder done, real art pass still open. military_hub.tscn exists and is reachable today, but reuses the Belters hub's ORC art/tileset outright rather than a dedicated gunmetal-gray/disciplined ISN look (see Vision above) — that art pass, and re-skinning this scene with it, is the remaining work here. The room-building code (station_hub.gd) already carries over directly, as expected — no code changes needed once the art exists, just new textures swapped into a cloned .tscn.

  5. Networked pass on both hubs — MultiplayerSpawner, position replication for on-foot characters, reusing whatever the local-only ship-interior controller established in step 2.

  6. Ship wear, supplies & repair loop (see dedicated section above) — the mechanic that actually ties hubs into ship maintenance. Needs combat to generate persistent hull/gun-damage and fuel/oxygen/ammo-consumption state first (none of which exists today — and is distinct from the existing per-shot energy system, CLAUDE.md item 23, which stays as-is), then the broken/depleted states in the ship interior, then repairs/supplies for sale at both hubs, then the wait-time pacing on top.

  7. Cosmetic decoration — the one maintenance system that doesn't depend on the room-upgrade architecture (step 8) or the wear loop (step 6). Can be built any time after the ship interior (step 2) exists.

  8. Room-based upgrades (see "Ship upgrades = new rooms" above) — the heaviest remaining lift, since it needs the ship interior to support a growable floor plan rather than the fixed-single-room approach every other on-foot scene uses. Do this after the fixed-room approach has already shipped for decoration/hubs, so there's a working baseline before taking on the harder architectural problem. Crops live here too now, not as a separate item — hydroponics is a purchasable room like any other upgrade (see "Ship upgrades = new rooms" above), not a starter feature, so it can't ship before the room-upgrade system exists.

  9. V2, not v1: additional solar-system exploration locations as more nav-table nodes. NPCs/dialogue, if still wanted — needs a minimal dialogue/prompt UI that doesn't exist anywhere in the project yet.

Decisions log

  • station_hub.tscn is the Belters (ORC) hub, not the ship interior and not a generic solar-system stop.
  • In-game currency is 100% separate from overview/money.md's real-money monetization.
  • Currency is named RAM (EVE Online ISK-style), server-authoritative in matchmaking-api.
  • Ship is the home base — combat and hub travel launch from inside it, not straight off the main menu, via an in-ship navigation table.
  • The nav table is a Helldivers-2-style solar-system graph; v1 has 3 destinations (combat, Belters hub, Military hub).
  • V1 scope is ship interior + the 2 hubs only. Solar-system exploration locations are v2.
  • Ship wear covers hull damage and gun damage (repairable), plus fuel, oxygen, and ammo (consumable supplies) — bought at the hubs, RAM only (no separate supplies currency), and both repairs and restocking take time rather than being instant.
  • Ship maintenance covers crops + cosmetic decoration + room-based upgrades + repairs/supplies (all 4 planned for v1, sequenced in the phased plan above — not simultaneous, and not blocking the hub/nav-table work).
  • Upgrades are new rooms added onto the ship, not a stat menu — the ship interior needs a growable floor plan, not a fixed single room (see "Ship upgrades = new rooms" above).
  • A room's only function is granting access to the system it houses — not also a stacking stat/capacity bonus.
  • Hydroponics (crops) is a purchasable room, not present on the starter ship — so it's part of the room-upgrade system (phased-plan step 8), not shippable before that system exists.
  • Hull/gun damage formula: every combat death randomly drains the hull or damages the weapons (one or the other, random per death); 50 deaths' worth fully depletes that system and requires a RAM repair at a hub. Purely deaths-driven, not tied to damage taken or match result.
  • NPCs are deferred past the first playable version.
  • Military hub is a functional placeholder (its own scene, reusing the Belters hub's ORC art/script wholesale) rather than locked/coming-soon — playable now, real ISN art swapped in later without touching the nav-table wiring.
  • Belters/Military hub exits and a match's pause-menu quit both route back to ship_interior.tscn (not the main menu) — the nav table is a real hub-and-spoke loop, not a one-way trip. Pause menu's "QUIT TO MENU" is now "QUIT TO SHIP".

Still open

  • A dedicated ISN art pass for the Military hub (gunmetal-gray, disciplined, distinct from the Belters hub's gritty patchwork look) — military_hub.tscn exists and is playable today but is reusing ORC art as a stand-in (see phased-plan step 4).
  • A real server-browsing entry point (the old, now-removed SERVER SELECT) — no nav-table node or other menu surface reaches it yet.
  • Fuel/oxygen/ammo depletion rate/formula (separate from the deaths-based hull/gun formula above), and what happens if they run out (blocked from queueing? a mid-match penalty?).
  • How a purchased room actually gets added to the ship — pre-built shell with locked-until-bought rooms, vs. real procedural attach/generate at purchase time (see "Ship upgrades = new rooms" above; leaning toward the pre-built/locked-room approach as the cheaper build, not decided).
  • Exact list of cosmetic decorations for a first pass — not needed until step 7 of the phased plan.
  • Exact list of purchasable rooms beyond hydroponics (armory for ammo/guns? a fuel-tank room? an oxygen/life-support room?) — not needed until step 8 of the phased plan.