Files
football/docs/specs/2026-05-12-match-logic-design.md
2026-05-12 10:54:09 +03:00

3.2 KiB

Design: Match Logic & Game Rules (M5)

Goal: Implement a high-level match management system to handle scoring, game timing, and state transitions (Playing, Goal Pause, Match Ended).

Architecture: Introduction of a MatchManager component that acts as a controller over the World. The World remains responsible for physics and AI, while the MatchManager handles the "rules of the sport".


1. Components

MatchManager

The central authority for the match state.

  • GameState: Playing, GoalPause, MatchEnded.
  • Score: ScoreRed, ScoreBlue (integers).
  • Match Timer: MatchDuration (total time) and CurrentTime (elapsed).
  • Pause Timer: PauseDuration (fixed duration for goal celebration) and PauseTimer (countdown).
  • Reference: Pointer to World.

World (Extensions)

  • CheckGoal() (team entities.Team, scored bool): Checks if the puck has crossed the goal lines (X < 0 or X > WorldWidth).
  • ResetPositions(): Resets the puck to the center and all players to their HomePosition, zeroing out all velocities.

2. File Structure

  • internal/game/match_manager.go (New):
    • Definition of GameState and MatchManager struct.
    • Update() method to drive the match lifecycle.
  • internal/game/world.go (Modified):
    • Implementation of CheckGoal() and ResetPositions().
  • cmd/game/main.go (Modified):
    • Replace World with MatchManager in the Game struct.
    • Update Update() and Draw() calls to go through MatchManager.

3. Data Flow

Main Loop \rightarrow MatchManager

Game.Update() \rightarrow MatchManager.Update():

  1. If Playing:
    • Call World.CheckGoal().
    • If goal \rightarrow transition to GoalPause, increment score, start PauseTimer.
    • If no goal \rightarrow call World.Update() (physics/AI) and increment CurrentTime.
    • If CurrentTime >= MatchDuration \rightarrow transition to MatchEnded.
  2. If GoalPause:
    • Decrement PauseTimer.
    • If PauseTimer <= 0 \rightarrow call World.ResetPositions() and transition to Playing.
    • World.Update() is skipped (game is frozen).
  3. If MatchEnded:
    • World.Update() is skipped.

World \rightarrow MatchManager (Goal Detection)

  • X < 0 \rightarrow (TeamBlue, true)
  • X > WorldWidth \rightarrow (TeamRed, true)
  • Otherwise \rightarrow (_, false)

4. Edge Cases & Handling

  • Double Scoring: The GoalPause state prevents CheckGoal from being called repeatedly until the world is reset.
  • Reset Collisions: ResetPositions explicitly sets Velocity = 0 for all entities to prevent immediate "explosions" from anti-clumping logic.
  • Boundary Stuck: CheckGoal is evaluated before physics clamping to ensure goals are registered even at high speeds.
  • Last-second Goal: Goals are processed before the match timer check, ensuring a goal on the final frame is counted.

5. Success Criteria

  • Puck crossing the boundary increments the correct team's score.
  • The game freezes for a few seconds after a goal.
  • All entities return to starting positions after the pause.
  • The match stops automatically when the timer reaches the limit.