Games [XUI2D] Performance

Erel

B4X founder
Staff member
Licensed User
Longtime User
Unlike regular apps where we don't need to worry too much about performance, developing real-time games requires us to continuously test our game and make sure that it has good performance.

The most obvious parameter is the FPS value. Like everything in life it is a bit more complicated than it might seem.

I will start with explaining the meaning of FPS and what you should expect.

It is important to understand the following statements:

1. Games look great when they run at 60 fps.
2. Games look good or fine when they run at 30 fps.
3. Games look bad when they keep failing to run at the desired FPS. The user inputs will be ignored and the whole game will be unresponsive.

The X2 framework is designed based on these statements.
X2.TargetFPS sets the desired iterations per second. This is set to 60 by default (30 in debug mode).
This means that the game loop and the physics engine will run at 60 iterations per second.
Ideally the screen will also be updated 60 times per second.
The value shown at the bottom of the screen counts the number of frames ready to be drawn (BC_BitmapReady in X2Utils).

The conclusion from statements #2 and #3 is that it is better to quickly lower the FPS ourselves than to let the game fail to keep up with the desired pace.

If the measured FPS is smaller than TargetFPS - 5 then it will only create a new frame every second iteration. This means that the measured FPS will be halved. The game loop will still run at 60 loops per second.
GS.ShouldDraw will be False during the non-drawing iterations.

If you are creating a delegate class then you should avoid making drawings when GS.ShouldDraw is False as the drawing tasks will not be used.

B4X:
Public Sub Tick (GS As X2GameStep)
   If GS.ShouldDraw Then
       GS.DrawingTasks.Add(...))
   End If
End Sub

It will try to return to TargetFPS after a while.

Explicitly setting the TargetFPS to 30 is not exactly the same as letting the FPS fall to 30 because the game loop continues to run at 60 FPS in the later case.

Some numbers

Based on my tests with the current examples:

- All examples run at 60 FPS on an old Nexus 5 from 2013 and all newer phones tested. Older devices (2010 - 2012) are not considered a relevant target for XUI2D.
- All examples run at 60 FPS on an old iPhone 5S and all newer phones tested.
- All examples run at 60 FPS on a Samsung SM-T580 10'' tablet.
You can see benchmark scores for the mentioned Android devices here: https://www.androidbenchmark.net/passmark_chart.html
Devices with score less than 2000 - 2500 are probably too weak for XUI2D.

- All examples run at 60 FPS on the four computers (Mac / PC) available here. Old netbooks are not considered a relevant target for XUI2D. XUI2D is multithreaded and will probably not run smooth on weak dual core PCs.


Tips

- Measure performance in release mode with debug drawing disabled.
- Test performance on all the relevant platforms. Different platforms behave differently.
- Always try to reuse graphics. Especially if the bodies can rotate. X2SpriteGraphicCache will create a new graphic for each rotation (based on the angle interval).
- Monitor the logs. It shows when new graphics are added to the cache.
- Pay attention to the number of bodies. If it keeps growing then you have a problem.
- Check 'destory if invisible' option (make sure not to create the body outside of the visible screen as it will be destroyed immediately).
- Uncheck 'tick if invisible'.
- BodyWrapper.IsInvisible tells you whether the body is invisible. You can use it to avoid drawing off-screen bodies.
- The simplest way to set the graphics is with 'graphic file x' in the map editor.
- Pay extra care when drawing with Canvas. See how it is done in the various examples.
- Prefer BitmapCreator over Canvas when you can.
- Once the drawing is ready you should extract a CompressedBC out of it and reuse it when possible.
- Never do something for x frames. Think in seconds or milliseconds instead.
- X2.TimeStepMs returns the duration of each step.
- New: You can add STATS to the build configuration symbols. It will add many log messages with the duration of the various tasks in the game loop.
- High resolution background images can have a large negative effect on the performance. Scale down the image:
B4X:
X2.SetBitmapWithFitOrFill(ivBackground, xui.LoadBitmapResize(File.DirAssets, "Sky.jpg", ivBackground.Width / 2, ivBackground.Height / 2, False))
In many cases the visual change will not be noticeable.
- If you see a significant slowdown when a body rotates for the first time then you should consider calling X2.GraphicCache.WarmGraphic. This is done in the Monster Truck example.
It prepares all the rotated frames instead of building them when needed.
It can have a negative effect if you use it too much as it can fill the cache.
- That's it for now. More tips will be added...
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Very good news!

