Key Points
- Created with C++ and UE4
- Focus on UI and feedback of data to the player
- Creation of a UI framework designed to manage Widget visibility and focus
- Sorting and filtering of data to allow for context sensitive menus
- AI agents using Behaviour Trees, Blackboards and NavMesh with custom C++ decorators & tasks
- Heavy use of interfaces and abstract classes allowing for heterogeneous instances for gameplay variation
- Management of game and player state through custom GameMode and PlayerController
- Custom components designed to extend functionality of existing UE4 systems
- Use of timers throughout, including custom ticks designed to optimise performance
- Use of delegates to broadcast data, reducing dependencies by loosely coupling code
AI & Orders
Players can issue orders to units/ships through the game such as move and attack, this was handled using a combination of UE4's behaviour tree system and an Order Manager class I created. Each unit held an array of orders that allowed for a data-driven approach, easily adding and removing orders both at compile time and runtime (I didn't add/remove orders at runtime in the game, but the system allows for it). The Order class holds some logic, however, its main purpose is to update the behaviour tree with the appropriate state, allowing the AI to execute the sequence of events tied to that order.
Some orders could be activated directly through the mouse (such as right-click on an empty space to issue a move order), however, most of them require binding to a button. When activating an order in this way, there are two ways in which input needs to be considered:
- Does it execute immediately? (Such as the Stop order)
- Does it require an additional input? (Such as the the Attack order)
The Order Manager class handles this by storing any orders that require additional input as pending, while changing the Player Controller's input state accordingly. Whether an order does indeed require an additional input is defined within the order itself.
Due to the use of polymorphism and a finite state machine with regards to Orders, I have created an extensible and modular system that can be used to easily create new behaviours by simply creating a new sequence of events within the behaviour tree, and by extending the base Order class to set its state.
UI Framework
I constructed my own UI Framework that was designed to manage the elements that were currently displayed on screen and update them with the appropriate data. The idea was to create an abstraction to reduce the number of dependencies that UI can often lead to. Each element seen within the UI is built using this framework, including the minimap, selection information and order buttons. I expanded upon this idea for my dissertation, where I improved the functionality of many elements, creating a more generic framework that can be slotted into an RTS project with minimal setup. Rather than cover these points here, I encourage you to check out Reusable UI Framework for RTS Games for more details.
Build Queue
One UI element that was unique to Starfall: Commander was the build queue. Players could create new ships at runtime through their Capital Ship by spending resources they have collected, each ship has an associated cost and build time. The player could queue a total 5 ships to be built, providing they have adequate resources. The build queue will then sequentially work through each ship, spawning a new actor once the build time had expired, similar to many RTS games.
This was handled through the use of the Abstract Factory pattern and interfaces. Each ship posses the IBuildable interface, allowing them to be constructed via the build queue. Once the ship is selected for building, providing the player has the necessary resources and that there is room in the queue, the object is added and a timer is started. The build queue stores a reference to a UI Widget that displays realtime updates using a progress bar on the remaining build time. When this reaches zero, the ship is spawned and moves to a rally point.
Gallery