Over the last few years, I have been gradually changing the way I approach gameplay development in Unreal Engine.
Instead of building every system specifically for a single project, I have been trying to identify the smallest set of reusable modules that could support several different games.
The objective is not to create one huge framework that attempts to solve everything.
The objective is to build a collection of independent gameplay plugins that:
-
Can be installed separately.
-
Communicate through clear interfaces and events.
-
Can be configured without modifying their internal code.
-
Work with both C++ and Blueprints.
-
Remain understandable and maintainable as a project grows.
-
Can eventually form a minimal foundation for building a complete game.
From a finished game to reusable systems
This approach comes from developing my cooperative game, DemonCountdown.
During its development, I created systems for interaction, inventory, crafting, health, damage, combat, multiplayer and enemy behaviour. They initially belonged to the game, but many of them were solving problems that would appear again in almost any other project.
The difficult part was not simply moving that code into plugins.
The real challenge was deciding:
-
What responsibility belongs to each plugin?
-
Which systems should know about each other?
-
Which dependencies are genuinely necessary?
-
What should be implemented in C++?
-
What should remain configurable or extendable in Blueprint?
-
When is a plugin complete enough without becoming too large?
The current minimal gameplay stack
At the moment, I see the framework as a collection of several layers.
1. Interaction
A generic interaction system should only be responsible for detecting and executing interactions.
It should not need to know whether the target is an item, a door, a crafting station or an NPC.
For example, I separated interaction availability from the interaction itself:
-
SetInteractionEnabledcontrols whether an actor can currently be used. -
PerformInteractionexecutes the player interaction. -
Blueprint events provide visual, audio or project-specific feedback.
This keeps the core interaction logic independent from the gameplay implemented by the interacting actor.
2. Inventory and crafting
Inventory and crafting are closely related, so they can reasonably belong to the same product while remaining internally separated into different components.
Items and recipes are defined as data, while components manage storage, transfers and crafting operations.
The UI uses reusable base widgets implemented in C++, but developers can create the final visual design in Blueprint without rebuilding the underlying inventory logic.
3. Health and damage
Health is a good example of a system that should be small and reusable.
Other systems may send damage or react to death, but the health component should not need to know whether the damage came from a melee attack, a projectile, an environmental hazard or an AI character.
A lightweight version can also be included as an optional dependency when another plugin only needs basic health functionality.
4. NPC and enemy AI
The AI system is responsible for perception, target selection, chasing, repositioning and executing configurable attack patterns.
However, the AI Controller should not directly depend on a particular enemy character implementation.
I use interfaces to request actions from the controlled Pawn and Data Assets to define attack patterns. This allows designers to create different enemy behaviours without duplicating the controller or rewriting the Behaviour Tree.
The AI decides what should happen. The Pawn decides how that action is visually and mechanically executed.
5. Spawning and encounter management
Spawning belongs to a different architectural level.
An individual enemy is responsible for its own behaviour, attacks and reactions. A spawner or encounter system is responsible for deciding where and when enemies appear.
A wave or horde system belongs one level higher again. It coordinates groups of spawners, multiplayer progression, encounter states and victory or failure conditions through the GameMode and GameState.
This distinction has helped me avoid turning the AI plugin into a collection of unrelated systems.
Complete plugins, not tightly coupled plugins
One of the most difficult balances is making each plugin useful on its own while still allowing it to cooperate with the others.
A modular plugin should be complete within its responsibility, but it should not attempt to own the entire game.
For example:
-
The interaction plugin does not need an inventory system.
-
The inventory can expose operations that an interaction triggers.
-
The AI plugin does not need to own the health system.
-
A melee damage module can communicate with any compatible health or damage receiver.
-
The horde system can spawn simple test actors without requiring the complete AI or damage stack.
Interfaces, delegates and optional dependencies make these combinations possible without creating a rigid framework.
C++ core, Blueprint extension
My preferred approach is to place the reusable rules and critical logic in C++ while exposing configuration and project-specific presentation to Blueprint.
C++ provides:
-
Stable base classes.
-
Clear APIs.
-
Reusable components.
-
Multiplayer authority and replication rules.
-
Validation and default behaviour.
Blueprint provides:
-
Animation and montage selection.
-
VFX and sound feedback.
-
UI appearance.
-
Project-specific reactions.
-
Fast iteration for designers.
The intention is not to replace Blueprint with C++. It is to give Blueprint a clean and reliable foundation.
Maintenance is part of the product
For a reusable plugin, the code is only one part of the work.
A plugin also needs:
-
Sensible default values.
-
Clean Blueprint nodes.
-
Tooltips and editor categories.
-
Quick Start documentation.
-
Example assets and a demo level.
-
Multiplayer validation where applicable.
-
Upgrade notes and a predictable release process.
If integrating or updating the plugin requires understanding its entire internal implementation, the architecture is probably not modular enough.
The long-term objective
The long-term goal is to provide a small collection of plugins that can be combined to create the gameplay foundation of different projects:
-
Interaction.
-
Inventory and crafting.
-
Health and damage.
-
NPC and enemy AI.
-
Spawning and encounters.
-
Multiplayer horde and wave management.
Developers should be able to use only one system or combine several of them without being forced into a particular character class, visual style or game genre.
I am currently developing and refining this architecture through my FAB plugins and real Unreal Engine projects.
I would be interested in hearing how other developers approach this problem:
-
Do you prefer several focused plugins or one integrated framework?
-
Where do you draw the boundary between AI, combat and damage?
-
Should optional integrations live inside each plugin or in separate bridge modules?
-
What systems would you consider essential in a minimal gameplay framework?
I will share more detailed breakdowns of the individual modules, their dependencies and the architectural decisions behind them in future posts.
Current systems, demos and documentation:
-
FAB: Fab
-
Website: https://vicagent.com
-
GitHub: george-plab (George) · GitHub
-
DemonCountdown: DemonCountdown on Steam
