RTS4 Data File Structure

There haven’t been any gameplay changes recently, instead I’ve been working on adding features for modding. The current proto data format automatically supports a lot of scenarios, but many common concepts can be tedious to write. The latest build includes some of those changes (and a lot of bugs).
RTS4 Release 9
Webplayer (Unity)

I’m working towards supporting advanced scripts like this RPG-style script:

Player.default {
  Level = 1;
  Experience = 0;
  NextLevelXP = $Level * 200;
  Health = 200 + $Level * 20;
  RequireComponent<AttackMelee> {
    Attack = 20 + $Level * 2;
    OnKill = (other) {
      Experience += other.$XPGain;
    };
  };
  Event(Experience >= NextLevelXP) {
    Level += 1;
  };
}
Grunt.default {
  XPGain = 1
}

Several fields (NextLevelXP, Health, Attack) are augmented by other fields. By default, these fields only include the augmentations that appear prior, adding a $ causes all augmentations to be used. Using this feature does introduce the possibility of cross-dependent fields which would crash the game; I’ll need to add some protections for that later (probably just not run those augmentations recursively). An example of something that would break it is:

Health += $BonusHealth
BonusHealth = Health * 0.5

The OnKill event handles giving experience when they kill a grunt. Any augmentations that appear in these scripts are somewhat special; a single augmentation is allocated at compile time, which starts off as the identity value; whenever the script is run, the augmentation value is changed by whatever the script says. This has the benefit of allowing any other augmentations later in the file to still be applied correctly (ie. if Experience *= 2 appears in a later technology, the experience will correctly be doubled until that tech is removed).

Finally, the script creates a level up event to be run when the players experience passes the required amount. Because of the $ in earlier dependent fields, changing the level later in the file still correctly affects Health/Attack/NextLevelXP.

Currently fields referencing other fields, and simple scripts are supported. Its also possible to define “APIs” (RequireComponent and RequireTechnology are now external APIs) to provide more functionality, without bloating the code.

AoM Farm Optimiser

I haven’t had much time lately for RTS4, but I needed a break from Uni work, so decided to build a quick farm optimising website. Drag around to pan the camera, click items on the right to select that type, and click in the world to place them. Select objects and drag them to move them, or press delete to delete them. The average distance is calculated as the average distance from 4 points on each farm to the nearest drop site.

Update: Added collisions and shadows, it looks a lot nicer now
AoM Farm Optimiser Screenshot (with shadows)
WebGL (IE11, Firefox, Chrome)

Bugfixes and tweaks

In this build I’ve lightened the UI a little more and given it a more consistent colour (everything is brown, instead of the stone being tinted blue). Also made some more icons and modeled/textured a Minotaur. Looks a little plain, but it’ll do for now.

RTS4 Brighter UI and Minotaur

I’ve also fixed up a desync bug, player technologies were not being correctly cloned, so players would likely see some stuttering after aging up. This was caused by entities registering their technology references to the player AFTER the player had already cloned active technologies; basically the age2 research could flicker on/off.

The game also supports having multiple games running at the same time (so I can simulate two “multiplayer” clients with high latency easily in unity). I’ve used that to fix a few more desync/clone errors, but it also makes it cleaner to start new games.

Webplayer

RTS4 UI Art

I spent the day fixing up the UI and drawing some nice textures so its a bit nicer to look at. They are still placeholder.
RTS4 UI Art

I also played a bit of Age of Mythology: Extended Edition and got frustrated at the loop icon being difficult to see (or just not showing at all..) so I made a really obvious visual effect for when autoqueue is active. I’m quite happy with how it turned out, and its fairly efficient (the mesh resizes to fit the arrows snugly as they bounce at the start). I would love to hear what you think of it!

RTS4 Progress

There were a few glaring features missing, but the last build was mostly complete functionally. I’ve since been working on getting the game to feel much more polished.

Prototypes

The prototype system used for unit configurations was changed to be far more flexible and will work more like CSS, where “technologies” (classes in CSS) have various selectors which determine which entities they are active for. Fields are overwritten in the same way, but a single units prototype can be spread throughout the file; the end result is that it is now easy to add upgrades that can have a significant effect on the game.
Unity RTS4 SignalFires upgrade example

Selection/Placement

I never paid much attention to selection previously, but entities can now be box-selected by boxing any part of them (instead of just their origin). The units centre is restricted to the current box selection, then that restricted point is tested against the units collider to determine if the unit should be boxed or not. Buildings also attempt to move to a valid nearby place when attempting to place them on top of another building (with standard 2D un-intersect style physics)

Projectiles

A game will obviously have a lot of projectiles (arrows, priest attack, etc.), which all act very simply. Theres now a special subsystem dedicated to handling projectiles in a much more efficient way than creating a new entity for each projectile. They are rendered and (soon) animated with the same prototype configuration as normal entities.

MiniMap

This one is a much more substantial feature addition. The game now has a minimap which rotates with the camera and shows/allows movements of the camera frustum. I may look in to dirty sectioning for it later, but the draw overhead is so minor that it probably doenst matter that its O(n).
Unity RTS4 MiniMap Screenshot

Optimisation

The game now tracks a separate list of entities which need to be updated each frame, which is only units tasked with a command. It is possible to reduce this to only units which have a move command, but the current method is likely fast enough. The game also has an EntityMap, which tracks nearby groups of entities (white boxes in the image below). Entities will delay repathing when given a new target until required. Loading is still too slow for my liking; it takes 80ms to parse the prototypes and 550ms to instantiate entities in the current demo map, but optimisations come later!
EDIT: Oops.. I still had some testing code in there; instantiating entities takes 50ms now.
Unity RTS4 EntityMap Debug View

Multiplayer

