Author Topic: Building bricks without lag?  (Read 1616 times)

So chainDeleteAll() is pretty self explanatory when you call it on a SimGroup for deletion.

How do you build 2000 bricks without lag though? All the bricks are saved to one file so I have to read it line by line in a for loop. Would I have to store all the lines in an array and then call a function in a schedule loop or is there a better way to do this?
Right now I just loop through all the lines at one time but it loads 2000 bricks so blockland freezes for a little bit while this happens


When you supply a time of zero to the schedule function, the engine will keep processing your code until it's time for the engine to tick. Once the tick is finished and other schedules held from before (I'm unsure of how the engine prioritizes them) have been processed, depending on prioritization, your script will continue.

tl;dr using "zero" for a schedule time makes your code wait until the engine has free time for you. Your "zero-schedule" script will execute as fast as possible without lagging the server.




* Packets are received all throughout the tick but the OS probably holds them in a buffer until Torque signals that it wants the packets.

** This window is for processing schedules that need to run and for processing other events like TCP receive events and other triggers.

** If the engine is spends too much time in the grey field, the server will start to "lag" as the processes of the next tick will be delayed.

As I'm no expert in the design of TGE, this is an educated guess as to how the game works. I really have no idea how the engine prioritizes schedules. The grey field may actually be mixed with the orange and blue fields. Perhaps one day I'll get around to looking at the source and attempt to understand it more.

As you can see, the engine will work on your script (with the "zero-schedules") until the engine has to tick again, after which your "zero-schedule" script will continue.
« Last Edit: July 24, 2013, 09:40:32 PM by Kalphiter² »

When you supply a time of zero to the schedule function, the engine will keep processing your code until it's time for the engine to tick. Once the tick is finished and other schedules held from before (I'm unsure of how the engine prioritizes them) have been processed, depending on prioritization, your script will continue.

tl;dr using "zero" for a schedule time makes your code wait until the engine has free time for you. Your "zero-schedule" script will execute as fast as possible without lagging the server.
Aah, I assumed as much. Thanks for the info.

I mean, Kalphiter's post is correct but it's more technical than necessary. If you think about it, every action you perform within a script takes time for the processor to execute. A while or for loop in Torque will not allow the game to move onto its next logic 'tick' until it has been completed. Therefor, while your 2k bricks are loaded, no other actions are preformed. You experience this as lag. To reduce this lag a common solution is to stagger the loading of the bricks, usually by turning the loop into a function that uses a schedule to recurse. A schedule with timer 0 will call the function again on the next logic tick, so if you load one brick per tick that would take two thousand ticks or approximately (assuming Kalphiter's diagram is correct) 62.5 seconds to load a 2,000 brick build. If you loaded ten bricks per tick it would take two hundred ticks or approximately 6.25 seconds to load.

A schedule with timer 0 will call the function again on the next logic tick, so if you load one brick per tick that would take two thousand ticks or approximately (assuming Kalphiter's diagram is correct) 62.5 seconds to load a 2,000 brick build. If you loaded ten bricks per tick it would take two hundred ticks or approximately 6.25 seconds to load.
Using a zero-schedule will keep calling the function but will pause when necessary.

i would advise loading the file to an array via zero duration schedule then construct the bricks with another zero length schedule

i did this once: i had a script that would build cubes and walls and lines and basic square shapes and stuff and i had major lag because i was trying to run the building commands instantly; the fix was to construct an array with all the commands within it then run them on a schedule with a little parser that called all the right functions.
you know, move the temp brick in a direction and plant a brick and whatnot

so yeah, arrays arrays arrays because ram is faster than file io

i would advise loading the file to an array via zero duration schedule then construct the bricks with another zero length schedule

i did this once: i had a script that would build cubes and walls and lines and basic square shapes and stuff and i had major lag because i was trying to run the building commands instantly; the fix was to construct an array with all the commands within it then run them on a schedule with a little parser that called all the right functions.
you know, move the temp brick in a direction and plant a brick and whatnot

so yeah, arrays arrays arrays because ram is faster than file io
Begin-to-start latency will be about the same no matter how you do it.

I would load the save into memory first anyway so as to avoid making the file unmovable.

Begin-to-start latency will be about the same no matter how you do it.

I would load the save into memory first anyway so as to avoid making the file unmovable.
yeah but it won't lock anything up doing it my way (your way?) right? so it's better

yeah but it won't lock anything up doing it my way (your way?) right? so it's better
It doesn't matter. Both will take about the same time.

Any way to return the brick that's created from the schedule or do I have to call a separate function that will actually make the brick and place it in the array that holds all my bricks?

Any way to return the brick that's created from the schedule
You cannot do that. You would be trying to get the return out of a function that hasn't even happened yet.

I'm not experienced in brick loading so I have no idea how one handles overlap issues. You'll probably need to make a new list of bricks because some may fail to load.

Any way to return the brick that's created from the schedule or do I have to call a separate function that will actually make the brick and place it in the array that holds all my bricks?

Code: [Select]
function loadNextBrick(%arrayPos, %arrayLen) {
    %brickData = parseBrickData(%arrayPos); // imaginary function
    %brick = new fxDTSBrick() { dataBlock = getField(%brickData,0); position = getField(%brickData,1); etc };
    $returnBrick = $returnBrick @ "\t" @ %brick;
    if(%arrayPos++ < %arrayLen)
        schedule(0, 0, loadNextBrick, %arrayPos, %arrayLen);
    return $returnBrick;
}

Code: [Select]
$brickArray = parseLoad("saves/whatever.bls"); //imaginary function
%idx = 15;
%brickIdAtIdx = getField(loadNextBrick(0, getFieldCount($brickArray)), %idx);

That's really the best way I can think of doing it.