Documentation
¶
Index ¶
- Constants
- Variables
- func AngleDifference(a1, a2 float64) float64
- func InterceptDirectionSimple(shooterPos, targetPos Point2D, targetVel Vector2D, projSpeed float64) (float64, bool)
- func NormalizeAngleSigned(angle float64) float64
- type BeamData
- type Client
- type ClientMessage
- type CombatManeuver
- type CombatThreat
- type FireData
- type InterceptSolution
- type LoginData
- type MessageData
- type MoveData
- type PhaserData
- type PlanetDefenderInfo
- type PlasmaData
- type Point2D
- type SeparationVector
- type Server
- func (s *Server) AddBot(team int, ship game.ShipType)
- func (s *Server) ApplyPendingTargetSuggestions()
- func (s *Server) AutoBalanceBots()
- func (s *Server) HandleTeamStats(w http.ResponseWriter, r *http.Request)
- func (s *Server) HandleWebSocket(w http.ResponseWriter, r *http.Request)
- func (s *Server) OrbitalVelocity(p *game.Player) (vx, vy float64, ok bool)
- func (s *Server) RemoveBot(botID int)
- func (s *Server) Run()
- func (s *Server) Shutdown()
- func (s *Server) UpdateBots()
- type ServerMessage
- type SpatialGrid
- type TeamCountData
- type Vector2D
Constants ¶
const ( // Shield Fuel Thresholds // These control when bots will activate shields based on available fuel FuelCritical = 400 // Emergency threshold - only shield for immediate threats FuelLow = 600 // Low fuel - shield for close threats FuelModerate = 1400 // Moderate fuel - shield for medium-range threats FuelGood = 2000 // Good fuel reserves - shield more liberally // Threat Assessment Constants ThreatLevelImmediate = 6 // Threat level that triggers immediate shielding ThreatLevelHigh = 4 // High threat level ThreatLevelMedium = 3 // Medium threat level // Distance Thresholds for Threat Detection TorpedoVeryClose = 2000.0 // Torpedoes within this range are always dangerous TorpedoClose = 3000.0 // Range for torpedo threat assessment EnemyVeryClose = 1800.0 // Enemies within this range are immediate threats EnemyClose = 2500.0 // Range for enemy threat assessment PlasmaClose = 2000.0 // Range for plasma threat assessment PlasmaFar = 4000.0 // Extended range for plasma detection // Shield Decision Weights // These control how threat levels translate to shield decisions ImmediateThreatBonus = 6 // Additional threat level for immediate threats TorpedoThreatBonus = 4 // Bonus threat level for threatening torpedoes CloseEnemyBonus = 3 // Bonus for very close enemies PlasmaThreatBonus = 5 // Bonus for plasma threats // Special Situation Thresholds ArmyCarryingRange = 3500.0 // Shield range when carrying armies DefenseShieldRange = 3000.0 // Shield range during planet defense PhaserRangeFactor = 0.8 // Shield when within 80% of enemy phaser range RepairSafetyDistance = 12000.0 // Minimum enemy distance to drop shields for repair (must exceed phaser range + buffer) // Team Coordination Thresholds BroadcastTargetMinValue = 15000.0 // Minimum target score to broadcast to allies BroadcastTargetRange = 15000.0 // Maximum distance to broadcast target suggestions // Ally Separation Thresholds // These control how bots maintain distance from teammates SepMinSafeDistance = 4000.0 // Maximum range to consider allies for separation SepIdealDistance = 2500.0 // Ideal spacing between bots SepCriticalDistance = 1200.0 // Emergency separation distance // Ally Separation Strength Multipliers SepCriticalStrength = 5.0 // Repulsion strength at critical distance SepIdealStrength = 2.0 // Repulsion strength within ideal distance SepModerateStrength = 0.8 // Repulsion strength beyond ideal distance SepSameTargetMult = 1.8 // Extra repulsion when targeting same enemy SepDamagedAllyHighMult = 2.0 // Multiplier for heavily damaged allies (>50%) SepDamagedAllyLowMult = 1.5 // Multiplier for moderately damaged allies (>30%) SepClusterMult = 1.3 // Multiplier when 2+ allies are nearby SepMagnitudeCap = 3.0 // Maximum magnitude scale to prevent erratic scattering // Target Scoring Weights (used by calculateTargetScore) TargetDistanceFactor = 20000.0 // Numerator for distance-based scoring (score = factor/dist) TargetCriticalDmgBonus = 8000.0 // Bonus for nearly dead targets (>80% damage) TargetHighDmgMult = 5000.0 // Multiplier for heavily damaged targets (>50%) TargetLowDmgMult = 3000.0 // Multiplier for lightly damaged targets TargetCarrierBonus = 10000.0 // Base bonus for army carriers TargetCarrierPerArmy = 1500.0 // Additional bonus per army carried TargetSpeedBonus = 300.0 // Bonus per warp of speed advantage TargetCloakedPenalty = 6000.0 // Penalty for cloaked targets beyond close range TargetDecloakBonus = 2000.0 // Bonus for cloaked targets within close range TargetIsolatedBonus = 2000.0 // Bonus for targets with no nearby allies TargetPersistenceBonus = 3000.0 // Bonus for keeping current target (prevents thrashing) TargetCloakDetectRange = 2000.0 // Range within which cloaked ships are worth attacking IsolationRange = 5000.0 // Range to check for nearby allies when determining isolation // Planet Strategy Thresholds CorePlanetRadius = 25000.0 // Distance from team home to consider a planet "core" // Sentinel Values MaxSearchDistance = 999999.0 // Sentinel for "no target found" in nearest-object searches WorstScore = -999999.0 // Sentinel for "no candidate scored" in best-candidate searches )
const ( // OrbitDistance is the distance at which bots attempt to enter orbit. // Must not exceed game.EntOrbitDist (900) for orbit to succeed. OrbitDistance = float64(game.EntOrbitDist) // Planet defense constants PlanetDefenseDetectRadius = 15000.0 // Range for bot to detect threats to friendly planets PlanetDefenseInterceptBuffer = 3000.0 // Additional range beyond bomb range to intercept threats PlanetBombRange = 2000.0 // Range at which enemies can bomb planets effectively )
Bot AI constants
const ( BotRoleHunter = "hunter" BotRoleDefender = "defender" BotRoleRaider = "raider" )
Bot behavior roles returned by selectBotBehavior
const ( MsgTypeLogin = "login" MsgTypeMove = "move" MsgTypeFire = "fire" MsgTypePhaser = "phaser" MsgTypeShields = "shields" MsgTypeOrbit = "orbit" MsgTypeRepair = "repair" MsgTypeLock = "lock" MsgTypeBeam = "beam" MsgTypeBomb = "bomb" MsgTypeCloak = "cloak" MsgTypeTractor = "tractor" MsgTypePressor = "pressor" MsgTypePlasma = "plasma" MsgTypeDetonate = "detonate" MsgTypeMessage = "message" MsgTypeTeamMsg = "teammsg" MsgTypePrivMsg = "privmsg" MsgTypeQuit = "quit" MsgTypeUpdate = "update" MsgTypeError = "error" MsgTypeTeamUpdate = "team_update" )
Message types
const GridCellSize = 3000.0
GridCellSize is the size of each grid cell in game units. Should be at least as large as the maximum collision detection distance. Using 3000 to cover plasma explosion radius (1500) with some margin.
Variables ¶
var BotNames = []string{
"HAL-9000", "R2-D2", "C-3PO", "Data", "Bishop", "T-800",
"Johnny-5", "WALL-E", "EVE", "Optimus", "Bender", "K-2SO",
"BB-8", "IG-88", "HK-47", "GLaDOS", "SHODAN", "Cortana",
"Friday", "Jarvis", "Vision", "Ultron", "Skynet", "Agent-Smith",
}
BotNames for generating random bot names
var (
DebugWeapons = false // Set to true to enable detailed weapon firing logs
)
Debug flags for various subsystems
Functions ¶
func AngleDifference ¶
AngleDifference calculates the smallest angle difference between two angles
func InterceptDirectionSimple ¶
func InterceptDirectionSimple(shooterPos, targetPos Point2D, targetVel Vector2D, projSpeed float64) (float64, bool)
InterceptDirectionSimple is a simplified version that only returns direction and success This is the interface that the existing bot code will use
func NormalizeAngleSigned ¶
NormalizeAngleSigned normalizes an angle to the range [-π, π]. This differs from game.NormalizeAngle which normalizes to [0, 2π].
Types ¶
type BeamData ¶
type BeamData struct {
Up bool `json:"up"` // true = beam up, false = beam down
}
BeamData represents army beam request
type Client ¶
type Client struct {
ID int
// contains filtered or unexported fields
}
Client represents a connected player
func (*Client) GetPlayerID ¶
GetPlayerID returns the player ID atomically
func (*Client) SetPlayerID ¶
SetPlayerID sets the player ID atomically
type ClientMessage ¶
type ClientMessage struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}
ClientMessage represents a message from client to server
type CombatManeuver ¶
type CombatManeuver struct {
// contains filtered or unexported fields
}
CombatManeuver represents a tactical movement decision
type CombatThreat ¶
type CombatThreat struct {
// contains filtered or unexported fields
}
CombatThreat tracks various combat threats. Fields are computed once per bot per game frame by assessUniversalThreats and cached for reuse by both combat and shield logic.
type FireData ¶
type FireData struct {
Dir float64 `json:"dir"` // Direction to fire
}
FireData represents torpedo fire command
type InterceptSolution ¶
type InterceptSolution struct {
Direction float64 // Direction to fire in radians
TimeToIntercept float64 // Time until projectile reaches target
InterceptPoint Point2D // Where the intercept will occur
}
InterceptSolution contains the result of an intercept calculation
func InterceptDirection ¶
func InterceptDirection(shooterPos, targetPos Point2D, targetVel Vector2D, projSpeed float64) (*InterceptSolution, bool)
InterceptDirection calculates the direction to fire a projectile to intercept a moving target. This is a pure mathematical function using the standard 2D intercept formula.
Parameters:
shooterPos: Position of the shooter (world units) targetPos: Position of the target (world units) targetVel: Velocity of target (world units per tick) projSpeed: Speed of projectile (world units per tick)
Returns:
solution: The intercept solution, or nil if no solution exists ok: true if a valid intercept solution was found
type LoginData ¶
type LoginData struct {
Name string `json:"name"`
Team int `json:"team"`
Ship game.ShipType `json:"ship"`
}
LoginData represents login request data
type MessageData ¶
type MessageData struct {
Text string `json:"text"`
Target int `json:"target,omitempty"` // For private messages
}
MessageData represents a chat message
type MoveData ¶
type MoveData struct {
Dir float64 `json:"dir"` // Direction in radians
Speed float64 `json:"speed"` // Desired speed
}
MoveData represents movement commands
type PhaserData ¶
type PhaserData struct {
Target int `json:"target"` // Target player ID (-1 for direction)
Dir float64 `json:"dir"` // Direction if no target
}
PhaserData represents phaser fire command
type PlanetDefenderInfo ¶
type PlanetDefenderInfo struct {
Defenders []*game.Player // All enemy players within detection radius
DefenderCount int // Count of enemy ships
ClosestDefender *game.Player // The closest enemy ship
MinDefenderDist float64 // Distance to the closest defender
HasCarrierDefense bool // Whether any defender is carrying armies
DefenseScore float64 // Calculated threat score (higher = more dangerous)
}
PlanetDefenderInfo contains information about defenders around a planet
type PlasmaData ¶
type PlasmaData struct {
Dir float64 `json:"dir"` // Direction to fire
}
PlasmaData represents plasma fire command
type SeparationVector ¶
type SeparationVector struct {
// contains filtered or unexported fields
}
SeparationVector represents the direction and magnitude to separate from allies
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server manages the game and client connections
func (*Server) ApplyPendingTargetSuggestions ¶
func (s *Server) ApplyPendingTargetSuggestions()
ApplyPendingTargetSuggestions applies buffered target suggestions after all bots have been processed, so processing order does not affect targeting decisions.
func (*Server) AutoBalanceBots ¶
func (s *Server) AutoBalanceBots()
AutoBalanceBots adds or removes bots to balance teams Players and bots count equally as team members for balancing
func (*Server) HandleTeamStats ¶
func (s *Server) HandleTeamStats(w http.ResponseWriter, r *http.Request)
HandleTeamStats returns current team populations
func (*Server) HandleWebSocket ¶
func (s *Server) HandleWebSocket(w http.ResponseWriter, r *http.Request)
HandleWebSocket handles WebSocket connections
func (*Server) OrbitalVelocity ¶
OrbitalVelocity returns the instantaneous tangential velocity of a ship that is currently orbiting a planet. If the ship is not orbiting, ok will be false.
The velocity is returned in world units per tick, which is the same unit that InterceptDirectionSimple expects for target velocity calculations.
type ServerMessage ¶
ServerMessage represents a message from server to client
type SpatialGrid ¶
type SpatialGrid struct {
// contains filtered or unexported fields
}
SpatialGrid provides O(1) average case lookup for nearby entities using a grid-based spatial hash. This reduces collision detection from O(n*m) to O(n) average case.
func NewSpatialGrid ¶
func NewSpatialGrid() *SpatialGrid
NewSpatialGrid creates a new spatial grid for the galaxy
func (*SpatialGrid) GetNearby ¶
func (g *SpatialGrid) GetNearby(x, y float64) []int
GetNearby returns player IDs that might be within range of the given position. The caller must still perform exact distance checks.
func (*SpatialGrid) IndexPlayers ¶
func (g *SpatialGrid) IndexPlayers(players []*game.Player)
IndexPlayers populates the grid with all alive players
func (*SpatialGrid) Insert ¶
func (g *SpatialGrid) Insert(playerID int, x, y float64)
Insert adds a player to the grid
type TeamCountData ¶
TeamCountData holds pre-computed team counts for broadcasting
Source Files
¶
- ai_constants.go
- bot_combat.go
- bot_handlers.go
- bot_helpers.go
- bot_jitter.go
- bot_navigation.go
- bot_planet.go
- bot_types.go
- bot_weapons.go
- bots.go
- combat_handlers.go
- communication_handlers.go
- debug_config.go
- game_helpers.go
- game_state_handlers.go
- handler_utils.go
- handlers.go
- intercept.go
- movement_handlers.go
- orbit_utils.go
- physics.go
- planets.go
- projectiles.go
- ship_management_handlers.go
- spatial_grid.go
- systems.go
- tournament.go
- victory.go
- websocket.go