Jump to content
  • Advertisement
Sign in to follow this  
zokeefe

What's Your Ios Game Loop?

This topic is 710 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

Just looking at what other people have done, what's been successful, and what pitfalls to avoid.

 

Current Prototype:

  • Game update is variable update time
  • Game update and rendering done in CADisplayLink callback running on main thread.
  • Audio update occurs on separate thread controlled by AudioUnit.
  • (Game-specific context): Game update takes ~5ms to complete

 

Thoughts:

  • I feel like variable-time game update might be OK on mobile given we don't have to worry about being preempted as much.
  • Don't know if this is how CADisplayLink is designed to work - perhaps should run game logic on background thread and only render in CADisplayLink callback? Not sure what synchronization issues arise here. Game logic could be allowed to update as fast as possible - or could cap to screen refresh rate.
  • Similarly, could push rendering into same background thread as game update. Again, not sure what synchronization issues arise here.

Goals (The same as everyone else?):

  1. Minimize input -> display latency
  2. Every screen refresh, the device should have an new/updated frame buffer to display.

(Placed in Graphics Programming and Theory because of CPU/GPU synchronization issues - of which I am most uninformed)

Edited by zokeefe

Share this post


Link to post
Share on other sites
Advertisement
  • I feel like variable-time game update might be OK on mobile given we don't have to worry about being preempted as much.
It is never okay to use a variable-step rate. It is trivial to implement and failure to do so is only out of laziness, as it never enhances your game, only adds to its instability.


  • Don't know if this is how CADisplayLink is designed to work - perhaps should run game logic on background thread and only render in CADisplayLink callback? Not sure what synchronization issues arise here. Game logic could be allowed to update as fast as possible - or could cap to screen refresh rate.
  • Similarly, could push rendering into same background thread as game update. Again, not sure what synchronization issues arise here.

  • Minimize input -> display latency

Keep your game thread in a waiting state and trigger it from the display link. Spend as little time as possible in the display link or you will interfere with input timing and responsiveness.
For simplicity, there is no reason to render on a thread separately from your logic thread—just do the update and then render on the same thread.


(Placed in Graphics Programming and Theory because of CPU/GPU synchronization issues - of which I am most uninformed)

Making a separate render thread is non-trivial and requires some experience. Stick to single threads now and research multi-threaded rendering when you are ready.
It is unrelated to anything specific to iOS, and is its own subject large enough to deserve its own research.


L. Spiro

Share this post


Link to post
Share on other sites

My loop is a little complicated, i work on PC and it should run on 60 or 30 fps dependent on hardware capibility.

 

I have multiple threads for each of the subsystems running( currently: network, audio, ki, physics and game logic, rendering)

 

User Input is collected in main thread at the beginning of the game loop, rendering draws always the scene calculated by the previous run of each subsystems;

 

Loop:

  1. Collect user input
  2. Trigger all subsystems
  3. Wait for finish
  4. Merge results and prepare next render frame
  5. Continue

This leads to the result that rendering is always on frame behind the user input.

Also various subsystems have their own copy of some parts of the scene to avoid race conditions. Which is a problem on huge scenes and low ram.

Share this post


Link to post
Share on other sites

@L.Spiro

 

Thanks for commenting :) I've read your blog - and as such am not surprised by

 

 

It is never okay to use a variable-step rate. It is trivial to implement and failure to do so is only out of laziness, as it never enhances your game, only adds to its instability.

I don't know if it's "trivial" (at least for me :P). Variable-step allows you to sim right up to start of frame easily, while to do this with fixed-step requires you to fudge all the renderable object transforms (at least just for rendering) No?

 

The other drawback of fixed-step is you don't know how many update steps you may take - which scares me since doing 1 game loop vs 2 game loops could blow my CPU budget for a frame out of the water and cause us to miss a rendered frame? (Included just for discussion :P).

 

 

 

Keep your game thread in a waiting state and trigger it from the display link.

OK :)

Edited by zokeefe

Share this post


Link to post
Share on other sites

@mgubisch

 

Thanks for commenting!

Interesting. Out of curiosity, how does one maintain separate threads for game logic & physics effectively? I would assume both want to be touching the same bits of data - to a large extent.

Share this post


Link to post
Share on other sites

The other drawback of fixed-step is you don't know how many update steps you may take - which scares me since doing 1 game loop vs 2 game loops could blow my CPU budget for a frame out of the water and cause us to miss a rendered frame?

