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>
5.5 KiB
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 Cardper ability above, each pointing at itsEnemyAbilityDefinition. - 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:
WaveGroupassets (TD/Run/Wave Group) — bags of weightedWaveDefinitionentries. Weights are relative 0–1 and default to 1 (equal odds). A zero weight warns inline and means the wave can never be drawn.PhaseDefinition(TD/Run/Phase Definition) —WaveGroups,BossGroups,EnemyUpgradeGroups.RunDefinition(TD/Run/Run Definition) —WavesPerCycle(5),CyclesPerPhase(3), and thePhasesarray. 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
- Author upgraded towers as ordinary
TowerDefinitionassets and add them toTowerPlacementManager.towerDefinitions(not tostartingDeck). - Wire the tree by filling each parent's
UpgradePathsarray with its children. - Each upgrade node's
GoldCostis its upgrade price — upgrade nodes are never placed directly, so the field is free to mean that. - 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.
- Create a
TD/Draft/Tower Upgrade Optionper node (BaseTower→UpgradedTower) and add it toDraftPool. 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
(
TowerCombatre-reads it every tick) but not the model — visual swap is an art task. - No 3-player map yet.
MatchRules.MaxPlayersis 3 and slot allocation caps there, but9Playeris 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.