-
Maps and saving
How a user can save a ongoing map in an efficient manner
I have previously described the system of having the configuration in a separate location rather than baked into the game. All maps/battles are essentially json configuration files which contain all of the map details – terrain, units, win conditions etc. These are ready made structured files which contain the initial snapshot of the game.
When a player plays a map, obviously that state changes. However, the state at any given point will always be in the same structure as the initial game map mode as all options are available on the initial map config (it is possible for example to start a map and already have a unit that has been marked as having done an action so that it may have slightly less actions available on the first turn). Therefore, the save system for the current state is a trivial process as it effectively does the opposite of the loading system. The game state is serialised back into the json format. Easy!
However, that is not the end of the story. How does the base entity config work? How does the AI config work? It is feasible to just copy all of that into the map files but that would be a lot of duplicate data with multiple save files and just seems so inefficient. Therefore, an additional section for the ‘environment’ is also added to the safe file. This effectively points to all of the additional files which need to be loaded in. Now it is possible for the configuration of the other files to change if someone alters the base config on github. Therefore some features of the game map could technically change after a save/load – AI could change or parameters of how entities work etc. However, I feel that changes would mostly be related to ‘balancing’ once a game mode is in production that this is a reasonable trade off rather than having loads of duplicate nearly identical config.
An environment section which details the additional files that are required for the map to load looks something like this:
"Environment": { "ENTITY_TYPE_CONFIG_FOLDER": "config/hacktics/version1/entities/types", "ENTITY_TAG_CONFIG_FOLDER": "config/hacktics/version1/entities/tags", "ENTITY_DEFAULTS_FILE": "config/hacktics/version1/entities/entityDefaults.json", "AI_CONFIG_FILE": "config/hacktics/version1/ai/aiConfig.json", "AI_CONFIG_DEFAULTS_FILE": "config/hacktics/version1/ai/aiConfigDefaults.json", "GAME_CONFIG_FILE": "globals/gameConfig.json", "MAP_SET_KEY": "hacktics/version1" }
-
New game modes!
A visual example of a new game mode currently being added
With the alpha version of the game pretty much complete, new game modes are being added as the ‘content’ of the game is only a couple of maps currently. The most recent is the ‘Medieval’ game mode which is a classic style of traditional warfare with swordsmen, archers and catapults etc.
Here is a demo of the gameplay from two AI players battling. It is just a few units put on a map and no interesting terrain yet but just an illustration of what is possible.
These are sample graphics and only a few units added so far but it does show the power of the engine as this was achieved in a few hours. More impressively the AI is not half bad considering that it is currently still completely untrained and has not been altered in any way for this game mode!
It is so easy to add new game modes using the configuration system and achieving this is pretty straight forward when you get a grips of the structures of the configuration files.
Also another disclaimer is that the timings of the AI turns are a bit quick and currently the units effectively throw particle effects at each other (which can land when the unit has already been registered as defeated!). All of these are just things that I have not got round to improving yet!
-
A touchy subject
Touch input! The considerations involved with making an intuitive input system for a phone or tablet
Touch input! Yep this is going to be a phone/tablet game so of course touch inputs are required. It has been an interesting technical exercise to convert touch inputs to the square grid based game – both short, long and drag touches being available. The game is almost ready for its alpha release so the focus is solely aimed towards usability.
What a user wants to do and have it intuitive is interesting. Say there is a unit that the player wants to avoid being attacked by. How best to display its ‘danger range’. The unit could attack, could move, or some combination of both. Having a long hold identifying the total move+attack action is tempting. However, what if the unit has more subtle mechanics than that? If the unit has multiple different attacks that are possible, if the unit could use a combination of movement and attacks and that will change its attack pattern, some attacks being much more effective so they take priority, some units cant attack but knowing its movement range is essential… It is not straightforward when you don’t know exactly what a unit will be able to do to plan what is best to be shown to the user.
There is the possibility of allowing the person making the configuration of each unit to choose what it wants to show. I.e if someone was making a ‘moving wall’ unit, then seeing the movement range would be most useful so that the opposition player can see if the unit has enough range to block up a strategic bottleneck. So each unit would have a set way of giving usability to the user interface. This is most likely how the development will end up but for now I have settled on if it can attack, show the attack range – otherwise show movement range.
There will need to be an extensive test with different users as people will find different ways of interacting and what they find intuitive.
-
Configuration Issues
Patching a dangerous process with decent alerting
This game is very much reliant on configuration and in particular user created configuration at present. Unfortunately it is currently a ‘hand made’ process. The configuration that is created unfortunately has a high chance of user error. In the meantime I have added a *bunch* or error catching and alerting the user to the issues. It will hopefully indicate roughly where the configuration errors are found and allow the user to apply a fix. This is linked to the concept of Configuration on a Branch where when developing the new config the developer will be able to get some proper debug information so when it is ready to go live and merged with the main branch there is a reasonable confidence of it being valid.
In the future I would like to make a tool to create the configuration in a more graphic and streamlined way but that is a long way away currently. At the very least there needs to be a schema and tooling to verify that the configuration is at the least valid. In a dream world, I would love to create a proper development pipeline with automated validation of the config – such as running the new configuration through a validation checker to ensure that the new config at least complies to the schema. Many many steps to go but for the meantime alerting users to the errors is a good start.
-
Configuration on a branch
How development configurations are managed using branches!
This game relies on multiple config files all pulled from the source control (github) which contains all of the details. Collaboration source control does allow multiple people to work on the same set of files without having too many conflicts to manage – if 2 people alter the same file at the same time there is a system to resolve all of the good changes. Now, when a game type is in development, not all updates need to be pushed to each game client. Therefore we have added the functionality to use different github branches in game!
A settings menu has been added to allow global settings to be added. One of those new options in the settings menu is the config branch to use. Therefore clients can set the development branches when testing/developing a new game mode and all of the config associated for that branch will be pulled. This system means that the game engine/install does not need to be changed when switching between development or the ‘main’ branch for ‘production’ gameplay. Game files that are outdated will need to be re-downloaded but it it requires no code changes.
-
First show off – Where we are
This is the first look at the current development of Realm Tactics. The sample game mode is Hacktics.
This is the first show off post of what Realm Tactics currently looks like. I have added a game mode which I have called Hacktics. The concept of this is that there are two hackers or similar which compete to control a network. So they move their programs around and try and capture more of the network than the opponent.
First off we have attacks. You can see that the DDOS unit (octopus thing) is currently selected to attack. It has a range attack with a minimum range currently highlighted with red. Any valid enemy units can be targeted and then attacks and counterattacks performed as required.
You can also see that this game mode has the concept of capturing the connectors and making paths of team connectors across the map. Each of the connectors (the wire things which are red/blue or grey when not captured). These share a local network so each entities that are connected to each other can share resources.
The initial iteration entity movement is also more or less complete. This will allow players to move tactically and allow them to outmanoeuvre their opponents.
All actions are essentially accomplished using the action menu. All actions that an entity can perform along with game based actions (Save, Zoom, Exit etc) will happen by selecting the option on the action menu.
Just to finish things off, we also have a main menu with a nested series of menus. This can be navigated to get to different game modes, versions of said game modes and maps within.
Obviously this needs some work as its not particularly fancy. But it works!
-
Time to buy stuff – Networking and Resources in game
Strategy games need resources to do things with such as upgrading and building stuff. How to create a system which does this in a generic way?
As with a lot of strategy games, there is quite commonly some form of resource that needs to be managed – for example if you had a medieval themed games then you may have food to buy swordsmen and wood to construct catapults. There may be areas of the map that supply those resources when either captured or worked on.
How I see it, there are essentially 2 different ways that this can be managed. Probably the most common way is by having a series of global shared resources. This is when the resources are gathered and put into a single bucket which can then be spent on whatever the player wants, regardless of where things are on the map. The concept of logistics is not relevant in this style of game as for example your ‘village’ which makes the resources can be immediately spent by your ‘barracks’ and there does not need to be any consideration of connection between the two. Another implication of this is if a player has two bases, they will still share resources so gameplay will not be as isolated.
As you have probably guessed, the second way of managing this is through a more local system of resources. This can take many forms such as discrete items of resources that need to be moved around to a networking system where resources are shared on a continuous connection requirement I.e if the enemy cuts one area that you control into 2 then they will then have 2 separated resource pools. This style can lead to the concept of logistics being more vital to gameplay and having remote bases more vulnerable and supply lines more important to protect.
Introducing the Network
Combining all of these concepts into a single engine could obviously be very complicated. I have therefore started with the concept of a ‘Network’. Each entity can be defined as using either a local network or the team network. These network objects look very much the same at a code level, however a local network needs to have all entities connected adjacently. Therefore if you have a game mode which only has the globally shared resources, then each team would just have a team network and each entity that can network will be subscribed to the single team network. Local networks just have the requirement that all entities are connected. You could imagine that this would lead to capturing ground types of games, or ‘wiring’ or ‘roads’ connecting strategic points together. If the network is severed, then currently the resources are split between the two networks based on the size ratio (ratio of number of entities in the resultant networks). In a single game mode, it is also possible to have a mix of team and local networks which could lead to some interesting tactics.
Now that there is a rough outline in the buckets of resources in play, time to move onto the resources themselves. Each network will have access to the same resources types (food, wood etc). Some entities will generate more of certain resources than others and some may drain resources. Entities such as ‘factories’ can consume resources when constructing other entities. Obviously these resources will be themed to the certain game type that is being played so all of those will need to make itself into some form of configuration file. Currently the number of resources are hard coded to be up to 3 as I believe that will cover most cases. Due to the user interface considerations, having more than 3 would be more difficult as it would need to be more dynamic so as not to look cluttered.
So there you have it, Networks are constructed which each will have its own pool of resources. Networks are either the global team network or multiple local networks. Any entity in a network has access to the resources that the network owns. Hopefully as a first implementation this will cover a large number of the desired game modes.
-
Creating the entity and map configuration
How to deal with managing a (hopefully) large churn of the configuration without annoying users
This game has the configuration; the stuff that actually defines how the game plays and what maps are available, from the engine. The engine is obviously essentially a load of code and is the thing that would actually be downloaded from a mobile app store and is the thing that I will be putting a load of work into. As I want that flexibility, the configuration cannot live in the code as otherwise if I or anyone else wanted to add any new maps or entities then you would need to create an update to the app (everyone hates lots of updates…). This could be frequent and I don’t want the app having constant updates, not to mention if there is more than one person working on maps and entities at the same time then it would be unmaintainable.
What is the solution here? It is to host the configuration remotely and have the game itself pull the configuration say when the app starts or the user wants to download a new set of maps etc. Ideally I would like multiple people to contribute to the game in these ways by coming up with cool new entities and maps and graphics. Luckily there are already lots of tools that are particularly good at managing a load of files with multiple contributes – git! So the plan is to have a public git repository which will hold the configuration for all the game essentially where people can contribute to. The game engine will pull files as required down from that git repository and of course all of the power of git can be used to manage the config on the server side.
In fact, here is the current public repository which I am using: https://github.com/James-Silvester/RealmTacticsConfig. Please feel free to have a peruse and get involved!
Although this may change in the future, it certainly works for now and allows me to make a build of the game as a completely separate process to tinkering with the configuration that is being run. So far all of the configuration is hand done, manually constructing the structure and figuring out where things go. In the future, I would love to make a sandbox within the game itself where entities can be edited and maps created. Those could eventually get pushed up to the configuration repository so could be consumable by other people. These however are all ideas for the long long backlog…
-
How to make an enemy – Giving the enemy some brains with artificial intelligence (AI)
Making the enemy intelligent is no easy task. The complexity of the final game will be a real challenge to make the enemy both tactical and adaptable to be an enjoyable opponent.
I do love the idea of being able to play against human opponents. However it would also be great to be able to play the game against non-human players. Therefore an AI system will need to be created. This… how shall I put it…. will be extremely difficult. Obviously a lot of games have AI systems. Most games the AI can seem relatively complex but are actually made up of lots of individuals following simple rules that overall create complex outcomes. There are exceptions such as real time strategy games where the AI is complex but can very much make or break a game. For strategy games, if the AI is not clever enough, random enough and adaptable enough it can severely damage the gaming experience. Every time the AI does something non-human or particularly stupid, a player will learn how to replicate that situation and start exploiting the AI and ultimately break the gameplay.
Moving back to this game, a turn based strategy game with multiple entity types and actions that each entity can perform. Games like chess it is possible to effectively simulate a bunch of possible moves and construct a decision tree, finding the best move to make based on the most favorable branches. In principle it would be possible to do the same for this game except for one thing – there are way too many possibilities. If there is an entity that can move 1 space, there are 4 possible destinations. If they can move 2 spaces, there are 12 possible spaces. 3 there are 24 spaces, 4 there are 40 etc. This is a situation that can easily get out of control when you have a lot of entities that are relatively mobile, not to mention all of the possible actions that can be taken (attack, capture etc). Considering I am wanting this to run on a phone in real time, that is very much off the table.
So there has to be a more restrained solution where it figures out a subset of possibilities. The solution which I have come up with and currently exploring is adding ‘Features’ to a ‘Heatmap’. During an AI turn, the system will loop over all entities on the AI team and will calculate features and add them to a heatmap. Once all of the features have been calculated, the ‘hottest’ square of the heatmap is proposed, escalating to the next if the move is invalid.
As an extra layer of abstraction, there will also be the concept of separate ‘Modules’. A module is a collection of features which link to a particular tactical decision that an entity can do. For example the ‘Attack’ module, a feature could be ‘Is enemy entity in range’ or ‘Is attack cost effective’, whereas a ‘Capture’ module feature could be ‘Distance to enemy headquarters’. Each module will calculate its best square on its heatmap and bid for its associated action to be taken.
This will leave a hierarchy:
- Modules which define a particular tactical decision (attack, capture, run away etc). Each module has multiple Features and a resulting action.
- Features which are calculable values for each entity in the current map configuration. The collection of features for a module added are calculated at each position on the map, summed and added to the modules heatmap.
- Heatmap The map grid which collects the features for a module. The best position can be found which dictates both the modules resultant action and the bid – The modules reckoning as to how effective its action will be.
- Resulting action will be performed by the module if it wins the bid. It will move the entity to the best heatmap square and perform the modules action.
For example, the Capture module will have a feature to capture the enemy headquaters. The best position on the heatmap will be the position closes to the enemy headquaters. If the capture module wins the bid, it will move the entity to that position and if it has reached the desire square then captures the enemy headquaters.
The specific modules and features will need to be somewhat manually defined from experience but down the line it may be possible to train the relative weights of each feature. In theory with enough features and weighting, it would be possible to have a learning system but that is very much down the line in the distant future.
-
How does stuff actually happen – What does the entity configuration do
Entity config time. How can a few numbers dictate how the game is actually played?
Right back at my first post, I did mention that one of my motivations of making this particular type of game is that I have a deep love of ‘Advanced Wars’. Each entity in that game (units and buildings) can do a number of actions which take place in a series of battles against the opponents. Ultimately with the aim to destroy all of the opponents entities or complete a specific objective I.e capture the enemy headquarters.
I certainly do not want to make a carbon copy of this game as for one it would not be as good and secondly this will be a product of my creation and I want it to stand on its own. That being said, it is a great model of how these types of games can be constructed. In particular, each entity can perform a certain number of actions which ultimately can be defined by some configuration. These actions include:
- Movement
- Attack
- Capture
- Resupply
- Build
- Defence
These are to name a few but to get to the point, each ability e.g attacking can vary wildly from each unit but for the most part fall into a small set of parameters. For example, an infantry unit and an artillery unit are used very differently and their interaction can create some very interesting tactical decisions. However, they are at its core very similar from a programming perspective but just vary on the parameters I.e artillery range Is longer, its strengths against different entities are different, artillery cannot use their attack once moved etc. But those are just a series of numbers and adding the other abilities and all of the other entity configurations together, ultimately make an exquisite game with lots of tactical gameplay and replayability.
Therefore what remains is to choose what actions to implement and for those actions, what specific properties to add. Ultimately the only consideration should be what combination of actions will make interesting gameplay.