Scripts / Simple Object Culling by Range

Author
Message
tomjscott
User Banned
Posted: 10th Jun 2014 19:23 Edited at: 11th Jun 2014 15:55
Here is a very simple way to improve your game's performance by showing/hiding entity's by their range from the player.



Put the following code in global.lua or your own global file if you know how to do that.







Then, you can simply create a default.lua script as follows:







Since the engine already assigns everything the default.lua script, which currently doesn't exist, your default.lua will automatically give you distance culling for every entity. If you don't want an object to have automatic culling then assign a different script.



Finally, if you want an object to do other things as well, then simply add the call to VisibilityCheck at the beginning of your main function. The return function can even help you to prevent any further processing on that object if you don't want it doing anything when not visible.



Caveat: I haven't tested this at all, but I see no reason it won't work. I will be trying it out as soon as I can since I need it myself. If there are any issues I'll gladly help sort them out.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
DVader
20
Years of Service
User Offline
Joined: 28th Jan 2004
Location:
Posted: 10th Jun 2014 19:46
I wrote a script pretty much exactly the same ( never thought to call it default.lua that would have saved me hours and hours lol ). However when I applied it to a lot of objects, it slowed my system more than it helped. I abandoned it awhile ago because it seemed to hinder early game performance rather than improve it.

Still, it may improve performance on small levels possibly and I certainly have not tried it since the latest update. I got sick of changing all my entities to use the script and vice versa when I decided it wasn't helping. If I try it again, I'll be sure to use the default tip!



SPECS: Q6600 CPU. Nvidia 260GTX. 8 Gig Memory. Win 7.
tomjscott
User Banned
Posted: 10th Jun 2014 19:51
Yeah, I haven't tried it yet so I wouldn't know about performance degradation possibilities. It did occur to me that all the checks per frame might have an impact, but wasn't going to assume that either. However, in looking at smallg's script, he's checking an arbitrary 1000 entities that might not even exist and so I don't see any reason why it wouldn't also have performance issues for the same reasons. I'll have to try it out myself and see what happens.

I'll think about it some more and think about improvements that might be possible when checking a lot of entities. I think there might be some things we can do to alleviate that as well. I'll post more info if I figure something out after testing it myself.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 10th Jun 2014 20:02
I've been thinking about this and I find it strange that having a few simple math calculations extra per frame per entity would somehow be slower than pumping out the thousands of polygons for that object and applying complex shader effects just seems wrong. I'm thinking this will improve performance, but I'll wait until I try it first to be sure.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
DVader
20
Years of Service
User Offline
Joined: 28th Jan 2004
Location:
Posted: 10th Jun 2014 20:19
I tried Smallg's occlusion script when I found my own attempt not working. Didn't help my performance either. Still had a similar frame rate even with a massive reduction of objects shown. Even in Dark Basic simply hiding an object is slower than not having an object there. I am figuring the hide in Reloaded suffers from the same. Spawning the entities within range would probably be faster, but would be aone off deal, you can't de-spawn and re-spawn them as far as I know, unless you can delete them and still spawn them possibly. Still with lots of objects even this will take it's toll somehow.

The advantage with using this method as opposed to smallg's is you can change the script for specific objects to have a greater or lesser range, dependent on their visibility from a distance. It did speed my game up when used sparingly, but not on mass.

You would think hiding 50% or more of the map would seriously boost performance, but it seems that the cost of running so many scripts ends up making performance similar if not worse. That is with my script of course, but it was mostly the same.

This is just my experience to date. People may have a lot more luck with it dependent on the map. I'm sure a few peeps will test it throughly for you!



SPECS: Q6600 CPU. Nvidia 260GTX. 8 Gig Memory. Win 7.
tomjscott
User Banned
Posted: 10th Jun 2014 20:23
OK, so I've figured out a simple way to make this reduce the checks significantly. A script would still run for each entity that had default.lua attached to it, but it wouldn't perform the range checking unless necessary. Again, I don't know if the original code has that much of a performance impact yet anyway, but this can only help not hurt.

