Gameplay System Module

What is the goal?

I wanted to create a tool that could be used to create many kinds of gameplay, utilising some common types that each would represent systems that games feature. This would require a heavily modular set of tools and classes that could then be derived and expanded upon for different games and teams.

This module was developed as part of my research into modular gameplay systems for my Bachelors Thesis.

What is it?

Throughout development I ended up with four base tools, GameplayAbilities, GameplayEffects, GameplayEvents & Attributes, that all can be used to author gameplay elements. These are derived from superclasses that define their base functionality and purpose, and allow us to encapsulate gameplay elements into reusable pieces for easier development. I took inspiration from Unreal's GameplayAbilitySystem when designing the module.

This module was used for creating the hack-and-slash combat featured in Access Acquired.

I want to hear more!

GameplayAbilities

In-editor view of the GameplayAbility blueprint and its properties.
Example of a blueprint implementation of a action as a GameplayAbility.
Example of a blueprint activation of a GameplayAbility.

These represent the actions that can be performed by an character. Supports complex activation requirements, cancelling of in-action abilities, cooldowns and more, giving full control over how actions interact with each-other and what they do.

GameplayEvents

In-editor view of the GameplayEvent blueprint and its properties.
Example of a blueprint implementation of a set of VFX work as a GameplayEvent.
Example of a blueprint activation of a GameplayEvent.

These encapsulate any VFX, SFX and other visual or game feel work into reusable events. Features global or per-actor uniqueness, DeltaTime syncing options, blocking and ending rules enforced through GameplayTags, can share lifetime with their activator and more.

GameplayEffects

In-editor view of the GameplayEffect blueprint and its properties.
Example of a setup of different Modules and its properties that are used for a GameplayEffect.

Temporary modifiers that can be applied to a GameplaySystem. They can modify attributes, GameplayTags, be represented in modifier bars, trigger other modifiers, abilities, events and more. This allows them to any number of modifiers a game might need, and as such also have alot of parameters to tweak the individual behaviours.

Modules

GameplayEffects can also utilise Modules which allows for further customization. Modules are UObjects, and can be derived to create any effect and behaviour that the existing properties can't make.
They are instanced per GameplayEffect, and can as such have properties themselves that are adjustable per GameplayEffect.

There are three types of modules, that each affect a part of the GameplayEffects behaviour:
Executors - Changes the application, reapplication and removal procedure
Conditions - Changes the application and reapplication conditions
Stackers - Changes the stacking behaviour of GameplayEffects with stacking enabled

Example of a TakeDamage module in use.

Example of a TakeDamage Executor module used to deal damage.


Changing the health attribute directly is ofcourse possible, but it would sidestep the entire damage system, which is usually not desired. By using a Module, we let the GameplayEffect generate a damage event that can be resolved normally.
This is especially important for the player, since they typically have unique feedback associated with taking damage (screen effects, sound effects, haptic feedback) which is vital to preserve when taking damage.

Attributes

In-editor view of a set of Attributes and their values.

These can be anything from health to damage multipliers - whatever is needed for your game. Modifiers can be aggregated and stacked which allows for complicated RPG-like stat chains of mixed types, such as additive, multiplicative or overriding effects. You can read more about the custom Slate UI under the UI section.

Levels and experience

A DataSet can be used to assign level-breakpoints, which will trigger when enough experience is gained. This can increase attributes and trigger fitting visual effects.

Screenshot of the debug view in action, with the properties it displays.

Integrated Debug UI

The framework features a custom Debug widget that automatically displays key properties of a GameplaySystem. It has input bindings that allow designers to quickly toggle it on and off, switch the displayed page and swap the displayed component.

Takeaways

Target Locking

What is it?

An ActorComponent that allows the camera to track enemies, locking onto them and keeping the screen centered when requested by the player. It creates MotionWarping targets to help the player target enemies even without input, or correct their input to stay on target.

What does it do?

Switch Targets

Players can switch targets by inputting a direction on the camera controls. While testing, I found that it was more intuitive to pick targets based on their location in screen space, as opposed to distance between targets. An input to the right would therefore switch from the current target to the nearest enemy on it's right, as they appear on screen.

