Docs: mark Tower Sell done; note budgeted pathfinding re-path scheduler

Updates Project_Context.md + Project_Roadmap.md for the tower-sell work (refund rules, coin VFX/SFX, refund excluded from income) and the PathfindingService budgeted re-path scheduler that removed the sell/placement frame hitch. Follows commit 0b4cde4 which landed the code + art.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Matt F 2026-07-14 23:21:32 -07:00
parent 0b4cde4590
commit 6c03a2f250
2 changed files with 9 additions and 5 deletions

View file

@ -4,7 +4,7 @@
A snapshot of **where the project is and how it works** — the authoritative reference for current architecture, implemented systems, conventions, and known debt. It pairs with [`Project_Roadmap.md`](Project_Roadmap.md), which is the forward-looking plan. When the two disagree, this document describes *what exists today*; the roadmap describes *what's planned next*.
Last substantial update: 2026-06-24.
Last substantial update: 2026-07-14.
---
@ -56,10 +56,11 @@ Unity **6.4 (6000.4.4f1)**, URP, IL2CPP, .NET Standard 2.1, Linear color space,
- `TowerPlacementManager` (server-validated placement queue) — `SpawnTower` now **seats towers flush on the ground from their mesh bounds** (`SeatOnGround`), so any pivot works (replaced the old hard-coded y=0.5). `Builder` build queue with staged construction/pause/cancel/refund, RTS selection, owner tinting.
- **Construction-phase build visuals:** `BuildSiteVisual` swaps between an ordered set of phase prefabs as a tower builds — `ConstructionPhaseSet` SO + optional per-tower `TowerDefinition.ConstructionPhases`, with a project-default set and a legacy cube Y-scale fallback. `BuildSiteVisual` resolves its def via `TowerTypeId` (catalog), like `TowerInstance`.
- **Tesla Coil tower:** Electric, `AllInRange` (zaps every enemy in range each 0.5s tick). `TeslaArcVisual` draws arced, crackling, HDR `LineRenderer` bolts that flicker, plus **real point lights** (emitter flash + per-impact lights at struck enemies, capped) so the electricity actually illuminates the scene — emission/bloom alone don't cast light.
- **Tower Sell** (branch `tower-sell`, verified in-engine 2026-07-14): selecting an owned, completed tower shows a **Sell** action in the command grid's **bottom-right** slot (owner-gated; a non-owner sees it disabled). `TowerInstance.RequestSellServerRpc` (owner-validated, like paint) refunds `TowerDefinition.SellRefundPercent` (default 0.75) of the tower's replicated `goldInvested` (placement + any future upgrade spend), except a `FullRefundIfUnupgraded` tower (the **Wall**) refunds 100% while `upgradeCount == 0`. The refund is **not** counted as round income — `PlayerGoldManager.AwardGold(amount, countAsEarned:false)`. Selling despawns the tower (`OnNetworkDespawn` un-stamps the footprint as a **batch** and clears selection) and broadcasts a coin **VFX + rustle SFX** through `SellEffectSpawner` (scene singleton mirroring `FloatingTextSpawner`) via `TowerPlacementManager.PlaySellEffectRpc` (routed off a persistent object because the tower despawns the same frame). `TowerInstance.ServerAddUpgradeInvestment` is the seam the future upgrade system writes to. The coin VFX is an **artist-authored** prefab (`FX_SellTower`: a Shuriken **mesh-particle** burst of the Blender `Coin` model with an **emissive** gold material — emissive so it survives the grimdark grade); `CoinBurstVfx` is the zero-art code-gen fallback, and new reusable `TransientEffect` self-destructs one-shot effect prefabs (for VFX-Graph effects that lack a Stop Action).
### Enemies & pathfinding
- `EnemyHealth` (replicated HP, damage types, `IsFlying`, held state), `EnemyStatus` (lingering effects: slow/DoT), `EnemyMovement` (A* path following, zone-leak attribution, death/sink sequence).
- `PathfindingService` (A* on the runtime walkability grid, octile heuristic, corner-cut prevention, line-of-sight path smoothing; re-paths on tower placement/removal).
- `PathfindingService` (A* on the runtime walkability grid, octile heuristic, corner-cut prevention, line-of-sight path smoothing). **Re-paths via a budgeted scheduler:** grounded enemies `RegisterMover`/`UnregisterMover`; on a maze change the service enqueues them and recomputes under a per-frame `recomputeBudgetMs` (default 1.5 ms) drain, spreading the work across frames so a placement/sell with a full wave present no longer spikes a frame (was ~0.5 s). Safe because selling only opens the maze and placement is BFS-guaranteed to leave a route, so a few frames of slightly-stale path is invisible.
- **Flying enemies:** path on the **baked terrain grid** (`LevelLoader.IsBaseWalkable`) so they soar over towers; compute once, never re-path; spawn elevated by `EnemyDefinition.FlightHeight`.
- Content: ~10 enemy definitions/prefabs (Crystal Golem / Cyclops / Ent variants, Undead Drake = the flying test enemy), 10 wave definitions.
@ -102,4 +103,4 @@ Unity **6.4 (6000.4.4f1)**, URP, IL2CPP, .NET Standard 2.1, Linear color space,
- **Catalog index 0 is a reserved sentinel** (valid `TowerTypeId`s start at 1) — easy to forget when wiring the catalog in the inspector.
- **Catalog-index identifiers aren't session-stable** — blocks cross-match persistence until a stable ID is added.
- **Paint system frozen**; **Race vs Builder** naming unresolved; the gold **"Buy Roll available any time"** rule is provisional and may change.
- **Stubbed/unbuilt:** tower Upgrade/Sell actions (HUD buttons disabled), enemy resistances/weaknesses, in-match race-pick countdown.
- **Stubbed/unbuilt:** tower **Upgrade** action (HUD button still disabled; the `TowerInstance.ServerAddUpgradeInvestment` seam is ready for it), enemy resistances/weaknesses, in-match race-pick countdown. *(Tower **Sell** is now done — see Combat & towers.)*