server

package
v0.0.0-...-a534920 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
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
)
View Source
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

View Source
const (
	BotRoleHunter   = "hunter"
	BotRoleDefender = "defender"
	BotRoleRaider   = "raider"
)

Bot behavior roles returned by selectBotBehavior

View Source
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

View Source
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

View Source
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

View Source
var (
	DebugWeapons = false // Set to true to enable detailed weapon firing logs
)

Debug flags for various subsystems

Functions

func AngleDifference

func AngleDifference(a1, a2 float64) float64

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

func NormalizeAngleSigned(angle float64) float64

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

func (c *Client) GetPlayerID() int

GetPlayerID returns the player ID atomically

func (*Client) SetPlayerID

func (c *Client) SetPlayerID(id int)

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 Point2D

type Point2D struct {
	X, Y float64
}

Point2D represents a 2D position

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 NewServer

func NewServer() *Server

NewServer creates a new game server

func (*Server) AddBot

func (s *Server) AddBot(team int, ship game.ShipType)

AddBot adds a new bot player to the game

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

func (s *Server) OrbitalVelocity(p *game.Player) (vx, vy float64, ok bool)

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.

func (*Server) RemoveBot

func (s *Server) RemoveBot(botID int)

RemoveBot removes a bot player from the game

func (*Server) Run

func (s *Server) Run()

Run starts the server main loop

func (*Server) Shutdown

func (s *Server) Shutdown()

Shutdown signals the server to stop background goroutines

func (*Server) UpdateBots

func (s *Server) UpdateBots()

UpdateBots updates all bot players' AI

type ServerMessage

type ServerMessage struct {
	Type string `json:"type"`
	Data any    `json:"data"`
}

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) Clear

func (g *SpatialGrid) Clear()

Clear resets the grid for a new frame

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

type TeamCountData struct {
	Total int
	Fed   int
	Rom   int
	Kli   int
	Ori   int
}

TeamCountData holds pre-computed team counts for broadcasting

type Vector2D

type Vector2D struct {
	X, Y float64
}

Vector2D represents a 2D velocity vector

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL