feat: initial commit with M1-M4 implementation
This commit is contained in:
49
docs/specs/2026-05-08-player-ai-design.md
Normal file
49
docs/specs/2026-05-08-player-ai-design.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Design: Player AI and Steering System
|
||||
|
||||
## Goal
|
||||
Implement autonomous players that move organically on the ice, reacting to the puck and each other, with randomized individual characteristics.
|
||||
|
||||
## Architecture
|
||||
The system is based on "Steering Behaviors", where players calculate a desired velocity based on multiple forces, which are then summed and applied to the player's physics.
|
||||
|
||||
### 1. Player Attributes
|
||||
Each player is assigned a set of attributes that define their physical and mental capabilities.
|
||||
- **Budget**: 10 points total.
|
||||
- **Distribution**: Each attribute gets a minimum of 1 point; the remaining 6 points are distributed randomly.
|
||||
- **Attributes**:
|
||||
- **Speed**: Affects `MaxSpeed`. Higher speed allows faster movement.
|
||||
- **Agility**: Affects `MaxForce`. Higher agility allows sharper turns and faster acceleration.
|
||||
- **Strength**: Affects collision impulse. Stronger players push the puck and opponents further.
|
||||
- **Tactics**: Affects the weight of steering behaviors (e.g., how effectively they seek the puck).
|
||||
|
||||
### 2. Steering Behaviors
|
||||
The `internal/game/steering.go` module will provide the following forces:
|
||||
- **Seek(target)**: Direct force towards the target (puck).
|
||||
- **Arrive(target)**: Similar to Seek, but slows down as the player reaches the target to prevent orbiting.
|
||||
- **Avoidance(others)**: A strong repulsive force to prevent players from overlapping.
|
||||
- **ZoneConstraint(homeZone)**: A soft force pulling the player back to their half of the ice if they stray too far.
|
||||
|
||||
### 3. File Structure
|
||||
- `internal/entities/player.go`: Defines `Player` and `Attributes` structs and the `NewPlayer` constructor with random attribute logic.
|
||||
- `internal/game/steering.go`: Pure functions for calculating steering vectors.
|
||||
- `internal/game/world.go`:
|
||||
- Manages the list of players.
|
||||
- Updates player positions using steering forces.
|
||||
- Handles collisions (Player-Puck, Player-Player) using the `Strength` attribute.
|
||||
- `internal/render/renderer.go`: Renders players as colored circles (Red/Blue), with size slightly scaled by `Strength`.
|
||||
|
||||
## Data Flow
|
||||
1. **Per-Tick Update**:
|
||||
- Calculate Steering Forces: `TotalForce = (Seek * Tactics) + Avoidance + ZoneConstraint`.
|
||||
- Apply Physics: `Acceleration = TotalForce / Mass` (capped by `Agility`).
|
||||
- Update Velocity: `Velocity += Acceleration` (capped by `Speed`).
|
||||
- Update Position: `Position += Velocity`.
|
||||
2. **Collision Resolution**:
|
||||
- If Player touches Puck: Transfer momentum based on `Strength` and `Velocity`.
|
||||
- If Player touches Player: Repel based on relative `Strength`.
|
||||
3. **Rendering**: Draw players at their current positions.
|
||||
|
||||
## Edge Cases
|
||||
- **Overlapping**: High-priority `Avoidance` force prevents players from stacking.
|
||||
- **Boundary Control**: Players are clamped to the ice rink boundaries.
|
||||
- **Damping**: A small friction coefficient is applied to velocity to prevent infinite sliding.
|
||||
Reference in New Issue
Block a user