Physics and entity-component system (ECS)

Started by
11 comments, last by Norman Barrows 7 years, 1 month ago

Hey guys. I'm trying to implement an ECS such that entities are simple arrays of IDs to components. To do this I need to move the physicality out of it. My question is, what is the structure of the physics components I need to use?

Here's my thought process:

Firstly, render components need access to physical positions, velocities (for motion blur), angles, and scale. Could we put all this in a separate component? Also, there's the fact that accessing information from a random component outside the rendering pipeline will slow things down due to data locality.

Secondly, not all objects need all three, scale, position, and angle. Should these be a separate component or is it not worth it?

Thirdly, physics engines and AABB collisions need access to the position, scale, and angle. Bullet has this inside their own classes. How should I deal with that? Should I update the position, angles, and scale every time I iterate the physics??

Finally, how do I implement containers for joints and other non-rigid-body stuff Should they simply be outside of the main ECS?

Thank you in advance!

Advertisement

Personally I just duplicate data across different components and then sync them as necessary. There's no good reason to try and reduce the engine's data such that there is no duplication. Similarly there's also not a great reason to reduce the code into tiny components. Big components, like really big, is perfectly fine.

Lastly, and this may not be what you were looking for, ECS is more or less a load of garbage (in my opinion). But I just don't like acronyms.

There is no answer to your question. You are trying to come up with a solution with no problem. What do you want to achieve? Simple entities bouncing around, ragdolls, physics puzzles? If you tell us what you want to do we might be able to help. From my experience there is no such thing as one physics component that 'rules' all ECS out there.

Components usually describe game concepts. E.g. a model component. Your model can then have a ragdoll. That would be something we could solve with physics. You can also have cars and you want the doors to be physically attached and break off and the player can pick them up for cover. This is also to some degree a physics problem, but might require a different solution.

The physics bodies usually replicate the entity transform. A simple solution to keep things in sync is to have an OnTransformChanged() event for the entity that updates the body position. In a real implementation you would only mark that body as dirty and only sync the physics bodies when accessing the physics world. E.g. for any kind of query or when stepping the world. After you stepped the world this works backward and you will write the transforms back to the entity.

Finally don't get over excited with the ECS. This is a very simply idea and I am surprised how complicated people think they need to make this. It is also not a very impressive problem to solve. I can guarantee you that if you apply for a job and put an ECS into your resume no one will lift an eye brow. People will not run around and say: "Look at this resume, this guy wrote an ECS". The opposite is actually more likely and no one will look at your resume. What I have seen about ECS on the internet is mostly outright crap. So if this is a learning project I recommend thinking of something else and don't waste your time on this.

What I have seen about ECS on the internet is mostly outright crap.

Quoted for truth. People are obsessed with them these days, and it means that people waste their time on problems like this where they're more worried about how to fit into the system than how to make the game.

Most component-based systems I've seen have a basic 'Transform' component which contains position, orientation, and scale. There might also be an optional 'Physics' component which contains velocity, mass, etc, and which drives the Transform component. If there's an external physics API being used, it will generate updated positions, velocities, etc., which then you'd inject into the relevant components. So the short answer is, copy the intrinsic properties into the physics engine, do the processing there, and copy the values back out again.

Personally I just duplicate data across different components and then sync them as necessary. There's no good reason to try and reduce the engine's data such that there is no duplication. Similarly there's also not a great reason to reduce the code into tiny components. Big components, like really big, is perfectly fine.

Lastly, and this may not be what you were looking for, ECS is more or less a load of garbage (in my opinion). But I just don't like acronyms.

My problem with that was data locality. I'm prioritizing speed (memory is still important, but not as important as speed), so rewriting data all the time and accessing objects randomly will slow things down. Also, that was indeed one of my ideas, decoupling positional data, which will apply to non-collideable objects as well as collideable objects.

That's basically what I wanted to know, that transformations are decoupled from AABB/physics components.

Also Dirk, I'm not designing my engine for a particular game yet. I know optimizations can be done if I did, but I'm trying to get it to work across future titles of mine, and then tweak where required, even if it's a lot.

I also know that as much as possible, making things as decoupled as possible leads to issues, but I just wanted to check if any optimizations could be used.

