I have not posted anything over the last few weeks, as I have been busy writing the WebSocket server (what gamers would call ‘the game server’) to load and save the game data. This requires a lot of rather boring work saving and writing files as JSON. Oh, and writing unit tests. Writing unit tests for a hobby project seems like overkill, but my scars from previous misadventures compelled my fingers to type them out anyway. Nevertheless, like tax returns, saving and loading stuff is boring but important, so I am plugging away.
I have been using the Tyrus project as my WebSocket implementation and it feels nice. Contrary to popular belief, feelings are important in software development. When you get a good feeling using some piece of technology, that means you are happy and productive, which is surprisingly important. Your inner nerd is telling you that your are getting things done better and faster. Good vibes like these are rarely felt in projects in big organisations, and explains a lot of the 300% cost blowout misadventures you read about in the IT press.
Going back to Java after many weeks of Dart has been interesting. Whilst the Dart ecosystem, is pretty solid already, the Java universe feels rock solid in comparison. My IDE almost reads my mind and completes my sentences for me. There are libraries to do nearly everything that I don’t want to – which is a lot. I would outsource all of my boilerplate development to a small horde of minions if I could. Writing file handling or my own list class got old in the nineties. Alas, I am not rich enough to employ minions to follow me around. Anyway, back to Java – the language issues are still there – who can love methods like getName() in this day and age? But the whole things does feel like a Jumbo 747 – unexciting but mature, robust, and guaranteed not to fall out of the sky.
So, as I grind out code to save and load dungeons, player data and so on, my idle thoughts have drifted to game AI. After some research in the more practical AI books, I discovered that what I was thinking of are called autonomous (intelligent) agents. I prefer autonomous, as no agent I could come up with could do my kids’ homework. I aim for my monsters and NPCs to act in a “non-stupid” manner – any performance above this level is a bonus.
Autonomous agents have the following properties:
- A collection of states, with some way of transitioning between them (moving, attacking, hiding, finding treasure).
- Inputs from the environment (objects, creatures, events)
- Outputs to the environment (run, fight, search,talk)
- Some memory of past events
- Self-directed, autonomous behaviour
Of these, the last point is a defining property that separates agents from plain old software. This property implies a dedicated thread of execution for each agent (conceptually at least). This means that I should be able to add agents to a game and they should “do their own thing”, without any extra coding of logic for that game. As much of the agent should be configuration driven, so I don’t have to write a million lines of code. Overall, I think that this approach will fit particularly well with Dart’s heavy emphasis on asynchronous behaviour.
Exciting stuff , but Robert Frost said it best:
But I have promises to keep,
And miles to go before I sleep
My experiments with agents will just have to wait.