If you need a cap, limit the number of updates you can do in a frame, but each update still needs to be of a fixed amount of time.
You have to be fine with having your game slow down and drop frames for this to work, which means online real-time multi-player games cannot do this, but generally iOS games can.


L. Spiro

Share this post


Link to post
Share on other sites

@mgubisch

 

Thanks for commenting!

Interesting. Out of curiosity, how does one maintain separate threads for game logic & physics effectively? I would assume both want to be touching the same bits of data - to a large extent.

 

As a wrote up in my first post some parts of the scene are stored in each subsystem which uses it. This makes some unneccesary copies which isn't really beautyful and is on my list to optimize.

 

Also each entity has a common set of properties which may be influenced by various subsystems(e.g. positon, velocity, aso).

Each subsystem wich wants to modify such a proberty sets a change flag to that property.

 

The merge result step collects all that change requests and applies it to the properties, during next loop run the renderer works with this properties.

If only one subsystem wants a change this is easy, just take it. If more than one subsystems wants to update the same part there is some kind of hierachy which subsystem wins.

In my desing this don't happen to often so i works fine for me.

 

At the beginning a had user input also as a subsystem, but this was somehow problematic so a apply user input at first, bevor the subsytems start to work.

I tried to make the tasks as fixed to one subsystem as possible, Movement is for nearly everthing handled by physics. Some exceptions like setting a fixed position of velocity is done by gamelogic. But in that cases gamelogic wins and in the next frame physics works with the new values and everthing runs as expected againg.

 

The idea to this came from an intel paper describing the demo they wrote many years ago as the introduced TBB. In that time a adopted this idea and modified it over the years. But the basic idea having a one or more separate threads for each subsystem stayed the same.

Share this post


Link to post
Share on other sites

It is never okay to use a variable-step rate

Just to reduce the hardness of L.S.'s stance here; all the console games that I've ever worked on (up until my indie project) have used a variable time-step. If your simulation can tolerate a wide range of delta-time values, and gameplay isn't affected by the varying quality of integration, then variable time-step result in a far simpler codebase...
 
I'm currently doing game engine contracting for a console games company, and have tried to convince them that they should really be using fixed time-step plus game-state interpolation... but have been unable to provide an objective argument to sway them so far. Their variable-rate system is working perfectly fine for them, and as we say, if it ain't broke, don't fix it.

Making a separate render thread is non-trivial and requires some experience.

While this is true, switching from variable-time-step to fixed-time-step + interpolation lays a lot of the foundations. The game-state interpolation system basically requires that the renderer's input data is separated from the live game-state data, which is required for a good multi-thread implementation :)

If you need a cap, limit the number of updates you can do in a frame, but each update still needs to be of a fixed amount of time. You have to be fine with having your game slow down and drop frames for this to work

You should generally do this in a variable time-step system too -- cap the amount of time that a single frame is allowed to simulate -- as the quality of the integration will be pretty terrible if you try to simulate too much time in one go. As in the fixed-time-step case, this will cause your game to go into slow motion if the actual framerate is too low. 

Out of curiosity, how does one maintain separate threads for game logic & physics effectively? I would assume both want to be touching the same bits of data - to a large extent.

The key to any good multithreading system is ensuring that no two threads ever need to share the same mutable data :)
For update/render, this means forming a pipeline where each frame, the update task generates a fresh blob of immutable data which is consumed by the render task.

The other drawback of fixed-step is you don't know how many update steps you may take

It's the same as in a variable-step architecture. You measure how long the previous frame took, and then advance the simulation by that amount of time next frame.

Share this post


Link to post
Share on other sites

@Hodgman

 

Thanks for the reply!

 

I'm currently doing game engine contracting for a console games company, and have tried to convince them that they should really be using fixed time-step plus game-state interpolation... but have been unable to provide an objective argument to sway them so far.

 

What argument are you using? :)

 

Their variable-rate system is working perfectly fine for them, and as we say, if it ain't broke, don't fix it.
 

 

This is where I am at now :) It's a 2D engine, my game update loop is very tight. The physics is entirely continuous. The only vulnerable aspect are objects undergoing acceleration dependent on velocity & position (using Verlet).

 

I wish I could find that object argument you were looking for - then I could stop worrying about this :)

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!