1. The B4A implementation received a significant performance boost with BitmapCreator v4.17.
2. TileMap was also improved and it now reuses the previous drawn map when the map moves.

With these changes as well as some optimizations in the existing examples, all the examples run at 60 FPS on a 5 years old Nexus 5 device.
 

JanG

Member
Licensed User
Longtime User
I'm sorry. I tested the unmodified examples in Release Mode. On my android TV Box <20fps. This box can play HD videos.
 

JanG

Member
Licensed User
Longtime User
I changed the screen size. No difference.

Another test (unmodified space invaders, b4j version) on a modern PC has 60fps. But on a netbook (Atom CPU N450, 2GHz) it has <20fps. If I change the windows size the fps is under 10! This means it is stuttering and therefore unusable. And a Visual Basic 6 demo on the same netbook with almost the same number of sprites has >160fps. And the CPU usage of java is about 70%. The compiled Visual Basic exe uses about 50% CPU.

I like b4x very much, but in my opinion for true multiplatform game development the performance is insufficient at the moment.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Few points:

- I'm very happy with XUI2D performance. It is much better than I expected when I started working on this framework.
- All the examples run smoothly on an old Nexus 5 and an old iPhone 5S. Android and iOS phones are the main target for XUI2D. I can stop here as all other points are less important.

I changed the screen size. No difference.
It depends how you did it. Android TV is a potential target and I do plan to investigate it. If you like you can start a new thread for further discussion.

But on a netbook (Atom CPU N450, 2GHz) it has <20fps
A weak netbook from 2010 is not considered a relevant target platform for XUI2D.

And a Visual Basic 6 demo on the same netbook with almost the same number of sprites has >160fps. And the CPU usage of java is about 70%. The compiled Visual Basic exe uses about 50% CPU.
- The number of sprites is not a key factor for comparison.
- How is your VB6 demo runs on Android and iOS devices? If it doesn't run then there is no point in comparing it with XUI2D framework.
- (hard to believe that the screen on your netbook is actually redrawn 160 times per second)
 

moster67

Expert
Licensed User
Longtime User
Android TV is a potential target and I do plan to investigate it
Offtopic:
That would be great Erel :) The AndroidTV platform has a lot of potential and while we already today can create apps for Android TV we cannot use its native views based on the leanback-library. I was thinking about trying to wrap it but I stopped since it is very much based on fragments...
 

sorex

Expert
Licensed User
Longtime User
I guess Jan's point can be summerized to "why isn't something that worked fine on a 2MHz machine not working on my machine that's more than 1000 times faster"

I bet the emulated mame version runs at full speed on his laptop.

The java port is a lot slower than its C(++) brother aswell.
The post is rather old so I don't know if it's still relevant but there he mentions java is almost 2.5 times slower than the gcc one
but on his macbook still good for a max of ~166fps (1000/6?) if I interpret it right altho I don't know what that test is about, an empty screen/world?
Others talk about up to 10x slower than gcc.

http://www.j15r.com/blog/2013/04/25/Box2d_Revisited

There's probably too much going on in box2d that kills performence on lower end computers maybe the drawing engine is the culprit as it is not GPU based.

But B4J remains good for the initial testing before moving on to mobile and while you (Erel) keep improving some parts like bitmapCreator things will turn out better in the end.

When I run it with nothing happening my cpu fan starts blowing because it still uses a full core even when nothing updates. It's like that object pausing mechanism is not working right.
 

