How to Make a Battlesnake Really Really Quickly

Not sure what a Battlesnake is? It's the computer game Snake from real old phones, but you write code to play it for you against other people's code. Real fun. Check out the official website.

tl;dr

$ npm init battlesnake
# You'll be prompted to answer a few questions
$ cd the-name-of-my-battlesnake # which you provided in the questions
$ npm run start
BattleSnake my-new-snake reporting for duty!
http://0.0.0.0:5000/snake/my-new-snake/0.0.1
Ngrok forwarding: https://8ca8140c53ed.ngrok.io/snake/my-new-snake/0.0.1

Setup

I've enjoyed watching Battlesnake quite a bit over the last year plus, and being a developer experience person I wanted to see how streamlined I could make the process of battlesnake development in the Javascript/Typescript ecosystem. I feel pretty good about having got the initial app creation down to three commands (assuming you have already installed node.js).

To use the scaffolder, run npm init battlesnake. You will be prompted to allow npm to install the scaffolder package, and then asked some questions used to populate your SnakeInfo object. The scaffolder supports Javascript and Typescript.

Once your Snake is scaffolded, enter the newly created directory, and run npm start to get your snake running. Battlesnake works by having a game server make HTTP requests to your snake. To facilitate this, your scaffolded project spins up a http server and uses ngrok to make the server available to Battlesnake's game engine. When you start your snake locally, you'll be given a publicly accessible URL to provide to the Battlesnake engine. You can start playing games immediately! To see how to register a snake and start test games, check out the Battlesnake Getting Started Guide.

Features

The developer experience doesn't stop once you've got a scaffolded project. You can speed yourself up by using the type system, in-context documentation, and abstractions to avoid writing repetitive boilerplate, and focus on writing your snake's brain.

Write your code in the problem domain

The battlesnake package, which your scaffolded snake automatically depends on, exports a class called Battlesnake. The core feature of the Battlesnake class is that it manages an HTTP server internally - when you call start on your Battlesnake instance, the server is spun up. But, you write code based on Battlesnake level events, like in reaction to when the game starts, the game requests a move from your snake for a game, or the game ends. No need to worry about managing your express app, middleware, making sure that your handlers are registered correctly. Just write type checked functions that are aware of the game data, not of the cruft.

Catch errors before you hit save

The battlesnake package also exports types. This means that you can use autocomplete/intellisense to navigate the Battlesnake data structures in your editor. It also means (if you choose to use Typescript) that your editor will catch if you're not returning the right object from your move handler before you even run your code, preventing runtime errors.

Read docs in your editor

Hover docs for battlesnake's onMove event handler register method in Visual Studio Code

The classes, methods, and types in the battlesnake package all provide docstrings, which your editor can use to display documentation to you in your own source code file, right where you need it. In most text editors, you can see this documentation when you hover over a piece of code in your editor.

Game ready by default

Battlesnake works by having a game engine make HTTP requests to your snake - that's why the SDK spins up an HTTP server under the hood. But if you're running your snake on your local machine, setting up Network Address Translation would be a pain, and on many networks you might not have the admin authority to do so. Battlesnake developers have used ngrok to tunnel requests from the game engine to their local snakes.

The scaffolded project uses battlesnake-plugin-ngrok to automatically spin up ngrok for your snake. This means not only do you not have to think about your HTTP library - you also don't even need to think about ngrok! It's already ready to go.

Ngrok even pulls in your local configuration - so if you have an account and are logged in with the CLI, it will know about that.

Where next?

Check out the battlesnake site to register your snake, provide your snake endpoint, and run test matches to see your snake in action, and tweak it to win! Happy hacking.

If you'd like to check out how this works, have a look at the monorepo on GitHub. If you have any questions, comments, bug reports, or feature requests, please file an issue on the issue tracker. For anything else, feel free to write to me on Mastodon or Twitter.