requirements clarifications
This commit is contained in:
@@ -23,16 +23,11 @@ This split is enforced at the CMake target level (see below). Tests link only ag
|
||||
|
||||
The simulation advances in discrete ticks. All game quantities — production timers, belt item progress, threat accumulation, wave timers, ship cooldowns — are measured in ticks, not wall-clock seconds.
|
||||
|
||||
- Tick rate: fixed at 30 Hz.
|
||||
- The outer loop advances `N` ticks per wall-clock frame, where `N` is derived from the selected game speed:
|
||||
- 0× → 0 ticks/frame (pause)
|
||||
- 0.5× → one tick every two frames
|
||||
- 1× → one tick/frame
|
||||
- 2× → two ticks/frame
|
||||
- 4× → four ticks/frame
|
||||
- Tick rate: fixed at 30 Hz; `tickDurationMs = 1000 / 30 ≈ 33.33`.
|
||||
- Ticks are driven by an accumulator that is independent of the render rate. Each render frame, the driver adds `elapsedWallMs × gameSpeedMultiplier` to an accumulator and flushes one `tick()` per `tickDurationMs` of accumulated time (so multiple sim ticks may run between frames at high speeds, or a frame may run no ticks at low speeds). `gameSpeedMultiplier` ∈ {0, 0.5, 1, 2, 4} per REQ-UI-SPEED; 0× freezes the accumulator (pause). The concrete driver lives in the Rendering section.
|
||||
- Config-level durations given in seconds (recipe durations, wave gap ranges, scrap despawn, etc.) are converted to ticks at config-load time.
|
||||
|
||||
Consequences: determinism, replayability, and the time-scale feature falls out for free.
|
||||
Consequences: determinism, replayability, and the time-scale feature fall out for free. The simulation advances the same number of ticks over the same amount of game-time regardless of whether the game renders at 60 FPS, 30 FPS, or a stuttery mix.
|
||||
|
||||
## Config Loading
|
||||
|
||||
@@ -56,7 +51,7 @@ See REQ-GW-COORDS for the authoritative tile-coordinate convention. This section
|
||||
|
||||
Simulation types shared across subsystems:
|
||||
|
||||
- `EntityId` — strictly increasing integer handle, allocated centrally by the simulation. Used for ships and scrap drops. Buildings are addressed by their anchor tile, not by `EntityId`.
|
||||
- `EntityId` — strictly increasing integer handle, allocated centrally by the simulation. Assigned to every targetable entity: ships, scrap drops, **and** buildings (including HQ and defence stations). Buildings additionally retain their anchor tile for spatial lookups and placement; the `EntityId` is the canonical reference used by ship-component target fields (`Weapon.currentTarget`, `RepairTool.currentTarget`, `ThreatResponse.currentTarget`, etc.), so a combat ship can target either another ship or a defence station uniformly.
|
||||
- `Rotation` — enum `{ North, East, South, West }`. The rotation applied to a building's surface_mask when placed.
|
||||
- `BuildingType` — enum covering every building type in requirements.md (Miner, Smelter, Assembler, ReprocessingPlant, Shipyard, SalvageBay, Belt, Splitter, Hq, PlayerDefenceStation, EnemyDefenceStation).
|
||||
- `ItemType` — tagged id of every transportable material (ores, ingots, intermediates, building_blocks, scrap).
|
||||
@@ -152,13 +147,17 @@ Buildings are plain structs with a fixed type determined at construction.
|
||||
|
||||
```cpp
|
||||
struct Building {
|
||||
EntityId id;
|
||||
QPoint tile;
|
||||
QSize footprint;
|
||||
Rotation rotation;
|
||||
BuildingType type;
|
||||
float hp; // relevant for HQ and defence stations; ignored otherwise.
|
||||
float maxHp;
|
||||
InputBuffer inputBuffer;
|
||||
OutputBuffer outputBuffer;
|
||||
// Production timer and current recipe, where applicable.
|
||||
// Production timer, the recipe currently running, and — for reprocessing
|
||||
// plants — the output item picked at cycle start (REQ-MAT-CYCLE).
|
||||
std::optional<Production> production;
|
||||
};
|
||||
```
|
||||
@@ -167,6 +166,21 @@ struct Building {
|
||||
- Belts and splitters are separate types owned by the belt subsystem, not general `Building` instances.
|
||||
- No ECS for buildings. A miner is never also an assembler; there is no composition benefit to decomposing buildings into components.
|
||||
|
||||
## Scrap
|
||||
|
||||
Scrap is the only non-ship, non-building entity in the simulation:
|
||||
|
||||
```cpp
|
||||
struct Scrap {
|
||||
EntityId id;
|
||||
QVector2D position; // world units, tile-fractional; ship-center convention
|
||||
int amount;
|
||||
Tick despawnAt; // absolute tick at which the scrap is removed
|
||||
};
|
||||
```
|
||||
|
||||
Created in tick step 9 (Deaths & loot) per REQ-RES-SCRAP-DROP, consumed by salvage ships in tick step 7 (ScrapCollector), and removed in tick step 11 when the current tick reaches `despawnAt`.
|
||||
|
||||
## Ships
|
||||
|
||||
Ships follow a component-composition model using `std::optional<Component>` members. Each orthogonal capability is a component; each behavior is also a component, ticked by its own system. A ship's "role" is just which components it has — not a class or an enum.
|
||||
|
||||
Reference in New Issue
Block a user