The idea is that you divide your game into stages or areas or zones if you prefer to call it that. But we're not talking about zone markers here. You could define these stages/zones by checkpoints or whatever you want. You create a global variable called gameStage. Set the gameStage to zero for the start of the game and then as the player hits checkpoints you can increment the stage. So, now that you have a gameStage, you can modify the VisibilityCheck function to return immediately if the object you are checking is not part of the current game stage or zone.

The only problem is defining what objects are part of what game stage or zone. This kind of kills the nice automation we had with using the default.lua script to gain visibility culling automatically for all objects, but it's a necessary evil if we want to divide this up by area/stage/zone. There are probably a few ways to assign a stage/zone to an entity with a global table being the easiest. I'll have to try some things to see what would be easiest and then report back.

But for now, I'll test my original version and see what impact it has and go from there. Or if anyone tries the original technique out, please let us know if it helps or hurts.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
smallg
Community Leader
18
Years of Service
User Offline
Joined: 8th Dec 2005
Location:
Posted: 10th Jun 2014 20:26
really? in my tests it definitely does make a difference, hiding objects after a 1000 range tends to increase my fps by about 30%
maybe it's just not your graphics card that is causing the bottleneck for you

life's one big game

windows vista ultimate

i5 @3.3ghz, 4gb ram, geforce gtx460, directx 11
tomjscott
User Banned
Posted: 10th Jun 2014 20:26
Quote: "Even in Dark Basic simply hiding an object is slower than not having an object there."


Well, having an object that still runs a script would certainly be more intensive than an object not there at all, but I still think we can work this out where it would be beneficial. I seriously need it myself so I'll be working full force on this to see what can be done.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 10th Jun 2014 20:28
Quote: "hiding objects after a 1000 range tends to increase my fps by about 30%"


That's encouraging. Maybe my script will be useful after all. It's extremely simple to implement.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
TattieBoJangle
10
Years of Service
User Offline
Joined: 7th Jan 2014
Location: United Kingdom
Posted: 10th Jun 2014 20:49 Edited at: 10th Jun 2014 20:50
StackHash_f40f Error when i try it m8





PC SPECS: Windows 8 Pro 64-bit, Intel I7 (PASSMARK 9529) 4GHz CPU, Asus R9 3GB GPU (PASSMARK 6858) 32GB DDR3 MEM (PASSMARK 2842)
tomjscott
User Banned
Posted: 10th Jun 2014 21:16
Quote: "StackHash_f40f Error when i try it m8"

Yep, it looks like this is the dreaded problem people are experiencing with player distance checks exceeding 18 or whatever. Lovely. I actually tested it with a simple map and fewer objects and the script runs fine, but with more objects it crashes. It's an engine bug. I don't know if there is a workaround yet for that. I'll see if there is something that can be done. I don't see why a certain number of player distance checks would cause a crash, but that's what was observed in other cases.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 10th Jun 2014 21:34
It might be something other than player distance check. I did a test starting with an empty map and just a default.lua script that has a main function, but doesn't do anything. It works fine until I place around 25-30 objects. Even though the script doesn't even do anything, it hangs on initializing physics. Something major wrong here.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
DVader
20
Years of Service
User Offline
Joined: 28th Jan 2004
Location:
Posted: 10th Jun 2014 22:12
I'm only going on my experience with my own script. Here it is.


Very similar to yours you will see. It worked great, but when applied to many objects I started to get worse performance. I used a couple of versions with different distances for different buildings rather than add a variable or array for it, just lazy sometimes, lol. Especially with Lua as I am still pretty new. Certainly as you say a more refined system may work better. Not sure what the return values are you use in your script? I'm used to return sending you back to a gosub . I hope you find a good boost from your tests! I just know from mine I was disappointed. An hour changing entity scripts to find none or worse performance gain. Again I wish I had called it default.lua ;p The thought just didn't occur to me.

