Tag: Progress

  • Procedurally Generated Maps

    Introducing the new procedural map generator

    Hand crafted maps are obviously pretty awesome and have had thought put into them. However, creating many maps takes time. Therefore let me introduce the procedurally generated map system.

    The map above was generated with some loose specifications. Firstly, the terrain was generated taking options from plains, mountains, rocks and forests. These have been specified to take up the whole map with defined ratios. Then neutral buildings generated in the center of the map. Finally teams entities generated in the left and right.

    Different map layouts and biases can be added. the layouts currently available are Left-Right, Top-Bottom, Bottom Left-Top Right and finally chaotic where the different teams entities are all mixed together!

    Along with that there is an option to specify if the map is to be mirrored so that the layout of all entities are fair between the 2 teams.

    The example here has a bias to give the blue teams more entities for an extra challenge!

    Next Steps

    The next development steps are to add layers for line based generation, for example addition of features such as roads and rivers. This will allow for some increased tactical considerations such as additional choke points and flanking.

    Currently the maps are 1v1. The next iteration will include the addition of specifying more teams using the existing create map tool and allowing the generation to add more teams with spacing accordingly.

  • Transporting

    The new transport feature of the game. Letting entities pick up and transport other entities.

    The idea of an entity that can transport another entity is not new. For example, in a war game you could imagine an ‘APC’ style unit picking up and transporting an ‘Infantry’ type unit quicker than the ‘Infantry’ could move on their own. Obviously this opens up a large number of tactical options and adds a certain dynamic feel to a game, the idea that all of your teams entities are working together more seamlessly.

    Therefore, we have not implemented transport to the game! In its current form, either the transporting or transported entity moves on top of the respective entity and can either ‘Load’ or ‘Pick Up’. Once a transported entity has another entity stored, it get a new option of ‘Unload’, which unsurprisingly drops the stored entity off in the transporting entities position. Of course, the transporting entity has presumably moved first and it could be many turns before unloading.

    The current transport config options are as follows:

    {
        "CanBeCarried": true, # Default false
        "CarryingAllowedSelector": SelectorConfig,
        "AbilityConfig": SpecificAbilityConfig,
        "EntitiesDroppedTurnEnded": false, # Default false
        "CarryMovementOverride": 2
        "EntityTagCarryMovementOverride": { "Infantry": 3 },
        "EntityTypeCarryMovementOverride": { "Mech": 2 },
        "DropOnDestroyed": true # Default false,
        "CanTransportEnemies": false # Default false
        "EntityCarryCount": 1, # Default 1
    }

    CanBeCarried, CarryingAllowedSelector – Tells the entities what they can transport and if they are allowed to be transported.

    AbilityConfig – The standard config which details how many times the ability can be used per turn.

    EntitiesDroppedTurnEnded – When the entity is dropped off, will it have its turn ended or the same state as if it was loaded this turn. i.e if its a new turn then the entity would be fresh with all its actions. If it had already used some actions and then got transported in the same turn, will it be able to use its remaining actions or have its turn ended.

    CarryMovementOverride, EntityTagCarryMovementOverride, EntityTypeCarryMovementOverride – Defines if the transporting entity’s movement is effected by what its carrying. I like the idea that if its carrying something big then it would move slower. Also opens up the possibilities of moving quicker if things synergize or using the transport system for loading in boosts of other sort.

    DropOnDestroyed – If the transporting entity is destroyed, defines if the transporting entities are also destroyed.

    CanTransportEnemies – Experimental currently. Defines if the transport can pick up enemies. Maybe with a pop out mechanism so that the enemy entities can break free say at the end of the turn.

    EntityCarryCount – Defines how many entities can be transported at once.

    The configuration is currently fairly experimental and not set in stone. There are lots of possibilities for this kind of action and many subtleties. For example, there is currently no reason that recursive transport cant be done or different effects based on the synergy with the transporting and transported entities! I am certain that there will be updates to follow as this ability gets tested and morphs.

  • Downloading config – Zips and Singles

    How does the game client get the latest game files?

    Realm Tactics runs all of its game system through downloaded config files. All terrain, units, attacks, sprites, AI config and map config are just files that need to be loaded for the game to work. The game client itself is completely divorced from all of that – not a single game mode included out of the box.

    It may be tempted to shove all of it in a big zip file which can be downloaded easily, unzipped and give all that is needed to play the game; making sure its all perfectly intact and internally consistent. However, that is a very static way of doing it and clients would need to either download the whole lot again when an update is make or to become stale and miss latest updates.

    At the other end of the scale, one could download each file individually when its needed. If this get performed each and every time then obviously the config would always be updated but that would be a load of downloads! We clearly need some compromise solution…

    Meta Files

    Our system is build on a bunch of meta files. These files as the name suggests contain the meta information about other files which should be present. For the most part, there is a meta file at each level of the config folder structure. In reality its fuzzier as meta files can reference other directories and also can reference sub-meta files (meta files in other locations), but for the most part consider that each directory (folder in the games file system) contains a meta file.

    These meta files are extremely small comma separated data files that detail what other files should be present – one file reference per line. When the user navigates to the menu that is linked to a directory, the game makes a quick call and downloads the latest meta file. This is a very lightweight call but lets the game check what the state of the game should look like. Each meta file entry has a version number. The existing version number of an entry is compared with the new version number of the new downloaded meta file. If the version has updated, this indicates to the game that the file has changed and it can call and get just the updated files that have changed. As most files will remain unchanged session to session, most files wont have an updated version number so no action is needed. As you can imagine, this hits a good balance with keeping the files updated with not making too many calls for files. But as some of you may be thinking, that is still a lot of individual files that will need downloading when the game is first loaded of if there has been a major change, affecting a bunch of files. There needs to be a way of cutting down the number of downloads for large updates…

    Downloading Blobs

    As mentioned at the beginning of the article, having a big zip with all of the files is a great way of getting a large number of config files at once. So, we have a happy hybrid approach. The meta system describe above is still in play but an entry in a meta file can represent a zip file to download and extract. This will of course overwrite all files that are conflicts. What is clever though is that the zip file entry will act in exactly the same way as regular files, having a version number and only download if the latest meta file indicates that it has been updated. The zip file itself will also contain all of the files and the associated meta files which has a record of the latest version codes for its contained files.

    So imagine a big update has been made. A new zip file is made which contains a bunch of files and meta files – all having their latest version codes. The game client downloads the zip and extracts it and puts in all the files that it needs. The game will no longer re-download the zip as its meta file already shows the latest version code. However, shock horror one of the files in the zip contains an error and an update needs to be maid! No worries, the zip file on the game config server doesn’t need updating, only the individual file that needs fixing and its individual meta version code bumped up. The game client will know that it has the correct zip, but sees the new version of the specific file and only that file is updated.

    Win-win! We have a great amount of control to create zip files containing a bunch of config whilst also having the ability to make small tweaks here and there as needed. All the while the game clients only download what is needed and is always kept up to date!

  • Conditions – How to win

    Adding the ability to have conditions attached to a map/battle. Now there can be a winner!

    Each map may have different conditions applied to it. The simplest version of this is when all enemy entities are destroyed then the remaining team wins. However, this game is all about being generic so the Conditions section has been added to the map configuration. Currently there is only one type of condition allowed; the WinCondition. There are various other condition types in plan:

    TypeDescription
    WinCondition (Implemented)Defines what conditions are applied to each team to win the game
    MessageCondition (In Plan)Defines what messages are presented to the user under what conditions, time and position
    CampaignCondition (Ideas Board)Allows events and results in other maps to effect the current map

    Currently only the WinCondition has been implemented. A detailed example for a win condition is:

        "WinConditions": [
            { // A team can win by destroyin all enemy units
                "TeamIds": ["TEAM_1", "TEAM_2"]
                "EnemyEntitiesRemaining": 0,
                "EnemyEntitiesRemainingTagFilter": "Unit",
                "TurnNumber": 0
            },
            { // Team 2 will win if turn 20 is reached
                "TeamId": "TEAM_2",
                "TurnNumber": 20
            },
            { // Team 1 will win if they capture the enemy's 'Origin' entity type
                "TeamId": "TEAM_1",
                "EntityCaptured": {
                    "Position": {"X": 9,"Y": 6},
                    "EntityType": "Origin"
                }
            },
            { // Team 2 will win if they destroy the enemy's 'HQ' entity type
                "TeamId": "TEAM_2",
                "EntityDestroyed": {
                    "Position": {"X": 3,"Y": 3},
                    "EntityType": "HQ"
                }
            }
        ]

    Additional fields can be easily added to the WinCondition to allow different win types. With the framework, these different types of winning conditions can be added to any map. The EntityCaptured and EntityDestroyed fields creates an EntitySelector object which is created at the start of a map and gets attached to the specific entity. Therefore even if say the entity moves or otherwise the condition can still track it.

    In the same way, additional condition types are planned to be created and will have a similar format. will allow a flexible and easily configurable way to add variety to a map.

    The current work started is the MessageCondition. This will contain the conditions in a similar structure of the win conditions – and will also contain many of the same fields. This will be linked to a new Message object or a collection of Message objects which will have various fields such as [Text, Position, Team]. This is a basic structure and could get a lot more complex with intertwined conditions and messages. But as a start it will allow basic messages to be sent i.e a simple tutorial or story.

  • Animations!

    An illustration of the new animation system which can be applied to any entity actions

    An animation system has now been added which allows different spritesheets and configuration to be added to each entity actions. Here is a (very!) small sample of an attack animation and the associated config:

    Which contains an idle animation and attack animation (cheating but actually using the same sprite sheet with the idle animation much slower!). The config which defines this unit is as follows:

    {
        "Name": "Peasant",
        "Description": "Standard, cheap but weak unit",
        "Sprite": {
            "FilePath": "units/peasant.png",
            "PixelsPerUnitX": 625,
            "PixelsPerUnitY": 675,
            "CycleTimeSeconds": 10,
            "Repeats": true
        },
        "Tags": [
            "Unit"
        ],
        "Movement": {
            "Movement": 2,
            "BlocksEnemies": true,
            "AbilityConfig": {
                "PointCost": 1,
                "UsesPerTurn": 1
            }
        },
        "Attack": {
            "DirectAttacks": [
                {
                    "Name": "Attack",
                    "Detail": {
                        "CanMoveAndAttack": true,
                        "BasePower": 0.4,
                        "Selector": {
                            "AllowTags": [
                                "Unit"
                            ]
                        },
                        "TagPowerModifier": {},
                        "AbilityConfig": {
                            "PointCost": 1
                        }
                    }
                }
            ],
            "Sprite": {
                "FilePath": "units/peasant.png",
                "PixelsPerUnitX": 625,
                "PixelsPerUnitY": 675,
                "CycleTimeSeconds": 0.25,
                "NumberOfLoops": 4
            }
        }
    }

    There are 2 Sprite blocks, one on the Root of the config which gives the idle animation and one on the Attack configuration which is applied to any attacks that are made (unless a specific one is given to a sub attack config). The new sprite configuration is pretty clever, simply give it a sprite sheet (or a static image) with other optional values:

    KeyDescription
    FilePath (Required)Points to the sprite sheet/image
    PixelsPerUnit(X/Y)Determines the unit size of each frame. The sprite sheet will automatically be split into each frame starting top left, proceeding along the row row and then down to the next. If not added then it assumes that the file is a single static image.
    CycleTimeSecondsHow quickly a complete cycle showing all frames takes.
    FramerateSimilar to the CycleTimeSeconds but allows the specific framerate (frames per second) to be defined.
    RepeatsDefine if its a continuous animation. For example, an idle animation repeats, a single attack does not. Animations that do not repeat complete for their entire duration and don’t get interrupted.
    NumberOfLoopsHow many loops of the animation to complete before it is finished.

    With the values give, it will automatically process the sprite sheet and incorporate it into the action at the particular level that is associated with. In this case the main attack confg but could be sub attacks, movement, capture etc.

    More specific sub-mods are in the plan e.g movement in the cardinal directions (so having 4 for the set up, down, left and right which play as the entity moves) and any other specifics for other actions that I can think of. The system is generic such that the config is the same for each animation and all that is needed is adding to the format and adding the correct hook.

    For illustration, the above units graphics are defined by this single example sprite sheet peasant.png:

  • Show off – Purchasing, Capturing and AI

    A speedy demo of the Hacktics game mode showing off some of the latest features

    As things progress, its hard to capture all changes in a single illustration. So here is a lightning example of two AI players battling over a network (hacktics game mode):

    The Hacktics game mode is all about capturing ground which generates more income which allows more expensive units to be purchased. This mode uses the ‘network’ concept such that only continuously connected captured locations generate income. Therefore it is possible to cut through an opponents network and disrupt their income. As you can see, the AI occasionally purchases additional units from one of its construction buildings.

    There are 3 units available:

    • Workers which can capture network but not attack
    • Viruses which have a direct attack
    • DDOS which have a range attack

    Each unit has a different cost and although not very visible in this video there are 3 different currencies at play. The more expensive units using the rarer currencies. In addition each location generates a different amount of income – the two ‘generator’ locations for example generate a high amount of the rarer resource.

    It takes a worker 2 actions to capture a location and the worker has 2 actions per turn. This leads to the ‘ability’ config where each type of ability that any entity can do can have associated ability config – detailing how many action points each ability costs, if it can be used multiple times a turn, if it ends the entities turn etc.

    The AI in this scenario acts reasonably intelligently (currently no training has been performed so not bad considering!). It understands the concept of the network and attempts to capture continuous locations in order to expand its income. It also attempts to purchase the most useful units it can given its current wealth. The units also attempt to engage intelligently and cause damage with an aim to get the best attack value while preserving themselves.

    Note that each entity in this scenario have direct attacks although other forms of attacks are available which have been experimented with – in particular splash attacks which causes damage to multiple units at a time.

  • 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.