Jump to content
  • Advertisement
Sign in to follow this  
Aqua Costa

Resizing game objects and components arrays

This topic is 2135 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

My engine uses a component based architecture where I have an array of GameObjects and a number of other arrays each storing a type of component.

 

Something like this:

struct GameObject
{
    //indices to each of the game object components (-1 if component isnt used)
    int components[NUM_COMPONENTS];
};
 
GameObject*            gameObjects;
PositionComponent* positions;
ModelComponent*    models;
 

 

In order to implement Level Streaming I load the level file (actually it's a world section for an open world game) in a different thread (core) and I need to resize each (or some, depending on the game objects of the level being loaded) of the arrays above to be able to store the new level objects.

 

Since the loading is done in a different thread I need some kind of synchronization with the main thread. But simply putting the main thread on hold while the new larger arrays are allocated and the memory from the old ones is copied causes the game to freeze for around second.

 

Any ideas on how to make it more efficient like distributing the time across a few frames or something?

 

Thanks!

Share this post


Link to post
Share on other sites
Advertisement

Since the loading is done in a different thread I need some kind of synchronization with the main thread. But simply putting the main thread on hold while the new larger arrays are allocated and the memory from the old ones is copied causes the game to freeze for around second.
 
Any ideas on how to make it more efficient like distributing the time across a few frames or something?
 
Thanks!

For streaming the only thing you can really do if an object isn't loaded is either refuse to draw it until it has finished loading in a secondary thread, or draw it with some kind of default model. It depends on the game of course but often if you're doing something like entering a new area and the nearby chunk of map hasn't loaded yet you may want to only draw the background and either some kind of manipulation of fog or to actually stop the game for a loading screen if it is of vital importance.

MMO's use the same kind of streaming but across the network, which is why objects tend to "pop up" after moving for awhile and the game may freeze or fade if you do something like teleport between areas because the client halts itself until it has at least the immediate surrounding data loaded, it's rather game by game in how you handle it. But the use of a secondary thread tends to be pretty much required. Using only one thread would simply cause stuttering each time you loaded an object even if you spaced them apart somehow.

Share this post


Link to post
Share on other sites

The freeze isn't caused by reaching a zone of the map whose data hasn't finished loading yet.

 

It happens when player is still in zone "A" and loading of zone "B" begins. Since zone "A" only contains say 1000 objects the GameObjects array can hold 1000 objects, but in order to store the zone "B" objects the GameObjects array must resize which requires memory allocation and copying of the old data to the new array which causes the freeze since the game cant update while the data is being copied.

Edited by TiagoCosta

Share this post


Link to post
Share on other sites


But simply putting the main thread on hold while the new larger arrays are allocated and the memory from the old ones is copied causes the game to freeze for around second.
 
Any ideas on how to make it more efficient like distributing the time across a few frames or something?

 

 

your streaming is not sufficiently preemptive. its should always complete background streaming before an asset is needed. if loading a world section all at once slows down the game too much, you'll need to start loading sooner, and spread it out over a longer period of time (multiple frames).

Share this post


Link to post
Share on other sites

The freeze isn't caused by reaching a zone of the map whose data hasn't finished loading yet.

 

It happens when player is still in zone "A" and loading of zone "B" begins. Since zone "A" only contains say 1000 objects the GameObjects array can hold 1000 objects, but in order to store the zone "B" objects the GameObjects array must resize which requires memory allocation and copying of the old data to the new array which causes the freeze since the game cant update while the data is being copied.

 

 

fundamental design flaw there.

 

actually perhaps more than one.

 

may not be that hard to fix though.

Share this post


Link to post
Share on other sites

But simply putting the main thread on hold while the new larger arrays are allocated and the memory from the old ones is copied causes the game to freeze for around second.

 

Streaming assets shouldn't have to be synchronized as long as each loader can work in its own segment of heap memory. The only synchronization that's needed is when pointers to the new data are added to the global pool of GameObjects*. Resizing even a large array of pointers (or use a std::queue) shouldn't have to cause any noticeable stalls.

Edited by eppo

Share this post


Link to post
Share on other sites


Use a two dimensional array to store your objects. Essentially it looks like this:
Object_array [CURRENT_LEVEL] = all objects in current area
Object_array[NEXT_LEVEL] = all objects in next area

You can then do a swap to change CURRENT and NEXT when needed.

Share this post


Link to post
Share on other sites

If reallocating and copying 2000 objects (pointers?) causes a one second freeze something else must be off.

Share this post


Link to post
Share on other sites

Why not consider using a grid structure where game objects are stored based on their two dimensional position in the map?  

 

Online MMOs like WoW break their entire map system into a grid structure.  At a high level, the map is broken into lets say a 64x64 grid of large tiles that are further subdivided into smaller cells.  This type of system lends itself well to querying for nearby objects, players, and entities for deciding who should receive chat bubbles as well as what should be streamed from server to client and what should be drawn on the screen beyond the terrain/skybox/weather.

 

In this case, you shouldn't have to worry about copying any information because what the player sees should be the contents of their current 2D cell position and perhaps the contents of the nearby 8 cells that surround their current cell.  This way when the camera gets too far from a particular cell, you know precisely what game objects to remove and unaffected cells that should remain in view are untouched.  It also allows you to forecast based on trajectory and speed which cells should start their preloading steps before the player arrives too closely to avoid pops of new entities, models, and characters while moving through the game world -- thus making a more fluid experience.

Edited by crancran

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!