game LAGS on physics collision

Apart from the custom font loading problem, the main problem I encountered with this Beta is that the game lags on every physics collision of two objects. 

So when I have a dynamic gameplay where a monster hits an object every second, destroys it and counts +1 to a score value - the game lags for about 100-200ms, the frame rate slows down and it’s impossible to play the game smoothly.

I don’t place any complex loops in my collision listener, just some basic parameter changing. I tried to cut out all the calls, but the lags encounter even when I have only this simple listener:

local function onLocalCollision(self, event ) if ( event.phase == "began" ) then score = score + 1; title.text = score; self:removeSelf(); self = nil return true end end

so there has to be something wrong in collision handling. Especially updating the text value increases the lag, but when I remove the title.text call and add some other code - the lag is there as well. I’m testing it on Lumia 625.

When I remove everything apart from:

self:removeSelf() self = nil

then there’s no lag. Could you have a look into it soon, please? 

Thanks,

Olaf

The text updating in this beta generally very laggy - when I have a static score screen where a timer that counts up the score points earned in a round, the text updating works VERY slow, even though the timer iteration timespan is set to 25 ms:

local gameRoundScore = 125 local tmr tmr = timer.performWithDelay(25, function(e) score.text = score + e.count) if e.count == gameRoundScore then timer.cancel(tmr); tmr = nil; end end,gameRoundScore);

So probably the text updating is mainly causing the lags, but as I said - even if I remove the text update call and leave some other parameter updates - the lags on collision events are back.

o.

Text bitmap generation is extremely expensive on WP8.  Far more expensive than the iOS and Android.  We’ve already optimized it the best that we can and it’s not going to get any better unfortunately.

The only way to work-around this is to use bitmap fonts, which is what Microsoft recommends and is what most AAA game studios use when displaying text that are updated frequently.  The reason bitmap fonts are faster is because all of the characters are pre-loaded in a single spritesheet and text is then formed/layed-out based on those already loaded characters.  There are 3rd party bitmap font tools that can help you with this such as TextCandy, bmGlyph, Font-Manager, etc.  In fact, using them will improve the text update performance on Android as well. 

That said, the bitmap font technique is only useful for text that’s under your control.  That is, you can guarantee that the characters you are using exist in your spritesheet.  The display.newText() function should be used for text that’s out of your control, such as text taken from the Internet like Facebook, Twitter, etc… and this will work fine in this case because you’re not going to be updating this text on every frame.

Oh and one other performance gotcha is with the print() function.  The print() function on WP8 is extremely slow when you’re running the app under the Visual Studio debugger.  This is an issue that all native WP8 developers face as well because the only means (that I’m aware of) to make log output appear in Visual Studio is via the native OutpuDebugString() function, which is famously slow in the Windows development world.  If you are not running your app under the Visual Studio debugger, then the performance is fine, but then you’ll have no means of acquiring the printed log output.

Joshua,

Thanks for the tips, I’ll research these bitmap fonts and will remove all the print() calls. I was wondering how to have the output to Visual Studio’s console as well, because now I can see only the “thread terminated with code XXX” stuff.

You can see your print() output via Visual Studio’s “Output” panel, but only if you set up your application’s “Debugger Type” for native.  You can do so as follows:

  1. Right click on your application project.

  2. Select “Properties” from the popup menu.

  3. Select the “Debug” tab on the left.

  4. Go to the drop-down box under “Debugger Type\UI Task” and select “Native Only”.

  5. Run your application in debug mode.

Yeah, the above wasn’t super obvious to me either when I started doing native WP8 development.  Later, I’ll look into seeing if it’s possible to output to either Managed or Native debug modes, as long as it doesn’t cause too much of a performance penalty.

Also, a simple means of getting rid of print() support in your app might be to override the print() function in Lua.  How about something like this?

-- Have the print() function do nothing on WP8. if (system.getInfo("platformName") == "WinPhone") then print = function() end end

Sounds cool, thanks for the guide!

Olaf,

I’ve been playing around with some of our physics apps.  I’ve discovered that the physics performance runs perfectly at 30 FPS, but at 60 FPS, physics objects appear to move at half the speed compared to 30 FPS.  Kind of an odd phenomenon that I’ve never seen happen on any other platform.  I tested this with our “ManyCrates” and “Chains” sample apps included with the Corona Simulator.  I’ll investigate to see what’s going on.  In the meantime, you’ll likely see better performance if your comment out the “fps” setting in your “config.lua”.  I know it seems crazy, but it actually improved performance.  (You’ll still have to avoid text updates and prints to see the impovement.)

Okay.  I think I know what’s going on.  By default, physics is framerate based, meaning that if the framerate slows down (ie: less than the configured FPS) then you’ll see the physics system slow down too.  Due to WP8 timer lateness issues that I was telling you about before, it looks like we’re not quite achieving 60 FPS which would cause a slow-down effect.

You can work-around this issue by changing the physics system to be time based.  You can do this by doing the following…

physics.start()

physics.setTimeStep(0)  – Setting this to zero makes it time based.

That said, I’m not sure if this is the issue you are seeing.  I’m not seeing any collision performance issues like you.  I’m seeing a framerate problem where we’re unable to achieve 60 FPS consistently causing physics system slowdowns.  (I’m going to look into improving the framerate later.)

Anyways, I hope the above info is useful.

Thanks Joshua, I’ll test it out today and will let you know the results. Should I make this physics.setTimeStep(0) call after every physics.start() call or just once after the first start?

OK, so it seems that the lags are caused by what you were saying - inconsistent physics frame rate. When I call physics.setTimeStep(0) (I do it once at the beginning) - it seems to look better (consistent frame rate), although it has consistently jitter motion as well. There are no slow downs but it’s generally not so smooth looking.

I tried to comment out the fps settings in config.lua, but here I get the same results running 30fps as with 60fps: there are frame rate slow downs if I don’t call setTimeStep(0), but once I call it - slow downs disappear, although the motion isn’t that smooth in general.

Does it make any sense?

Okay.  So it definitely sounds like a framerate issue then at this point.

I’m not seeing the jitter effect that you are seeing.  At least not with our physics sample apps.  Although, you probably would see an effect like that if you loaded an image during gameplay.  Are you loading all images and imagesheets into memory before starting your game?

And regarding the physics.setTimeStep() function, you only have to call it once.  You don’t have to call it after every physics.start() as you have observed.  The system remember what you’ve last set it to.

Yes, all my objects are preloaded as an imageSheet so this shouldn’t be an issue. The jitter I’m observing isn’t that obvious but it’s the general feeling that the motion isn’t super smooth as it is with the frame-rate based physics simulation (apart from the slow-down parts, of course).

Maybe it’s because the time base simulation is a bit offset to 60 or 30 fps, and that’s why the movement calculations don’t look that smooth? I don’t know, just guessing. If you could check later what’s causing the the frame-rate simulation slow-down, it would be great. Thanks.

After some testing I noticed that there are tiny slow downs also in a time based physics simulation. They are not so obvious like the ones in a frame rate based simulation, but it seems that something is causing the phycis frame rate inconsistency here as well. Just letting know.

Olaf,

I’ve been spending time looking into improving rendering performance for the last couple of days and improving framerate/timer accuracy.  Particularly for 60 FPS apps.  I’ve noticed that on my Lumia 920 it was taking at least about 20 milliseconds to update/render per render pass and most of that time was with synchronizing the UI thread with the rendering thread.  I’ve managed to reduce that time by 10 milliseconds, making a huge performance improvement.  I’m now getting about ~45 FPS on a Lumia 920.  Unfortunately, I don’t think it’s possible to get it to render any faster on that particular device.  At least with a XAML based app, because Corona is competing with Microsoft’s XAML UI framework for the rendering thread (i.e.: there is only 1 rendering thread on WP8 and it must be shared) and about every few render passes there is an “additional” 10-15 millisecond delay until XAML UI blocks us.  Note that in order to achieve 60 FPS, we must be able to render every 16 milliseconds, and that delay is making it impossible.