@smallg, It really ran as badly as it did without the script for me, or with the one above applied to many of them. I only made a small zone to test it at the start, rather than a large zone around the entire level. Perhaps that would have worked better. I was too busy getting my game working to worry about it, fps was reasonable I was just being greedy , even 1 fps would have been worth it I have a Nvidia Geforce 660 GTX now rather than my older 260, but things still struggle more than I would have thought. Maybe my old Q6600 is starting to struggle with some aspects of Reloaded possibly. It should cope though to be honest The 660 was certainly not the boost I imagined it would be, although it was a boost non the less

It may be with more time it would have shown performance boosts, but from the first test I figured, hmm, not looking good, lol. Mainly because I remember the old DB days of doing the same to little effect. I have seen people who have had great success though, so maybe it was just me being too quick to move on.

I'm surprised they haven't got a speed boost from quads, as I know from tests in DB that the plugin for DB helps maintain a lot of performance. I'm sure I may have made something half decent (half decent to look at, the ai would have been dreadful ), if I hadn't moved to AGK very shortly after. I think that it used quads, not sure, but whatever it did, it made a great difference to rendering speed! It will be nice to see proper occlusion implemented, as whatever we do with Lua, it is not going to be as fast as TGC can do with C++ in the main engine.

We as users can only twiddle so much. My twiddling didn't amount to much, but that is not to say yours will end up the same. If you or smallg, or anyone makes a script that will give better performance I and I am sure many will gladly use it! You never know we might give TGC some ideas they can improve on within the engine



SPECS: Q6600 CPU. Nvidia 260GTX. 8 Gig Memory. Win 7.
tomjscott
User Banned
Posted: 10th Jun 2014 22:20
Quote: "If you or smallg, or anyone makes a script that will give better performance I and I am sure many will gladly use it! You never know we might give TGC some ideas they can improve on within the engine "


Well, right now I can't use this at all because of the problem with the engine bombing on too many scripts, which has me really worried that I'll see this eventually anyway when my level gets more scripts for other purposes. I hope they can confirm this bug quickly and give us another hotifx. This is a pretty serious issue.

The return value I provided in my version was an idea I had while writing it up. Basically, you might called the VisibilityCheck function from a script on an entity that you want to do more things with, but you might not want it to do that extra work if it's not even visible. So if you check the return value then you can exit out and not do any more processing.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
smallg
Community Leader
18
Years of Service
User Offline
Joined: 8th Dec 2005
Location:
Posted: 10th Jun 2014 23:15
so i did a quick test again with the occlusion, here are the screen shots

this is with occlusion active


this is without the occlusion script (roughly the same location)