Was working well previously, but some of the newer optimisation and validation changes have probably broken things. Dont expect this to work terribly well until nearer to release.

Webplayer

Back to RTS4

The previous tutorial series covers most of the basics for an RTS. I probably wont be doing any others for a while as I’d now like to concentrate on RTS4. There has been some quite significant progress made to the project; with the cleaner design from the UnityRTS tutorial series, and the separation of simulation from visuals, the project is much easier to work with now.

Separation of logic

In the UnityRTS projects, although updating happens at a fixed time interval, the coupling of the simulation and visuals makes it difficult to have simulations running in the background and ties the game more closely to the Unity engine (which with Unreal looking so nice, I want to avoid). These two functions are now separate, and each client now runs two simulations concurrently; one for the last known server state, and one for the clients visuals. Each network message is first run on the server, if it is prior to the clients visuals simulation time, the client sim is synced to the servers sim, and then rolled forward to the correct client time. This gives clients no lag while still minimising network bandwidth. As the visuals are separate to these simulations, they can smoothly interpolate whenever the client simulates incorrectly.

Prototypes

The decoupling of the simulation from the Unity visuals means that entities can no longer be described by components on a prefab. To replace and extend this system, each entity now has a prototype object, which calculates any stateless properties (its max health, build time, etc.). Getting a field is not as simple as looking it up by name; Prototypes have a list of technologies which can be enabled or disabled which augment fields, enable / disable components, and even enable / disable other technologies (both for just this entity, or for all entities owned by the player).

These toggleable technologies mean that entities can very simply support buffs and debuffs, by for example enabling a SlowPoison technology. The system also handles armoury upgrades by enabling the HardenedShields player-wide. And it can even be used to handle tech unlocks, for example by enabling age2 player-wide, which can in turn augment the villagers Builds list to include Barracks and Farms.

I dont fully understand the effects system in AoM, but this seems more extensible and quite happy at how many common RTS concepts it can support cleanly. None of my previous attempts included anything like this, so its great to finally understand it.

Unity RTS4 Prototypes example code for Villager

Multiplayer

With the changes above, multiplayer is now functional. I’m using the RPC support in Unity to send messages (after serialising them to byte arrays) which conveniently handles lobbies and NAT punchthrough for me.

 

The current version can be played here (with multiplayer disabled at the moment). I also added in the older models instead of boxes.
RTS4_7.4
Webplayer

RTS4 – Cliff models

Using a mesh for the cliff face turned out to be quite a bit more difficult than I originally thought. It’s finally working, though still incomplete. I’m not sure its worth the processing requirements and complexity it adds. I’ll probably disable it and decide later. Using a mesh means the cliff can have nice crevices that match the texture mapping, and have little ledges and rocks poking out. Otherwise without using a mesh, I’ll add some variation to make it look less rigid, but the texture wont match the mesh as nicely.

Other problems that this approach presents:

  • The cliff model would not be able to wrap around a raised plateau without a geometry seam (potentially showing through to the void below)
  • Matching the cliff model offset between terrain chunks is very complicated and unlikely to ever work completely (nasty geometry seams between each chunk)
  • Floating point errors cause holes in the geometry or can potentially crash the game
  • The cliffs are significantly higher poly
  • A mesh should be made for each cliff type, adding to the workload

This picture from Unity RTS shows a hand-modeled example of what I was going for.
RTSCliff2
Notice the darker sections of the cliff texture are inset.

RTS4 – Progress update

I’ve got back into the WebGL port of RTS4. I had previously done a lot of work for.. something.. I can’t quite remember, but I left it in a broken state. It’s now been fixed and had a little more progress made:

  • The UI is all data-bound through Knockout
  • Users can now box-select stuff
  • Units/buildings have a visual thing below them when selected
  • Constructing things now has a construction phase
  • The object bounds are used for building/attacking/gathering (instead of the unit walking to the object centre)
  • Scripts are combined into a single all.js file, reducing the load on my poor server
  • Models (including animations) are loaded in a much smaller binary format, meaning MUCH faster load times, and less content to download
  • Model transforming happens through an (as yet unseen) node.js server, which also opens a socket to the client; some basic multiplayer tests/features shouldnt be too far off.
  • Basics of an “EntityGroup” class, which manages a collection of entities that satisfy a list of requirements. (the “Villies” print out is using this system to count units)

I made a few models earlier, and since they look much better than the current build, ill post them here instead.

rts4models
“Play” in browser (IE11 or Chrome)

Next step will probably be terrain and other visual improvements. The action system also needs to be revamped; the over-engineered “resources” system needs to be integrated into the entities themselves, rather than a separate component (health and population are considered resources in this system). The resources overhead is insignificant, and almost every entity that needs behaviours, needs resources. This may make it easier to integrate more concepts (like line of sight) to be resources (probably to be renamed to “properties”), which will make buffs much easier.

Note to self: I’d also like to have a concept of “abilities”, such as “move” and “face direction”, so that the correct action can gain access to the abilities they need (otherwise a unit ordered to move left but attack right wont know which order should control movement)

ModHQ and UI Editing

I’ve integrated the UI viewer/editor into ModHQ and fixed up some performance problems. It now loads in about 2 seconds on my (fairly low specd) laptop. It also has a nice new loading screen.

ModHQ_Load

The program is essentially read-only at this stage, any changes you make with the unit prototypes or UI wont be saved back to your data files. However, all changes made through the Data Files tab will.

ModHQ_Dat

In this screen, double click any item to convert it to XML and open it, you can then make edits in your xml editor, and save it back to have it compiled and inserted back to the data file. Textures can be viewed through this tab, but will not successfully save back to the data file.

As before, you can check and uncheck items in the UI Editor tab to see their contents

ModHQ_UI

Download: ModHQ (.Net 4 + source)