I got a review!!
Herminio S 14 July 2014
A good extension that needs better commenting.
Gave it a weekend of implementing, and was disappointed the performance wasn't much different. I'm guessing its because I implemented it into a complex 2D platforming engine, rather than just using it for basic collision checks.
In my platforming code wherever I used: instance_place, place_meeting, collision_line or collision point, I replaced them with SGS versions of them, making sure that my platforming still worked as intended. The game functioned correct but the performance practically stayed the same...
I'm not factoring that^ into my score since it could have been my implementing.
But this is a universal critique: The API could use better commenting. The only reason I implemented this is because I copied the example file, but maybe the reason I had no luck with it is because I didn't actually KNOW how anything really worked, or the relations between the scripts. I studied it to the best of my ability and kind of assumed how things worked...A PDF would have helped.
As a result I updated the system with a new example callback script, fixed the docu-comments and added a READ_ME script
Herminio, PM me if you have troubles, maybe your setup is not right or maybe your original game did not needs sgs... or maybe you still have the original collision events in there
New readme script added
TMC_SGS works to improve the collision speed from Studio's default collision system.
You need to be aware of how things work to allow for a proper porting from Studio's collision event to the TMC_SGS system.
first in a controller object, you create a sgs field
on room_start or create:
global.ai_sgs_field = sgs_field_create(sgs_demo_obj_ai,256);where sgs_demo_obj_ai is the target object, can be a parent or a specific object
where 256 is the size of the grid cells for the room, this value should be twice as large as your largest object and big enough the encompass the target object speed. having this too small may cause skipping, lag the system or even fail if the number of generated cells is too enormous, for example if your room is 100000x1000000 and your cell size is 32, that would make 9765625 cells, and will fail to allocate the grid at worst, or hang the system at best
Do this for every collision types you wish to convert to, using another global for each types, ultimately you may use parenting and only have one field, it's up to you. You can segregate the object type either in the collision_check function or the collision event callback script later.
global.ai1_sgs_field = sgs_field_create(sgs_demo_obj_ai2,256);
global.ai2_sgs_field = sgs_field_create(sgs_demo_obj_ai3,413);
global.ai3_sgs_field = sgs_field_create(sgs_demo_obj_ai4,128);or
global.all_ais_sgs_field = sgs_field_create(sgs_demo_obj_ai_parent_obj,256);Note that having multiple fields you can set the cell size to different values depending on the circumstances.
if the cell size is too large, like the same size as the room, then well then the system will act in a manner similar to Studio's collision system and give no benefits
Second you need an initial step iteration, you call this after you create the field and every step or end step after that:
sgs_step(global.ai_sgs_field,(1000000/room_speed) * frameskip);where global.ai_sgs_field is the field you created and frameskip is the number of frames to skip, it is a good idea to allow frame skipping so the system does not bog down the cpu calculating the field content each step especially if not running under YYC
Do this for every field you created...
sgs_step(global.ai1_sgs_field,(1000000/room_speed) * 4);
sgs_step(global.ai2_sgs_field,(1000000/room_speed) * 6);
sgs_step(global.ai3_sgs_field,(1000000/room_speed) * 8);or
sgs_step(global.all_ais_sgs_field,(1000000/room_speed) * frameskip);Your cell size and the frameskip act together to limit the cpu processing and so you have to take the object size, speed and the frameskip into consideration. for example if your object is 200x200 and travels at 100 in speed (unlikely) and your framskip is 6, meaning it fills the cells every 6 frames, then your object may have traveled 600 pixels and so your cell size should be 600+200....
You have to test and tweak until you are satisfied there is no skipping in collision and the framerate is optimal. Be sure to have a debug output for fps_real and tweak until it is the largest value
Note that having multiple fields you can set the skipping to a different values depending on the circumstances
If you are replacing collision events with SGS:
In your object that has the collision event you wish to replace with sgs, copy the collision event code,
name it obj_collides_with_obj, for example: bullet_collides_with_ship
delete the original collision event, ultimately you can change the event to user event 0 or whatnot to keep the code intact if you want to revert later.
Paste the code in the callback script at the location preferable to your situation, see the script for more details.... and type in the object name or parent object name for the collideswith object you are handling. If your object has multiple collision events, copy and paste the code section to handle all the other object, and nuke the collision events in the object of course.... Or make a new callback event for each collision if you have individual fields...
Now in your object, add a end step event if you did not have one and add the code that will emulate the collision event.
alarm = 1;
}if you have separate field, do this for every field... ultimately you may have multiple collision callback scripts or a single all encompassing script. it is up to you.
If you are replacing a collision function with a sgs equivalent, simply call the script matching the function you want. For the function to work, the sgs field must have the object type in question in the cells of course
//collision point here.
We have tested the event emulation versus the collision functions and tested all collision functions against each other and there is no noticeable difference between sgs_collision_point() and sgs_instance_place() and sgs_place_meeting() and *sgs_collision_event_emu(). (*if the callback performs an early exit.)
sgs_collision_line() is slower than the other functions but still faster than Studio's version, unless the line encompasses the entire room, in which case use studio's collision_line().
sgs_instance_nearest() is much faster than studio's and also has a range value which is usually how you would use the feature. the range is needed to limit the search in the affected cells. DO NOT USE IT if you do not want to use a range; that is do not call it with a range that makes it look in the entire set of cells in the field. use Studio's version in that case.
Edited by icuurd12b42, 15 July 2014 - 05:26 AM.