the level has multiple AI, custom scripts for crafting (which currently like to crash due to this annoying multiple script bug i'm still getting post 1.0071), shops etc - it's my testing area for kobk scripting with a load of objects thrown in for the occlusion test

as u can see the FPS definitely changes

life's one big game

windows vista ultimate

i5 @3.3ghz, 4gb ram, geforce gtx460, directx 11
tomjscott
User Banned
Posted: 10th Jun 2014 23:32 Edited at: 10th Jun 2014 23:33
Quote: "which currently like to crash due to this annoying multiple script bug i'm still getting post 1.0071"




Yes, this is very annoying. It totally trashes my idea for this culling script, which I thought had some promise. I think they need to fix this like immediately and release a hotfix tomorrow. And I'm not joking. This is serious.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 11th Jun 2014 15:58
It works now. The fix is to add the init function in default.lua. I've updated the original code snippets to reflect this. I've tried this out now on my full map. At first I only saw a small increase in fps, but as soon as I left my first area and was out of range, the fps went up by about 20. I'm realizing now that my first area is the big culprit for my fps issue. Probably because I have too many animated trees there. Anyway, this script should give your fps boost. At least it does in my case.

I'll still be working on any ways to improve it or other ways to get an fps boost.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
TattieBoJangle
10
Years of Service
User Offline
Joined: 7th Jan 2014
Location: United Kingdom
Posted: 11th Jun 2014 16:05
Thanks tomjscott much appreciated.





PC SPECS: Windows 8 Pro 64-bit, Intel I7 (PASSMARK 9529) 4GHz CPU, Asus R9 3GB GPU (PASSMARK 6858) 32GB DDR3 MEM (PASSMARK 2842)
BarZaTTacKS
10
Years of Service
User Offline
Joined: 3rd Feb 2014
Location:
Posted: 11th Jun 2014 16:15
Can someone assist me with what is the init function? What does it do? Any research into LUA brings me to what seems to be a different language than what we use here.
PM
tomjscott
User Banned
Posted: 11th Jun 2014 16:19
Quote: "Can someone assist me with what is the init function? What does it do? Any research into LUA brings me to what seems to be a different language than what we use here."


Very simple. The init function is a function that gets called when the entity is first created and then is never called again after that. You can use it to set up some initial things for the entity.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
BarZaTTacKS
10
Years of Service
User Offline
Joined: 3rd Feb 2014
Location:
Posted: 11th Jun 2014 16:38 Edited at: 11th Jun 2014 16:39
Ok so using this will cause the script to only be run once? What is the benefit if any to having a script be called over and over again? Why is a script init and then it is called again in main?
PM
tomjscott
User Banned
Posted: 11th Jun 2014 16:49
Quote: "Ok so using this will cause the script to only be run once? What is the benefit if any to having a script be called over and over again? Why is a script init and then it is called again in main?"


No, the script will still run every frame, but the init function will only execute once. So, the engine is initializing and preparing to run and as it creates entities, their init function gets called. Then once the game starts running, the entity's main function is then called every frame in order to perform updates to that entity. Init is useful for setting initial variables for the entity or doing things like storing off its e value somewhere globally accessible as I've shown people elsewhere.

What is the benefit of calling the script over and over? It is so you can have the entity change over time. It can move around, show or hide depending on what's going on, play or not play its sounds, etc.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 11th Jun 2014 20:27 Edited at: 11th Jun 2014 20:27
Here is a little clarification on my VisibilityCheck function for anyone wondering how the return value can be used. I know at least one person was a little confused on that. In the general case where you are just allowing all newly created entities to use the default.lua script, this would not apply. But in the case where you have special entities that you want to do things within the main function, here is an example of what you could do:







Now, that's not to say that you might want an entity to do something every frame even if it is invisible. If that's the case then just ignore the return value or don't even check it.



So, in the case of a special dynamic entity, you override its main script from default.lua to a special script like you see in the code snippet above. If you don't want to check visibility at all, just remove that line altogether.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
The Tall Man
9
Years of Service
User Offline
Joined: 24th May 2014
Location: Earth
Posted: 11th Jun 2014 22:26
The first thing that comes to my mind is the repeated function calls. Don't know much about LUA, but it seems to me to have a similar paradigm to C++. And in C++, if you want to write high-speed code within a loop and must be fast in real-time, one of the biggest things you can do to increase speed is to eliminate function calls that are within your loops. smallg's script did it all in one function, without hundreds of function calls per frame (it was just the one). Another thing to be mindful of is the way loop counting is handled. It's best to count down to 0 rather than counting up. Counting up always checks against a data threshold, whereas counting down checks a hard 0. The CPU even has instructions dedicated to that specific function. So it's much faster on the CPU for high-speed loops. I hope LUA passes this ability on to you.

One thing you might consider is that if you're game/area is basically on the same Y level, eliminate the Y portion of your distance calculation.

An idea also is to find a way to check only entities that are already near your distance threshold, thus likely to require a transition between Show<-->Hide.

But the ideal way to do it performance-wise is to use zones, as Tom I see you're moving in that direction. If you can assign (before runtime) static objects to an area zone, not by position, but by visibility from within that zone. Then whenever the player enters that zone, show all objects within it, hide all others. When the player leaves the zone, reverse the process. Only do the hide/show just once, when the Player makes the transition across the zone boundary. This way it's all handled in one frame, not every frame. And distance calculations are never needed at all. This paradigm only applies to objects that stay in one place.

I did something similar to this zone type of occlusion system in DarkGDK a few months ago and it works great! I used an additional occlusion flag that was separate from the regular show/hide flag. This way the occlusion system doesn't interfere with other processes that require show/hide.
PM
tomjscott
User Banned
Posted: 11th Jun 2014 22:43
The script actually works quite well as-is so far. Although I definitely want to improve it. I've seen very good fps increase thus far.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
The Tall Man
9
Years of Service
User Offline
Joined: 24th May 2014
Location: Earth
Posted: 11th Jun 2014 22:46
Oh - so adding that Init thing solved your problem with its speed?
PM
tomjscott
User Banned
Posted: 11th Jun 2014 22:50
Quote: "Oh - so adding that Init thing solved your problem with its speed?"


The init function prevented it from crashing. I couldn't even test it before. But since I've gotten it running, I saw a 20 fps increase outside my main zone, which seems to suffer from fps issues mainly due to too many animated trees. But once it hides those objects, my fps went up by 20. So it works essentially. The extra function calls didn't hurt, it helped.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
The Tall Man
9
Years of Service
User Offline
Joined: 24th May 2014
Location: Earth
Posted: 11th Jun 2014 22:52
Cool!
PM
tomjscott
User Banned
Posted: 11th Jun 2014 22:53
that's not to say that I don't want to reduce the number of function calls. I'll work on my zone concept next, but maybe not before the competition ends. I need to get that working first. And with this change alone it'll help me enough to get by for now.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
The Tall Man
9
Years of Service
User Offline
Joined: 24th May 2014
Location: Earth
Posted: 11th Jun 2014 23:22 Edited at: 11th Jun 2014 23:24
Wow that's right, the competition ends in just a few days, doesn't it? I guess they didn't extend the deadline this time.



Well the idea about using a zone in this context couldn't be a total system, so much as to deal with a specific problem area or two where it would be needed. It's Lee's job to make it work automatically for every portion of the map (as his development priorities permit).



A debugging idea I just had though... To find slow scripting areas, commands, or function calls, you could (assuming LUA lets you do this) set up a key that will disable a script or script portion. It would disable it whenever that key was down, and you could watch its effect on your frame rate.
PM
tomjscott
User Banned
Posted: 11th Jun 2014 23:42
True. If the engine did better with occlusion culling then we wouldn't have this issue to deal with. For example, objects occluded by terrain should be eliminated from the rendering pipeline and so forth. Maybe all these solutions will eventually not be needed. I sure hope so.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
The Tall Man
9
Years of Service
User Offline
Joined: 24th May 2014
Location: Earth
Posted: 11th Jun 2014 23:48 Edited at: 12th Jun 2014 00:04
Actually I don't think this (or many other engines) do this type of occlusion at all. I first noticed the issue about 15 years ago while playing a commercial game. To me, it was unthinkable that this issue wasn't addressed and solved 20 years ago and present in the core of everything, for it is so basic and goes without saying.
PM
tomjscott
User Banned
Posted: 11th Jun 2014 23:55
Quote: "Actually I don't think this (or many other engines) do this type of occlusion at all. "


All AAA engines do. I assure you. There are actually OpenGL functions specifically for occlusion culling checks to eliminate things from the pipeline because they are occluded by other objects or terrain. I'm sure DirectX must have something similar.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007
tomjscott
User Banned
Posted: 12th Jun 2014 04:10
So, I decided I wanted this to work better before proceeding with my entry. I've come up with a new way of doing it that I think will give us the best we can get right now. It involves special zone markers that can have dynamically adjustable visibility ranges, automatically figures out which entities are in which zones, and only does range checking on a per zone basis. This should pretty much be about as good as you can get and still keeping it really simple. I'm working out the code now and if all works out, I'll post new scripts soon.

System Specs: OS - Windows 7 Home Premium 64-bit SP1, CPU - AMD Phenom II X4 945, 3.0Ghz, RAM - 8Gb DDR3, GFX Card - 2048MB NVIDIA GeForce GT 640, FPSC-R Version - Beta 1.007

Login to post a reply

Server time is: 2024-04-25 17:21:41
Your offset time is: 2024-04-25 17:21:41