0
\$\begingroup\$

The question I have may generate different opinions from different developers, but I'd still like to have an answer on this.

Its all about the updating and rendering steps of the game loop, and their use under multi and single threaded environments.

Currently, there is one thread running, which takes care of sequentially executing events , logic and rendering. Sometimes, the logic part may wish to change the game state to something else, and in between do some loading of files.

The result is that the game hangs completely while loading, and then proceeds to normal rendering of the new state. To go around this, i could make another thread, do the loading there while the main thread renders a smooth loading animation, and then proceed normally.

The real question is about if i don't create another thread. I could refresh the screen from the logic thread, and provide some basic loading screen, which could be not so smoothly updated while the files load.

In fact, this approach is not loved by a lot of developers, as it scrambles render code in the logic step, which may cause problems of different sorts..

Hope its clear!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ What exactly are you asking? \$\endgroup\$
    – Darcara
    Commented Aug 1, 2012 at 18:13
  • \$\begingroup\$ I was hoping you could get that from the text, anyway, i want to know if it is ok to refresh the screen from the logic step, which puts rendering code where it shouldnt be. \$\endgroup\$
    – Grimshaw
    Commented Aug 1, 2012 at 18:54

2 Answers 2

1
\$\begingroup\$

There is nothing directly wrong with keeping rendering in your logic thread, especially for simpler games that aren't in need of extreme performance. Indeed, even if you keep rendering, if logic is blocked on file I/O then the game is still going to look and feel like it is hung up.

The correct solution to your problem is to use event driven programming for your logic and file I/O. If logic needs a resource, it should start loading it in the background (using either a thread or asynchronous I/O APIs), and expect that the rest if the game and logic keeps running until that request is complete. If the game must stop and wait because the resource is critical, logic can at least handle a friendly loading screen ( or better, some kind of interactive amusement) while it waits.

Short version: just don't make API calls that block and stall the application, unless those calls themselves are on another thread.

\$\endgroup\$
1
  • \$\begingroup\$ That is a reasonable answer, it works for sure, thanks! \$\endgroup\$
    – Grimshaw
    Commented Oct 1, 2012 at 22:39
0
\$\begingroup\$

You should not put render code into your update method.

If you can break your code into parts where you would call Render(), you can also easily just exit for this frame and let the render function do its job.

I'm assuming all resources that you want to load share a common interface that defines methods like Load() and IsLoaded() (and a few more for unloading). Given a list of these resources to load you have the option to simply load one and be done, like

bool everythingLoaded = true;
foreach(ILoadableResource resource in resourcesToLoad){
  if(resource.IsLoaded()) continue;
  resource.Load();
  everythingLoaded = false;
  break;
}

if(everythingLoaded){ ... }

That will render a frame after every resource loaded. As long as you can guarantee that not one resource will take longer than ~33ms - render time(=30fps) you will have a smooth animation. Alternatively you can load as many as possible while keeping track of a high precision timer until you reach ~33ms (render time should be close to non existent and since the scene will be most likely static you could go even further up)

If you are loading huge resources that take long to load but absolutely must maintain a smooth animation you need to chunk your loading process further, or use another thread. For loading chunks you could consider giving the interface a GetChildren() function and load everything recursively before you load the parent resource. To actually get chunks of data to load you would need to prepare your data that way, like splitting a huge texture into smaller parts and have the parent resource assemble that together. Although I guess at this point a threaded solution should be much simpler.

\$\endgroup\$
1
  • \$\begingroup\$ This is indeed a solution to my problem, though I start to agree with the threaded solution, it doesn't seem to justify the hassle, i'd say.. \$\endgroup\$
    – Grimshaw
    Commented Aug 1, 2012 at 21:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .