and I assume the stuff about the anti-aliasing for actives is also true for backdrop objects?
and I assume the stuff about the anti-aliasing for actives is also true for backdrop objects?
-Loop optimization for moving objects-
Normally, whenever you make multiple objects that require precise movement, you loop through each one with a foreach and then start a different set of actual movement fastloops for each object. The process looks something like this:
-objects that need to move are looped through with a foreach loop
-the ID of each object is recorded on this foreach,
-movement fastloops are run for each individual object and its ID is compared, to move it pixel-by-pixel according to its velocities, also checking for collision
Let's assume that you have 5 objects moving at 5 pixels per second on the X axis. Using the above method, that is 25 Fastloops required for movement. As your object count grows, so does the number of fastloops, until eventually, the sheer amount of loops bogs your application down. My personal limit on my (old and very weak) laptop is about 170 moving objects with collision before the FPS drops low enough to become unplayable. That adds up to at worst 850 fastloops fired. I could probably manage more objects just moving around if they didn't require collision, but in action games collision is usually a necessity.
Naturally, the limitations of the traditional method with fastloops got to me, and I sat around brainstorming for an hour or so. The following method is the result of that, and astoundingly simple:
-objects that need to move are looped through with a foreach loop
-the highest absolute velocity of the objects is recorded (which would be 5, like earlier)
-movement fastloops are run only 5 times
-each object decides to move by checking whether its absolute velocity is >= to the move loop index
Using this method, you don't need to specify which object is currently moving, because Fusion does it for you: any object with an absolute velocity higher than the loop index is scoped. To remove an object from the loop, you would set its absolute velocity to 0, which means it wouldn't be scoped whenever the loop fires. Thanks to the comparison to the loopindex, you can also have objects that move at independent speeds. If an object only has a velocity of 1, it will remove itself from the scope after one loop, whereas another object would keep going through iterations until it reaches its cap.
Now lets go back to our earlier scenario, of 5 objects moving at 5 pixels per second. With the new method, that amounts to only 5 fastloops vs the old 25! Starting to look like an improvement, but let's check what my new object limit is using the new method: 2000
Now there is a significant improvement! The second method yields a total object gain of 1830! All moving simultaneously, all with collisions working! And there are still only 5 loops running each frame. The old method would be using 10,000 loops each frame, and probably crash the application on even the strongest computer!
You don't need to worry about objects having independent movements, like an enemy that uses a certain behavior or the player's standard movement. All you need to do is handle physics separately, before the movement loops happen. I added a couple different behaviors in the following example for you to play around with:
loop optimization test_2.mfa
(I threw the "un-optimized" examples together quickly, so there are leftover values from the normal examples in there and the debug string isn't accurate. Ignore them. Fine detection is also OFF by default. Turning it on doesn't change much, though. My FPS dropped from 45 on average to 30-40 on average in the optimized bench.)
I don't think I need to explain the "Real world application" benefits for this method, do I? Practically everyone will benefit, especially mobile users where loops completely wipe their performance.![]()
That's a clever way to handle lots of instances with fastloops,
never thought of the problem this way, thanks for sharing!
[bookmarks this thread for future reference]
Tried the anti-aliasing trick with very resource-taxing situations in P3D,
when lots of actives are onscreen,
but sadly it didn't make any difference (neither plus nor minus),
wonder which other concurrent setting/circumstance makes it unleash that extra-power![]()
Could you try in a new mfa, and/or upload a screenshot of your various application, frame and active object settings?
Must this (pre-emptively setting larger dimensions) be done also for arrays that are loaded from file?Say you have 50000 values to write in the array,
and you are setting them one by one within a loop from index 0 to 49999
if your array has X dimension 1 at start
running the loop would take about 250/300 times more than if the array had 50000 X dimension at start!
This is because in first scenario the array is expanded 50000 times vs none.
Great thread!
Posts like these and the new library website is really building the Fusion knowledge bank.
@ Volnaiskra:
will do further testing later when back home,
I wonder if this is because P3D also "scales" those objecs >> forces some specific setup for antialiasing? (tried with both quality settings)
can't do without scaling, but will make a blank mfa to test scaling and the overall thing, which sounds very interesting
tried removing the shader also but that didn't help either (same performance with antialiasing tick on/off without shader applied)
I would suspect an array loaded from file is directly expanded to full size only once (optimized way),
but never tested, so that would be something worth testing too
(just going to save my 50000 entries and try to load with preset index 1 or 50000)
btw, forgot to say that this can be done dynamically:
if the largest dimension is unknown while working in frame editor,
but known within the runtime,
you can "write" a foo value/string to largest known index before the loop tales place
(or write values backwards from largest to smaller index)
i.e.
...
>>> set array_maxindex to (say, 50000)
>>> write value/text "whatever" to array_maxindex
>>> start loop "fill array" array_maxindex times
on loop "fill array"
>>> ....
this will expand just once before the loop takes place
Great thread.
I think it should be seriously highlighted somewhere that these optimisational 'facts' are running on D3D9 PC runtime as in no way would some of these reflect a mobile device. I just think we need a bit of mitigation there as some users may/will expect these to be coherent across all the runtimes, so establishing these base results that are base runtime results and not per exporter.
For example, your PNG8/24/32 is marked as 'has no effect' yet this has a substantial effect on Mobile Exporters such as Android and iOS. You have to remember PC runtime is usually dealing with a PC with 3+ ghz of processing power, 4+ GB of RAM and 2+ GB of GPU RAM, whereas some mobile devices are still averaging around half of this power and nowhere near the profile of a PC's GPU. Only the high-end ones but you cannot speculate that all your mobile users only yield high-end devices otherwise you'd be cutting off a wide chunk or distributing an app that looks like it is struggling because you didn't profile correctly.
I agree, Danny. That's why I gave a very detailed summary of my testing environment at the beginning of my results, and mentioned not just once but several times that I encourage people to test on different runtime and setups and add their results here.
You may well be right about PNG and mobile. But there's only one way to find out for sure![]()
@ Volnaiskra: I'm failing to reproduce the antialiasing boost,
this super-simple file gives same results both with antialiasing turned on and off:
antialiasing_test.mfa
(just wait few seconds for the framerate to drop, at least, in my average desktop machine goes around 20)
(p.s. tried with moving bouncing ball objects too, same result)
Re-reading your original post,
is it required for the object to be moved in a fastloop for this increase to show?
Do you have a simple test file working on your side,
so I can try and see if it happens here too, or there might be something machine-specific?
Happygreenfrog confirmed that too, so wonder what might be missing here, I want faster games with just a tick too ()
For the array loading, did a quick test, and it seems there's no difference in the array size before loading a file,
so I suppose this optimization is for writing-on-runtime only, and makes no difference when loading an array file.