GKEntity/Component update cycle best practices
Asked Answered
J

1

8

The subject

My question is about the division of the update cycle when combining Apple's frameworks in order to respect the typical patterns and good practices on the subject, since most of the documentation and example code has not been adapted to Swift yet (or at least I can't find it anywhere).

There are so many ways to manage the update cycles in GameplayKit that I'm not too sure what is a good way of combining everything.

The elements

First and foremost: every class (GKComponent and GKEntity (sub)classes) in the Entity/Component has an update() method that you can override to perform per-frame updates. That has to come from the update cycle of the current GKScene/SKScene.

Then you have the GKComponentSystem that you can use to fire up the update() methods of every component from a given type that has been added to it. I see the point, it's very handy.

But I also want to use the state machine system and it also has an update cycle of it's own... Combining all that got me confused.

My situation

In the case where I have a subclass of GKEntity with an instance of a GKStateMachine created on initialization. The state machine has a few states (for the moment: 'Spawn', 'Normal', 'Stunned' and 'Death'.

State cycle

Right now, I'm creating a big "cookie cutter" with my GKEntity subclasses and create all the components it's gonna use during the initialization. But it's becoming very impractical. For instance, I have a MovementComponent, which is a subclass of GKAgent2D. I created a singleton that manages entity creation, so after the instance is created, if loops through all the entity's components and add them to the related GKComponentSystems. The singleton has an update() method of it's own that updates passes the call to the GKComponentSystems. Some of the components I use do not need per-frame update, so no GKComponentSystem has been created for them and I update them manually as required.

If I come back to my entity, since I create everything at once and use GKComponentSystems to update the components, my component's update method is loaded with guard and if-let statements because I need to access the entity's state machine, check if it's a state where the entity can move (Normal state) and do its thing or escape the function. This is not efficient in my view: the move component doesn't need to get updated when it's spawning, stunned, or dying.

On top of that it makes my use of GKStateMachine completely overkill since my update methods are empty: the components get updated by the GKComponentSystem anyway.

My ideas

  1. Drop the GKComponentSystems completely and simply loop through all my entities (maybe sort them in different collections at some point if need be) and call their update() methods. Dispatch the updates to the state machine which in turn will update the components involved in that state.

  2. Keep the GKComponentSystems and use the state machine to juggle with the components, for example by adding and removing the MovementComponent from the component systems when entering and exiting the Normal state.

Option 1 is straightforward but could cause problems on the long run when my structure gets more complex becasue some components could need to be updated before others. Having each entity update its own components would scatter the update process.

Option 2 can get confusing too in a way, but my biggest concern is about the creation/removal of the components. Do I only take them out of the GKComponentSystems or do I take them out of the entity completely? What is the most efficient way of doing it?

The actual question

which one of my options would be the best? is there any better way of doing it.

Jalisajalisco answered 15/1, 2017 at 19:23 Comment(4)
It's a SO.travesty that this gets closed by 5 people that have no demonstrated interest in SpriteKit and GameplayKit. This question is inherent to ANY consideration of using SpriteKit, even without GameplayKit. Combined, it's the FIRST, and subsequent design/architecture question that's running throughout use. And there are people like MarkBrownsword and a few others that have the experience and nuanced understanding to not only provide objective overviews, but also specific, accurate and targeted recommendations. That's not opinion. They are EXPERTS. Nobody else could answer this question.Encephalic
Therefore, and with direct annoyance at these people voting to close this, justify yourselves. You're not experts until otherwise proven. Can you demonstrate a deep and profound understanding of ECS, game loops and state machines? Where's your "runs on the board" with SpriteKit and GameplayKit? Just because you five do not understand this question's pertinence and specificity doesn't mean others don't. I don't have the insights and wisdom to answer this question, but do at least understand its inherent purposefulness and what's required to answer it... an expert. Muting your closure reasoning.Encephalic
@Encephalic : thanks a lot for that. I appreciate.Jalisajalisco
I'm having the same type of conundrum right now, and I've been experimenting with using protocols, structs and extensions, in addition to the GKEntity/GKComponent classes... i'm unsure it will work, but I'm looking, like you, for best practices here.Aronarondel
C
3

If you are using GKComponentSystem to perform updates, then I would go with just that. I think a component should update only once per frame.

It's not clear from your question what you need to do with StateMachines, but there is no reason to not have them involved either directly in your GKEntity or contained within a GKComponent like the DemoBots IntelligenceComponent.

Caster answered 15/1, 2017 at 20:48 Comment(4)
See my rant above, below the question. Annoying that such a wonderfully pertinent question to the process of choosing and using GameplayKit gets closed by those with no interest in this. A clear foible in the SO "design".Encephalic
@Encephalic Thanks. Glad I'm not the only one thinking that!Caster
@MarkBrownsword : I edited the question if you don't mind having a look at it again. I'll dig in DemoBots and try to get a better picture than just putting the pieces of the puzzle laid by Apple's reference together.Jalisajalisco
@MarkBrownsword in a sign of... the coming of Half Life 3... maybe... this question has been re-opened!Encephalic

© 2022 - 2024 — McMap. All rights reserved.