„Age of Total Heroes” - Custom RTS System

Hi RTS developers and fans :slight_smile:

First of all, sorry for the ugly WIP name, it shows only my main inspirations: Age of Empires 2, the Total War series, and Company of Heroes. My work is not a recreation of them, but all the 3 have a significant reason to be highlighted, I will describe later why…

Disclaimer: Non-artist thread, all visual stuff is placeholder! :slight_smile: Artists to join the project welcome!

Credits: The animated unit models are from the Rome Total Realism Platinum Edition mod of Rome Total War I, with the written permission from the modding team. Many thanks again! Other assets are my own work or free stuff.

Introduction

[SIZE=12px]What and Why?[/SIZE]

The project is about making the right tool for creating RTS games with as many intelligently moving and fighting units as possible, that can be a good basis of a competing AI too. So the main focus is on creating a great single player experience by a custom pathfinder and movement system, as it is the most essential core part of any RTS game, and keeping performance as high as possible. Originally, it was started as a free-time game project, but converting it into a distributable tool probably would result in more benefits for everybody… :wink: The RTS system presented here is highly inspired and finally** very close to what is used in Company of Heroes**. it is worthy to watch this presentation (free registration needed): http://aigamedev.com/premium/present…h-destruction/ and th e pdf: http://files.aigamedev.com/insiders/…estruction.pdf

The target is to handle 400-500 unit actors with skeletal animation, or even more if the units consist of only static meshes (with some rotating mesh components for vehicles). Beyond the existing optimizations detailed below, GPU limitations can be stretched a bit by restricting the camera to a top down style, while the **CPU bounds **are to be increased in near future by multithreading a couple of processes currently only spread over a few frames by dividing up heavier tasks.

The test environment consists of a **landscape and static meshes **like rocks, their surface is tested to be passable or impassable for more unit capabilities, and afterwards other destroyable objects are inspected as instanced static mesh based foliage actor components, and special obstacle and building actors storing their own tile and cluster information. Its area size is currently set to 300x300 tiles with a 0.5m resolution, but it can be easily increased to e.g. 500x500 tiles with 1m resolution, depending on the actual game.

Game Types

  • Classic build-develop-recruit-fight style, like Age of Empires games, where you can build your base with defensive walls, control individual units and groups of soldiers in formations, and play against more AI opponents simultaneously.

  • Real-time battles, as part of a campaign or of a turn based game, like Total War games, featuring open field and siege battles, where units are in nice formations and armies, do not get lost in a complex destructible environment, and the AI player can realize and utilize the benefits of terrain and defensive buildings effectively.

Past

The UE4 project is based on a working testbed project made with 3DGamestudio for a long time (written in a C based language called Lite-C, developed within an own WYSIWYG world editor, which is free and open source, but excludes the RTS related parts), that only features the battle pathfinder and movement system. I decided to switch to UE4, as it is a cutting edge and very inspiring engine, allowing a much better workflow, and because C++ is the best friend of RTS game programmers. :slight_smile: UE4 strongly won my little contest against CryEngine and Esenthel Engine (Unity fell out much earlier). In the beginning of the transition, I dropped the idea of making a custom runtime editor again, because UE4 editor is a really cool extensible tool, and supports game modding.

Present

The core is written in C++, only the required parts are exposed to Blueprints, ensuring comfortable usage for non-programmer game developers, flexible customization and extension possibilities. The system of custom C++ base classes helps artists in the team to create their own Blueprinted actors, components, data assets etc., and to set up different military units within minutes, while keeping everything performance optimized, without the need of in-depth knowledge of the whole system.

[SIZE=12px]Future[/SIZE]

The plan is to convert the current code project into a plugin that can be used via a Blueprint example template, and to distribute it possibly on the Marketplace. The target is a really user friendly system despite its complexity, but for future users probably it would be the best practice to extend the base classes by a code project. Built onto the custom pathfinder and movement system, an integrated AI system is another great target (influence maps for building position planning, potential fields for army positioning, defensive wall building by using the pathfinder etc.).

https://s26.postimg.cc/495nbtnyh/Pre_Demo01.png

