From 05a7412bb2f117b835bfeac1cceb8802f087395b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 23 Nov 2025 07:50:35 +0000 Subject: [PATCH] docs: Add Tower Arena Demo plan for controlled POC showcase - New TOWER_DEMO.md documenting the arena-based approach - Manual coordinate capture workflow for defining combat zones - Implementation sketches for arena bounds checking - Updated PROJECT.md with current status and known limitations --- bot-docs/PROJECT.md | 15 +++- bot-docs/TOWER_DEMO.md | 181 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 bot-docs/TOWER_DEMO.md diff --git a/bot-docs/PROJECT.md b/bot-docs/PROJECT.md index c87d6a71..a14998a7 100644 --- a/bot-docs/PROJECT.md +++ b/bot-docs/PROJECT.md @@ -18,6 +18,7 @@ Bringing bot support to PlanetSide through the PSForever server emulator project |----------|---------| | `HANDOFF.md` | **Start here** - Context for new Claude instances | | `PROJECT.md` | This file - Overview and status | +| `TOWER_DEMO.md` | **NEW** - Controlled arena demo plan | | `GAME_FEEL.md` | Behavioral spec from user's notes | | `ARCHITECTURE.md` | Technical design decisions | | `CODEBASE_MAP.md` | Key files with line numbers | @@ -131,12 +132,24 @@ See `CODEBASE_MAP.md` for file locations and line numbers. - PlayerControl works perfectly with stub BotAvatarActor - Must use `registerAvatar()` not `registerPlayer()` (locker needs GUID) +### Known Limitations (POC) +- **Wall shooting**: Bots can shoot through walls (no server-side collision data) +- **No tracers**: Visual bullet trails not rendering (investigating) +- **Random movement**: No pathfinding, just wandering + ### Next Steps -- [ ] Faction-specific spawn commands (!botnc, !bottr, !botvs) - **IN PROGRESS** +- [x] Faction-specific spawn commands (!botnc, !bottr, !botvs) - DONE +- [x] AI toggle (!boton / !botoff) - DONE +- [ ] **Tower Arena Demo** - Manual coordinate capture for controlled showcase (see TOWER_DEMO.md) - [ ] Terrain following (Z height) - [ ] Bot class differentiation (loadouts will be revised for prod) - [ ] Population scaling (auto-spawn/despawn based on real players) +### Long-term (Post-POC) +- [ ] UBR mesh extraction for world collision +- [ ] Navmesh generation for pathfinding +- [ ] Proper LOS (line-of-sight) checks + --- ## Faction Behavior & Game Feel diff --git a/bot-docs/TOWER_DEMO.md b/bot-docs/TOWER_DEMO.md new file mode 100644 index 00000000..2c9dda9f --- /dev/null +++ b/bot-docs/TOWER_DEMO.md @@ -0,0 +1,181 @@ +# Tower Attack Demo + +## Overview +A controlled demonstration of the bot combat system at a single tower location. By manually capturing coordinates, we create a bounded "arena" where bots behave correctly without needing full world geometry. + +## Why This Approach +- **Wall shooting problem**: Bots currently shoot through walls (no server-side collision) +- **Full solution is massive**: UBR mesh extraction + navmesh generation = huge project +- **POC needs to be demonstrable**: Bots shooting through 4 concrete walls isn't a demo, it's a bug showcase +- **Scrappy but effective**: Manual coordinate capture gives us a working showcase + +--- + +## Implementation Plan + +### Step 1: Choose a Tower +Pick a tower with good sight lines and clear boundaries: +- [ ] Select tower location (user to provide) +- [ ] Capture tower coordinates via `/loc` command in-game + +### Step 2: Define Combat Arena +Capture boundary coordinates by walking the perimeter: + +``` +/loc at each corner point: +- Northwest corner +- Northeast corner +- Southeast corner +- Southwest corner +- Height bounds (ground level, top platform) +``` + +### Step 3: Implement Arena System + +```scala +// Combat arena definition +case class CombatArena( + minX: Float, maxX: Float, + minY: Float, maxY: Float, + minZ: Float, maxZ: Float, + name: String = "unnamed" +) + +// Check if position is within arena bounds +def isInArena(pos: Vector3, arena: CombatArena): Boolean = { + pos.x >= arena.minX && pos.x <= arena.maxX && + pos.y >= arena.minY && pos.y <= arena.maxY && + pos.z >= arena.minZ && pos.z <= arena.maxZ +} + +// Only engage if BOTH bot AND target are in the arena +// This prevents shooting through walls into/out of the arena +def findTarget(botState: BotState): Option[Player] = { + val arena = currentArena // loaded from config + + zone.LivePlayers.filter { p => + isInArena(botState.player.Position, arena) && + isInArena(p.Position, arena) && + p.isAlive && + p.Faction != botFaction && + // ... other existing checks + } +} +``` + +### Step 4: Optional - Interior Exclusion Zones +Define boxes for building interiors where bots won't engage: + +```scala +case class ExclusionZone( + minX: Float, maxX: Float, + minY: Float, maxY: Float, + minZ: Float, maxZ: Float, + name: String = "interior" +) + +// Skip targets in exclusion zones +def isInExclusionZone(pos: Vector3, zones: Seq[ExclusionZone]): Boolean = { + zones.exists { zone => + pos.x >= zone.minX && pos.x <= zone.maxX && + pos.y >= zone.minY && pos.y <= zone.maxY && + pos.z >= zone.minZ && pos.z <= zone.maxZ + } +} +``` + +--- + +## Demo Scenario + +### Setup +1. Spawn 3-5 NC bots around tower perimeter +2. Player approaches as TR/VS +3. Bots engage when player enters arena bounds +4. Combat feels natural - no wall shooting because everyone is in open area + +### What to Show +- Bots spot player and react (2-second delay) +- Bots track and engage target +- Accuracy/recoil system visible in hit patterns +- Bots die when killed, respawn after delay +- Weapon drawn, muzzle flash, sound effects + +### Known Limitations for Demo +- [ ] No tracers (investigating - may be client-side animation issue) +- [ ] Bots don't navigate around obstacles (random wandering only) +- [ ] Single hardcoded arena location + +--- + +## Future: Scaling Beyond One Tower + +Once the single-tower demo works, the approach can scale: + +1. **Multiple arenas**: Define several towers/bases as combat zones +2. **Config file**: Load arena definitions from JSON/YAML +3. **Auto-generation**: Eventually parse map data for structure bounds +4. **Full solution**: UBR mesh extraction for complete world collision + +--- + +## Coordinate Capture Workflow + +When ready to capture tower coordinates: + +``` +1. Log into game, go to chosen tower +2. Walk to each boundary corner, type /loc +3. Record coordinates in format: + + Tower: [Name] + Continent: [home1/home2/etc] + + Boundary Points: + - NW: (x, y, z) + - NE: (x, y, z) + - SE: (x, y, z) + - SW: (x, y, z) + + Height Bounds: + - Ground: z = [value] + - Top: z = [value] + + Optional Interior Exclusions: + - Room 1: (minX, minY, minZ) to (maxX, maxY, maxZ) +``` + +--- + +## Tracer Investigation Notes + +**Current status**: No visible tracers despite multiple approaches + +**What we've tried:** +- AvatarEvents with AvatarAction.ChangeFireState_Start +- LocalEvents with LocalAction.SendResponse(ChangeFireStateMessage_Start) +- Adding WeaponFireMessage broadcast + +**Hypothesis**: +Tracers for hitscan weapons may be purely client-side, calculated from: +1. ChangeFireState (weapon is firing) +2. PlayerState position/orientation +3. Client renders tracer based on facing direction + +**Why it might not work for bots**: +- Missing animation state that triggers tracer rendering +- Client needs specific packet sequence it's not receiving +- Suppressor weapon specifically may handle differently + +**Lower priority for now** - focus on arena system first. + +--- + +## Status + +- [ ] Tower location selected +- [ ] Coordinates captured +- [ ] Arena bounds implemented +- [ ] Exclusion zones defined (optional) +- [ ] Demo tested and working +- [ ] Video/screenshots captured