Sign in to follow this  
KanonBaum

Lock specific objects only in game update while everything else stops

Recommended Posts

KanonBaum    277
Say I come across an event in a game and I want everything to "freeze" and not move or update. (Drawing routines can or cannot be the exception), however, only a few select objects can continue to update. A scenario that I can imagine this to play out would be in a level-up situation. Everything pauses, but the main player while it undergoes a cool animation and stats increase before resuming everything else in the game.
This, I would think, would be a little different from "just freezing enemies in place". In that design, enemies are still updating, but with a timer or some kind of limiter.

How would the update-pipeline look to allow for such things? Just a quick thought of this had me thinking of how it could look in C++ possibly using threads? (Or would that be overkill?):

[source]
threads::lock_object(pPlayer);
threads::unlock_all_when(&ActorClass::FinishAnimation, pPlayer);
pPlayer->LevelUp();
[/source]

It's not a good design. It's just something I scribbled down when I had the time. Wanted to know if you all had any ideas to accomplish this task?

Share this post


Link to post
Share on other sites
Hodgman    51224
Using threads for this is definitely wrong.


Some simpler ideas:
* Send one delta-time to some objects, and another delta-time to others.
* Simply don't call update on objects you don't want to be updated (e.g. keep two lists of objects, ones that are always updated, and ones that are only updated during 'gameplay').

Share this post


Link to post
Share on other sites
KanonBaum    277
However simple as they may be, how would one set up the design to function correctly in most scenarios?

Simply not calling an update is fine, but how would you go about making sure the ones that are supposed to update in this state actually do? I mean, yeah, you'd store the objects in some manner but having a list of objects called "not_to_update_list" and "update_list" seems to under-step it.

Share this post


Link to post
Share on other sites
ApochPiQ    23003
I'd just have a boolean flag in the update dispatcher; if the flag is cleared, do a normal update, otherwise look at a "short list" and only update objects in that list. When you enter limited-update mode, you copy off the last known state of every object that shouldn't be updated and render/etc. based on that state; when re-entering normal updates, you merge the updated objects' states back into the main simulation state and off you go.

Share this post


Link to post
Share on other sites
Soaps79    116
If your game objects have access to your current game state, you could do it right in their Update function. Make a boolean accessable to the objects, and have them check against it before updating (animating, moving, etc) The first line of Update on the objects you want to lock could be (psuedocoded):
[source cpp]void Update()
if ( gameState.isCharacterLeveling() ) // returns true if leveling animation is happening
return;[/source]
This way, they will still draw but not move or update their logic. I did something similar in a recent project for a pause screen.
Another approach would be in the engine itself. The one I was using, the base Entity class had 3 flags:
[source cpp]bool m_active, m_visible, m_animating;[/source]
When the engine went through its loop, for each entity it would check (abbreviated version):
[source cpp]if (entity->isActive()) entity->Update();
if (entity->isAnimating()) entity->Animate();
if (entity->isVisible()) entity->Draw();[/source]
Using this, for a situation similar to yours (a major power animating), I was able to have the enemies still animate (after being set to idle anims) and draw but not think or move just by turning m_active to false when the game entered that state.

Share this post


Link to post
Share on other sites
ApochPiQ    23003
[quote name='Soaps79' timestamp='1311355418' post='4839030']
If your game objects have access to your current game state, you could do it right in their Update function. Make a boolean accessable to the objects, and have them check against it before updating (animating, moving, etc) The first line of Update on the objects you want to lock could be (psuedocoded):
[source cpp]void Update()
if ( gameState.isCharacterLeveling() ) // returns true if leveling animation is happening
return;[/source]
This way, they will still draw but not move or update their logic. I did something similar in a recent project for a pause screen.
Another approach would be in the engine itself. The one I was using, the base Entity class had 3 flags:
[source cpp]bool m_active, m_visible, m_animating;[/source]
When the engine went through its loop, for each entity it would check (abbreviated version):
[source cpp]if (entity->isActive()) entity->Update();
if (entity->isAnimating()) entity->Animate();
if (entity->isVisible()) entity->Draw();[/source]
Using this, for a situation similar to yours (a major power animating), I was able to have the enemies still animate (after being set to idle anims) and draw but not think or move just by turning m_active to false when the game entered that state.
[/quote]

This strikes me as painfully brittle.

What if I decide, six weeks down the road, that I want not one but [i]five[/i] different situations that might freeze the game for a special animation? Now I have a crapload of dependent code to update, whereas with my suggestion it's really just a matter of writing code to build the shortlist. Much less fragile and much easier to reason about and extend.


Share this post


Link to post
Share on other sites
Soaps79    116
I understand that my approach could be brittle, I haven't worked on any huge projects.

[quote name='ApochPiQ' timestamp='1311217743' post='4838269']
I'd just have a boolean flag in the update dispatcher; if the flag is cleared, do a normal update, otherwise look at a "short list" and only update objects in that list. When you enter limited-update mode, you copy off the last known state of every object that shouldn't be updated and render/etc. based on that state; when re-entering normal updates, you merge the updated objects' states back into the main simulation state and off you go.
[/quote]
I guess what I don't understand about this approach is how you fill the "short list". Would you have the entities that want to continue updating make a call to say "Add me to the short list," before switching to updating just that one? I'm just thinking that you won't know at the start of the program who would be in there, because for instance, maybe the player has a party consisting of 4 characters that would need to be in there on their own when they level.

Share this post


Link to post
Share on other sites
ApochPiQ    23003
I left that open-ended on purpose; the specifics of how to do it really depend a lot on the rest of the engine architecture.

For instance, it might make sense to just hard-code a set of rules that traverses the game data and picks out the appropriate objects. Or maybe you have an entity model and you can use a system to traverse the entity structure automatically. Whatever; it's hard to generalize here because there are so many different ways to represent game data out there.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this