Roquelike bullet hell ability system

This ability system was developed as part of a group project with four classmates, a roguelike bullet hell game following a wizard named Arnold, who must survive increasingly difficult waves of enemies by growing stronger and unlocking new abilities.

The project called for a flexible ability system capable of supporting both passive and input-driven ability activation. Key requirements included a modular architecture that made adding new abilities straightforward, as well as a dynamic inventory system to manage them.

While pick-up and achievement logic for abilities were not implemented within the project’s timeframe, the system is fully built to support dynamic inventory management and can be readily extended to accommodate these features in the future.

Design

The ability system is built around an inheritance-based architecture, supported by three core handler classes. The AbilityHandler is responsible for managing cooldowns and ability activation. The AbilityInventory handles all inventory-related logic, including picking up, removing, and tracking the availability of abilities. Finally, the AbilitySystem acts as the central hub, combining the two handler classes under a single interface while managing references, input handling, and GUI visualisation.

All abilities inherit from a shared base class, which defines the core functions and behaviour common to every ability. This makes extending the system straightforward, adding a new ability is as simple as creating a new class and inheriting from the base.

Abilities Show off

This is the passive ability made for the showcase of the game concept, it’s called magic-ring. This ability gets called every 7,5 seconds when in the inventory and casts a big ring of AOE projectiles in a radius around the player. It’s very effective to help push out some more damage to survive the wave.

This is the Fireball, the offensive ability for this prove of concept. It is our offensive ability, a slow moving projectile with huge area of effect that can wipe-out huge amounts of enemies in 1 cast. To balance it out a bit it can only be cast every 10 seconds.

Ability Class

The base ability class serves as the backbone of the system, though it is not the physical manifestation of an ability itself, rather, it is the class that reperesents the ability that lives within the inventory and is updated every frame. It is responsible for spawning objects and sprites that interact with the environment at runtime. An AbilityType enum is used to classify each ability, determining whether it behaves as a passive or an offensive, input-driven ability.

To implement a new ability, all that is required is to inherit from this base class, keeping the system clean, consistent, and easy to extend.

Ability Handler

The AbilityHandler is responsible for managing the core runtime logic of the ability system. This includes iterating through all active cooldowns and decrementing their timers each frame, automatically triggering passive abilities once their cooldown has elapsed, and activating offensive abilities in response to player input. The class is designed to work in close coordination with the rest of the system to fulfil its role effectively.

Ability Inventory

The AbilityInventory is a central component of the system, responsible for tracking every ability the player currently holds regardless of type. It exposes this data to any class that requests it, enabling other systems, such as the AbilityHandler for cooldown management or the GUI for visualisation, to function without needing to manage ability data themselves.

As mentioned, the inventory includes built-in support for adding and removing abilities, providing a clean and accessible interface for any pick-up or inventory management system to hook into.