Camera Tracking

A CameraModifier is applied to the owning Actors Camera component, which is responsible for the target tracking and ensures only one tracking modifier is applied at once.

World-Icon

When a target is locked, a WidgetComponent is enabled and lerped towards targets location. It queries the targets TargetLockingComponent to allow it to decide the location of the icon to ensure that different-sized targets all have the icon centered on their body.

Aim assist

During playtesting, we found that it could be difficult to keep the players attacks on enemies during the chaotic combat. To help this, actions that involve movement or require targeting can request MotionWarping points to be placed. The played animations can then use these points to rotate towards the targets direction.

Any Actor with a TargetLockableComponent is tracked within a certain distance.

When an action requests a target, one the first successful option is picked:

The active-input-override was added during the implementation, since I noticed very quickly that whenever the aim assist tried to track a target my own input would be ignored which just felt frustrating, rather than helpful.

Finally, while I was at it I added an extra feature where whenever a target is found very close to the direction the player inputs, it will place a MotionWarping point on it to it to ensure the attack is facing the target.

Takeaways

Networked Tank Battles

What is it?

A fully networked game, ran over the local network with my own network protocol and game engine. It handles automatic LAN discovery, connecting multiple separate clients, timeouts for unresponsive clients, disconnects and reconnects. Packets are sent from the Server 10 times per second, with Client sending input 20 times per second, but can be customised for different game types.

I want to hear more!

Diagram that shows the relations, interactions and responsibilities of Server-side classes.
Diagram that shows the relations, interactions and responsibilities of Client-side classes.

Object-Oriented Design

The engine supports polymorphic handling of abstract GameObjects, which is the core Super class that all Game entities derive from. Objects can then implement multiple functions to expand their functionality, such as signing up to the Controllers are assigned to objects on creation, and handle the objects replication & serialization, interpolation and - in the case of PlayerControllers - input.

Physics Engine

Colliders are used to describe physics shapes, which are represented as a collection of convex 2D points. Participating entities will receive callbacks when colliding with other entities and receive any generated collision data. I use Separating Axis Theorem to detect collisions between game-ticks. Minimum Translation Vector is used to accurately separate objects with respect to their position and rotation.

Ticking and Timers

TimeManager which Ticks objects and handles asynchronous actions and timers.

Network Protocol

It handles automatic LAN discovery, connecting multiple separate clients, timeouts for unresponsive clients, disconnects and reconnects. Packets are sent from the Server 10 times per second, with Client sending input 20 times per second, but this can be customised for different game types.

Diagram that explains the content of a Server-packet that is sent to clients.
Diagram that explains the content of a Client-packet that is sent to the server.

Reliable Messages

Each message is tracked, stored and resent in each packet until it is confirmed to be received by the other end. An algorithm is used to encode packet-level acknowledges into a uint32, allowing a single packet to describe the acknowledge state of 32 messages. Some messages will always need to be tracked, such as spawning of player-controlled objects so that connecting Clients can replicate them correctly.


These so called 'Critical' messages are stored and later sent for any newly connected client. They can then be queried and removed in case the message is no longer valid, such as when a player leaves and their controlled object is removed.

Takeaways

Bachelors Thesis

Picture of the front page on my Thesis.

What is it?

In the paper I explore how the Gameplay System can be used to facilitate game feel in game development. The Gameplay System was created throughout the development of the 3D hack and slash game Access Acquired.

From my experience as the sole programmer on the team of Access Acquired, I noticed the need for generic solutions to common game concepts. By finding an approach that would allow delegation of the implementation to the designers themselves, I would be able to focus on other technically complex areas of game development that require my skillset instead. This approach could possibly benefit other teams with limited resources, be it time or programmers.

I want to read it!

The full text is available in the link below, which gives a different perspective into the development of the Gameplay System and its goals. There you can also read my co-authors, Meike Lenting's and Jamie Braad Sernbo's, work in their respective area of Access Acquired.

You can find my individual thesis on page 30.

Click me for thesis!