Files
Space-Theme/docs/game_rulebook_v1_2.md

14 KiB
Raw Permalink Blame History

Galaxy Forge — game_rulebook_v1_2.md (SSOT) v1.2

Single Source of Truth für Game-Logik, Baukasten-Systeme und Generator-Regeln


0) Zweck & Arbeitsweise (SSOT)

Dieses Dokument ist die Single Source of Truth (SSOT).
Codex/Entwicklung darf nichts implementieren, was dem widerspricht.

Wenn etwas fehlt oder unklar ist:

  1. Default-Regeln in diesem Dokument anwenden,
  2. Entscheidung im Decision Log (am Ende) festhalten,
  3. danach erst implementieren.

1) High-Level Vision

Galaxy Forge ist ein persistentes Weltraum-Browsergame, dessen Inhalte datengetrieben sind:

  • Spieler (und später ggf. User-Designer) erstellen Blueprints (Gebäude, Schiffe, Forschung, Rassen, Spezialisierungen) über einen Baukasten.
  • Blueprints bestehen aus Capabilities (Flags), Effects (standardisierte Bausteine), Requirements, Access Rules.
  • Balance soll möglichst automatisch über ein Punkte-/Budget-System + Auto-Cost funktionieren, um Admin-Aufwand zu minimieren.

2) Kernbegriffe

2.1 Blueprint (universell)

Ein Blueprint ist ein datengetriebenes Objekt mit einheitlichem Schema:

  • kind: building | ship | research | race | specialization | space_object (erweiterbar)
  • key: eindeutiger String
  • name: Anzeigename
  • tags: freie Taxonomie-Strings
  • capabilities: freie Taxonomie-Strings (Flags)
  • effects: Liste standardisierter Effekt-Bausteine (kleine, feste Bibliothek)
  • requirements: Liste standardisierter Requirements (kleine, feste Bibliothek)
  • access: Whitelist/Blacklist nach Race/Specialization (und später ggf. weitere Dimensionen)
  • balance: Budget/Punkte/Auto-Cost (für usergenerierte Inhalte)

Wichtig: Neue Tags/Capabilities/Blueprints müssen ohne Codeänderung möglich sein.
Neue Effect-Typen oder Requirement-Typen erfordern ggf. Code (Engine-Erweiterung) und sind bewusst klein zu halten.


3) Ressourcenmodell

3.1 Ressourcenarten (SSOT)

Galaxy Forge verwendet diese Ressourcen (erweiterbar, aber stabil halten):

  • metal (Metall)
  • alloy (Legierung)
  • crystals (Kristalle)
  • energy (Energie)
  • credits (Credits)
  • population (Einwohner)
  • water (Wasser)
  • deuterium (Deuterium)
  • food (Nahrungsgüter)

Einheiten & Lokalisierung:

  • Interne Berechnung und Speicherung erfolgt in SI-nahem Format (z.B. Temperatur immer in °C als temperature_c).
  • UI darf je Sprache/Setting anzeigen:
    • Fahrenheit: F = C * 9/5 + 32
    • Celsius: unverändert
  • Umrechnung ist reine Anzeige und hat keinen Einfluss auf Serverlogik.

3.2 Zeitbasierte Simulation (serverseitig, authoritative)

Der Server speichert pro Planet:

  • aktuelle Mengen pro Ressource
  • last_resource_update_at

Beim Lesen oder bei Aktionen (Bauen, Abholen, Missionen etc.) muss der Server Ressourcen nachziehen:

  1. dt = now - last_resource_update_at
  2. net_rates_per_hour = calc_net_rates(planet) (Produktion Verbrauch, inkl. Drossel)
  3. amount += net_rates * dt/3600
  4. optional: clamping auf 0..cap (siehe 3.3)
  5. last_resource_update_at = now

3.3 Caps (Speicherlimits)

Caps sind optional pro Ressource und entstehen über Effects (z.B. capacity_add).
Wenn Cap für eine Ressource nicht definiert ist, gilt cap = infinity (Default).
Caps dürfen auch für energy existieren (Batterien).


4) Multiplikatoren-System (Planet + Race + Spec + Research + …)

4.1 Grundsatz

Blueprints definieren Grundwerte (z.B. Mine produziert 50/h).
Der tatsächliche Effekt entsteht durch eine Multiplikator-Kette.

Für eine Ressource r gilt:

effective_value(r) = base_value(r) × Π (1 + bonus_i(r))

  • +10% = +0.10, 15% = 0.15
  • Multiplikation ist Absicht (Synergien, komplexeres Wirtschaften)