Features

  • fast hierarchical pathfinding (low level: tiles, high level: clusters i.e. small areas), supporting ground and naval units,
  • automatic map decomposition by a single actor providing the database of the pathfinder, evaluating terrain tiles and areas for the AI, with customizable map parameters (boundary size, tile size, cluster size)
  • units can have different movement capabilities (by default 4: infantry, cavalry, siege/vehicle, ship) and different size (1x1, 3x3 etc. given in tile size),
  • complex,** optimized unit update** including pathfinding, movement, avoidance, and collision resolution (priority based push-bounce), utilizing a LOD system in behavior too for better performance, smoothing out game thread CPU load by spreading the update over more frames, no actor ticking (only components),
  • rendering optimized easily customizable unit actors and components: units are usually animated skeletal meshes in close view, and they switch to animated sprites over a certain distance (both is optional, it can be managed in unit Blueprints), but in the Blueprinted class any mesh component can be added (e.g. a stationary static mesh and some rotating static meshes as wheels for vehicles), nearly all of them has specific base classes added with proper default values,
  • coherent group movement, custom formations, automatically resolving getting stuck or bottleneck situations,
  • buildings can be obstacle like, or have walkable floors e.g. as** castle walls, ladders, stairs, and towers**,
  • unit and group selection by single click or selection box, or double click to select all similar ones onscreen,
  • Total War styled RTS camera system (can be easily restricted to top down only), separated from mouse click handling (which is done in PlayerController and HUD), thus easily exchangeable with own camera systems (using Pawn or SpectatorPawn class).

[SIZE=20px]Development[/SIZE]

Tool

It is currently a single person project what I do in my free time, thus not lightning fast, but not slow at all. Since my primary aim is to create my own RTS game, and to convert it into a distributable tool is only secondary, I cannot say an exact date of the release.

Moreover, I need a little market research on: is there interest at all or the engine default NavMesh is good enough for developers; what would be the minimal acceptable feature set, or would it be better to wait a bit and provide more extensions; is the source code essential or not; pricing, support conditions, managing updates and bug-fixes etc. Any related suggestions welcome :slight_smile:

What is sure is that I will put here posts about the **actual state of the development **regularly, and some other blog posts describing the system in details how it works and why certain solutions has been found to be the proper ones.

Game

I am open to join existing RTS game developer teams, if we can find the common way, or I will establish one to realize the game of my dreams. :slight_smile:
Beside game development, I am big fan of historical literature (Thucydides for president!), and ancient-medieval warfare (but also familiar with WW2 or modern weaponry and tactics) and its economical/social background.

System requirements

When you see FPS or other performance related data, please take into account that I use an old laptop just over minimum requirements of UE4, more exactly: i5 2.5GHz, 6GB RAM, SATA HDD, AMD Radeon HD7670M 1GB GPU (with very rarely or never updated drivers thanks to Samsung).

https://s26.postimg.org/48xdal3d5/RTSUnit_Move_Test2.png

Nice job! This looks really interesting. Cant wait to see more.

Yesss!!! Big TW fan here, keep up the great work! :slight_smile:

This is super cool!

If you released this as a plugin either on the market place, Gumroad or Itch.io then I would give you 50 bucks minimum.

That said - How many AI at once can this handle and Would it be able to handle a game like Mount and Blade?

Does this work well with the World Composition Toolset?

Thanks!

Apparently I forgot to mention that I am targeting to manage 400-500 units in a game level (I will extend the 1st post with some more info).

Currently only the individual unit system works, which has both a GPU and game thread CPU limit on my old laptop, in case of 400 units continuously moving and visible on screen the FPS falls below 30. If some of them are idle or out of screen FPS goes higher. The group formation system is under porting to UE4, spawning works, but the update will only be ready in the beginning of May. It will produce more optimized unit control, movement, and pathfinding, thus more intelligent behavior beside better performance!

What the system outputs for unit actors is a “move to desired target” behavior, so there is no any real AI stuff now. There will be options to create AI for unit and group level too, the latter one will be the preferred one and more optimized. It will definitely affect performance…

To use World Composition or something similar is a target indeed! There is a system established but very WIP to handle more levels loaded runtime with their own RTS map data, but I thought rather to use code for this level loading procedure from Rama’s plugin, and merge map data after loading the levels…

Blog post #1 : Overview

BLOG POST #1

Hi,

I am planning to regularly post here information about the actual state of the development, and also about the details of the RTS system, to let you understand better what it really is. Let’s start with a basic overview!

Overview

Background

Beside the rendering limitations of GPU+CPU, controlling many units while running a strong AI results in significant CPU load too. Doing many pathfinding searches, and selecting the right behavior in this scale, while maintaining a relatively high and smooth FPS is not an easy job. Beside this high load, it is a general requirement in RTS games to support various sized units with very different movement capabilities, what can highly increase pathfinding related data requirements. Furthermore, game AI must be fed by a good database, what should be used with, and practically tightly connected to the pathfinder system.

Description

