Communication between objects and systems in Game engines.

Started by
11 comments, last by Dirk Gregorius 8 years, 11 months ago

Heya! I've been doing some work on a little engine for myself, and I've stumbled upon a little thing that I'm not entirely sure how I should approach. I'm not sure how I should handle instances where an object needs to communicate with one of the modules of the engine. A specific example of this would be for a raycast. If I have a player who needs to care about whether or not their on the ground for example, when I update the player I'm going to want them to shoot a raycast down to see if there is in fact something beneath them. This would mean that the object needs to know about the physics systems existence, a dependency that I'd rather avoid! Searching through some older topics I've seen a suggestion that the objects store a pointer to the scene, and then the scene contain things like the collision system etc, an idea that scares me for similar reasons. Am I just being too paranoid about this? Functionally it would work to have these dependencies, should their existence bother me or would anyone be able to explain to me some better designs on avoiding these kinds of dependencies?

Advertisement

you could just create something that manages that task separately, like a player collision manager.

that gets access to the player and the scene and takes care of all the logic it needs inside of its own update function.

This way the player stays cleaner as does the engine code.

Plus it gets easier to maintain, say if you wanted to change from a raycast to an ellipsoid collision detection.

It doesn't work for every situation but it keeps things tidy and easy to tweak.
If you only need something really simple you could just do a single raycast and player update in the main update function, should only be a few lines of code.. but then that approach can get messy quickly as things get more complex.

All that said there are many many ways to skin a cat :)

I think this is a good question! E.g. it is not immediately clear who would own the render device or physics world in an ECS. Say you have a destruction and ragdoll system. Who would own the physics world? Even worse, the movement and potentially other systems (e.g. fighting) also want to use the physics world for some sort of raycast/sweep or volume query. I can imagine this is similar for the scene-, particle- and UI system. They would need to share the render device.

I think having dependencies between systems is the worst solution. It would totally defeat the reason one chooses an ECS architecture in the first place. Personally I like to think of these special classes (e.g. render device, physics world, input device, ...) as special services that can be shared between systems that need them and are owned by the application or current scene.

Really depends on the architecture of your system. You should have a generic system that handles all movable entities (since your npc's will also need to walk on the ground), and that system knows about the entity's location and velocity and will know about the object in the world and can work the physics interactions of those objects.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

If you haven't gotten too far in your engine development, you really should have a generic entity that respects the physics system. This includes all movable and collidable objects in your game. If your player can fall and stand on the ground, bump into other objects or walls, then I presume there are other objects too that share this same functionality. These objects should inherit from a common parent. This is where you put your collision code.

http://www.gamedev.net/topic/651944-very-general-question-about-structuring-of-game-classes/#entry5122283

http://www.gamedev.net/topic/650640-is-using-static-variables-for-input-engine-evil/#entry5113267

Characters are a slave to the physics engine, and both are slaves of the scene manager, which is a slave of the current game state, which defines the rules of gameplay.

There is no reason to have cross-breeding or illogical dependencies between these systems.

Character has a member—a structure containing the data needed for physics (inverse mass, velocity, position, etc.)

Scene manager passes that information to the physics engine, along with information about the rest of the stage, so that the physics engine can perform collision detection and resolving and write outputs (new positions and velocities, perhaps you can add a boolean to say whether it is on the ground or not, etc.) for each object.

Done and done.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

A specific example of this would be for a raycast. If I have a player who needs to care about whether or not their on the ground for example, when I update the player I'm going to want them to shoot a raycast down to see if there is in fact something beneath them. This would mean that the object needs to know about the physics systems existence, a dependency that I'd rather avoid!

But, for this specific example, you cannot.

It is intrinsic in your problem you want to shoot a ray which somehow "hits" your collide-able world. It already knows something physics exists.

Ok, ok, let's stop the nitpicking.

Your solution is: interfaces. In the sense of base classes with virtual function calls.

WAIT! Isn't virtual call super expensive?

It is, but not to the point you want to sacrifice your mental health. In my experience the cost of raycasts and sweeps is way, way higher and that specific inefficiency gets easily lost in the great scale of things.

But perhaps the most important part is

write games, not engines

don't make your decision based on example. Don't let your target be out of your vision. What your final product is, that's what it should drive your decisions and your efforts. Use real world data.

So, if you have to do a raycast (per frame I assume) a solution might be viable. One per entity... perhaps you might start looking in a different direction. Several per entity, per frame... you'll need to get smart.

But again, your question has a general solution: with no hard data to talk about, just use virtual base classes.

Am I just being too paranoid about this?

Most likely. Explore your problem first and then attack it with a better understanding and data. You'll get ahead faster and hopefully the end result will be better as well.

Last note: in theory since C++11 you can do function objects (without going crazy with the syntax). In practice, std::function / lambdas are even more powerful than function overriding however I often find more convenient to go with base class interfaces as there are often relations between the various calls.

Previously "Krohm"

If you only ever have one physics system implementation, I don't really see a much of a benefit of having the game object access it through an interface. It could be useful for unit testing though (e.g. provide a mock physics system to test your game object).

If you want to remove the dependency, have higher level code that knows about both the game objects and the physics system, and let it be the intermediary (something like L. Spiro suggested).

I am liking the idea of the higher level code with knowledge of both ideas, and then keeping the actual character in the dark about everything, seems to be what most of you are suggesting too. So if I'm getting this right, the player itself will basically just be a block of data, it has some render information, its transform, and maybe some collider information, but it doesn't really do anything. Then I have some higher level systems like one for keeping objects grounded that has information about the physics world. the gamestate passes everything that needs to be effected by this system to it, all the players/npc's etc. Another example could be like... a player controller that tells the player to move based on input or something. Nothing is actually done by the character, only by things who's purpose is telling the player to do things.


write games, not engines

Yeah haha, this is something I'm trying to push on myself, it's so easy to get lost in the idea of engine construction and completely forget about what you wanted to use the engine to make. I'm just making small scale 2D stuff too, so I really don't need to go overboard on engine construction.


If you only ever have one physics system implementation, I don't really see a much of a benefit of having the game object access it through an interface. It could be useful for unit testing though (e.g. provide a mock physics system to test your game object).
The benefit lies in avoiding implementation-specific structures, all the "private helper funcs" etc. Unfortunately, C++ header files are not properly separated. I will admit my project was quite involved and for a short period of time it even had multiple physics implementations available.

Maybe you are smart enough to write everything in a single file and be done with it; I have the habit of keeping my files small.

Previously "Krohm"

This topic is closed to new replies.

Advertisement