4.2 Quellen der Boni (Standard-Kette)

Boni werden gesammelt (Reihenfolge nur für Debug/Anzeige):

  1. Planet (konkrete Planet-Modifier)
  2. Race (Rassenmodifier)
  3. Specialization (Spezialisierungsmodifier)
  4. Research (Forschungsmodifier)
  5. optional später: Events, Artefakte, Offiziere, Allianzboni …

4.3 Separate Behandlung von Produktion & Verbrauch

  • Produktion (produce, convert outputs) und Verbrauch (consume, convert inputs) können getrennte Boni haben.
  • Default: Wenn kein spezieller Bonus existiert, wirkt ein Bonus nur auf das passende Feld (prod vs consume).

4.4 Debug-Breakdown (Pflicht für UI)

Die UI soll optional einen Breakdown anzeigen:

  • Base
  • Planet
  • Race
  • Spec
  • Research
  • Result

Das ist essenziell für Transparenz & Balancing.


5) Weltmodell & Space Objects

5.1 Koordinaten

Koordinaten sind galaxy:system:position (G:S:P).

5.2 Space Objects (Mehrfachobjekte pro Koordinate)

An einer Koordinate können mehrere Space Objects existieren:

  • planet
  • wormhole
  • blackhole
  • station
  • anomaly
  • mission_marker
  • debris_field
  • beacon
  • … (erweiterbar)

Ein Planet ist ein Space Object vom Typ planet.

5.3 Targeting für Flotten/Missionen

Ein Ziel kann sein:

  • target_object_id (bevorzugt) oder
  • (coords + target_type)

Dadurch kann die UI z.B. „anfliegen: Planet / Wurmloch / Station“ auswählen.


6) Planetklassen & Universum-Generator (Constraints + Budget)

6.1 Planetklasse ist „Vorgabe-Regelwerk“

Planetklassen (ice/desert/rock/…) geben dem Generator:

  • Constraints (MUSS): harte Min/Max-Bedingungen für bestimmte Resource-Modifier
  • Bias (SOLL): Verteilungspräferenzen, welche Ressourcen eher hoch/runter gehen

Beispiel (Ice):

  • water immer >= +50%
  • energy immer <= 60%

6.2 Planet-Modifier werden pro Planet gezogen und sind stabil

6.2a Temperatur (einfach, performant)

Jeder Planet hat eine Temperatur als Einzelwert in °C:

  • DB/State-Feld: temperature_c (integer, z.B. -40 bis +80)
  • Planetklasse kann optional temperature_range_c: [min, max] definieren.
  • Der Universum-Generator würfelt die Temperatur deterministisch (Seed) innerhalb des Ranges und speichert sie am Planeten.
  • Wenn kein temperature_range_c definiert ist, gilt Default: temperature_c = 0 (°C).

Wichtig (v1): Es gibt keine Tag/Nacht-Simulation und keine zeitabhängigen Temperaturkurven. Temperatur ist in v1 primär:

  • Anzeige/Flavor (UI)
  • späterer Input für Terraformer/Planet-Anpassung

Damit bleibt die rückwirkende Ressourcenberechnung (z.B. 15 Tage) trivial performant.

Terraformer (später):

  • darf temperature_c verändern (mit Kosten/Constraints),
  • ohne dass der Ressourcen-Tick komplizierter wird, solange Temperatur nicht aktiv in Produktionsformeln genutzt wird. Jeder Planet hat:
  • planet_class_key
  • planet_seed
  • konkrete Modifier-Werte pro Ressource (werden gespeichert)

Warum speichern?

  • Balancing-Änderungen sollen nicht rückwirkend alte Planeten verändern.

6.3 Budget-/Score-System für Vergleichbarkeit

Planeten sollen trotz Spezialisierung vergleichbar sein.

Definiere:

  • Gewichte W[r] pro Ressource (Wertigkeit)
  • Modifier m[r] pro Ressource (z.B. +2.0 = +200%, 1.0 = 100%)
  • Planet-Score S = Σ(W[r] × m[r])

Jeder Planet gehört zu einem Tier mit target_score:

  • normal: S ≈ 0
  • rich: S ≈ +0.4
  • legendary: S ≈ +1.0 (Spawnwahrscheinlichkeiten per weight)

Generator-Regel:
Nach Anwenden der Klassen-Constraints werden die restlichen Modifier so ergänzt/justiert, dass S im Zielbereich liegt (epsilon).

