# Galaxy Forge — game_rulebook.md (ARCHIV) **Hinweis:** Maßgeblich als SSOT ist ab jetzt `docs/game_rulebook_v1_2.md`. Dieses Dokument bleibt nur als Archiv erhalten. *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) ### 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 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) ### 6.5 Temperatur 1) Planet hat Feld temperature (z.B. integer °C) 2) Planetklasse kann temperature_range haben (min/max) 3) Generator würfelt Temperatur deterministisch (Seed) innerhalb Range --- ## 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) `consume` — −X 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) Architektur-Pflichten: Modularität wie Drupal (Slim-Backend) ### 13.1 Grundsatz: Alles ist ein Modul Das Projekt wird **modular** aufgebaut. Jede fachliche Domäne liegt in einem eigenen Modul. Beispiele (nicht abschließend): - `Module\Auth` (Login/Registrierung/Sessions) - `Module\Users` (Profile, Gruppen) - `Module\Permissions` (Rechte/Policies/Middleware) - `Module\Blueprints` (Baukasten: Blueprints, Taxonomie) - `Module\PlanetGenerator` (Planetklassen, Generator, Seeds) - `Module\Economy` (Ressourcen-Tick, Multiplikatoren) - `Module\BuildQueue` (Bauzentren, Jobs, Finalize) - `Module\Universe` (Space Objects, Koordinaten, Generator-Admin) - `Module\Admin` (Admin UI/Tools, sofern getrennt gewünscht) **Pflicht:** Neue Features müssen einem Modul zugeordnet werden (oder neues Modul erstellen). Keine „God-Classes“ im globalen Namespace. ### 13.2 Technische Leitlinien (Slim + PSR) Backend basiert auf **Slim** und PSR-Standards: - PSR-4 Autoloading (Composer) - PSR-7 Request/Response - PSR-15 Middleware - PSR-11 Container (DI) **Modulstruktur (Empfehlung):** Jedes Modul kann enthalten: - `Routes.php` (Registriert Endpoints) - `Controller/` (Request-Handler) - `Service/` (Business-Logik) - `Domain/` (Entities/Value Objects) - `Repo/` (DB Zugriff) - `Policy/` (Permission Checks) - `Migrations/` (optional; oder zentral, aber mit Modul-Prefix) - `Tests/` (unit + integration) ### 13.3 Routing-Pflicht - Jedes Modul registriert seine Routen selbst (z.B. `Module\X\Routes::register($app)`). - Jede Route muss: 1) Auth-Middleware (wenn nötig) 2) Permission-Middleware (wenn nötig) 3) Input-Validation (Schema) enthalten. ### 13.4 Server-Authority-Pflicht Auch wenn UI Buttons versteckt werden: - **Die Server-API ist die letzte Instanz.** - Jede kritische Aktion muss serverseitig Permissions prüfen. --- ## 14) Permission-System (feingranular + negative permissions) ### 14.1 Ziel Ein Drupal-artiges, feingranulares System: - Permissions sind **Strings** - gehören logisch zu einem Modul - steuern UI (Knöpfe/Seiten) und API (Actions) - unterstützen **negative Permissions** (Deny/Override pro User) ### 14.2 Permission-Namensschema (Pflicht) Permission Keys verwenden das Schema: - `..` Beispiele: - `planet.admin.generate` - `planet.admin.regen` - `planet.public.view` - `blueprints.admin.add` - `blueprints.public.suggest` - `forum.public.read` - `forum.public.write` **Pflicht:** Jede Permission wird einem Modul zugeordnet und im Modul registriert (z.B. `Module\PlanetGenerator\Permissions::definitions()`). ### 14.3 Rollen/Gruppen + User Overrides Es gibt: - **Roles/Groups** (Benutzergruppen): erhalten allow-Permissions - **User Overrides**: erlauben explizit `allow` oder `deny` pro Permission **Regel der Auswertung (Pflicht, stabil):** 1) Wenn User eine **explicit deny** für Permission hat → **verboten** 2) Sonst wenn User eine **explicit allow** hat → erlaubt 3) Sonst wenn eine seiner Rollen die Permission erlaubt → erlaubt 4) Sonst → verboten **Deny gewinnt immer**, außer bei einem optionalen Sonderfall: - `system.superadmin` (wenn aktiviert) kann deny ignorieren (SSOT-Default: Superadmin existiert, aber nur manuell setzbar). ### 14.4 Negative Permissions (Beispiele) - Gruppe „Spieler“ hat `forum.public.read` und `forum.public.write` - User spammt: Admin setzt User Override `deny forum.public.write` → User kann weiter lesen, aber nicht schreiben. Genauso für: - Vorschläge neuer Gebäude: `blueprints.public.suggest` - Chat/PM: `comms.public.send` ### 14.5 Permission-Middleware (Pflicht) Jede geschützte Route nutzt Permission Middleware, z.B.: - `requirePermission('planet.admin.generate')` UI darf Buttons nur zeigen, wenn: - `can(user, permission)` true Aber: UI ist nur Komfort. Server prüft immer. ### 14.6 Datenmodell (Minimal) Empfohlenes DB-Modell: - `roles (id, key, name)` - `permissions (id, key, module, description)` - `role_permissions (role_id, permission_id)` (allow-liste) - `user_roles (user_id, role_id)` - `user_permission_overrides (user_id, permission_id, effect)` - `effect` in `{allow, deny}` Optional: - Cache-Tabelle oder Cache-Layer für „effective permissions“ pro User (Performance). ### 14.7 Auditing (Empfehlung) Für Admin-Aktionen (z.B. Universe regen) sollte es ein Audit-Log geben: - `audit_log (who, what_permission, action, target, at, metadata)` --- ## 15) 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.1 ergänzt: Slim-Modul-Architektur + Drupal-artiges Permission-System inkl. deny Overrides.