- Edited
Hello! I recently decided to start making a sort of RPG battle engine. The core ideas are that it's real-time combat inspired by MMOs, where you cast actions with costs and cooldowns from a hotbar, except without movement and with multiple controlled characters at once. I'm also aiming to make the battle engine specifically isolated from the other parts of the code, following something that should loosely resemble an MVC pattern?
So far, I've been trying to figure out how I'm going to structure it and I may need advice on how. Attached is my first draft.
The 'Battle' node is the engine. There's a 'Party' node for each side of the battle (should just be Enemy and Player, for now) and a 'Fighter' node for every character fighting.
- 'Battle' handles most of the processing while 'Party' and 'Fighter' mainly store data; when the player tries to use an action, 'Battle' receives a signal with the action, caster and target, checks the caster's Fighter node to see if they can cast it (whether or not the action is available to them, if they have mana, if it's on cooldown), checks the target's Fighter node for anything that would prevent it (untargetable?) and if not, processes the effect of the action. When damage is dealt to a fighter or if they die, a method is called on Fighter that processes damage and calls a signal to check for effects (and display FlyText).
- All actions are stored within the action_list resource while action specifically available to a Fighter are stored in their build resource, inside character_sheet.
- The Party node contains anything that relates to an entire party, whereas the Field node contains anything that relates to every fighter on the field (field effects).
The View node groups visual elements together, and CharacterVisuals specifically groups FighterSprite nodes. Animations are triggered by the signals set off by the Battle engine (though I'm not planning to make any yet).
The Controls (probably a bad name) node groups UI and control-related nodes. It's hazy, but one way could be to have several Buttons placed relative to Hotbar, spawned from the hotbar_setup resource, that trigger the aforementioned signals when pressed. Then FlyText nodes display when damage is dealt or healed, and ParameterBar nodes are directly bound to each Fighter's HP and MP and displayed relative to their sprite's position.
That's the gist of it, but I'm a bit uncertain. First off, I'm worried that I'm using too many nodes. Some of these nodes seem like they may not end up having many methods or even properties, and I'm not sure if that's okay? At what point is it unnecessary to make something a node? Are the nodes I'm using to keep different components grouped, like View and Controls, okay, or should I just leave their children at the root? And should something like the Fighter node be a plain Object-derived class instead ?
Also, I'm wondering about how I should represent actions. What I know is that they should have a name, a description, a cost, a cooldown type (global vs individual), a cooldown duration, a targeting type
(single or multi), maybe an attack type, and most importantly, effects. To give an action complex effects, I need it to carry a method; so does that mean every action should be a class, or an instance of one? One thing I am thinking is that if an action can be an Object, then it would not be difficult to implement actions with cast times, where the Object lives for as long as the casting is going on and calls its effect method if it's completed then is freed, or is just freed if it's cancelled. But that doesn't seem super clean and seems bad memory-wise...?
Could anyone give me some opinions on how this could be improved and how the gaps could be filled here?