6.4 Ablauf Planetgenerierung (deterministisch)

  1. planet_class anhand spawn_weight wählen
  2. alle m[r] = 0 initialisieren
  3. Constraints anwenden (min/max + ggf. random within range)
  4. aktuellen Score S berechnen
  5. Rest-Modifier verteilen (unter Einhaltung globaler Bounds + Bias), bis Zielscore erreicht
  6. Falls unmöglich: re-roll oder Tier wechseln (SSOT-Default: re-roll bis max N; dann Tier switch)

7) Baukasten-System: Capabilities, Effects, Requirements, Access

7.1 Capabilities (Flags) — frei erweiterbar (Formular-Add)

Capabilities sind freie Strings, z.B.:

  • menu:research
  • menu:bank
  • menu:spy
  • menu:black_market
  • menu:lottery
  • shipyard:small|medium|large|mega
  • defense:orbital
  • terraforming
  • ground:cloning
  • stargate

Regel (Feature Unlock):
Ein Menüpunkt/Feature ist verfügbar, wenn der Spieler mindestens einen Besitz/State hat, der die Capability liefert:

  • meist: mindestens ein Gebäude mit capabilities enthält menu:xyz
  • alternativ: Forschung kann Capability gewähren (grant_capability)

7.2 Effects (kleine, feste Bibliothek)

Der Baukasten erlaubt nur diese Effect-Typen (v1):

  1. produce — +X pro Stunde Ressource
  2. consumeX pro Stunde Ressource
  3. convert — Inputs/h → Outputs/h (z.B. 20 metal + 5 energy → 5 alloy)
  4. capacity_add — Cap +X für Ressource (z.B. Lager, Batterie)
  5. queue_slots_add — zusätzliche Bau-/Queue-Slots (z.B. Bauzentrum)
  6. points_add — +X pro Stunde für Punkt-Ressourcen (z.B. research_points, spy_points)
  7. modifier_add — Additiver Bonus (z.B. +0.02 metal prod) auf Ziel (by_resource/by_tag/by_key)
  8. grant_capability — schaltet Capability frei (v.a. Forschung)

Hinweis: Neue Effect-Typen sind möglich, aber erfordern Code-Erweiterung und SSOT-Update.

7.3 Requirements (kleine, feste Bibliothek)

Der Baukasten erlaubt diese Requirements (v1):

  • building_count (min count eines bestimmten Gebäudes)
  • building_tag_count (min count aller Gebäude mit Tag)
  • research_level (min Level einer Forschung)
  • has_capability (z.B. menu:research muss vorhanden sein)
  • player_race_in / player_race_not_in
  • player_spec_in / player_spec_not_in

7.4 Access Rules (Whitelist/Blacklist) — überall gleich

Zusätzlich oder alternativ zu Requirements können Blueprints access definieren:

  • allowed_races, blocked_races
  • allowed_specializations, blocked_specializations

Regeln:

  • Wenn allowed_* nicht leer → muss enthalten sein.
  • Wenn in blocked_* enthalten → verboten.

Beispiel: Roboter dürfen keine Klonfabrik, aber dürfen Robotik-Werkstatt:

  • clone_factory: blocked_races=["robot"]
  • robot_workshop: allowed_races=["robot"]

8) Gebäude (Buildings) — stackable/levelable und Bauzentren-Queues

8.1 Gebäude-Modelle

Gebäude unterstützen mindestens:

  • stackable: man baut N Instanzen (Count)
  • levelable: ein Gebäude hat Level L (Upgrade) (hybrid ist optional später)

8.2 Paralleles Bauen über Bauzentren

Es gibt ein Gebäude (Blueprint) mit Capability/Effect, das Queue-Slots liefert. Standard: build_center ist stackable und hat Effect queue_slots_add: +1 je count.

Regel:
queue_slots = base_slots + Σ(queue_slots_add effects)
SSOT-Default: base_slots = 0 und mindestens 1 Bauzentrum im Startpaket.

8.3 Bauauftrag (Build Job)

Ein Bauauftrag enthält:

  • planet_id
  • building_key
  • mode:
    • stackable: delta_count
    • levelable: target_level
  • started_at, finish_at
  • slot_index (0..queue_slots-1)

8.4 Start eines Bauauftrags

  1. update_resources(planet)
  2. freie Slots prüfen (active_jobs < queue_slots)
  3. Requirements + Access prüfen
  4. Auto-Cost berechnen (oder config cost)
  5. Ressourcen sofort abziehen
  6. Job anlegen (finish_at)

