Skip to content

Add Standard Game Mode specification and RFC#1

Open
coreyja wants to merge 1 commit intomainfrom
push-swtnvzzkuxyu
Open

Add Standard Game Mode specification and RFC#1
coreyja wants to merge 1 commit intomainfrom
push-swtnvzzkuxyu

Conversation

@coreyja
Copy link
Member

@coreyja coreyja commented Jan 13, 2026

In order to help standardize the Battlesnake rules, and allow for alternate engine implementations, this is a first draft of a spec document for the Standard Game Mode!

Its goal is to be the source of truth for how to run a Battlesnake game. It should cover all edge cases and be sufficiently detailed that it alone can be used by future implementations.

This is based off the Go rules repo, but we have NOT yet gone through and documented where each specification item is implemented and tested. I'd like to do this in follow ups after we agree on this initial spec!

@nosnaws
Copy link

nosnaws commented Jan 15, 2026

Hey @coreyja, what kind of feedback are you looking for?
I gave it a quick read and it looks fantastic! I’ll plan to do a deep read of it this weekend.
Cheers!


### 1.2 Board Dimensions

Standard board sizes are:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if it's worth mentioning here - standard board sizes are all odd dimensions for competitive purposes:

  • Head-to-head collisions are only possible when all players start on all "black" or all "white" checker board spaces.
  • Applying that to even dimension game boards creates asymmetry in starting positions
  • Visually, having a single center coord makes for dramatic gameplay

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes love this added color!

Visually, having a single center coord makes for dramatic gameplay

Ahh hadn't thought of this before personally, thats cool!


