After some feverish activity on the dungeon editor and game engine, my thoughts have returned to the more sedate realm of design and architecture. No smoking jackets or pipes required, just thinking time.
So far, I have a few pieces of work that could be added to the game, but things are a bit all over the place. Tyrus or Rikulo, which does what, do I need two servers… All these questions need to be answered before the game can progress as a whole. Needless to say, as this is a fun project with zero budget, there is no project manager riding me to do things in a predictable and orderly manner. I can do whatever I want, in whichever fashion I choose. Still, there’s no point is going in circles from analysis paralysis or fooling about. Finishing things is always nice.
So, the major ‘pieces’ of the game tech stack currently floating about in my head are:
1) WebSocket Server – realtime game details and management.
2) Web Server – the web server (the Rikulo one)
3) Dart Browser Voodoo – Dungeon Editor, monster arena and other goodies – the actual bits players care about.
Each of these pieces are either browser based or server based. With Dart, it is important to keep in mind whether your libraries/packages are client-only, server-only, or both. Certain Dart libraries work on only one of these environments (dart:io), while others can be on both (dart:convert). So you can build a library with the browser in mind and later try and use it on the server, only to find your Dart compiler or VM very unhappy with you. I got bitten by this a little bit, but got myself out of a potential mess with relatively little pain. Lesson learnt.
All this pipe smoking and hand-waving eventually boiled down to the following principles:
- Do as much work in the browser as possible
- Minimize network bandwidth
- Prefer the WebSocket Protocol over Http
- Data streamed in standardised text format (JSON and YAML)
- Store stuff in files on the server
Ok, I can live with that. Now some details and a picture.
The Web Server
The web server keeps track of the minimal amount of static player data:
- Name, id, and email
- Other user preferences I have not thought of yet (the usual social media cruft)
- Data transferred as text (YAML)
So, for a player the web server would store something like the following:
Player: Id: 123456789 Alias: DartJunky Email: firstname.lastname@example.org
That’s about it for now. I’m sure there will other bits, but nothing to worry about for now.
The WebSocket Server
The WebSocket server manages real-time play and static game data:
- Current game state for a player
- All dungeon and item data
- Data transferred as text (YAML)
So the WebSocket server will store all the interesting stuff. Here’s a sample of what I plan todo (in YAML of course, because it’s my data format of month).
player: id: 123456789 name: DartJunky current_games: game: id: 781 dungeon: 100 character: 2 game: id: 782 dungeon: 101 character: 3
character: id: 3 name: Mongo the Mad class: wizard level: 3 money: 33 attributes: strength: 12 agility: 6 intelligence: 15 dexterity: 11 constitution: 6 armor: 4 hitpoints: 25 items: id: 3331 id: 1231
game: id: 781 name: Lair of the Chicken character_location: 45,55 character_health: 13 npc: monster: id: 334 location: 33,44 health: 12 monster: id: 788 location: 13,44 health: 6 items: item: id: 897 location: 12,12
All the graphics and wizbangery is done in the browser. Kind of obvious I’ll admit, but I wrote it down for completeness.
The browser code will:
- Convert text based data (dungeon specs, character specs and state) into dart objects
- Continually update the WebSocket server with new game state. This will a stream of small packets of information – ideal for web sockets
- Receive state updates from the WebServer Socket
A Typical Scenario
The idea is that the web site is the gateway and manager of the game experience, whilst the WebSocket server and browser do all the gameplay heavy lifting.
Here’s how it would work:
- User logs in to the web site, and gets their user id and a session key. (Under the hood, of course, all the player sees is that they have logged in).
- The browser then gets the relevant player data from the web socket server and draws the web page.
- User picks a game they want to continue, or does something else, like create a new character or buys a shiny new mace.
- Browser talks to web socket server and updates all the user changes.
- Player keeps playing….
- WebSocket server keeps the state updated, with minimum bandwidth fuss.
There is some unresolved issues around the browser game state and WebSocket game state, but I do not have enough experience to sort this out in advance. I’ll figure it out as I go.
So that’s the plan. Things seem OK for now – fairly simple, no bad smells in the code, no police sirens. In one word or less, good enough.