To both of you, I understand that ECS isn't a magic spell that fixes everything, and that AI, Physics, and Game Logic are only used as containers for a very non-componentalized system. Still, in trying to maximize memory performance, as memory is often a bottleneck in these kind of situations, I need to design things to use as much data localization. I'm not particularly proud of the system because, as you said, it isn't anything out of the ordinary, but it is the system I'm using and is, as such, relevant to the discussion.

Sorry, I don't want to sound offensive, but what you are writing makes no sense at all. You are optimizing for speed without knowing what your games are going to do and where your bottlenecks will be. I can guarantee you that copying some data from and to the low-level systems (e.g. physics or graphics) will not be a bottleneck on any recent machine for the scope of any game you will implement. What I really don't get is why people want to write engines without knowing how games are made. Why not write some simple games and come up with some simple libraries (e.g. model renderer) that help you reach your goals? Learn how games are made, how assets are created and imported, what is actually fun when playing a game. In my opinion there are one million better projects then implementing an ECS.

Just my 2 cents...

Sorry, I don't want to sound offensive, but what you are writing makes no sense at all. You are optimizing for speed without knowing what your games are going to do and where your bottlenecks will be. I can guarantee you that copying some data from and to the low-level systems (e.g. physics or graphics) will not be a bottleneck on any recent machine for the scope of any game you will implement. What I really don't get is why people want to write engines without knowing how games are made. Why not write some simple games and come up with some simple libraries (e.g. model renderer) that help you reach your goals? Learn how games are made, how assets are created and imported, what is actually fun when playing a game. In my opinion there are one million better projects then implementing an ECS.

Just my 2 cents...

You didn't sound...THAT offensive haha. And I didn't mean that copying some data between the systems will be a hit to the performance. I mean it adds up. There's some stuff you don't need a game plan to know there's a better way to do things. I already do have a model renderer that I worked on extensively, and I'm working on some more stuff for the renderer including ssr, etc. I'm working on importing assets like right now (a map file format). I'm planning to work on physics and other stuff soon. But I NEED a structure. Are you like, against ECS? Like it's not a difficult thing to implement (it's kind of hard to get just right though).

But in general, games have similar systems. My end-goal is to develop a flexible system that will allow me to create several games with, and every tiny thing I do contributes to that. It also contributes to the performance, so if I plan properly, I can cut it down. I know I can make optimizations if I create every game from the ground up. But people use Unreal, Source, and Unity, and those aren't game-specific, and games on them typically run really well. I'm not saying I'm at that level, I'm just saying there's nothing wrong with this approach. I'd rather continually build one good engine than many small ones, which would hinder the artists involved, etc. If that's for not you, no problem, but it's not something illogical.

"But I NEED a structure."

The hard truth is good sense of structure can never come from some kind of methodology like ECS. It only comes from experience. This is why Dirk is recommending to learn much more about games and how they are made. ECS does not solve real problems, and making games requires real problems to be solved, not fake ones.

"My end-goal is to develop a flexible system that will allow me to create several games with"

That's a fine goal, but ECS will not help you -- experience will.

"But people use Unreal, Source, and Unity, and those aren't game-specific, and games on them typically run really well"

Eehhh typically games on those engines have a lot of trouble standing out from other games made with the same engine. It still takes a lot of work to use these tools and make a good product. And majority of Unity games never make any money... Also these companies have teams of tons of people to make features. People do not buy Unity or Unreal to use an ECS. They buy them for features, like art asset pipeline, or technical support, or full physics engine integration, or multiplayer features. From personal experience I have heard people express they would buy Unreal to make a game simply because they have knowledge in the Unreal domain, and could get the game finished quickly -- this makes business pitches easier to sell. Again, it's coming down to experience here, not ECS.

Yeah as has been said, "I want to design for performance" and "I want to design by numbers (using patterns as a playbook)" are conflicting goals IMHO.

Design patterns are useful to create a shared vocabulary between engineers and to create a canonical implementation of that vocabulary. FWIW, ECS isn't even a recognised pattern throughout the sofware industry, and it's certainly not somethinf that you should commit to walling youself into, before asking how to fit all your other goals into those walls... That's backwards.

As for the question though - it's common for the visual transform and the physics transform of an object to be different. e.g. if using a fixed time step, which interpolates graphics state from game state.

I would recommend drawing out your required data flow for a frame as a directed acyclic graph first, and then design your framework to fit that data flow, not the other way around.

This topic is closed to new replies.

Advertisement