# 2.0 Refactor — Editor Setup Checklist The 2.0 code landed on `2.0_design_refactor` and compiles clean, but the new systems are **data- and scene-driven**. Nothing runs until the assets below exist and the scene objects are wired. Work top to bottom — each section depends on the ones above it. --- ## 1. Scene objects (both `9Player` and `Main`) Three new scene objects are required. Two are plain MonoBehaviours; one needs a `NetworkObject`. | GameObject | Component | NetworkObject? | Notes | |---|---|---|---| | `RunState` | `RunState` | **Yes** | Assign the `RunDefinition` asset from §3. | | `WaveVote` | `WaveVote` | **Yes** | `Options Per Vote` defaults to 3. | | `EnemyUpgradePool` | `EnemyUpgradePool` | No | Fill `options` with every card asset from §2. | `WaveManager` **no longer has a `waveDefinitions` array** — that field is gone. Its two new serialized fields are `Draft Time Seconds` (30) and `Vote Time Seconds` (25). > Both new NetworkBehaviours are scene objects, so they must be present *before* the host starts. --- ## 2. Enemy-buff cards Two asset layers, because network identity and phase gating are separate concerns. **Abilities** (`TD/Enemy Abilities/…`) — what a buffed enemy *does*: - Split On Death — already exists; **re-check its fields**, they changed. It now has `SplitCount`, `HpPercent`, `SpeedPercent`, `ScalePercent`, `LivesCostPercent`, `FlightHeightPercent`, `ScatterRadius`. - Flight, Blink, No Bounty, Gold Theft — new, need assets creating. Add every ability asset to the scene's existing `EnemyAbilityPool`. Its `noAbilityWeight` field is **gone** (abilities are voted in now, not rolled). **Cards** (`TD/Enemy Upgrades/…`) — what players vote on: - One `Ability Card` per ability above, each pointing at its `EnemyAbilityDefinition`. - One `Double Up Card` (vote-meta; grants no ability). Then: add every card to `EnemyUpgradePool.options`, and group them into one or more `EnemyUpgradeGroup` assets for phase gating. --- ## 3. Run structure Build bottom-up: 1. **`WaveGroup`** assets (`TD/Run/Wave Group`) — bags of weighted `WaveDefinition` entries. Weights are **relative** 0–1 and default to 1 (equal odds). A zero weight warns inline and means the wave can never be drawn. 2. **`PhaseDefinition`** (`TD/Run/Phase Definition`) — `WaveGroups`, `BossGroups`, `EnemyUpgradeGroups`. 3. **`RunDefinition`** (`TD/Run/Run Definition`) — `WavesPerCycle` (5), `CyclesPerPhase` (3), and the `Phases` array. **MVP needs one phase.** The `RunDefinition` inspector shows a live validation panel and a per-phase capacity readout. Get it green before pressing play. ### The constraint that will bite A phase must supply **`WavesPerCycle` waves with DISTINCT enemy types**. Enemy buffs are keyed to a wave slot, so two slots sharing an enemy type would make "which wave did this buff apply to" ambiguous. Ten waves in a pool is *not* enough if they only use three enemies. The inspector reports distinct-type count per phase; the draw fails loudly at match start otherwise. Ten wave definitions and ten enemy definitions already exist, so the content floor is met — but check the type spread. --- ## 4. Gold config `GoldConfig.Waves` is now indexed by **global encounter number**, counted continuously across the whole run — cycles do **not** reset it. One phase of 5 waves × 3 cycles + a boss needs **16 entries**. Missing entries pay zero for that encounter. --- ## 5. Player prefab Add **`PlayerTowerUpgrades`** to `Player.prefab`, alongside `PlayerTowerDeck` / `PlayerDraft`. Without it, tower-upgrade draft options can't apply and the Upgrade buttons never appear. --- ## 6. Enemy prefabs Any enemy that should be able to carry wave buffs needs an **`EnemyAbility`** component on its root. `WaveManager` logs a warning naming the prefab if a buffed wave spawns an enemy without one. `SplitOnDeath` and any size-changing buff need the prefab's **`NetworkTransform` to sync scale**, or minions render full-size on remote peers. --- ## 7. Tower upgrade trees 1. Author upgraded towers as ordinary `TowerDefinition` assets and add them to `TowerPlacementManager.towerDefinitions` (**not** to `startingDeck`). 2. Wire the tree by filling each parent's `UpgradePaths` array with its children. 3. Each upgrade node's **`GoldCost` is its upgrade price** — upgrade nodes are never placed directly, so the field is free to mean that. 4. **Footprint must match the parent.** A differently-sized upgrade is rejected: the tower's occupied/unwalkable tiles are stamped at its current size, and converting would leave the grid describing a shape the tower no longer has. 5. Create a `TD/Draft/Tower Upgrade Option` per node (`BaseTower` → `UpgradedTower`) and add it to `DraftPool`. Prerequisites need no explicit list — a node is offered only once its parent is reachable (in the deck, or itself unlocked). Existing `TowerUpgradeDraftOption` assets **changed meaning**: they used to swap the deck entry, they now unlock an upgrade node. Re-check any that exist. --- ## Known gaps - **Upgraded towers keep the parent's mesh.** Switching the definition changes stats immediately (`TowerCombat` re-reads it every tick) but not the model — visual swap is an art task. - **No 3-player map yet.** `MatchRules.MaxPlayers` is 3 and slot allocation caps there, but `9Player` is still the only authored level. - **Tower vulnerability is not built** — Savage, Mind Control, AOE EMP, Fart Miasma and Dummy all need towers to be damageable/disableable, which doesn't exist. Deferred by agreement. - **Relics** untouched, as agreed.