Finally, I found the available NavMesh and simple tile based systems not suitable for this purpose (even the time sliced ones), and after a long research and testing, I established my own “little” system, which is very close to what you can see in Company of Heroes: a tile and cluster based two level hierarchical pathfinding, supporting more (by default 4) unit capabilities, and different unit sizes by using so called clearance maps. It means you can have e.g. infantry, cavalry, and siege units on ground plus ships on water, and in all capability categories the pathfinder supports 1x1, 3x3 or larger unit sizes (measured in tiles). What makes it hierarchical: **tiles are used for short range unit pathfinding, clusters are used for long range group pathfinding. **

This method has the following benefits:

  • a significant decrease in search times beside producing optimal paths,
  • paths can be** dynamically updated with low performance cost**, resulting in fast response to environment and enemy troop position changes,
  • allows detailed environment evaluation, supporting advanced AI behavior, and enabling to set player units and groups to auto mode, by defining their task without micro-managing them continuously.

It is also essential to **handle the ever-changing environment **effectively runtime, like rising and destructing buildings, so the RTS map database is divided into static, stationary, and dynamic sections to manage it fast enough.

To have a good visual debugging system is another must, and widely used with more options, some of them are available through editor checkboxes, but most of them only by C++ defines and preprocessor directives, to have an optimized game code finally. Currently it is solved by UE4 standard DrawDebugBox(), DrawDebugPoint(), and DrawDebugLine() functions, but a faster, shader based debug view option is planned in near future using dynamic textures for landscape, terrain models, and buildings.

A final cluster arrangement (used by the long range pathfinder) can look like this, with a basic debugging visualization showing tile correspondence to clusters:

http://s26.postimg.org/6bylqroeh/RTSMap_Clusters.png

At high slope regions they are subdivided into smaller ones for more optimal pathfinding, what can be also checked by a simpler, less performance eater debugging view (cluster middle tiles are also represented):

http://s26.postimg.org/nb7k60zm1/RTSMap_Cluster_Under_Mouse.png

**Processing the level
**
Of course, the pathfinder and AI system should understand the game level geometry. This is done by the map decomposition system, which is done simply by an actor that you can drag into the game level, set its size given in tiles, and define tile and default cluster size. Just hit generate, and it will create the pathfinder maps in the following sequence:

Static part:

  1. create basic tile and cluster database, clusters (small areas) with a uniform distribution and shape,
  2. measure the surface of landscape and terrain models, set tile properties based on slope,
  3. set cluster properties based on included tiles, subdivide them into more specific ones if needed, evaluate special areas like hill-side, hilltop, summit, deep water, shallow etc.

Stationary part:

  1. detect instanced static mesh components and actors (small obstacles),
  2. detect large obstacle and building actors, create new clusters if needed, set their properties if a database available (otherwise set these areas impassable)

The above described map decomposition process can be generated in more ways:

  • design-time for pre-made maps (requires more disk space, but fast on game start),
  • on startup for random maps (slower map loading time),
  • combined: make the slower map surface detection (static part) and evaluation on design time, and do the fast actor processing (stationary part) on game start (useful when only building and vegetation arrangement differs),

Moreover, all the three method can be used also for levels consisting of more sub-levels, loaded in mosaic arrangement or by world composition (WIP).

The final result is the stationary clearance map (used by the short range tile pathfinder):

http://s26.postimg.org/ewwivonyh/RTSMap_Stationary_Clearance.png

Special objects

