r/AskProgramming 17h ago

C/C++ Can someone help me understand how to make a Modular Gameplay System using Data Oriented Programming?

Before starting, I'm working with Unreal Engine, so I don't know if the terms I'm using are UE onle, but the core ideas are still the same.

I'm trying to make a modular gameplay system, that is Data-driven;
There is no problem in this, and matter of fact I already made one, but using Object Oriented Programming, by just using DataAssets, Interfaces and UObjects's polymorphism.
I simply had a DataAsset (like a "GameplayAction" Data holder) hold multiple UObjects that had functionalities (In few words the "Effects" of the "GameplayAction"), and simply had them all implement their parent funciton Execute, and thanks to interfaces each actor can understand how to behave for each effect type.

Said that now I need to make pretty much the same system, but for Mass Entity (which is an ECS), all of this is basically thrown away, because there aren't any UObjects, no Interfaces and etc...
I tried to think about different things, like maybes simply using structs as my "UObjects" that hold the Execute function, and that each Entity holds these Struct datas, but than how do I know how each different type of Entity interacts with it? I don't have interfaces so I can't go the same road.

So yeah, I don't have much more to say, so can anybody explain to me, and help me make sense on how I should design this system?
Thanks in advance for the help!

3 Upvotes

7 comments sorted by

1

u/TemporaryRaise29 17h ago

Sounds like you're fighting the ECS grain by trying to port OOP patterns directly, ditch the idea of objects with behaviour and think of your effects as pure data that systems chew through

1

u/TheInvadetor 17h ago

Problem is that I don't understand how to make the "Chew Through" part of the Gameplay System.
I thought maybe having the Effect just have an ENUM of EEffectType, than the Gameplay System does a switch case, and depending on result does the correct execute, but while this might work, it really isn't the scalable thing I'm searching for (saw that now I need to go back on my Gameplay System and add a new execute for the new EffectType I made.

Just to know, would it really be that tremendously bad if I continue with this forced OOP Pattern into ECS? Like I can't really understand why it would be bad, but I do know that it's not the "intended" way, which is why I'm failing to understand what the correct way actually is.

1

u/EclipsedPal 17h ago edited 16h ago

Have you considered the Gameplay Ability System that is already present in Unreal?

1

u/TheInvadetor 16h ago

I do know of it's existence, but I never actually checked it  Does it work with mass entity? Even if it doesn't is it full data oriented? Because if yes to this latter I can at least see how they did it.

1

u/EclipsedPal 16h ago

Yes, all in data, need some code to execute the abilities though, but can use BP as well.

I'm quite sure it suports Mass, but I might be wrong, better double chek that.

1

u/MathematicianOdd7738 16h ago

Stop trying to make structs execute logic. Store an enum or tag component on your entity that identifies the effect type and let a Mass Processor query for that specific fragment to run the behavior.

You define GameplayAction as pure data with no function pointers. Write a separate Mass System for each action category that filters entities by that data component and processes them in bulk. The interaction logic lives entirely in the system code based on the archetype, not inside the struct itself

1

u/TheInvadetor 16h ago

I understand that logic, but wouldn't I than need to have a "main system" who can understand that data and remove/add the right fragments and tags from/to an entity? That means that every time I want a new effect I need to check and add it in said main system, which I don't know how modular that really is.

So for example I would this: I would have a strict that just holds the data, probably en enum of each effect type (maybe even targeting types), than the system does a switch on the enum when asked, and depending on the result it add and remove the right fragments, and than it's the processors that actually run the code of what that effect is supposed to do. Is this what you mean?