Soccerbots is a turn-based 1v1 soccer simulation. You control 4 players trying to score goals against an opponent's 4 players.
Core Loop:
- Engine sends you the current game state
- You respond with 4 actions (one per player)
- Engine processes all actions and advances one tick
- Repeat for ~7200 ticks per match
Standard soccer field layout:
- Goals at opposite ends (your goal vs opponent's goal)
- Walls around the perimeter (ball and players bounce off)
- Penalty boxes around each goal (players cannot enter, ball can)
- Center line divides your half from opponent's half
Each player has:
- Position (vector)
- Direction (vector)
- Radius (collision size)
- Pickup radius (distance they can grab the ball)
All players are identical - no special roles or stats.
Each turn, send exactly 4 actions (one per player):
PlayerAction {
movement_vector: (x, y) // Max magnitude 1.0
pass_vector: (x, y) // Optional, max magnitude 1.0
}
Movement: Players move in the direction specified (magnitude 1.0 = full speed)
Passing: If holding the ball, kick it in the pass_vector direction (magnitude 1.0 = hardest kick)
The ball has three states:
- Any player can pick it up
- Ball enters FREE state when no one is holding it
- If ball enters a player's pickup radius, that player gains possession
- Tie-breaker: If two opposing players reach the ball simultaneously, coin flip decides
- One specific player owns the ball
- Ball follows that player around
- Stealing: If opponent players get within pickup radius, they add "capture ticks"
- 1 opponent nearby = +1 capture tick per turn
- 2 opponents nearby = +2 capture ticks per turn
- At some threshold, possession transfers to opponents
- Passing: Ball owner can use pass_vector to kick the ball
- Ball is moving through the air after a pass
- Passing team cannot recapture until ball leaves all their pickup radii
- Prevents immediate re-possession and tiny passes
- Inaccuracy: All passes have ±10 degrees random error
- Once ball leaves all passer pickup radii → becomes FREE
- Get the ball into the opponent's goal
- When scored, field resets for kickoff
- Match ends after ~7200 ticks
- Highest score wins
Field resets (all players choose new positions) when:
- Goal scored
- Ball stuck (stopped moving for too long)
- Endgame triggered
During reset:
- Players must stay on their half of the field
- Must maintain minimum distance from ball
- Choose positions strategically
If tied at the end of regular game play:
- Field resets
- Ball has no friction (keeps moving forever)
- Entire wall becomes the goal
- First goal wins
Don't rely on endgame, it's chaotic by design!
- Ball control is everything - possession leads to scoring opportunities
- Positioning matters - cut off opponent passes, create your own lanes
- Team coordination - 4 players working together beats 4 individuals
- Defend your goal - opponents only need one good shot
- Add randomness - predictable bots get exploited
- You can submit a bot at any point in time
- For the final tournament, we will use your most recent submission before the submission deadline
- Submit though the
mm-cli. Further instructions in the starterpacks
- Before the bot submission deadline, we will have ongoing Friendly tournaments.
- Our server will run some matches every 30 minutes with bots that have been submitted.
- You will be able to see the current leaderboard as well as matches played
- A full round-robin will be played to determine the final score of teams
- A win is 3 points, a tie is 1, and a loss is 0
- The more points, the higher rank
The engine uses a turn-based system to accept your bot's player action inputs. Each turn your bot has a fixed amount of time (relative to the engine's execution speed) to respond, and if your bot times out, the engine will output an error message in the game log.
Clone a starterpack (Java/Python/Rust) and follow the directions in its README.
Join the Discord server and ask in #ask-a-question-here.
