Entities and Components

I really like this design pattern, and am pleased that Apple is advancing the idea.

But there are a couple of things I am not crazy about in this particular implementation.


It seems wedded to the idea of a variable deltaT.


Variable delta Ts are usually a bad idea. It results in non-deterministic gameplay outcomes. Where identical circumstances, identical user inputs and so on, produce different gamplay outcomes because of frame rate. In my experience this can be a) bad or b) very bad.


I am guessing the intention is to solve the problem of variable frame rates.

A better solution is to decouple simulation from rendering. I would suggest having a fixed gameplay tick, (using an integer tick time) and decouple rendering from gameplay by using interpolation.

This is roboust. Graphics run as fast as the hardware can allow, while gameplay is deterministic. (there are other benefits too).


A good way to do this is have all gameplay logic work using an integer: TickTime

While the renderer uses a float: RenderTime.


The current entity and component solution, as written, also makes it harder to write client/server network code.

In a modern client/server implementation it becomes useful to roll back time (and state) and retrospectively change state and resimulate.

So a network-friendly entity/component would include a function to record states to a ticktime-based recorder and then re-update from a recent tick value.


I'd suggest allowing:


setTickRate(ticksPerSecond:Int)

updateForTickTime(tickTime:Int)


Just a suggestion.

Replies

You mention advancing. What is the advancement?


I believe that the entity/component model is solving the same problem that default protocol implementations are, and each is currently helpful only because neither addresses the root problem: that one must be able to see itself as multiple things at the same time. The "play" that you perform, as a guitarist, is not the same "play" that you perform, as a person pretending to be a cat, for example. Segmenting oneself into components that comprise the whole, and only allowing one implementation of a method, do no allow addressing oneself as a entity who does the same thing in different ways.

Not sure this is related to what I am saying.

The component model is a sound alternative to a deep inheritance hierarchy.

But the specific implementation in GameplayKit prevents the sort of usage that some would regard as optimal.

Nobody requires you to pass in a variable delta time to updateWithDeltaTime:


The component system, statemachines and other GK or SK functions that you call manually and take a delta time parameter work perfectly fine when you:


a) ignore the parameter (pass any value, just don't use delta in your calculations)

b) pass a fixed delta time (ie 0.033333333)


Et voilà, fixed timestep. 😉


However, there's the exception of built-in functionality. I think currently this relates only to the GKAgent classes. I assume if you pass them a delta time of 0 they will just do nothing, but they should still work fine with a fixed delta-time.

While that's a workaround. I'd argue that an API should embody best practice. Not make it more difficult.

Variable delta t is really not that. It's a quite a dangerous methodology for games, and can give rise to impossible-to-recreate bugs, and different gameplay outcomes on different hardware.


And with network games, out of order simulation is essential.


That means for any given update, it's not possible to assume the component's current state is valid.

A update for tick 100 needs to go off and recall the prior state for tick 99. So the component needs to know the true time to access the correct state info.


My suggestion. Replace UpdateWithDeltaTime to UpdateForTime(time:Float) or UpdateForTickTime(time:Int)

With this call, the programmer could still implement a variable delta-t simply by caching the prior t value.

I don't expect much to change here. SpriteKit physics is nondeterministic and I'm convinced it's because they use a variable timestep. I filed a detailed radar about this long ago and nothing has changed. When I brought this up on the previous incarnation of these forums I was stunned that I was bitterly criticized for stating that a physics simulation should be deterministic.

Agree. I've given the topic of "delta time" and why we should try to avoid it a thorough treatment two years ago.


But on the other hand, it's been used by SpriteKit already, so it makes sense to continue to support that notion. You're still free to ignore it of course, except for the fact that SpriteKit itself is internally delta-time driven. For instance physics updates never produce the same result over the course of several frames - that's terrible for certain games, and completely and utterly makes it impossible to do game recordings with physics (unless you use the new video-recording capabilities).

Sometimes fixed is good; sometimes it's not. Always assume that it's not fixed, multiply appropriately, and when it's fixed, you're covered.


http://forum.unity3d.com/threads/game-slower-faster-on-different-computers.69124/#post-2133045

There are physics apps and games that can never come about until we have a deterministic physics engine framework. Perfect repeatabilithy is reqjuired for those apps. Just because other apps don't require such a feature is a flimzy excuse for you being criticised.