Planet Wars AI Competition with C# and Excalibur.js
This past weekend Erik and I built out a Planet Wars server (written in C#) and an Excalibur.js-powered visualization (written in TypeScript). Planet Wars is an AI competition where you build an AI that competes against another player to control a solar system. A map consists of several planets that have different growth rates and an initial number of ships. You have to send out a "fleet" of ships to colonize other planets and the player who controls the most planets and has destroyed their opponent's ships wins the game.
At work we are hosting our 6th Code Camp and recently we started hosting an AI competition internally. You can find past competition agents for Ants and Elevators, for example.
The visualization for Planet Wars is fairly simple, made even simpler using the power of Excalibur.js, the engine we work on during our spare time. We basically just use an Excalibur timer to query the status of the game state and update the state of all the actors in the game. For moving the fleets, we just use the Actor Action API.
For the game server, we are using a HighFrequencyTimer to run a 30fps server and then clients just send commands via HTTP, so any kind of agent will work like Python, Perl, PowerShell, or whatever! Anything that speaks HTTP can be a client. The server runs in the context of a website so we can easily query the state using a singleton
GameManager. This wouldn't work in a load-balanced environment but it doesn't matter since people develop agents locally and we run the simulations on one server at high-speed to produce the results. If you backed the server with a data store, you could replay games but right now there's only an in-memory implementation.
To keep the server and client models in-sync, we use Typewriter for Visual Studio which is amazing and super useful not just for syncing client/server but also generating web clients, interfaces, etc. from C# code. I plan to write a separate post on some Typewriter tips for Knockout.js and Web API.