Star-Dust

Expert
Licensed User
Longtime User
There's probably too much going on in box2d that kills performence on lower end computers maybe the drawing engine is the culprit as it is not GPU based.
I reached the same conclusion when I met with the same obstacle making my 3D library.
Although BitamapCreator has excellent performance (it is very well done) not being based on the GPU has limits it can not overcome.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
There's probably too much going on in box2d that kills performence on lower end computers maybe the drawing engine is the culprit as it is not GPU based
This is not exactly true. GPU is used to make the drawings as ImageView is hardware accelerated.

I reached the same conclusion when I met with the same obstacle making my 3D library.
Although BitamapCreator has excellent performance (it is very well done) not being based on the GPU has limits it can not overcome.
The usage of BitmapCreator in XUI2D is very different than the "normal" usage.
1. All the "drawings" are actually fast array copies retrieved from "compressed bitmap creators". This is a structure that was designed for fast writing of existing graphics (unlike the standard BitmapCreator which is a read/write structure).
2. The drawings happen on a background thread so the game is free to process inputs and to update the display while the new bitmap is generated.

As I wrote above, the main target platforms are mobile phones. The games will run nicely on most desktops however if you have an old / weak PC then it will run slower. It doesn't matter what you do as the JavaFX engine itself is not lightweight.
 

sorex

Expert
Licensed User
Longtime User
running this space invaders clone > https://github.com/sjhorn/SpaceInvaders

needs 3-6% CPU

ok, it's minimal compared to what box2d has to offer so it can't be really compared but for what you visually see this is what one would expect cpu wise.

the xui2D version spikes upto 76% here for 'the same' game.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
running this space invaders clone > https://github.com/sjhorn/SpaceInvaders

needs 3-6% CPU

ok, it's minimal compared to what box2d has to offer so it can't be really compared but for what you visually see this is what one would expect cpu wise.

the xui2D version spikes upto 76% here for 'the same' game.
This comparison means exactly nothing. You are derailing this thread. Please start a new thread for any other discussion.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I guess that I was not clear with the purposes of this thread.

I'll explain the three purposes:

1. Explain what FPS means and how it behaves in XUI2D.
2. Provide optimization tips and potential pitfalls <---- this is the most important purpose.
3. Provide general expectations about the performance on the various platforms.
I'm happy to say that the performance on the two main platforms, Android and iOS phones, is good and is actually better than I expected when I started building XUI2D.

You are all welcome to start new threads and discuss related or unrelated topics.
 

JanG

Member
Licensed User
Longtime User
Another performance test for Space Invaders:

Device: Samsungs Galaxy S3 (Android)
fps: <30, stuttering graphics

compared with "Invaders Deluxe" (better graphics) on same device:
fps: unknown, but very smooth movements

Sorry to say that, for education and learning it is okay, but if you sell it on the market you will get problems, because a lot of users do have older devices. And they will complain, believe me ;) .

EDIT1:
If I shoot enough enemies, at some point the game runs smoothly on the S3. But with starting the next level, it is <30fps, shooting enemies, 60fps, etc...
 
Last edited:

Don Oso

Active Member
Licensed User
Longtime User
I check in one of my cheap test android phone Bmobile Ax605 cost here US$ 45, and space invaders run smooth ..
WhatsApp Image 2018-08-27 at 19.39.16.jpeg


bmobile.jpg

Specs
  • Bmobile AX605
  • Screen: 3,5 "
  • Android 4.4.2 KitKat
  • Dual Core 1.3 GHz
  • 4 GB internal memory
  • RAM: 512 MB
 
Last edited:

JanG

Member
Licensed User
Longtime User
Thank you for the recording. It shows exactly my explained problem: fps < 30fps. There is a big difference with 60fps. E.g. the shootings are much more smooth and faster. I can see this difference very clearly when my s3 switches from <30fps to 60fps.
 
Top