# Cross-GDD Review Report > **Date**: 2026-04-30 > **Reviewer**: Claude Code (consistency + design theory agents) > **GDDs Reviewed**: 6 (node-system.md, tower-assembly.md, shop.md, event-system.md, progression.md, CombatNodeArchitecture.md) > **Systems Covered**: Node System, Combat System, Tower Assembly, Shop System, Event System, Progression --- ## Consistency Issues ### Warnings ⚠️ **[C-W1] Tower Assembly Dependency Direction Is Inverted** - **Files**: `tower-assembly.md` (Dependencies, line 207) - Tower Assembly lists **Node System as an upstream (hard) dependency** — but the relationship is reversed. Node System **calls into** Tower Assembly during Assembly Phase. Tower Assembly is the **downstream** service, not the upstream. - **Correct model**: Node System → (calls) → Tower Assembly. Tower Assembly is downstream. - **Impact**: Logical error in dependency model. Does not block implementation. - **Fix**: Swap direction — Tower Assembly should list Combat System as downstream consumer, and remove Node System as upstream dependency. ⚠️ **[C-W2] RunStats.goldEarned Loss-Path Contract Not Formally Sealed** - **Files**: `node-system.md` (Edge Cases), `progression.md` (AC5b), `CombatNodeArchitecture.md` (§12.3.2) - Design intent is **consistent**: zero gold on loss. `CombatNodeArchitecture.md §12.3.2` correctly states `GainedGold = 0` on loss, and `node-system.md` Edge Cases states "no partial rewards." - However: `progression.md` AC5b says `totalGoldEarned += goldEarned` on loss — correct only if `goldEarned == 0`. The **RunStats schema** (`goldEarned >= 0`) allows non-zero values without a loss-specific constraint. - No AC in `node-system.md` formally seals: `runStats.goldEarned == 0` on loss. - **Impact**: Design intent is consistent; GDD contract is not airtight. A future implementer could introduce a non-zero gold-on-loss path without violating any AC. - **Fix**: Add explicit AC in node-system.md: `"**GIVEN** the player loses Combat at any node, **WHEN** `RecordRunEnd` is called, **THEN** `runStats.goldEarned == 0`."` ⚠️ **[C-W3] Event System Does Not List Node System as Dependency Source for BossBonusGold** - **Files**: `event-system.md` (Dependencies, line 178), `node-system.md` (line 122, line 223) - `BossBonusGold = 200` is declared in `node-system.md` but `event-system.md` does not list `node-system.md` as a dependency source for this value. - Not a functional issue — `BossBonusGold` is not referenced in Event System mechanics. - **Fix**: Add `BossBonusGold` sourcing note in `event-system.md` Dependencies if the value is ever used in event design. --- ## Game Design Issues ### Warnings ⚠️ **[G-W1] Tag System GDD Does Not Exist — Tag Stacking Is Unconstrained (HIGHEST PRIORITY)** - **Files**: `tower-assembly.md` (TagAggregation), `design/gdd/tag-system.md` (**DOES NOT EXIST**) - `TowerAssembly.AggregateTowerTags()` produces `TotalStack = occurrence count (1–3)` per tag. The GDD explicitly states: "the effective power multiplier semantics of this count... are defined in the Tag System GDD." - **The Tag System GDD does not exist in the codebase.** - **Structural dominant strategy**: If `Stack=3` is strictly better than `Stack=2` or `Stack=1` for any tag, the optimal tower always uses 3 copies of the best available tag. The "optimization puzzle" has a single solution. - **Fix**: Write `design/gdd/tag-system.md` before implementing Tower Assembly. Define stacking semantics (linear? diminishing returns? multiplicative ceiling?). ⚠️ **[G-W2] Event Rewards Share Rarity Budget with Shop — No Distinct Tier** - **Files**: `event-system.md` (ER4: AddRandomComps), `shop.md` (SR1), `progression.md` (pool unlock chain) - `AddRandomComps` calls `InventoryGenerationComponent.BuildEventRewardComponents()` — the same generation pipeline as shop. - Events cannot reward a rarity the player hasn't unlocked in Progression. - Event System pillar ("narrative surprise and meaningful stakes") is undermined when the reward tier is identical to shop. - **Fix**: Consider a separate event rarity budget (e.g., events drop at most Blue even if player has Red unlocked), or a distinct reward category. ⚠️ **[G-W3] Sell Price at ~50% Actively Discourages Experimentation** - **Files**: `shop.md` (SR6, Formula 2), `tower-assembly.md` (Fantasy line 20) - Tower Assembly fantasy: "free reconfiguration," "optimization mastery under constraint" - Shop sell formula: `Round((minPrice + maxPrice) / 2.0f)` — ~50% of max buy price - Player who buys a White component for 100, tries it, sells it back gets 50. Half their experiment cost is destroyed. - Free disassemble partially offsets this — but if inventory is full and player wants to try a new component, they must sell something. - **Fix**: Make sell ratio a tunable knob (recommend 60–70%) or add a component enhancement sink that uses excess components. ⚠️ **[G-W4] Assembly Phase Has 5 Simultaneous Panels — Cognitive Load Risk** - **Files**: `tower-assembly.md` (Assembly Phase Screen, UI Requirements) - Panels: Inventory Grid + 3 Assembly Slots + Assembled Towers + Combat Roster + Next Node Preview - The GDD's own design note: "Ready button is enabled and clicking it proceeds... without modification." — the designed workaround is to click Ready when nothing needs doing. - **Structural problem**: Players who understand the game will click Ready almost every time after the first few runs. The elaborate UI becomes noise. - **Fix**: Merge Assembled Towers panel with Combat Roster (single "Your Towers" panel with roster checkboxes), or introduce a "Quick Assemble" mode that hides unused panels. ⚠️ **[G-W5] "Build Toward the Boss" Fantasy Conflicts with Boss Scaling Formula** - **Files**: `tower-assembly.md` (Fantasy line 22), `node-system.md` (Boss HP formula) - Tower Assembly fantasy: "each assembly decision accumulates toward the final confrontation; the boss fight is where build quality is ultimately tested." - `BossEffectiveHp = BaseHp × 2^completedLoopCount` — Boss HP scales with rounds survived, not player power. - Better build → faster kill → fewer loops survived → lower effective HP. The boss IS a test of kill speed, not raw survivability. - The stated fantasy implies build quality = being powerful enough to win, not kill-speed pressure. - **Fix**: Revise Tower Assembly Fantasy line 22 to reflect kill-speed pressure, not "build quality tested." ⚠️ **[G-W6] Difficulty Spike at Normal→Hard Before Component Pool Catches Up** - **Files**: `progression.md` (pool unlock chain), `node-system.md` (Plain theme node sequence) - Green pool unlocks on first Normal win. Hard difficulty unlocks after defeating Boss on Normal. - Player enters Hard with only Green components. The first 4 Hard combat nodes are fought with inadequate tools. - **Fix**: Consider starting Green pool available before first win, or give Hard difficulty a more generous starting loadout. ⚠️ **[G-W7] Gold Cap (9999) Is Effectively Unreachable in Normal Play** - **Files**: `shop.md` (MaxPlayerGold), `node-system.md` (per-run gold ~1100) - ~1100 gold per full winning run. 9999 cap. ~9 wins to cap, assuming minimal spending. - With free disassemble and no repair mechanism, spending pressure is low. A skilled player accumulates excess gold with no outlet. - **Fix**: Consider a prestige mechanic that converts excess gold into permanent upgrades, or significantly lower `MaxPlayerGold`. --- ## Cross-System Scenario Issues **Scenarios walked:** 1 (Full Run End chain) ### Full Winning Run — RunEnd Chain 1. Node System: Boss defeated → fires `NodeCompleteEventArgs(CombatWon=true)` 2. Node System → `Progression.RecordRunEnd(runStats)` with `{goldEarned, nodesCompleted=10, bossDefeated=true, coinsEarned}` 3. Progression: `LifetimeStats` updated → unlock evaluation → `UnlockedEventArgs` with `UnlockResult[]` 4. UI / Run End Screen: Toast popup for new unlocks **Issues found:** ⚠️ **G-W7 (display gap)**: Run End Victory screen cannot display "Gold earned this run" without a data path. `UnlockedEventArgs` carries no `goldEarnedThisRun` field. This was G2 in the 2026-04-29 review — flagged as blocking — but is a **display gap, not a crash**. The screen shows 0 gold implicitly. Recommend adding `goldEarnedThisRun` to `UnlockedEventArgs` for UX completeness. --- ## GDDs Flagged for Revision | GDD | Reason | Type | Priority | |-----|--------|------|----------| | `tower-assembly.md` | C-W1: dependency direction inverted; G-W1: Tag System GDD missing; G-W5: boss fantasy conflict | Consistency + Design Theory | **High** | | `event-system.md` | G-W2: event rarity budget not distinct from shop | Design Theory | Medium | | `shop.md` | G-W3: sell ratio tunable knob; G-W7: gold cap tuning | Design Theory | Medium | | `node-system.md` | C-W2: loss gold AC gap; G-W6: difficulty spike | Consistency + Design Theory | Medium | --- ## Verdict: **CONCERNS** No blocking issues — no system is mechanically broken. All 6 systems are implementable and internally coherent. Warnings present — 7 warnings and 1 scenario info item. These should be resolved before or during implementation but do not prevent architecture work from beginning. **Most urgent**: G-W1 (Tag System GDD missing) — without it, `TagAggregation` output is undefined and Tower Assembly cannot be fully implemented. --- ## Recommended Actions 1. **G-W1 (HIGHEST)**: Write `design/gdd/tag-system.md` — define tag stacking semantics before implementing Tower Assembly 2. **C-W1**: Fix Tower Assembly dependency direction — swap Node System from upstream to downstream 3. **C-W2**: Add formal AC in node-system.md sealing `runStats.goldEarned == 0` on loss 4. **G-W5**: Revise Tower Assembly Fantasy line 22 — "build toward the boss" should reflect kill-speed pressure 5. **G-W2**: Event System — consider separate rarity budget for event rewards 6. **G-W3**: Shop — make sell ratio a tunable knob 7. **G-W6**: Progression — address Normal→Hard difficulty spike before component pool upgrade 8. **G-W7**: Shop — consider gold cap tuning or prestige mechanic 9. **C-W3**: Event System — add BossBonusGold sourcing reference to Node System