UnityTowerDefense/Project_Roadmap.md

29 KiB
Raw Permalink Blame History

Unity Tower Defense — Project Roadmap

Purpose

This document consolidates outstanding work for the Unity Tower Defense project into a single sequenced plan. It supersedes the roadmap section of the existing context summary while preserving all engineering decisions, design rules, and architectural patterns documented there. The context summary remains the authoritative source for completed-work details and design rationale.

The roadmap is organized in three phases:

  • Phase 1 — Functional gameplay completion. Everything required to have a playable, end-to-end tower defense match.
  • Phase 2 — Visual prototype. Proves out the painted-miniature aesthetic on a single tower and a single enemy, using sourced reference content (Space Marine + Hormagaunt) as placeholders.
  • Phase 3 — Path to commercial production. Notes on the IP swap-out, art lead hiring, and what changes when production art begins.

Phase 1 — Functional Gameplay Completion

This phase carries forward all pending systems from the existing context document. The order below is the recommended sequencing; some items can run in parallel where noted.

1.1 Character pipeline mini-session (NEXT)

Already identified as the immediate next task in the existing roadmap. Establishes the rigging and animation pipeline that everything downstream depends on.

  • Mixamo character + animation download walkthrough
  • Unity Humanoid rig setup
  • Animator Controller with idle / walk / build states
  • Replace Builder cylinder with rigged animated character
  • Connect Claude to Blender via MCP (first-time setup, walkthrough needed)

This pipeline becomes the foundation for both the prototype enemy and any humanoid towers in Phase 2.

1.2 HUD

Can run in parallel with later items in this phase. Several existing systems have stubs awaiting HUD consumers.

  • Canvas + components: minimap, portrait, context panel, 4×3 tower/upgrade grid
  • Tower buttons calling TowerPlacementController.BeginPlacement (replaces TowerPlacementTestTrigger)
  • Rejection message display subscribing to TowerPlacementController.OnRejectionMessageReady
  • Build progress bar above active construction (consumes BuildJob / BuildSiteVisual state)
  • Cancel-shelved-tower button or context-menu gesture (deferred from Path D2)
  • Settings menu eventually owning EdgePanEnabled, scroll sensitivity, etc.

1.3 Match state and player slot mapping

Several systems currently hold stubbed mappings that must be resolved before multiplayer is meaningful.

  • MatchState NetworkBehaviour — global match data: current wave, lives, race-pick timer
  • PlayerMatchState NetworkBehaviour — per-player: race selection, etc.
  • Authoritative client-id → PlayerSlot mapping. Replaces the five stubbed mappings in TowerPlacementManager, TowerPlacementController, CameraController, PlayerBuilderSpawner, and Builder.

1.4 Combat system

