I’m wondering what the best practices are for keeping your game’s logic modular, so you only have to write code once to use things all over your game.
I keep hearing about custom objects / behaviours, but I cannot find a way to make custom behaviours interact with objects from outside their scope. For example, I can’t have a behaviour on my enemy that checks for a collision with the player because there is no way I can reference the player in the enemies behaviours (as far as I can tell). Using external events seems to be an okay way of doing what I’m looking for, but having to add my external event to every scene manually seems a little clunky.
no… the simpler way is to use external events. (my opinions here)
even without that… its quite easy to just make an event group that manage a whole aspect of the game. for example…
lets say you want to manage all enemy AI using a module. Simply make a group of event that input the object variables of enemies, do simple math with them (ex: enemy hp% left multiplied by distance to player + random number between 0-9 multiplied by innate agressivity = current agressivity). you use for each instance, and you put an object group that encapsulate all enemies. (all of this doesn’t need to be in an external event btw). also… going modular allows you to put some delay to certain CPU heavy modules (pathfinder, dynamic light, etc…)
honestly… custom behaviours are overrated. the fact that they cannot interact with other objects is terrible. This limitation is good for making extensions that can be use by many people, but its trash for a single project (IMO)
object groups are a direct upgrades.
modular coding is really just a way of thinking rather than features in a game engine. If your game engine really cannot do any modular stuff. ditch the engine.
For example, I can’t have a behaviour on my enemy that checks for a collision with the player because there is no way I can reference the player in the enemies behaviours (as far as I can tell)
A collision condition is typically something you want to keep in the main events. Usually a good rule is:
interactions between objects in the main events
logic that applies to 1 object (or other objects very closely related to this one, for instance particles) in an extension/behavior.
The goal is to sort things not hide them. If you want to tidy your room and toss all the closes straight into your closet. Sure, your room looks tidy, but good luck finding your 1 blue sock pair.
This template is organized into extensions and behaviors:
Depends on what you mean by modular and if you mean engine independent modularity.
If you are using gdrvy no code events 100% for everything one could argue nothing is modular since you are locked into gdevelop. Yes you could reuse your modules in other gdevelop projects but only gdevelop projects.
My goal is always to completely separate logic from rendering. So not only could my modules be reused in other gdevelop engines but in any engines using my logic.
But then that means more code and less gdevelop no code. So more JavaScript and json.
It does allow for true modularity regardless of engine and regardless of rendering. It doesn’t care if I decide to go 2d or 3d as an example.
Meaning you could switch to say use Babylon.js or three.js (which gdevelop sits on top of) or say playcanvas if you want full webgpu support for a bigger project.