Now, if this was a pure DirectX C++ WP8 app, no XAML, then I think it’s absolutely possible to achieve 60 FPS because we would then have absolute control over the rendering system (i.e.: not competing with a UI framework for rendering time).  But a XAML based app is needed if we want to support native UI and ad libraries in the future, which is a requirement for many Corona developers.  Plus, some features are only available on the .NET side, making a XAML based app required as well.

Interestingly enough, I know that Unity for WP8 is a XAML based app as well.  I remember chatting with them and Appcelerator last October, hearing that their WP8 apps were 30 FPS.  I can’t help but think that they’re running into the same issue I’ve mentioned above because they’re competing for the rendering threads time too.

In any case, I did make significant performance improvements and I plan on sending out another update in the middle of next week.  It should be noticeably smoother.

I’ll also talk with my Microsoft contacts on getting that version tested by them on a higher end WP8 device to see what the framerate is.  Interestingly enough, they consider my Lumia 920 a low-end device, so, I’d be interested to know how well it runs on their better devices.  Just note that it may take 1-2 weeks until I can those test results from them.

Joshua, Thanks for the update and your effort! 'll test it out, but 10ms faster sounds like a good improvement. I didn’t realise that Unity WP8 apps run in 30fps only. Probably it’s the general problem then. If it runs smoothly at 30fps without slow-downs, that would be something acceptable in a gameplay. Because now, as I mentioned you before, I’m seeing slowdowns even at 30fps with frame rate simulation and tiny slow downs with time based simulation. Thanks in advance for sharing the next build wih David in the same Dropbox folder as you did last time.

According to the statistics, Lumia 520 is the most popular windows phone. So it makes sense targeting this device and I presume 30fps would be the maximum for it.

Will we be able to set FPS in config.lua dynamically during startup or at the runtime in the future?

>>  didn’t realize that Unity WP8 apps run in 30fps only.

That’s from what I was told last year.  I’m not sure how it is today.  I’ve briefly searched Unity’s forums on this topic and there does appear to be several developers struggling to get a good framerate.  It did seem like some developer managed to get it above 30 FPS though, but not quite reach 60 FPS either.  My general searches on the 60 FPS topic (non-Unity based) is that you really need to build a pure native C++ DirectX app to get that high framerate, which means you lose the other features I mentioned above.  In any case, I think that 10 millisecond improvement per render pass was a huge improvement, but I’ll let you guys be the judge of it on the next update I send out.

>> According to the statistics, Lumia 520 is the most popular windows phone.

Yeah, I’ll have to make sure to test it on that specific device.  I know that Microsoft is trying to tackle the low-cost phone market like Android did, so, achieving good performance on low-end devices I think is important too.

>> Will we be able to set FPS in config.lua dynamically during startup or at the runtime in the future?

That’s actually possible to do now on iOS and Android.  You can call the system.getInfo(“model”) function to fetch the device’s model name.  This is more useful on iOS than Android.  You’re not able to fetch device model on WP8 yet.  It’s on my to-do list.

Lerg said: >> Will we be able to set FPS in config.lua dynamically during startup or at the runtime in the future?
 
That’s actually possible to do now on iOS and Android.  You can call the system.getInfo(“model”) function to fetch the device’s model name.  This is more useful on iOS than Android.  You’re not able to fetch device model on WP8 yet.  It’s on my to-do list.

:huh:  @Joshua.  I don’t think that’s what @Lerg was asking…

You can make a call to system.getInfo() within the “config.lua” file and set parameters dynamically, such as FPS.  You can then set the FPS by the device’s model name.