Imperium uses some game data that could be fairly dynamic. This includes things like the single- and multiplayer scenarios, engine parameters and all AI behavior scripts. Initially all this data was included in the normal game bundle. Easy solution as there’s really nothing to do but to load then data when needed. It’s also not very dynamic. To tweak a parameter, improve the AI slightly or just fix some issue in a scenario I would have to create a new version and submit it to the App Store. There it would be subject to the normal app review delay, making any form of quick turnaround impossible. Clearly not ideal.
To solve this I added an asset server to the normal multiplayer server. This game server runs on some hosted server and will be used for multiplayer games. It was quite simple to add some extra requests to allow the server to also serve asset data from a set of known files. The game would upon startup request a list of available assets. Each asset in the list would have a version and Imperium would compare the version to a local version and request a new version if the server had a newer one. Easy to set up and manage. The server side would just be a simple text file containing the asset index which could be easily updated as new asset versions were created. The problem with this solution is that the server is not really 100% done yet and requires some work in order to scale and be robust enough. That requires time that I don’t have right now.
In order to not have to work on the server asset handling I moved the static assets to Apple’s iCloud and access them via CloudKit. The conversion was quite easy and the code is now a lot simpler. The simplicity is mostly because I don’t have to worry about network communication myself, that’s handled by CloudKit. I also do not have to worry about scalability or stability of the server, that’s also handled by someone else. The asset downloading is perhaps a tiny bit slower now, but there will not be too frequent changes anyway so that’s a hit I’m willing to take. For single player games my own server will not be used at all for now, it will be back in the picture when it’s time to finish the multiplayer side. The game will download only changed assets by using a similar version attribute. Each game keeps track of the last version of assets it has downloaded and just asks CloudKit for any new assets with a higher version. Sometimes the result is empty, sometimes it’ll get some assets.
The drawbacks of using CloudKit is that the asset handling is a bit more cumbersome from my point of view. Uploading assets has to be done via Apple’s CloudKit dashboard and there is no easy form of automation available that could, say, sync the assets that I have locally with those on CloudKit. There is a web service that can be used to build such a thing, but it’s far too low level for this to be a viable task for me to do now. So assets will have to be manually click-click-click uploaded when they change. Not a terribly big issue once the game has been released, but while developing it’s a bit annoying.
But there’s been progress at least, some minor part has been finished. 🙂
The original tutorials for Imperium were not too great. Or specifically the third one was a bit buggy and it was easy to do something that confused the tutorial and messed up the progression. That tutorial has now been redone and it’s much less fragile and easier to play. The game will still require all three tutorials to be played through before allowing any online or campaign games to start. That’s just to make sure that all players have at least some form of grasp what the game is about before jumping into online battles without any idea how to play.
There has been a possibility to put updated content on the server and have the game download that when it starts up for quite a while. Now I however changed the system so that a lot of the real game content is always downloaded from the server instead of being shipped with the game. When starting up for the first time all scenarios, campaign data, AI data as well as all help files will be downloaded from the server and saved locally on the iPad. From then on each start will check if there is some updated data and download if available. This allows for trivial distribution of new scenarios, update old ones, tweak the AI and write new help documentation without having to do an App Store update. The server side resource system is also very simple to handle, so I see this as a very nice improvement.
As normal, if you want to play the game is it is now, get in touch and I’ll set up a TestFlight version for you. So far there have been absolutely no interest for any of the test versions I’ve released over the years. I assume that’s an indication that this type of game really isn’t interesting to anyone, or that Imperium simply looks boring or bad. I assume it’s the former.
The multiplayer code in Imperium has seen a lot of work this summer. It’s shaping up quite well and it’s soon in a state where it can be tested live. Setting up games works fine via a server hosted by https://www.digitalocean.com/. Latencies seem to be ok but I still need to do some measuring to make sure there are no issues. The lobby works ok and it’s possible to set up games that others can join.
The video below shows how to set up an online game from scratch as well as how to edit armies.
The multiplayer code in Imperium has seen a bit of activity lately. A new server has been written to work as the backend server and the old PubNub backend was ditched. Before that I used Photon, but it was a real cluster mess when used from Objective-C, it was quite clear that they did not care one bit about keeping that API up to date. So, an own simple server it was. That server is open source and can be downloaded from GitHub. I will host the backend where Imperium connects to on Digital Ocean.
The main change to the multiplayer code is that previously multiplayer battles were predefined scenarios with a fixed map and fixed units. That meant that there was not too much variation between battles. The new thing is that the player can define own armies which are used in multiplayer battles. These armies are a bit like decks in Clash Royale and similar games. There can be three different armies defined and they can contain any kind of units. When the player starts a multiplayer battle he/she first selects the army to be used and then proceeds to either host a game or join an existing game.
The army selection screen looks like this:
Army selection screen
Select the current army from the buttons on the left, view the contents of the selected army on the right and then tap Play to continue with the multiplayer setup.
Pressing Edit takes the player to the army editing screen where the contents of the selected army can be changed.
Army editor screen
When creating an army there are two limitations:
the army can contain a maximum of 20 units
the total cost of the army can be max 1000 credits.
The three buttons on the left select what troop types should be shown on the right side field. The Standard troops (shown above) are normal infantry and cavalry troops. The Artillery troops contains all artillery units and the Support troops are various smaller support teams such as machine guns, mortars, snipers and flamethrowers.
All units have a cost associated with them. An army can cost 1000 credits. The cost of each unit is shown after the unit name.
All units are available as individual units as well as larger formations. The larger formations all come with a headquarter unit and various other units. The larger formations give price discounts as well as a headquarter as a bonus unit. The contents of each larger formation is shown below the formation name.
This is a minor post just to mention that there’s now a new weapon type in Imperium. It’s quite easy to add new weapon types, especially if they are similar to some old weapon type. The new one is a sniper rifle which basically is a normal rifle with a longer range and far better accuracy. Normal infantry shooting with normal rifles are not very accurate at all, they mostly shoot in the correct direction. The sniper rifles are meant to be used by small support units of a few men, not big formations. The role of all the support units is to provide specialized support to the bulk of the troops. The sniper units will join the other support units: mortars,machine gunners and flamethrowers.
In other news, there is not much other progress. I tried to improve the scenario selection screen with a new commissioned background, but it did not work out how I intended it. I’ll see what to do about that, but for now it sapped my motivation pretty badly and I can’t really be bothered to put in any serious effort.
Imperium will use a dedicated server for handling online games. An online game is always between two human players that currently have online access. The server is written in Python and is very minimal. The server handles both TCP and UDP:
TCP is used for all setup for the games, such as lobby handling, announcing games, player data etc.
UDP is used for all updates once the game has started.
The server know about announced games and connected player and handles the starting of games when a player has joined an announced game. Basically everything that relates to handling a lobby. Anything to do with the real Imperium data or logic is unknown to it. When the games start the server becomes a simple data relay that just forwards packets to the other player. The only exception here is a ping packet which the server answers.
Imperium will have a really simple “lobby” where available games are shown and you can choose to host a game of your own. There will be no filtering, ranking or similar, all open games are available to all players. Initially when players connect to the lobby they enter a name that will be shown to other players. No filtering or sanity checks are done (yet) on these names. Time will tell if that needs to be done.
Once a name has been entered Imperium will connect to the server and show the lobby. The lobby lists games that other players host that currently await an opponent as well as the scenarios that the local player can choose to host. To join a game in the lobby simply tap on it and it will start. To host an own game just select a scenario from the list and tap Host on the next screen. Imperium will now show a waiting screen while it waits for some other player to connect to the game. Once a player connects the game starts. As soon as both players have loaded the scenario in question the server starts the game.
Game engine architecture
It’s quite hard to get a good architecture for doing realtime games. As time is a factor when resolving action it all depends on where the action is resolved so that it’s fait to both players. There are a few possibilities:
the server resolves all action and the players just display the results and handle input. This is fait to both players, but requires a server with full knowledge of the game logic, basically a client without any graphics. Imperium’s server is very dumb and doesn’t know anything about the game other than sending some data back and forth.
one player does all the calculations. This is unfair to the second player who will always have a lagging connection to the server. The local player will be able to perform actions and see results a bit faster, thus getting an unfair edge.
both players calculate all action. This would be fair to both players, but would be a bit complex when it comes to keeping it all in sync.
both players handle the calculations of the local player’s units.
The last of the options has been chosen for Imperium. Each client will handle the calculations for all the local player’s units. This is fair to both players as both handle their own units without any lag. There will be a fair deal of synchronization going on as both clients will send all changed missions to the other as well as updates for moving units. This method will make it possible that a client acts on old data, for example firing on a unit that technically has moved out of range. But as the action is very slow paced and it doesn’t really matter much if some limit will be exceeded a bit, this shouldn’t really be a problem.
All the updates for units that move or change state somehow will be sent as UDP packets to minimize lag. Periodically extra data with all missions etc will be sent so that both clients can keep their state in sync.
Some real like issues have more or less prevented me from doing much on Imperium since the last update. I won’t have much time over this fall, but there has been some progress though and I’ll try my best to push out a new test version soon.
The AI has seen a bit of an overhaul and now the foundations are looking very good. The rules that actually make the computer units do things will still need a lot of work, but everything needed to make those decisions is ready. The efficiency of the AI code is also improved and the AI calculations are now spread out more in order to avoid hiccups in the game when the AI is executed.
There is now a new weapon type: howitzers. These are guns that can be used to do direct fire just like the other cannons but they can also be used to provide indirect fire just like the mortars. Their range is longer than that of the mortars, so howitzer units can be used to provide efficient fire support and attack units they can not see themselves.
Headquarters automatically rally units that have routed that are within their command control radius. Now the headquarters can also be given an explicit rally mission that has the headquarter focus on a particular own unit and makes it rally much faster.
The networking component will be PubNub. Originally Photon was to be used, but their Objective-C API is a real mess and very hard to use. It’s basically just a very low level set of calls without any documentation whatsoever apart from a badly designed example application. I wasted a lot of time with Photon in the past and during the summer while trying to get the new version to work. PubNub is much cleaner and the API is magnitudes easier to use. It has not yet proved itself to actually work in a realtime game context though, so we’ll see how it goes. The idea now is to see if the multiplayer could be added to version 1.0 after all.
It seems that Imperium is now more or less feature. I’m looking at the Trello lists where all features, todo:s and bugs are listed and they are more or less empty right now. Of course there are some items left, but none of those are really too important. So it seems that there really isn’t too much new that needs to be added at least right now. There is obviously a lot of balancing and tweaking to be done, that all important “polish” that everyone raves about.
What now is needed is content such as scenarios and a narrative that holds it all together. This is not something I’m good at. In fact, I suck at making content that requires a creative imagination. 🙂 Of course, the scenario editor is still open source so anyone can help out. The scenarios are even easy to test on an iPad directly from the scenario editor. If you’re interested, get in touch and I’ll get you started.
Once there are 15-20 ok scenarios the game can be released. I do plan on adding more content later after release, but there must be a solid base set at release. Nobody wants to buy a game with 1h of play time.
I’ve recently added a fair deal of features to Imperium and thus making it quite feature complete. In my opinion strategy game engines always need to handle fatigue and morale if it makes sense for the scale and game type. Until now Imperium hasn’t had neither. I’ve now added the first versions of both to the engine and it seems to be a good addition.
Fatigue is simply how tired the unit is. It is tiring to roam around a battlefield, possibly at a fast pace and always be doing things. Everything the unit now does will affect the fatigue by either increasing it or lowering it. A unit that stands idle will rest and a unit that does something else will gain fatigue. Some missions are more tiring than others, i.e. it’s much harder to assault than to stand still and fire. Even firing will make the unit tired eventually.
Currently there is a penalty that affects most things when the unit gets sufficiently tired. It’s a linear modifier which makes all activities a bit slower and less efficient.
Morale affects how well a unit performs in combat and when fired upon. A unit starts out with full morale and every time it takes casualties the morale drops a bit. Units slowly gain morale as time goes by, especially if they are in command control with their headquarter. A unit whose headquarter has been destroyed or which is simply too far away will lose morale faster and gain it slower.
When units take a heavy beating and the morale drops too much they will break and rout. Routing units are out of the game until they have retreated far enough and rallied. Rallying is faster if the headquarter is near. A unit that has just rallied will break easily again.
Needless to say both fatigue and morale introduce a lot of complexity into the engine and it’ll take a while to balance them properly. Hopefully I’ll be able to make the units react somewhat realistically and not create super units that never tire or which break immediately when fired upon. 🙂
Yesterday I started thinking a bit about adding a pause button to Imperium that would pause the simulation but still allow orders to be given. Previously I’ve thought that it would be a massive undertaking and require a lot of work on the simulation side. When I thought a bit about it I came to the conclusion that it should not be that hard after all, in fact it could be quite simple. Seems it was simple after all and there is now a nice pause button up in the right corner.
Tap the button once to pause and again to resume the normal action. All I basically had to do was pause the simulation, and that functionality has always been there. I wonder why I never thought about this before.