This custom RTS system utilizes some special objects, usually inherited from ARTSEntity abstract actor class:

  • small obstacles: little objects should be avoided by units, can be destroyable or used for resource gathering, cannot be owned,
  • large obstacles: similar to small obstacles, but they have their own cluster, resulting in better pathfinding,
  • buildings: like large obstacles, but can be owned, and additionally they can contain tile and cluster data of their floors, i.e. they can be used to make a siege game with towers, gates, and defenive walls (currently csv files store the tile and cluster data (surprisingly easy to create it with Excel or OpenOffice), but it is planned to make a building editor level or blueprint,
  • units: can be owned, controllable builder/gatherer/fighter actors, normally with a skeletal mesh or static mesh component, capable to do short range tile pathfinding to the assigned desired target tile, executing and optimized movement,
  • groups: can be owned, can contain large number of units and organize them into different formations, automatically order units where to move and what to do based on group order received from player or AI; capable to do long range cluster pathfinding, but also does short range tile pathfinding in complex environments e.g. in bottleneck situations or labyrinth like regions to have a snake like shape,

And there are many other smaller or larger, but definitely important classes and structs handling formations, reading in formation data files, tile pathfinding, cluster pathfinding, reading building data files, animation sets etc. They will be detailed when editor functionalities are introduced in a later post.

**Planned or WIP Features
**

  • container buildings (town center, mines, defensive towers),
  • carrier units (ships, vehicles, siege towers),
  • save/load system (based on the custom ID system),
  • main menu
  • advanced player system (supporting more civilization tech trees),
  • multithreaded tile and cluster pathfinders,
  • multithreaded static map decomposition,
  • movement prediction (better collision avoidance in crowded areas),
  • more realistic vehicle pathfinding and movement, calculating with turn radius (based on Marco Pinter’s article and demo),
  • hexagonal or octagonal base clusters shape beside the existing rectangular ones,
  • influence maps and potential fields for game AI

Thanks for reading!

News #1

NEWS #1

Hi,
I have great news, a milestone is just completed:

**GROUP MOVEMENT IS WORKING! **

Tested with two formations (line and wedge), several groups, hundreds of units, and apparently nothing wrong (after a few days of bug-fixing, ha-ha). Groups can avoid the lake and other impassable areas, while units are trying to keep their relative formation positions depending of the actual direction of the group, using some speed boost if necessary. On diagonal movement zig-zag path shape and group direction is smoothed fine.

Multiple groups pathfinding and movement:

  1. Initial positions:

http://s26.postimg.org/qora93knd/group_move_1.png

  1. Assigning a target over the lake, and getting paths (some debugging info drawn):

http://s26.postimg.org/frpykbxvt/group_move_2.png

  1. On the way:

http://s26.postimg.org/gva2waiix/group_move_3.png

  1. Beyond the lake groups are turning towards target, and formations are kept:

http://s26.postimg.org/5t4zxuog9/group_move_4.png

**
Path smoothing:**

http://s26.postimg.org/7c0e2tv0p/group_path_smoothing_1.png

Now ready to move on, to assemble a little siege testbed town to examine group behavior in really complex environment, full with bottlenecks requiring sharp turns and formation reforming, to walk through gates, narrow streets, stairs leading up to defensive walls, and also to find places to avoid towards target, if it there is a longer but faster way.

A video is coming soon!

Looks really good, What sort of performance are you getting with so many units on screen at once?

I would love to see the nr of units increased (TW style) if that’s possible :smiley: some 3rd person controll of the soldiers would be epic :smiley:

Hi,

on my nearly 4-year-old laptop (specs. in 1st post), if 300 units - each consisting of a skeletal mesh and a flipbook lod - are on screen, and animating/pathfinding/moving/colliding, FPS stays continuously over 30. Until this, the bottleneck is my GPU hardware, around 400 units the bottleneck becomes the game thread, min. FPS is about 25, which is great because it means I can optimize it further by e.g. better collision avoidance (movement prediction), multi-threading, or path sharing. When less units are visible (top down camera), or more units are idle, FPS is increasing nicely to slightly over 40. In near future I will make a new testbed level with a town, where a different more advanced formation positioning system is used, what costs a bit more performance, but works more smoothly in crowded areas. So there are a lot of things to implement/test on my to do list. :slight_smile:

I planned to post screenshots always with unit stats, but sometimes I forget it… :rolleyes:

By the way, what about your marketplace RTS product, how well it performs with a few hundred units? I guess it uses the built in navmesh pathfinder.

Hi,

unfortunately there is no instanced skeletal mesh implemented in UE4… :frowning: But I have a plan, as always :smiley: In future, I want to replace my current flipbook lod with a static mesh component, animated by a shader (like in my original project made with another game engine), then there would be a chance to use instanced static mesh components somehow…

Here comes another “but”: probably it would require a different unit pathfinder, something more “stupid”, more CPU friendly. In TW there are large areas, even city walls are wide, maybe a potential field or vector field system would be better in that case. I have just researched it in the past few days, it can also be hierarchical as my system, and can be based on my current A* implementation, so not impossible to add it later as a secondary unit pathfinding solution… But I’m not sure its performance would be much superior.

I thought of 3rd person control too, once I made it with a navmesh based group pathfinder when I tested Esenthel game engine, so this “hero mode” is really possible, I add it to my “little” list. I think it will be allowed only for special units to be followed/protected by other own units…

Sounds impressive look forward to seeing your progress. Unfortunately we don’t have RTS style characters to test performance out properly in our RTS Template as the main bottleneck when we have a lot of units on screen is the fact the default unreal character has something like 40K Polys.

yes, even the mobile mannequin is too high poly for RTS, and bone quantity does also matter a lot…

Currently a simple modular wall system is being created for testing the multi-level pathfinder (by default two building floors are available, what can be a ground floor and a 1st floor in case of a gate, or an inner and a top floor in case of a tower without ground floor entrance):

http://s26.postimg.org/u4nzwe79l/RTSModular_Walls01.png

Video #1

**VIDEO
**
Long range movement test with a couple of groups in line formation.

Video #2

VIDEO

In this short video you can see how to control a group of individual units within short range (in future they will form a group immediately), and what is more exciting, groups moving up and down walls, using different pathfinder methods.

Groups can automatically detect bottlenecks and reshape according to the available space. When arriving back to an open field region, they form back to their original shape. A simple but effective priority based collision resolution is applied, when avoidance is not good enough (sharp building edges, crowded corridors).

Video #3

NEWS

After a short holiday, a video is here again!

Thanks to the quality improvements made in the last weeks, group cohesion has become quite good. Currently no error resolving used on unit separation (which is now a really rare issue!), it is detected only, but of course will be handled in near future, to make the current system a game ready tool.

In this short test video 8 groups are spawned, each consists of 36 units. They receive move orders to different locations, in a complex environment containing bottlenecks like castle gate, or stairs leading onto building floors. As you can see they need no additional help, everything just works fine, beside good enough performance. :slight_smile:

The simplistic debug visualization highlights:

  • cluster areas by little boxes (used by cluster pathfinder),
  • cluster path steps of the selected group by a line with a sphere on the top,
  • the group’s tile path used or alignment by large dots,
  • unit targeting by red and green dots representing desired and real target tiles respectively.

This looks really interesting. My project probably don’t need to have too smart AIs, but do need good quality LODs.
You mentioned using shader to animate a static mesh, I’d assume that would be baking vertices local offset to a map, and UV offset to get the animation frame to get value.
But since I am not quite experienced on the material system yet, how do you avoid texture filtering/mipmapping to alter the value you want? (like access precise which pixel to get.)

Maybe I’m just overthinking it, you could just have a pre-allocated array of vertices info per frame and just have shader call a function to fetch the result.
But that’s on GPU, and I don’t know how to do this properly.

Questions, what’s the requirement for the LODs you have there? You mentioned bone amount, how many poly could affect performance.
So the real question then becomes, how do you budget the amount of AIs?
It would involve overhead to go through all the AIs, run the AI action, draw them with animation blended.
What do you use as guide to generate your content? Like for 100 agents, AI action can not be over 1ms, and draw them should take less than 3ms?

Hi,

as I mentioned

, but I had no time to switch to the static mesh component version, still use flipbook component. I had to deal with making the pathfinder more robust first.

The plan, what worked with DirectX9 HLSL and should work with UE4 materials, is to manage UV coordinates at pixel shader texture sampling to get the proper window of the texture, by defining the type of animation (row), setting the column section based on unit heading angle and camera angle i.e. actual mesh angle difference (column shift), and to set the actual animation frame (column). Since I will use it for far lod, I do not panic because of filtering and mipmapping (it is fine with flipbboks currently). What I don’t know how proper shadows would be achieved, I just hope I would not need tricks… The above mentioned parameters should be passed by the actor to the its material.

I do not have exact ms limits, but since I have an old laptop with an old video card, I want to achieve 33ms (30FPS) for both the game thread and the GPU (the drawing thread time is always lower).

Normally my performance limit is the GPU, so I keep materials very simple, poly count under 1000 for vegetation (they have usually 2 materials) and unit models too (single material), use 3 lods (earlier I used 4, but lod switching is more expensive with UE4 that I expected), the 3rd lod has approx. half the vertices and polys that the 1st, and my infantry units have a common skeleton with only 20 bones (but usually 17 would be enough). With the default mannequin I would get terrible performance even with 100 units onscreen.

The CPU load gets higher that GPU over a certain unit quantity, I mean when all the units are moving and onscreen, earlier it was around approx. 400, now lowered towards 300 as the increased pathfinder quality needs more heavy calculations… My main focus is this area, because I expect players to have a bit better graphics card that mine, and the game thread will need more power for further tasks like GUI handling, AI decision making and planning (fortunately its potential fields and infuence maps can be made hopefully fast enough by the help of the pathfinder system). So multithreading and a new vector field pathfinding (under research and development) are the milestones ahead. If I can lower the game thread time, I can deal with rendering optimization again.

Nice job bro!

How do you manage formations?
You calc individual pathfinding for each unit, or group them?