sim: deltoid-loop D3 pitch economy

This commit is contained in:
deltoid-loop 2026-09-07 01:17:41 +02:00
parent 8419b35ba7
commit 37460e86c1
4 changed files with 102 additions and 0 deletions

1
game/__init__.py Normal file
View file

@ -0,0 +1 @@
"""Pitchwell game package (sim stubs; no Godot required)."""

13
game/sim/__init__.py Normal file
View file

@ -0,0 +1,13 @@
"""Godot-less Pitchwell sim stubs."""
from .pitch_economy import Economy, SumpWell, Worker, START_PITCH, WORKER_LOAD, WELL_CAPACITY, SEEP_PER_SEC
__all__ = [
"Economy",
"SumpWell",
"Worker",
"START_PITCH",
"WORKER_LOAD",
"WELL_CAPACITY",
"SEEP_PER_SEC",
]

67
game/sim/pitch_economy.py Normal file
View file

@ -0,0 +1,67 @@
"""Pitch economy stub — numbers from docs/GAMEPLAY.md (Sump Wells / Start / Carry)."""
from __future__ import annotations
from dataclasses import dataclass, field
# GAMEPLAY.md: Start 500 Pitch
START_PITCH: float = 500.0
# GAMEPLAY.md: Worker load 100
WORKER_LOAD: int = 100
# GAMEPLAY.md: Sump Wells finite 2500, seep +0.4/s while claimed
WELL_CAPACITY: float = 2500.0
SEEP_PER_SEC: float = 0.4
@dataclass
class SumpWell:
"""Finite Pitch node. Claim via finished refinery in radius (GAMEPLAY.md)."""
remaining: float = WELL_CAPACITY
claimed: bool = False
has_refinery: bool = False
def claim_via_refinery(self) -> None:
"""Claim well by finishing a refinery flag (GAMEPLAY.md)."""
self.has_refinery = True
self.claimed = True
def tick_seep(self, dt: float) -> float:
"""Seep +0.4/s while claimed; depletes remaining. Returns Pitch extracted."""
if not self.claimed or self.remaining <= 0.0 or dt <= 0.0:
return 0.0
extracted = min(self.remaining, SEEP_PER_SEC * dt)
self.remaining -= extracted
return extracted
@dataclass
class Worker:
"""Carry load 100 (GAMEPLAY.md). Stub — load cap only for now."""
load: int = 0
capacity: int = WORKER_LOAD
def can_pick(self, amount: int) -> int:
return max(0, min(amount, self.capacity - self.load))
@dataclass
class Economy:
"""Faction Pitch pool + claimed wells."""
pitch: float = START_PITCH
wells: list[SumpWell] = field(default_factory=list)
def add_well(self, well: SumpWell | None = None) -> SumpWell:
w = well if well is not None else SumpWell()
self.wells.append(w)
return w
def tick(self, dt: float) -> float:
gained = 0.0
for w in self.wells:
gained += w.tick_seep(dt)
self.pitch += gained
return gained