footballsimulationengine

repository·master·Indexed 41 days ago

https://github.com/gallagheraiden/footballsimulationengine

A football (soccer) match simulation engine version 5.0.0 that allows for iterative, state-based match play. It handles player movement, ball physics including z-axis/gravity, and specific player actions. Key functions include initiateGame() to start a match, playIteration() to advance the simulation state, and startSecondHalf() to switch team sides.

Tokens
2.5K
Snippets
13
Records
15
Agent score
52%

What's inside footballsimulationengine

  1. Understand the Match Details object structure

    master

    The matchDetails object is the primary state container passed between all engine functions.

    Key Fields:

    • kickOffTeam / secondTeam: Objects containing team metadata and player arrays.
    • pitchSize: Array [width, height].
    • ball: Contains position [x, y, z], withPlayer (boolean), direction, and lastTouch details.
    • ball.ballOverIterations: An array used to track ball movement over time. If empty, no new ball movements occur.
    • half: Current half number.
    • kickOffTeamStatistics / secondTeamStatistics: Objects tracking goals, shots, corners, freekicks, penalties, and fouls.
    • iterationLog: An array of strings providing a summary of events in the last iteration.
  2. Override player actions

    master

    In the player object returned during iterations, you can override the default action (which is 'null' for normal simulation) to force specific behaviors.

    Valid Actions:

    • 'shoot' (Requires player to have the ball)
    • 'throughBall'
    • 'pass'
    • 'cross'
    • 'tackle'
    • 'intercept'
    • 'slide'
    • 'run'
    • 'sprint'
    • 'cleared'
    • 'boot'

    Note: Any invalid action will result in the simulation running as normal.

  3. Initiate a match with initiateGame()

    master

    The initiateGame() function is a Promise that starts a new match. It requires two team objects and a pitch information object in JSON format. It returns a matchDetails object containing player start positions, match statistics, ball position, and an iteration log.

    initiateGame(team1, team2, pitch).then(function(matchDetails){
      console.log(matchDetails);
    }).catch(function(error){
      console.error("Error: ", error);
    })
  4. Progress the match with playIteration()

    master

    The playIteration() function is a Promise that advances the simulation by one step. It accepts the matchDetails object (the output from initiateGame or a previous playIteration) and resolves with an updated matchDetails object, representing the new state of the match and player positions.

    playIteration(matchDetails).then(function (matchDetails) {
      console.log(matchDetails);
    }).catch(function(error) {
      console.error("Error: ", error);
    })
  5. Switch sides with startSecondHalf()

    master

    The startSecondHalf() function is a Promise used to switch the sides of each team (e.g., at halftime). It accepts the current matchDetails object and returns an updated version with teams swapped.

    startSecondHalf(matchDetails).then(function (matchDetails) {
      console.log(matchDetails);
    }).catch(function(error) {
      console.error("Error: ", error);
    })
  6. Configure Team JSON data

    master

    Each team must contain exactly 11 players.

    Key Requirements:

    • currentPOS: An array [widthPosition, heightPosition]. For the starting configuration, height placement should not exceed half the pitch height.
    • skill: Values should not exceed 100. Note that skill.jumping refers to the height a player can jump in centimeters (and should typically be > 100).
    • height: Player height in cm.

    Example Team Structure:

    {
      "name": "Team1",
      "players": [{
          "name": "Bill Johnson",
          "position": "GK",
          "rating": "75",
          "skill": {
            "passing": "20",
            "shooting": "12",
            "tackling": "20",
            "saving": "20",
            "agility": "20",
            "strength": "20",
            "penalty_taking": "43",
            "perception": "75",
            "jumping": "30",
            "control": "60"
          },
          "currentPOS": [
            340,
            0
          ],
          "fitness": 100,
          "height": 200,
          "injured": false
        }...],
      "manager": "Aiden"
    }
  7. Run a full match simulation workflow

    master

    A standard simulation lifecycle involves initializing the game, playing a series of iterations, switching to the second half, and continuing iterations until the match is complete. Because each iteration returns a new state, you must pass the output of one iteration as the input to the next.

    // 1. Initialize
    let matchState = engine.initiateGame(team1, team2, pitch);
    
    // 2. Play first half
    matchState = await engine.playIteration(matchState);
    matchState = await engine.playIteration(matchState);
    
    // 3. Switch to second half
    matchState = await engine.startSecondHalf(matchState);
    
    // 4. Play second half
    matchState = await engine.playIteration(matchState);
    matchState = await engine.playIteration(matchState);
  8. Initiate a game with initiateGame()

    master

    Use initiateGame(team1, team2, pitchDetails) to set up a new match. This function validates the input teams and pitch, populates match details, determines the kickoff team via a decider, and sets initial player positions. It returns a matchDetails object which serves as the state for the entire simulation.

    Parameters:

    • team1: The first team object.
    • team2: The second team object.
    • pitchDetails: An object containing pitch configuration.

    Returns: A matchDetails object containing the initial state of the game.

    const { initiateGame } = require('./engine');
    
    const matchDetails = await initiateGame(team1, team2, pitchDetails);
  9. Simulate match progress with `engine.playIteration()`

    master

    The simulation progresses through discrete steps called iterations. Use engine.playIteration(inputIteration) to advance the game state. The function accepts the current state of the match (the inputIteration) and returns a new state object representing the match after that iteration has been processed.

    let nextIteration = await engine.playIteration(currentIteration);
  10. Run a single simulation step with playIteration()

    master

    Use playIteration(matchDetails) to advance the simulation by one discrete step (one iteration).

    Process Flow:

    1. Validates the current matchDetails state.
    2. Processes injuries.
    3. Moves the ball.
    4. Determines the closest players to the ball for both teams.
    5. Calculates and executes player movements and ball actions (e.g., passing, shooting).
    6. Checks for offsides.
    7. Updates the iterationLog.

    Returns: The updated matchDetails object. If the iteration results in the end of a specific game state, the object may contain an endIteration flag (which is deleted before returning).

    const { playIteration } = require('./engine');
    
    // matchDetails is obtained from initiateGame()
    const updatedMatchDetails = await playIteration(matchDetails);