Skip to content

Filter to enable imperfect information for standard mode#127

Open
IKenTN wants to merge 6 commits intoBattlesnakeOfficial:mainfrom
IKenTN:main
Open

Filter to enable imperfect information for standard mode#127
IKenTN wants to merge 6 commits intoBattlesnakeOfficial:mainfrom
IKenTN:main

Conversation

@IKenTN
Copy link

@IKenTN IKenTN commented Nov 13, 2025

I've implemented an imperfect information mode for the standard map (only currently). I'm fairly new to GO, but I've tested it from the snake side too and it seems to work as intended.
New features:

  • a new -i flag to view the radius for all snakes
  • saves food in gamestate and shows it globally on the spawning turn for all snakes
  • filters all information for each snake and only returns things within the view range

@IKenTN IKenTN requested a review from bvanvugt as a code owner November 13, 2025 13:56
@IKenTN
Copy link
Author

IKenTN commented Dec 11, 2025

Some information:

  • I used a map because I needed to save the food spawns to enable global visibility (I assume every map has a different food spawn mechanism, but I only needed to tweak the standard one slightly)
  • I have now set the view range to 5 as standard (it was previously adjustable with a flag), since I also edited the visualisation inside the board repo and needed information on the view range (If you have any suggestions on how to incorporate this information into line 205 of play.go without making significant changes to the rest of the file, please let me know)

@coreyja
Copy link
Member

coreyja commented Feb 10, 2026

Hey @IKenTN sorry for the long time without a review!

Going to leave my high level comments here, but will leave a few code level comments as well!

My first question is how you all intend to work with this new map for your upcoming tournament, and what the goal of getting it merged is? Totally just so I understand! I love this mode and totally down to get it merged, but understanding how you all intend to use it will help with that I think!

I recently took over Battlesnake, and one thing I'm working on right now is re-writing the core infrastructure in Rust. And that's relevant here, because I'm already considering this repo almost 'legacy' and so I'm happy to do whatever makes it easiest to support you all with the tournament and game mode! I love this mode, so I will want to port it to over to Rust at some point but I'm getting ahead of myself.

I noticed the bit of gymnastics to use GameState, since its a string valued map. I think this is the only usage of GameState in the repo today, so if it would make it easier to either relax its types, or just change em to integers I think I would be ok with that.

Snake Experience

As far as the snake experience here, I don't love sending the 'sentinel' values of 0 for health and { X: -1, Y: -1 } for body segments you can't see 🤔 I think the health of 0 is likely to trip up lots of snakes, as would the -1 coordinates.

So if snakes are already going to have to be custom coded, could we maybe make it more explicit in the API? For this mode maybe we can make some 'experimental' API changes that aren't part of the official spec?

Body Segments

For these I think first we should decide if snakes should get the full lengths of their opponents? Right now I think snakes get the full length if they can see the head of the snake, and its completely invisible otherwise.

One idea — maybe we can add a nullable length field to snakes, and if you can see the head of a snake we include it? And then we can just filter out body segments that aren't visible, which I think might be slightly more intuitive? But curious how you all are thinking about this and what would work best for the tournament snakes!

And right now if you can see the head, you also know the index of all the body segments. If we wanted to preserve this we could send the body segment index in the filtered body array.

Health

I think it might feel best from the snake POV to have this be nullable, and if its not filled in you just don't know that snake's health.

But I also don't necessarily think these are show stoppers! Especially if there are already snakes/infra/anything else that is built around these health and coordinate values. They obviously require less code changes than what I am suggesting!
Basically tell me what, if any, changes you are up for and we can figure something out!

Comment on lines +76 to +83
for k, v := range editor.GameState() {
if strings.HasPrefix(k, "food_spawn_") {
spawnTurn, _ := strconv.Atoi(v)
if spawnTurn < lastBoardState.Turn {
delete(editor.GameState(), k)
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think its strictly needed to cleanup these values, but its probably a good idea anyways!

for _, f := range boardState.Food {
visible := manhattan_d(f, head) <= viewRadius
key := fmt.Sprintf("food_spawn_%d_%d", f.X, f.Y)
spawnTurnStr, spawned := boardState.GameState[key]
Copy link
Member

Choose a reason for hiding this comment

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

In a bigger refactor this feels like state that we could just fold into the actual game structs. It would fit with the TTL value that has been discussed being added for things like hazards in the past. But I'm just chatting, no action item!

@ymahlau
Copy link

ymahlau commented Feb 12, 2026

Hi @coreyja thanks for the review!

To give a bit of background on the design decisions on our side: We developed the new game mode for a university class in our own simulator. At the time we did not want to change the API for users, because our students should both participate in the online leaderboard and the new game mode. Therefore, we used the "sentinel" values to keep both the effort on our side low and make it easy for the students to participate in both game modes.

The intended rules for the new game mode would be:

  • a snake never sees the health / length of other snakes
  • food is only globally visible in the turn when it spawns
  • If a snake sees multiple patches of another snake's body, then our rules would add a "filler" in between to signify that there is something not visible of the body.

To explain the last point: if we were to simply give a list of the body parts that are visible then there may arise situations where it is not clear if part of the body is missing. This could also be used as simply part of the game rules. We felt it more natural to give players this information, though there are no strong feelings attached here. I do think the first two points whould stay, because they make for fun gameplay.

@IKenTN, Coreys comments seem to indicate that this intented implementation is not the same as implemented in this PR. Thoughts?

For our competition in the summer, we will use the API as described above, because we internally have a working engine for that. However, for the online leaderboard, I agree that it would be worthwhile thinking about how to make the API as good as possible.

Also while having the custom view radius as a filter, which can be combined with other game modes would technically be the "cleanest" implementation, we had intended this PR to do as little code changes as possible and implemented the mode as a single map. But if you are re-writing the repo anyways then we could also define having a filter as a new goal. I am not sure how this should be implemented though.

If you are re-writing the whole codebase, what do you think should be the best next steps to get this mode implemented? Should we leave this PR as a draft/prototype, then wait for your re-write and implement there? I guess it would make sense to keep the integration of this PR in mind when doing the re-write.

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.

3 participants