16
\$\begingroup\$

For example sake:

  • Let's say there are 10 rooms in the world.
  • And let's say the world is inhabited by 10 entities.
  • And each entity has it's own "daily routine" where it performs certain actions in the room and also might navigate between the rooms as well.

Given that the player can only be in one room at a time, what is a good way to keep track of the actions the other entities are performing in other rooms offscreen?

  1. The most straightforward option is to check on each of the 10 entities on every frame, check their position/state and determine whether or not the entity should be in the room where player is located in at any given time. ( This however feels really resource heavy especially as the room/entity amount is increased. )
  2. Another option is to keep track of the time that has passed since the start of the game, then each of the entities checks whether its pattern intersects with the room the player is on, and if it does it checks against the time whether or not the entity is supposed to be in the same room at this particular time, entities whose patterns do not intersect with the current room the player is located in do nothing until the player enters a room which their pattern intersects and only at that point calculate whether or not they should render. ( But if they interact with the room, then they will have to always check the state of the rooms which intersect their route in order to determine their location at that point in time, which is not that great. )

  3. The third option I came to would be to first of all only look at the routes which intersect the player location (as described previously), secondly upon entering a room, check if the player is in that room, if not then to only check the state of the room and how long will it take to proceed to the next room. For example a janitor NPC enters the room, checks the state of the room, sees that there is a spillage made by player, calculates how much time it will take to clean that up and how long the pathing will take etc. And until the mentioned time is due to enter the next room we only check if the player is in the room. The exact location of the NPC for rendering purposes would only be calculated when the player enters the room.

After brainstorming a while I came to the third option, but I was wondering if perhaps there is a known or better way to handle things like these?

\$\endgroup\$
  • 1
    \$\begingroup\$ This question reminds me of a dev-blog I read for a game called Project Zomboid. \$\endgroup\$ – Sumurai8 Sep 7 '15 at 16:41
12
\$\begingroup\$

A very simple approach is to use "AI Level of Detail." Roughly, this means that you update AI more frequently the closer it is to the player/camera. You can also reduce the complexity of AI calculations that are farther out, esp. for path-finding. After all, if the player can't see the character well or at all, there's no point putting in a ton of effort into simulating the character at the highest accuracy.

In your example, the room the player is in might get the highest accuracy (AI updates every frame, full resolution). The rooms adjacent might get the next highest accuracy (updates every 10 ticks, remove path smoothing and animations). All the other rooms can get the lowest accuracy (updates every second, low-resolution path-finding, eliminate non-essential NPC-to-NPC interactions).

Bigger and more complex games can (and have) used similar approaches. They might simplify combat calculations, teleport characters rather than path-finding them when they need to move, etc.

If your game is big enough that you can't keep the whole thing in memory at all times, a good solution then is to store the last update time in the room's saved data, and replay its simulation offscreen (at its lowest resolution) when it's loaded back up.

If you expect AI to move into "live" areas from unloaded "asleep" areas on a schedule, you'll either want to create super-low-fidelity data for those regions to keep in memory at all times (e.g., just the coarsest navmesh detail level and key object/character locations) or you'll want to periodically cycle those areas in (e.g., keep X "asleep" areas in memory and simulation at low fidelity with infrequent updates and then round-robin those through all the "asleep" areas that have key active NPCs in them, unloading and loading areas as you do so).

\$\endgroup\$
1
\$\begingroup\$

I'd store the entities which are currently in a room in that room instance, the room object would also keep track of when which entities need to be updated (eg. travel to another room or change something in that room, etc.). And I'd also update one (or more) room each second (maybe in another thread).

When you update a room, the NPC positions should be updated and all the actions they have performed which interact with the room since the last update should be handled as well, lastly the time of the next needed update should be checked / updated.

If an entity travelles from one room to another, it's instance should be stored in the other room and the entity's next update should be updated as well.

This way you only have to keep updating the current room and the rooms which have a scheduled update at that moment in time, updating the other rooms is just optional (but recommended if you have an AI which updates whenever the player moves or does something).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.