Skip to the content.

Unreal Engine,WWise May 2024 – August 2024 8 Generalist & AI Programmer
Dare Academy Finalist Presented at EGX x MCM 2024 London

Description

A first-person action-packed wave-defence experience with some resource management mechanics or as described in the game's pitch:

"Chempunch is an intense wave defence action game focusing on reactive but aggressive gameplay in a chempunk world. Alone but far from helpless, you must protect your slums from an oncoming horde, using chemicals you route around your body to empower different actions."

Me pointing at Chempunch Banner At EGX
Team Work illustration

Enemy Horde AI System

The AI was originally designed for a mode where enemies rushed an objective and the player intercepted them. This later shifted to wave defence, but the AI kept its flexibility.

Goal Prioritization

Enemies choose between the player and the objective based on navmesh distance, weighted by configurable scalars. To avoid erratic switching when scores were close, I stabilized decisions by adjusting how often priorities were updated in the behavior tree.

Strafing Behavior

To support strafing, I separated movement and attack goals. By tweaking their weights, enemies could act aggressively, rush the objective, or strafe while firing—creating variety in enemy types.

Player Awareness

Enemies use sight (via Unreal’s perception system) and sound (e.g. gunfire, ally deaths) to detect and track player. Player location is individually tracked by enemies and forgotten after a short delay.

Tactical Ranged Positioning

Ranged enemies maintain their distance by stepping backward while maintaining line of sight. This is handled through Unreal’s Environment Query System (EQS).

The Behaviour Tree

Team Work illustration
Team Work illustration

AI Coordinator – Managing Group Enemy Behavior

The AI Coordinator controls group-based enemy decisions that require coordination, like deciding which enemies attack the objective and which ones defend them. To avoid overwhelming the player, a designer-defined limit sets how many enemies can attack at once. This caps the potential damage output and ensures a mix of behaviors. The class is a Singleton and uses the Observer pattern, with enemies subscribing to receive role updates. These roles are applied by modifying blackboard values, which guide behavior tree logic. At the start of each wave, the coordinator runs an EQS query to find defending positions arranged in a spiral around the objective (slightly offset to leave space for attackers). These positions are wrapped into custom Responsibility structs that define what each enemy should do. Attack responsibilities always have higher priority. When an enemy dies or unsubscribes, its task is reassigned to the nearest available enemy, keeping the group behavior fluid and adaptive.

Congestion-Aware Pathfinding

To reduce bottlenecks in enemy movement and ease the burden on level designers, I extended Unreal’s default pathfinding system with a congestion-aware routing mechanism. A custom data structure, the Congestion Map, tracks traffic density across navmesh nodes by associating each node with a congestion score (an unsigned integer). Every X (contrallable parameters) frames , the system:

This data is then fed into a custom FCustomRecastNavQueryFilter, which biases pathfinding away from highly congested areas. As a result, enemies naturally spread out and avoid forming predictable chokepoints, making encounters feel more dynamic and organic.

Early prototype of the congestion-aware pathfinding system:

Wave System

Implemented the full wave logic, including timers, active spawners, door control, and randomised enemy distribution. All parameters are exposed in the Unreal Editor, allowing designers to easily configure and test wave setups without code changes.

Dynamic Difficulty

Developed a designer-friendly system that tracks a score, which increases when enemies are defeated and gradually decays over time and if enemies hit the target objective. This score feeds into custom editor curves to dynamically scale enemy cap and spawn rate, adapting the game’s intensity in real time.

back