50 lines
2.8 KiB
Markdown
50 lines
2.8 KiB
Markdown
# 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.
|