Restructures the game around the cyclical run loop from Game Design Doc V2: 5 waves = a cycle, 3 cycles = a phase, each phase ends in a boss. - New TD.Gameplay.Waves: WaveGroup / PhaseDefinition / RunDefinition author the run as draggable weighted pools; RunState owns phase/cycle position, the drawn wave slots, and the per-slot enemy buff sets. WaveManager's flat wave array is gone -- it now only runs the encounter RunState points at. - New TD.Gameplay.EnemyUpgrades: the post-wave enemy-buff vote, with public live-replicated ballots so the HUD can show who voted for what. - Inter-wave flow is now strictly sequential: draft -> vote -> build, each stage ending early once every player has acted. - Enemy abilities inverted from per-instance random rolls to deterministic, stacking per-wave-slot sets. Six cards ship: Split (reworked), Flight, Blink, No Bounty, Gold Theft, Double Up. - Tower upgrades are a two-step tree: a draft pick unlocks a node, gold converts an already-placed tower in place. - Boss encounters flag their enemies and drive a boss HP bar. - Player cap reduced to 3 via MatchRules.MaxPlayers. - GoldConfig is now keyed by global encounter number rather than wave index. Compiles clean; NOT yet verified in-engine. Editor wiring still required -- see Docs/2.0_Setup_Checklist.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
129 lines
5.5 KiB
Markdown
129 lines
5.5 KiB
Markdown
# 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.
|