- `body[0]` is the snake's **head**
- `body[length-1]` is the snake's **tail**
- Adjacent body segments MUST be orthogonally adjacent (Manhattan distance of 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manhattan distance of 1 or 0 (to account for next bullet point)


| Constant | Value | Description |
| ------------ | ----- | --------------------------- |
| `MAX_HEALTH` | 100 | Maximum and starting health |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not list starting health here - that's a function of board initialization using MAX_HEALTH, not necessarily a constant

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh ya fair! I do think its true that for Standard mode starting == max, but I think its worth touching up the wording since other game modes are coming soon enough anyways 😆

Each turn executes the following phases **in order**:

1. **Game Over Check** - Determine if the game has ended
2. **Movement** - Apply snake moves
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth including that snake moves are requested, either before or as part of this step? Just to be super clear what state snakes receive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya good callout! This was too focused on just the rules eval, but does need that context to make sense as a spec I think

### 2.2 Turn Numbering

- Turn 0 is the **initial state** before any moves
- The first move request is sent during turn 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth saying that start request gets turn 0 too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, probably! In general this spec could probably talk about the actual Snake requests a bit more 🤔


If a snake does not provide a valid move (timeout, invalid response, etc.), the implementation MUST apply a **default move**.

The default move is determined by the relationship between the head and neck:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably worthwhile stating that the intent of the default move algorithm is to "maintain the intent of the previous move", ie; keep moving forward.

The algorithm exists purely because the previous move can be deduced from body state. But the result could also be achieved by storing and applying the move from turn N-1.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I actually made a similar edit this morning before realized you left such great comments 😆

I also like adding the note that its re-producible from board state, but could just be implemented by remembering the last move too!

If neck.Y == 0 AND head.Y > 0: default = "down"
```

If the snake has fewer than 2 body segments, or no direction can be determined, the default move is `"up"`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth abstracting out a MIN_SIZE constant of 3, and applying it in these cases. I don't think that actually exists in my code, but could.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, no reason to have hard-coded "magic numbers" in the spec 👍


### 3.4 Simultaneous Movement

All snake moves are applied **simultaneously**. The order in which snakes are processed during movement MUST NOT affect the outcome. Each snake's new position is calculated based on the state at the **start** of the movement phase.
Copy link
Member

@bvanvugt bvanvugt Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order in which snakes are processed during movement MUST NOT affect the outcome.

This is good wording!

snake.health = snake.health - 1
```

### 4.2 Starvation Elimination
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small detail but we've intentionally moved away from "starvation" language (it likely still exists in some places) - both for social impact reasons, and because food is not the only source of health, and movement is not the only source health reduction.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, great point! Changing now!

If multiple snakes' heads occupy the same food position:

- **All** snakes consume the food (health restored, growth applied)
- The food is removed once
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be described as two distinct phases:

  1. Food Consumption: Grow any snakes whose head shares the coordinates of food
  2. Food Removal: Remove any food whose coordinates are shared with the head of a snake

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes I think that matches the impl closer, and I think makes it clearer how things happen.


### 5.1 Food Consumption

A snake consumes food when its **head** occupies the same position as a food item.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth mentioning that by this spec, food can only exist where a snake body or tail is not (but can share head coords)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup I think so! I'm also thinking about how much the food spawning needs to be defined as part of this spec... Starting to think it really should be cause can't impl a standard game without it really.

Which we can def do! And likely just leave a note that randomness is 'unspecced' for now, and we can follow up with a deterministic randomness RFC after this (which I have a draft of too somewhere)

Elimination checks MUST be performed in this order:

1. **Out of Health**: Check if `health <= 0`
2. **Out of Bounds**: Check if any body segment is outside board boundaries
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooo nice callout on any body segment.


When a snake collides with another snake's body, the collision is attributed to the **other** snake.

When multiple snakes could be credited for a body collision (in edge cases), the elimination MUST be attributed to the **longest** snake involved.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if multiple snakes are tied for longest?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes, I was too Duels brained here lol

The game ends when **one or fewer** non-eliminated snakes remain:

```
count = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be cleaner if named 'num_non_eliminated_snakes' or similar.

### 8.2 Winner Determination

- If exactly 1 snake remains: that snake wins
- If 0 snakes remain: no winner (draw or mutual elimination)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably remove the "mutual elimination" here and just go with "draw", which can then be defined cleanly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh ya no need for a fancy term here, that's just a "draw" lol


### 8.3 Game Over Check Timing

The game-over check is performed at the **beginning** of each turn, before movement. This means:
Copy link
Member

@bvanvugt bvanvugt Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably makes it important to know when move requests are sent to snakes.

@coreyja
Copy link
Member Author

coreyja commented Feb 4, 2026

@nosnaws thanks for taking a look! Any comments or feedback you have is great.
My goal here is that someone could take this spec file, and fully implement a Battlesnake game engine from it 😆

Which is a lofty goal, so there are definitely things that are under-specced for that. And I think there are likely parts of that we won't spec here (for example how randomness works), but ideally I think it would be cool to have a 'formal' spec for basically everything we reasonably can!

@coreyja
Copy link
Member Author

coreyja commented Feb 4, 2026

@xtagon to continue our Discord convo from a few weeks ago here if you don't mind.
I'm definitely interested in a more formal language to define the rules in! But I think I want to do this first, but down to do that eventually and assuming it goes well call that the 'canonical' version.
I want to do the English speccing cause:

  • It seems like a fun excersice, since I'm not used to writing formal specs
  • Battlesnake seems simple enough to formally spec in English

But I'm happy to be proven wrong on both those fronts 😆

Also I do agree I was using pseudo-code here as a crutch so tried to cleanup up most/all of it. And will continue on my next passes!

Introduces formal specification for Battlesnake Standard mode, enabling
alternative implementations to achieve compatibility with the official
rules engine.

RFC (rfcs/2026-01-standard-mode-spec.md):
- Motivation for formalizing existing rules into a spec
- Scope and relationship to future PRNG spec

Spec (specs/game-modes/standard.md):
- Coordinate system and board state representation
- Turn phase ordering (game over, movement, starvation, hazards, feeding, elimination)
- Movement mechanics including default move logic
- Elimination rules with exact priority ordering
- Head-to-head collision resolution
- Examples in appendix

Note: Full reproducibility requires upcoming PRNG specification for
randomness in initialization and food spawning.
@coreyja
Copy link
Member Author

coreyja commented Feb 4, 2026

@bvanvugt Thanks for all the detailed feedback!!

Folded it in a bit quickly this morning, and want to take a fuller pass on my train home today

@xtagon
Copy link

xtagon commented Feb 5, 2026

@coreyja Makes sense! We could also link to specific lines (github permalinks can highlight lines) of the Go rules in reference to certain rules in the spec. It might help not just with readers of the spec, but help with the process of us defining it. I know I pour through the Go code a lot when implementing my own engines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants