PSF-BotServer/bot-docs/HANDOFF.md
2revoemag 2e5b5e0dbd feat: Add bot player system for PlanetSide population
Initial implementation of server-side bots that:
- Spawn as real Player entities with full equipment
- Move and broadcast position updates (10 tick/sec)
- Take damage and die with backpack drops
- Respawn after death
- Combat system with accuracy model (adjustment vs recoil)

Includes project documentation in bot-docs/ and Claude agent helpers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 00:22:30 -05:00

314 lines
11 KiB
Markdown

# PlanetSide Bots - Handoff Document
> **Read this first** if you're a new Claude instance or agent picking up this project.
## What Is This Project?
We're adding **bot players** to PlanetSide 1 via the PSForever server emulator. The goal is to make the game world feel alive even with low real player population.
### The Vision
- Hundreds of bots per server (scaling down as real players join)
- Bots that feel like real players, not mechanical turrets
- V-menu chatter, teamwork, attitude/personality systems
- Infantry first, vehicles later
### Key Stakeholder
The user is a **veteran PlanetSide player** (decade+ experience) and serves as the expert on "game feel". They have detailed notes on how bots should behave. Always defer to them on gameplay questions.
---
## Project Structure
```
PSF-LoginServer/
├── bot-docs/ ← Bot project documentation
│ ├── HANDOFF.md ← YOU ARE HERE - Start here
│ ├── PROJECT.md ← Overview, goals, status
│ ├── GAME_FEEL.md ← Behavioral spec (vision, movement, V-menu, classes, etc.)
│ ├── ARCHITECTURE.md ← Technical design decisions
│ ├── CODEBASE_MAP.md ← Key files with line numbers (CRITICAL REFERENCE)
│ ├── POC_PLAN.md ← Phased implementation milestones
│ ├── DEV_SETUP.md ← Development environment setup
│ └── SKETCHES/ ← Conceptual code (not production)
│ ├── BotActor_v1.scala
│ └── BotSpawner_v1.scala
├── src/main/scala/net/psforever/
│ └── actors/bot/ ← Bot implementation code
│ ├── BotManager.scala
│ └── BotAvatarActor.scala
└── ... ← Rest of PSForever server codebase
```
### Read Order for New Instance
1. **HANDOFF.md** (this file) - Context and decisions
2. **CODEBASE_MAP.md** - Where things are in the code
3. **GAME_FEEL.md** - How bots should behave
4. **SKETCHES/** - Conceptual code to understand approach
---
## Key Technical Decisions Made
### 1. BotActor Approach (NOT SessionActor)
We decided to create a new `BotActor` rather than emulating `SessionActor` because:
- SessionActor's main job is handling network packets from clients
- Bots have no client, so no incoming packets
- BotActor can be optimized specifically for AI needs
- Less overhead, better scalability
### 2. Server-Side Native Bots
Bots are first-class server entities, not fake clients connecting from outside.
- Bots use existing `Player` and `PlayerControl` code
- No network overhead
- Actions broadcast through same services as real players
### 3. Bot Identity
Bot characters use:
- **High positive IDs** (900000+) to avoid collision with real DB players
- **No special characters in names** - use `xxBOTxxName` format (not `[BOT]Name`)
- Predefined loadouts per class
### 4. Tick Rate
- 10-20 FPS for bot AI decisions (not 60)
- Can reduce further for bots far from real players
- Server load monitoring will inform final values
---
## Bot Architecture Summary
```
BotManager (per zone)
├── Monitors real player population
├── Spawns/despawns bots to maintain target count
└── Manages one Ace per faction (last to logout)
BotActor (per bot)
├── 10 FPS tick loop
├── Vision cone detection (60-90 degrees)
├── Decision making (attack, retreat, objective, help)
├── Movement execution
├── State broadcasting
└── Controls a Player entity
BotAvatarActor (stub)
└── Minimal - just accepts messages PlayerControl sends
Player + PlayerControl (existing code)
├── Player entity with Vitality, inventory, etc.
└── PlayerControl handles damage/death (already exists)
```
---
## Spawn Flow (Critical Path)
```scala
// 1. Create avatar (HIGH POSITIVE ID - 900000+)
val avatar = Avatar(900000 + botNum, BasicCharacterData(name, faction, sex, head, voice))
// 2. Create player entity
val player = new Player(avatar)
player.Position = spawnPosition
player.Spawn()
// 3. Create typed stub avatar actor (MUST be typed ActorRef)
val typedSystem = context.system.toTyped
val botAvatarActor: ActorRef[AvatarActor.Command] =
typedSystem.systemActorOf(BotAvatarActor(), s"bot-avatar-$botId")
// 4. Register GUIDs (ASYNC - use registerAvatar, NOT registerPlayer!)
TaskWorkflow.execute(GUIDTask.registerAvatar(zone.GUID, player)).onComplete {
case Success(_) =>
// 5. Join zone population
zone.Population ! Zone.Population.Join(avatar)
// 6. Spawn player (creates PlayerControl actor)
zone.Population ! Zone.Population.Spawn(avatar, player, botAvatarActor)
// 7. Broadcast to clients
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.LoadPlayer(...))
case Failure(ex) =>
log.error(s"Failed: ${ex.getMessage}")
}
```
---
## Broadcasting (How Bots Appear to Real Players)
Bots broadcast their state via the same channels real players use:
```scala
// Position updates (10-20 times per second)
zone.AvatarEvents ! AvatarServiceMessage(
zone.id,
AvatarAction.PlayerState(guid, pos, vel, facing, crouch, jump, ...)
)
// Weapon fire
zone.AvatarEvents ! AvatarServiceMessage(
zone.id,
AvatarAction.ChangeFireState_Start(playerGuid, weaponGuid)
)
// V-menu voice commands
// (Need to investigate ChatMsg format)
```
---
## Bot Classes (From User's Notes)
| Class | Role | Behavior |
|-------|------|----------|
| Driver | Vehicle operation | Low priority for gunning, wants to drive |
| Support | Heal & Repair | LOVES gunning (can heal vehicle), prioritizes healing |
| Hacker | Infiltration | Door unlocking, base capture |
| AV | Anti-Vehicle | Tank hunters |
| MAX | Heavy Exosuit | AI/AV/AA variants, switches based on intel |
| Vet | Versatile | Jack of all trades, ADAD movement, vengeance system |
| Ace | Empire Leader | ONE per empire, last to logout, uses Command Chat |
---
## Implementation Status
### COMPLETED (POC Working!)
- [x] BotAvatarActor stub (typed actor, absorbs messages)
- [x] BotManager (spawns bots, handles async GUID flow)
- [x] `!bot` chat command for testing
- [x] Bot spawns visible to players
- [x] Bot takes damage from players (PlayerControl works!)
- [x] Bot movement (10 tick/sec, random wandering, PlayerState broadcasts)
- [x] Multiple bots work independently
### KNOWN ISSUES (Expected for POC)
- No backpack on death (likely because bot has no items/loadout)
- Walks through walls (no collision detection)
- No Z-height adjustment (melts into stairs, terrain)
- Walk speed slightly fast for animation (4 units/sec, try 3)
### NOT YET IMPLEMENTED
- [ ] Bot loadout/equipment
- [ ] Bot shooting (weapon fire broadcasts)
- [ ] Bot death/respawn cycle
- [ ] Terrain following (Z height from map data)
- [ ] Collision avoidance
- [ ] Pathfinding
- [ ] V-menu voice command sending
- [ ] Celebration coordination system
- [ ] Vengeance/attitude system
- [ ] Population scaling (spawn/despawn based on real players)
---
## Resolved Questions (Through Trial & Error)
1. **Avatar IDs**: Must be POSITIVE. Negative IDs break packet encoding (32-bit unsigned). Use 900000+.
2. **PlayerControl + stub AvatarActor**: WORKS! BotAvatarActor just absorbs messages, PlayerControl functions normally.
3. **GUID Registration**: Must use `registerAvatar()` not `registerPlayer()` - locker needs GUID for PlayerControl init.
## Open Questions for PSForever Devs
1. **Bot identification**: Should we add `isBot: Boolean` to Player?
2. **Spawn point access**: Best way to find valid faction spawn locations?
---
## Spawn Location Logic (For Future Implementation)
When a player dies, they choose from up to 3 spawn options (all must be friendly-owned):
1. **Nearest Tower** - Guard towers scattered across continents
2. **Nearest AMS** - Advanced Mobile Station (deployable spawn vehicle)
3. **Nearest Base/Facility** - The main base spawn tubes
**Special Cases:**
- **Sanctuary** (home2, home1, home3): Only one spawn option (the sanctuary itself)
- **Warpgates**: Can spawn at warpgates your faction owns
**For Bots:**
- Currently: Respawn at original spawn position (simple)
- Future: Query zone for valid faction spawn points, pick nearest or random
- Need to find: `SpawnPoint` instances, check faction ownership, calculate distance
**Code References to Investigate:**
- `SpawnPoint.scala` - Spawn point trait and calculations
- `Zone.spawnGroups` - Map of building -> spawn points
- `Building.Faction` - Check ownership for spawn eligibility
---
## Important Behavioral Notes
### From GAME_FEEL.md (Key Points)
- **Vision**: 60-90 degree FOV, distance-based spotting time
- **Movement**: Newbies run straight, Vets do ADAD + crouch spam
- **Retreat**: Vets retreat at low HP, Drivers save vehicles, everyone retreats when out of ammo
- **V-menu**: "Needs" always fire, celebrations are coordinated (1-6 responders, staggered timing)
- **Vengeance**: Vets remember who killed them, may seek revenge, taunt on success
- **Panic**: Non-combat bots (repairing) panic when shot, run to cover while swapping weapons
- **Chaos**: The goal is authentic battlefield chaos - spam bullets, grenades, voice commands
### What NOT to Do
- No bunny hopping (almost no one jumps except MAX dodging AV)
- No laser accuracy (bots should miss)
- No instant reactions (bots need reaction time)
- No perfect coordination (spread out, don't stand on same pixel)
- No mechanical behavior (turrets are terrible, we want human-like chaos)
---
## Development Environment
```bash
# Server codebase
cd PSF-LoginServer
sbt compile # Compile
sbt server/run # Run server
# Requirements
- Java 8 JDK
- sbt (Scala Build Tool)
- PostgreSQL 10+
- PlanetSide client (version 3.15.84.0)
```
---
## Context for Future Agents
If you're a **coding agent** tasked with implementation:
1. Read `CODEBASE_MAP.md` for file locations
2. Read `SKETCHES/` for conceptual starting points
3. Start with Milestone 1: spawn a static bot that appears in-game
4. Test empirically - compile, run, connect with client, observe
If you're a **research agent** investigating something:
1. The PSF-LoginServer codebase is in `./PSF-LoginServer/`
2. All server code is under `src/main/scala/net/psforever/`
3. Tests are under `src/test/scala/`
4. Use grep/glob to find patterns
If the user says **"update the docs"**:
1. Update the relevant .md files
2. Keep `CODEBASE_MAP.md` current with any new discoveries
3. Add line numbers when referencing code
---
## Last Session Summary
**Date**: 2024 (context creation date)
**Accomplished**:
- Analyzed PSF-LoginServer codebase architecture
- Mapped spawn/broadcast/GUID flows
- Created behavioral spec from user's notes
- Sketched BotActor and BotSpawner concepts
- Documented key files with line numbers
**Next Steps**:
- Set up dev environment
- Start Phase 1: spawn a static bot
- OR wait for dev team answers on open questions