The most architecturally significant pending system. This blocks the Phase 2 tower animation work (towers can't have target-acquired/firing states to animate until something generates those states).

  • TowerCombat component on tower prefabs. Component-per-behavior rather than flat fields on TowerDefinition — see existing lessons.
  • Targeting logic: range check, target acquisition, target prioritization (closest, lowest-HP, etc.)
  • Projectile prefabs and hitscan handling
  • Damage application against enemy HP

Architectural note for Phase 2 setup: when designing TowerCombat, expose the following events for visual consumers (these will drive tower animation in Phase 2):

  • OnTargetAcquired — first enemy enters range
  • OnTargetLost — no enemies remaining in range
  • OnFire — weapon discharges (per FireRate cycle)
  • CurrentTarget reference for procedural rotation

1.5 Enemy system

  • Enemy NetworkBehaviour (HP, movement, type, debuffs)
  • Spawning system driven by waves / match state
  • Enemy prefab pipeline for Phase 2 prototype

1.6 Pathfinding

  • A* on the runtime walkability grid (consumes LevelLoader.IsWalkable)
  • 4-connected, no diagonals (matches existing maze validation)
  • Re-pathing on tower placement/removal events. Fire on: TowerInstance spawn/despawn, construction-start, construction-finish, shelved-tower despawn.

1.7 Lobby & Connection (COMPLETE — 2026-05-17)

Replaced the bare "Start Host" button with a proper main menu → lobby → match flow. Lobby is its own scene; players gather, pick races, ready up, and the host starts the match.

v1 shipped (Direct IP, Option A host-leaves-closes-lobby):

  • MainMenu scene — Host / Join (with IP+port field) / Quit / Quick Start (dev shortcut)
  • Lobby scene — player list, per-player Select Race button opening the race-selection overlay, ready toggle, host-only Start button, Leave button
  • LobbyService NetworkBehaviour scene singleton — Start Match RPC, Return to Lobby RPC
  • NetworkBootstrap static — wraps UnityTransport host/join/disconnect. Designed for the Steam swap-out below: same call sites, different transport.
  • SessionFlow DontDestroyOnLoad singleton — routes disconnected peers back to MainMenu on host loss
  • PlayerMatchState extended with IsReady NetworkVariable and SubmitRaceRpc / SubmitReadyRpc for client → server submissions
  • PlayerBuilderSpawner refactored to spawn on NetworkSceneManager.OnLoadEventCompleted for the Match scene, not on initial player spawn. Pulls race-specific BuilderPrefab from RaceRegistry when available, falls back to the inspector default. Re-spawns cleanly across Match → Lobby → Match cycles.
  • Match-end overlay extended: Retry (back to lobby) AND Return to Main Menu (this player only)
  • Host leaves → all clients return to main menu via SessionFlow.OnClientDisconnectCallback (Option A). Same applies if the host clicks "Return to Main Menu" after a match.
  • Race data + selection UI delivered as part of 1.7 (originally scoped for 1.8): RaceId enum expanded to 16 slots, RaceDefinition ScriptableObject (Id, DisplayName, Icon, BuilderName, BuilderDescription, LoreText, BuilderPrefab, Towers stub), RaceRegistry (DontDestroyOnLoad singleton in MainMenu — single source of truth across all scenes), RaceSelectionOverlay (4×4 grid + detail panel, taken-race greying with picker badge, Esc/X close, server-side exclusivity enforced via SubmitRaceRpc).
  • Quick Start dev button in MainMenu — bypasses lobby: hosts → waits for PlayerMatchState.Local → sets Race1 + ready → loads Match scene directly. Coroutine in MainMenuController.QuickStartCoroutine.

1.7-Future Steam Lobby Migration (Option C — DEFERRED)

When the Steam SDK is integrated (post-1.7, before 1.8 or in parallel), the Direct IP backend is replaced with a Steam-backed lobby provider. The lobby UI and gameplay code do not change. The migration touches only NetworkBootstrap and adds a LobbyProvider abstraction behind it.

What changes:

  • Add Facepunch.Steamworks (recommended) or Steamworks.NET to the project
  • Use Steam app ID 480 (Spacewar) during development; switch to the actual app ID once Steam page is provisioned
  • Replace UnityTransport with SteamNetworkingSocketsTransport (community-maintained NGO transport)
  • Refactor NetworkBootstrap from static helpers into an IConnectionProvider interface with two implementations:
    • DirectIpConnectionProvider (existing behavior, kept for LAN testing and DRM-free distribution)
    • SteamConnectionProvider (Steam lobby create/join, friend invite via Steam overlay, Steam P2P sockets)
  • Add lobby browser UI to MainMenu scene (currently just Host/Join buttons)
  • Friend-invite flow: handled by Steam overlay (Shift+Tab → invite friend); join request lands in the existing Lobby scene
  • Host-leaves behavior upgrades from Option A → Option C: Steam lobbies persist independently of the game host, so a new host can be elected from remaining members rather than tearing the lobby down. This is the deferred behavioral upgrade flagged for migration time.

Notes for the migration:

  • Lobby code already factored to read player state from PlayerMatchState (carries across scene loads) and lobby-wide state from LobbyService — no UI rewrite needed
  • The IConnectionProvider abstraction is the single seam between gameplay and transport; everything else stays put
  • Both providers should coexist in the codebase so DRM-free builds (itch.io, direct distribution) can still ship without Steam
  • Steam Direct fee ($100 USD) is required to publish on Steam but NOT for development — Spacewar app ID 480 is free to use

1.7.5 Terrain architecture

Decision deferred per existing context document; Builder code is already terrain-agnostic. Recommend deciding after the character pipeline mini-session and before Phase 2 begins (the visual prototype will look very different on Unity Terrain vs mesh-based terrain).

Options previously discussed: Unity Terrain, mesh-based (Blender), ProBuilder, per-tile heights via volumes.

1.8 Race system (Path E) — PARTIALLY COMPLETE

Data model and lobby selection UI shipped as part of 1.7 (2026-05-17). Remaining work is gameplay-side integration of the race payload during a match.

Already done (delivered with 1.7):

  • RaceDefinition ScriptableObject with Identity / Builder / Lore / Gameplay-payload sections
  • RaceRegistry DontDestroyOnLoad singleton (placed in MainMenu, persists into Lobby + Match)
  • RaceId enum (None + Race1..Race16) — 16-slot grid reserved
  • Lobby race-selection overlay (4×4 grid + detail panel + exclusivity enforcement)
  • PlayerMatchState.RaceSelection NetworkVariable + SubmitRaceRpc
  • PlayerBuilderSpawner reads race-specific BuilderPrefab when available
  • Two placeholder RaceDefinition assets configured with the default builder (proves the data path works without race-specific content)

Still pending:

  • Replace lobby race-pick with in-match race-pick overlay (timer-based auto-lock, MatchState.RacePickTimer) — OR retain lobby pick and remove the in-match flow concept. Open decision (see 1.10 reconciliation question).
  • Multi-builder race support — revisit PlayerBuilderSpawner to spawn N builders for races that need them
  • TowerRegistry filtering by active match's race rosters (currently shows all registered towers regardless of race)
  • Auto-discovery of RaceDefinition assets (today's flow: drag each asset into RaceRegistry.Definitions manually)
  • Replace TowerPlacementManager.towerDefinitions[] inspector array with race-driven discovery
  • Race-specific builder prefabs (currently every race uses the same default builder)
  • Real race content (display names, lore, icons, distinct builder visuals) — placeholder races exist but are interchangeable

1.9 Camera polish

Flagged for revisit; not blocking anything.

  • Cursor-anchored zoom near map edges (Q3c flagged as revisitable)
  • Center-on-builder hotkey (e.g., Space)
  • Initial camera position taking race or match phase into account

1.10 Tower Customization & Meta-Progression (DEFERRED — DESIGN CAPTURED)

Long-term cross-match progression loop. Recorded here so Phase 1.8 race-system design and Phase 2 visual prototype work can anticipate the customization data model when they're scheduled. Not blocking Phase 1 exit criteria — a single match is fully playable without it.

Core concept

  • Every player starts each match with the same base tower set — a small fixed roster (universal or per-race; see open question below).
  • End of match awards a customization reward, drawn from a Warhammer-themed pool. Win and loss draw from different pools — winning unlocks higher-tier / rarer rewards, losing still progresses at a slower rate so no match is truly wasted.
  • Reward types:
    • Paint color (e.g. Macragge Blue, Mephiston Red, Caliban Green) — applied to tower visuals, can carry gameplay effects (see below)
    • Sticker decal — chapter badges, regimental icons, faction sigils
    • Other Warhammer-aligned customizations: transfers, weathering, base styles, freehand-style elements
  • Customizations are persistent across matches via a player profile / save system.
  • Applied via a customization menu (does not exist yet) reachable from the main menu, showing owned customizations and per-tower application slots.

Gameplay enhancements via customization

Cosmetics double as upgrades. The pattern mirrors the real-world Warhammer hobby loop (collect → paint → customize) translated into mechanical progression:

  • Stat modifiers — extended range, increased damage, faster fire rate, larger splash radius
  • Damage-type changes — applying a particular paint scheme grants Fire / Cold / Poison damage to an otherwise basic tower
  • Special effects — chain hits, slow effects, DoT — driven by specific decal or paint combinations
  • Layering / set bonuses — applying multiple customizations from the same "faction" might unlock additional effects (e.g. full Salamanders paint kit + chapter decal grants a flamer-style damage profile)

Required systems (none exist yet)

  • Player profile / persistence — local save for now, account-bound later. Tracks owned customizations + per-tower application state.
  • CustomizationDefinition ScriptableObject — stat-delta fields, visual asset references (decal texture, color values), rarity tier, reward-pool tags.
  • Tower stat modifier stack — extend TowerDefinition (currently flat fields) to accept a layered modifier stack from applied customizations. Affects targeting, damage, range, fire rate at runtime.
  • End-of-match reward roll — server-authoritative draw from win/loss pool, replicated to the relevant player. Anti-cheat: server owns the roll, not the client.
  • Customization menu UI — main-menu-accessible. Browse owned, browse locked, apply / remove per tower in the base set.
  • Networked applied-customization state during a match — towers must visually reflect each owner's applied customizations on every peer, AND stat modifiers must be authoritative on the server.

Open question — interaction with the Phase 1.8 race system

Phase 1.8 currently assumes race-driven tower rosters (each race has its own distinct set of towers). This new direction suggests a flatter, customization-driven model. The two systems need reconciliation before either ships:

  • Option A: Race remains the primary tower-set distinction. Customizations layer on top of race-specific towers. Each race owns its own customization pool.
  • Option B: Race becomes one customization category among many. Tower set is universal across players; "race" identity emerges from the player's chosen paint scheme / decal kit.
  • Option C: Hybrid — small universal base set + larger race-locked roster, both customizable. Customizations affect both.

Decision deferred until both 1.8 and 1.10 are actively scheduled. The choice has significant implications for content scope: Option A means N races × M customizations each; Option B means one tower set × (M customizations × N "factions"). Option B is dramatically less art work per tower.

Why this is deferred

  • Not required for Phase 1 exit criteria (a single match plays fine without cross-match progression).
  • Phase 2 visual prototype doesn't depend on this — the painted-miniature aesthetic provides the visual scaffolding customization will eventually exploit, but the prototype tower's paint scheme can be hard-coded for the demo.
  • The data model interaction with Phase 1.8 needs to be resolved first (see open question above).

When to schedule

Earliest reasonable slot: after Phase 1 exit criteria are met and Phase 1.8 race-system design has the customization-interaction question resolved. Could run in parallel with Phase 2 (no overlap with visual prototype scope) or after Phase 2 if visual direction needs to prove out first.

Phase 1 exit criteria

A complete match is playable end-to-end: race pick → builder spawn → tower placement and construction → wave spawning → enemies path through the maze → towers shoot enemies → enemies die or leak → match concludes. Visuals are placeholder. All systems in this section are functional.


Phase 2 — Visual Prototype

Begins only after Phase 1 exit criteria are met. This phase exists to prove out the painted-miniature visual direction on minimal content (one tower, one enemy), so the direction can be communicated to a future art lead with concrete, in-engine examples.

Prototype scope and constraints

  • One tower — Space Marine in Ultramarines colors, standing-ready pose, with idle / aim / fire animation states
  • One enemy — Tyranid Hormagaunt with walk / death animations, animated on 2s for the Spider-Verse-style stepped-frame effect
  • Sourced reference content. The Space Marine and Hormagaunt are placeholders pulled from existing third-party models. They are private prototype assets only — see Phase 3 for the swap-out plan.

IP guardrails for the prototype

These hold throughout Phase 2 and until the Phase 3 swap-out is complete.

  • Repo mafoster134/UnityTowerDefense remains private on GitHub. No public builds, no itch.io demos, no public streams or videos showing GW-derived assets.
  • Internal multiplayer testing with friends over private connections is acceptable; anything resembling public distribution is not.
  • Don't redistribute GW source files. Kitbash from photos/concept art into your own meshes and textures rather than embedding GW-shipped assets directly. Cleaner swap-out later.
  • Maintain a plain-text asset manifest in the repo listing every asset using GW IP that needs replacement before commercial release.

2.1 Shared visual infrastructure (one-time investment)

Builds the technical scaffolding all Phase 2 assets (and all future production assets) consume.

2.1.1 Painted-miniature URP shader

Custom Shader Graph variant of URP Lit, saved as MiniatureStandard.

  • Standard PBR inputs: albedo, normal, metallic, roughness, AO
  • Fresnel rim term added to the lighting output. Drives a subtle lighter color along glancing angles. Fakes the drybrush highlights miniature painters apply to raised edges. Critical for the "photographed painted miniature" read.
  • Crushed shadow curve — adjustment that deepens the shadow-to-midtone transition. Mimics how miniatures look under photo-studio key lighting.
  • Optional: subtle screen-space painted-noise overlay at very low intensity for tactile texture.

This shader is reused by every painted-miniature asset going forward.

2.1.2 Lighting and post-processing setup

Project-wide, applied via the existing DefaultVolumeProfile system.

  • Strong directional key light at ~45° elevation, slightly warm
  • Soft fill light from opposite side, cool-tinted
  • Subtle bounce light from below to lift bases (GW studio-shot reference)
  • AO intensity raised slightly past realistic
  • Tilt-shift DOF in the volume profile — slight blur at top and bottom of frame to sell diorama scale
  • Color grading toward saturated, warm-shadowed
  • Slight vignette

Applied to URP-Medium first; ported to URP-Low / High / Ultra when those quality tiers are configured (existing pending work).

2.1.3 On-2s animation system

A MonoBehaviour (working name SteppedAnimator) attached to objects whose animation should appear at ~12fps despite the game running at 60fps. Selectively applied to skeletal animation; effects, projectiles, and UI remain smooth.

Implementation approach:

  • LateUpdate samples the current Animator pose
  • Quantizes time to 1/12-second steps
  • Holds previous-frame pose on intermediate frames
  • Configurable target framerate (default 12fps; can be tuned per-asset)

Design rule: stepped animation applies to skeletal body animation and weapon-target tracking rotation only. Muzzle flashes, projectiles, and UI run at full framerate. The contrast between stepped and smooth is what sells the Spider-Verse effect — global stepping looks broken.

2.1.4 TowerVisualController component

New component on tower prefabs. Bridges the gameplay-side TowerCombat events (built in Phase 1.4) to the animation system.

  • Subscribes to TowerCombat.OnTargetAcquired, OnTargetLost, OnFire
  • Sets Animator parameters: HasTarget (bool), Fire (trigger)
  • Drives procedural torso/turret rotation toward TowerCombat.CurrentTarget via LateUpdate LookAt on a designated pivot bone
  • Pure local visualization. No NetworkBehaviour, no networked state. Each client renders animation state from its own read of the networked combat state.

This component, like MiniatureStandard and SteppedAnimator, is one-time scaffolding that every future tower consumes.

2.2 Prototype tower — Space Marine (Ultramarine)

2.2.1 Reference and source acquisition

  • Pull 812 reference images of Ultramarine Tactical / Intercessor Marines in standing-ready poses. PureRef board.
  • Acquire base model from MyMiniFactory, Sketchfab, or CGTrader. Prefer "miniature-scale" models with proportions already correct for tabletop aesthetic over high-detail "video game" models.

2.2.2 Mesh prep

  • Decimate / retopo to 5k15k tris
  • Re-UV (most source models have UVs optimized for 3D printing, not texturing)
  • Reasonable texel density for 2K texture target

2.2.3 Texturing

Substance Painter (or alternative). Build the painted-Ultramarine look in layers:

  1. Base coat — Macragge Blue equivalent. Slightly desaturated steely middle value.
  2. Recess shading — darker blue-violet wash driven by curvature map. Makes armor plates read as separate panels.
  3. Edge highlighting — Calgar Blue / Fenrisian Grey territory. Visibly broken and slightly streaky, not perfect lines. Single most "miniature-painted" visual cue.
  4. Final extreme highlights — near-white blue, applied only to the absolute sharpest edges, very sparingly.
  5. Gold trim on aquila, helmet rim, weapon details. NMM-painted gradients photograph better at top-down distance than real metallic.
  6. Black undersuit and weapon casing — flat very dark navy with subtle blue rim highlights. Avoid pure black.
  7. Battle damage — small chips on edges showing silver underneath the blue. Used very sparingly.
  8. Base — broken urban rubble or red Mars-like sand. Skull or two. Optional static grass tuft.

Critical: paint deliberate brushstroke variation into the albedo. Slight value/hue shifts across flat surfaces. Airbrushed-gradient textures will read as CGI; broken-application textures read as painted miniature.

Consider community-made "Warhammer / miniature / tabletop" smart materials in the Substance Share library as a starting point; customize from there.

2.2.4 Animation states

Three states minimum, retargeted from Mixamo "rifle" animation set onto the Humanoid rig (leveraging the Phase 1.1 character pipeline work):

  • Idle — relaxed stance, bolter held at low ready, subtle breathing/sway loop
  • Aiming — bolter raised, tracking target. Procedural torso pivot rotates toward CurrentTarget via TowerVisualController LateUpdate LookAt; clip provides upper-body pose.
  • Firing — short burst animation: muzzle flash effect, recoil pulse, optional casing eject

Animator Controller transitions:

  • Idle → Aiming: HasTarget == true
  • Aiming → Idle: HasTarget == false (with ~1 second blend back to relaxed pose)
  • Aiming → Firing: Fire trigger (returns to Aiming on completion)

Apply SteppedAnimator to the body Animator and the torso pivot rotation. Muzzle flash and projectiles remain smooth.

2.2.5 Integration

  • Create TowerDefinition asset. DisplayName "Space Marine" (will become original-faction equivalent in Phase 3). FootprintSize 2×2. GoldCost per economy tuning. BuildTime 4 seconds (matches existing test value). Combat fields per TowerCombat design from Phase 1.4.
  • Plug into TowerPlacementManager.towerDefinitions[] for testing (eventually replaced by race-driven discovery from Phase 1.8)
  • Verify the existing BuildSiteVisual ghost system handles the new prefab correctly (green/white/red tinting for build stages should work as-is)

2.2.6 Time estimate

Roughly 2543 hours total. Bulk of time in texturing (812h) and animation retargeting / state machine (610h). Shader and lighting are one-time investments amortized across all future towers.

2.3 Prototype enemy — Tyranid Hormagaunt

2.3.1 Reference and source acquisition

  • Reference images of Hormagaunts in scuttling poses. Note the four-legged-with-scythe-arms body plan.
  • Source model from same channels as the tower. Hormagaunts have a distinct silhouette that's forgiving for proportions but demands clean topology around the joints for the on-2s animation to read well.

2.3.2 Mesh prep and rigging

  • Decimate / retopo as for the tower
  • Custom rig (Mixamo's Humanoid rig won't fit the four-legged plan). Mixamo's "Quadruped" auto-rigger is a possibility, or hand-rig in Blender.
  • Skinning and weight painting

2.3.3 Texturing

Same painted-miniature pipeline as the tower, tuned for organic Tyranid biology:

  • Chitin plates with hard-edge gradients (purple-to-bone is the canonical Hyve Fleet Leviathan scheme)
  • Recess shading deeper than on the tower — Tyranid sculpts have very pronounced cavities
  • Subsurface treatment on flesh areas (mouth, claws, exposed muscle)
  • Bone highlights drybrushed onto chitin edges
  • Glossy claws and teeth

2.3.4 Animations

Pulled from Mixamo "creature" set or hand-authored:

  • Walk / scuttle cycle — fast, low to the ground
  • Death — stagger, collapse

Apply SteppedAnimator aggressively here. The scuttling gait at 12fps is the signature visual moment of the prototype — this is where the Spider-Verse effect is most visible and most rewarding. Generic Mixamo creature animation often looks floaty at 60fps; stepped to 12fps, it reads as deliberately stylized.

2.3.5 Integration

  • Hook into the Phase 1.5 enemy system. HP, speed, damage stats per enemy type design.
  • Walks the maze via Phase 1.6 pathfinding.
  • Takes damage from the Space Marine tower's projectiles via Phase 1.4 combat system.

2.3.6 Time estimate

Roughly 1729 hours. Quadruped rigging is the wildcard — could compress significantly with auto-rigging tools or expand if hand-rigged from scratch.

2.4 Demo scene

Final integration step. A small purpose-built scene demonstrating the visual direction in motion.

  • Single Space Marine tower placed and animating
  • Wave of Hormagaunts spawning and pathing toward an exit
  • Tower acquires targets, aims, fires; Hormagaunts die in stepped-animation glory
  • Camera positioned to show the tabletop-diorama framing
  • Tilt-shift DOF, painted-miniature lighting and post all active

This scene becomes the artifact you show to candidate art leads in Phase 3.

Phase 2 exit criteria

The demo scene runs in-editor showing the painted-miniature aesthetic working end-to-end with real gameplay (towers shooting enemies, enemies dying). The visual direction is clearly communicated. The shared infrastructure (MiniatureStandard shader, lighting setup, SteppedAnimator, TowerVisualController) is in place and reusable.


Phase 3 — Path to Commercial Production

Notes only. This phase is not actionable until Phase 2 is complete and the decision to pursue commercial release is made.

3.1 IP swap-out

The prototype Space Marine and Hormagaunt must be replaced before any public release. Two paths:

  • Original-faction replacement. Develop original factions in the painted-miniature aesthetic. The "heavy armored warrior order" archetype and "horde swarm" archetype are not owned by anyone; the specific GW execution is. Production art lead's first major task.
  • GW license. Possible but selective. GW has licensed indie tabletop-adjacent games; the bar is meaningful. Worth investigating if the prototype demo is strong enough to take to GW directly.

The data model already supports clean swap-out: TowerDefinition is asset-referenced, so replacing the prefab and texture references is the only gameplay-side change. Code is unaffected.

3.2 Art lead hiring

The Phase 2 demo scene is the primary recruitment artifact. Look for:

  • Tabletop miniature painting experience or demonstrable understanding of the aesthetic
  • 3D character/prop authoring at game-asset quality
  • Comfort with stylized PBR pipelines
  • Familiarity with Unity URP and Shader Graph (or willingness to learn)

3.3 Production scope expansion

  • Multiple races (Phase 1.8 architecture supports this; content fills it)
  • Full tower roster per race (likely 610 towers each, with upgrade paths)
  • Full enemy roster (armored, fast, flying, boss types)
  • Map variety
  • Audio direction matching the visual direction (orchestral / industrial / hobbyist's-table ambient?)

3.4 Production guardrails carried from Phase 2

The asset manifest tracking GW-derived content must hit zero entries before any public build, public repo flip, or marketing material.


Cross-phase principles preserved from existing context

  • Debug to root cause. No defensive workarounds, no per-frame state-correcting hacks. Find the actual cause and fix it correctly.
  • Re-state design intent before coding. Confirmed valuable across multiple sessions; continues into Phase 2 visual work where the same restate-before-build approach prevents asset rework.
  • Server-authoritative gameplay; local-only UI/visual state. Selection, animation state, ghost visuals all stay client-side. Only gameplay-meaningful state is networked.
  • Existing engine and rendering decisions stand. Unity 6.4 → next LTS migration plan; URP; IL2CPP; .NET Standard 2.1; Linear color space; new Input System; Force Text serialization.