8.5 Abschluss

Wenn now >= finish_at:

  • stackable: count += delta_count
  • levelable: level = target_level
  • Job entfernen
  • optional: Report/Event

9) Zerstörbarkeit & Bombardierung (Gebäude können zerstört werden)

9.1 Gebäude-Property: destroyable

Gebäude können properties.destroyable haben:

  • Default: true
  • Wenn false, darf Bombardierung dieses Gebäude nicht reduzieren.

Optional:

  • structure (Robustheit)
  • bombard_priority (Zielgewicht)
  • debris_yield (Ressourcenanteil der Kosten als Trümmer)

9.2 Minimalregel (v1)

Bombardierung reduziert direkt:

  • stackable: count sinkt
  • levelable: level sinkt Kein separater Damage-State im v1.

10) Balance für usergenerierte Inhalte: Punkte + Auto-Cost (Anti-Exploit)

10.1 Ziel

User sollen Inhalte bauen können, ohne das Spiel zu brechen. Admin soll nicht jedes Ding manuell balancen müssen.

10.2 Grundregel (Anti-Exploit)

User wählen Effekte, nicht frei Kosten/Zeit.
Kosten/Zeit/Upkeep werden automatisch aus Effekten abgeleitet (Auto-Cost).

Optional gibt es einen Tradeoff-Slider (z.B. „billiger vs schneller“), aber nur in engem Korridor:

  • Default: max ±2 Budgetpunkte oder max ±20% Abweichung.

Damit ist „0 Kosten + lange Zeit“ nicht ausnutzbar, weil Kosten nicht frei sind.

10.3 Budget pro Blueprint-Kategorie

Jede Kategorie hat ein Budget (Startwerte v1, später balancen):

  • building: z.B. 15
  • ship: z.B. 20
  • research: z.B. 12
  • race: z.B. 0 (Summe Traits muss nahe 0)
  • specialization: z.B. 0 (nahe 0)

10.4 Scoring (Power Score)

Jeder Effect trägt Punkte bei, abhängig von:

  • Ressource (über Werttabelle)
  • Art des Effekts (produce/convert/stats/modifier)
  • Inputs (consume) reduzieren Score
  • Constraints/Exklusivität kann Score reduzieren (z.B. „nur race robot“ erlaubt -> leichter Preisabschlag möglich)

Werttabelle (v1, grob):

  • metal: 1.0
  • crystals: 1.2
  • deuterium: 1.3
  • water: 1.1
  • food: 0.9
  • energy: 0.8
  • alloy: 2.5
  • credits: 0.7 (population/points separat)

Die konkrete Score-Formel ist ein Implementierungsdetail, muss aber:

  • deterministisch
  • transparent (UI zeigt Score)
  • nicht trivialisierbar

10.5 Auto-Cost Ableitung (Grundsatz)

cost und build_time steigen monoton mit Score. Optional zusätzlich: upkeep (consume) als natürliche Bremse, statt Hardcaps.


11) Start-Defaults (v1)

  • Universe: 9 Galaxien, 499 Systeme, 15 Positionen (anpassbar per config)
  • Start: 1 Planet pro Spieler
  • Start: 1 Bauzentrum (damit mindestens 1 Queue-Slot existiert)
  • Planetklasse: temperate (oder nach Race preference), aber Generatorregel gilt
  • Gebäudeanzahl: keine Hardcaps (Balance über Kosten/Zeit/Upkeep)

12) Konfig-Dateien (Empfehlung)

  • config/universe.json (Seeds, Dimensionen, Tier-Weights)
  • config/resources.json (Werttabelle, caps defaults)
  • config/planet_classes.json (spawn_weight, constraints, bias)
  • config/blueprints/*.json (Gebäude, Schiffe, Forschung, Rassen, Specs)
  • config/taxonomy_capabilities.json (optional UI-Hilfe/Labels)

13) Decision Log

  • [2026-02-03] v1.0 erstellt: Baukasten-Blueprint-System + Planet-Generator (Constraints+Budget) + Build-Center-Queues + destroyable Flag + Auto-Cost Prinzip.
  • [2026-02-03] v1.2 ergänzt: Planet-Temperatur als gespeicherter °C-Einzelwert, keine Tag/Nacht-Simulation; UI-Lokalisierung (°C/°F Anzeige).
  • [2026-02-03] Default festgelegt: Ohne temperature_range_c gilt temperature_c = 0 (°C).