question for pros: wait / wait randomly

The place to discuss scripting and game modifications for X³: Reunion.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

User avatar
euclid
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 13298
Joined: Sun, 15. Feb 04, 20:12
x4

question for pros: wait / wait randomly

Post by euclid » Fri, 20. Jan 06, 01:30

I'm wondering whether some lag/freeze/ctd problems are due to scripts forced to wait.


What I'm trying to say is this:

There are many game scripts necessary to play X3. Some scripts run permanently, some run only when triggered, others only once when starting the game or loading a savegame.

However, only one single script can run at a time.

Therefore scripts contain wait commands which divide in two groups: deterministical like '@wait 20 ms' and statistical like '@wait randomly between 10 ms and 50 ms'.

So if one script is ''waiting'' another script can run until it 'hits' the wait command, which enables another script to continue, and so forth...

In the optimum case there may be intervals where no script is running (all in wait states) and intervals where precisely one script is running (all others are waiting). But, of course, this is not the reality.

Most of the time several scripts are 'awake' and willing to run. But since only one of them can run at a time the others are forced to wait, building up as a ''heap'' over time.

I'm not a computer/software expert so I do not know what this ''forced wait state'' means in terms of game play. However my guess is that it shows as lag and, depending on the size of the ''heap'', can lead to freeze or even ctd.



What do you think?


Cheers Euclid

Cycrow
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 22227
Joined: Sun, 14. Nov 04, 23:26
x4

Post by Cycrow » Fri, 20. Jan 06, 01:45

well, the way scripts work, is pretty much the same as how multi tasking works

waits rn't the only commands that allow other scripts to run, theres various commands that add interupts

any freeze or lag is due to the game engine not updaing quick enough or getting blocked, so even if all scripts were made to wait, the game engine still gets updated and rendered.

its the lack of waits that causes the freezeing, as the engine is trying to process the whole script and cant move on until it hits an interupt

User avatar
euclid
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 13298
Joined: Sun, 15. Feb 04, 20:12
x4

Post by euclid » Fri, 20. Jan 06, 02:03

Cycrow wrote: ........its the lack of waits that causes the freezeing, as the engine is trying to process the whole script and cant move on until it hits an interupt
So essentially you agree?

If my 'hypothesis' is correct then it would make some sense trying to optimize the wait commands in all scripts.

Cheers Euclid

Cycrow
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 22227
Joined: Sun, 14. Nov 04, 23:26
x4

Post by Cycrow » Fri, 20. Jan 06, 02:29

its mainly the while loops that need some waits, so adding interupt points within ur loops can prevent freezing.

User avatar
Burianek
Posts: 2981
Joined: Mon, 29. Dec 03, 03:29
x3tc

Post by Burianek » Fri, 20. Jan 06, 04:57

Generally, the more interrupts and waits you throw into a script, the less likely it is to cause game freezing problems. (because the nicer it will play with its fellow scripts)

When I'm designing a script, I usually like to set some minimum threshold of performance to the script, such that the user won't think it's taking too long. Then I put in as many waits as possible without compromising that minimum level of performance.

Said another way, if the user won't care if it takes 5 seconds or 0.01 seconds for a particular section of code to execute, make it slower. Prevents one script from monopolizing the cpu. If it's important that a piece of code runs quickly, by all means don't put a wait in that section.

Note that loops are really the only place you absolutely need to use waits. Sequential code just isn't going to be long enough to notice any run time. It's only iteration where you can get yourself in trouble.

Cheers.
"Nature's first green is gold" . . . stay golden.

User avatar
Red Spot
Posts: 3461
Joined: Fri, 4. Feb 05, 13:44
x3

Post by Red Spot » Fri, 20. Jan 06, 10:23

initialization scripts (setup/init/al.plugin) -> dont use waits .. these scripts wait for the previous to finish before the next runs ..(make them short and simple)

other scripts -> it cant hurt to put in an extra wait .. (it may not be needed .. and could even make your script 'slow' .. but it cant 'hurt' .. not having them in there could hurt your game much more ..)



G

User avatar
euclid
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 13298
Joined: Sun, 15. Feb 04, 20:12
x4

Post by euclid » Fri, 20. Jan 06, 12:34

Thanks for the input, guys.

Still there are some open questions.


-----------------------------------------------------------
Burianek wrote: Generally, the more interrupts and waits you throw into a script, the less likely it is to cause game freezing problems......
What is the difference between a 'wait' and an 'interrupt' command?
Red Spot wrote: initialization scripts (setup/init/al.plugin) -> dont use waits .. these scripts wait for the previous to finish before the next runs ..
When do they run? If you starting X3 or if you load a savegame? Also what determines the hierarchy (which runs first, second etc..)

-----------------------------------------------------------

What is still unclear to me: What happen if several scripts are not in a wait state (nor interrupted)?

Since only one can run at a time: who/what decides which runs first? What are the others doing (forced wait) during that time?


What you guys said above refers to one script. What I'm trying to find out is the balancing of wait states in each script taking into account all permanently runnig scripts.


Cheers Euclid

Sadjevehzuz
Posts: 3
Joined: Wed, 26. Oct 05, 15:32
x3

Post by Sadjevehzuz » Fri, 20. Jan 06, 14:06

First of I want to say that I'm not an experienced X3 scripter so this might be completely irrelevant.

However from a general programming standpoint:

The X3 engine keeps track of all the running processes (scripts). This is done by a scheduler, there are many
types of schedulers. According to the MSCI handbook X2 uses a scheduling scheme called "cooperative multitasking".
This means that the scheduler can’t interrupt a running process by itself, it has to wait for the running process to
release control, i.e. execute a wait command. It can then look at all the processes currently wanting to execute ("forced wait") and choose one to hand over control to.

So how does it choose which process to hand over control to? Most likely (and this is where the guesswork comes in) it is based on priorities.
The main game processes (graphics rendering, AI, collision detection etc) will have a high priority and if any of them want to execute they are given control. Only if no high priority process wants to execute will control be handed to lower priority processes (scripts), it will then most likely choose the script that has been waiting to execute the longest.

This means (if I’m correct) that there’s no reason to worry about lagging the game by using wait.
However excessive use of wait will lead to a lot of context switches (switches between processes) which of course do take up some cpu time. So its probably not a good idea to place a script like this on every object in the game.


while(true) wait(very short time)
witty text here

Cycrow
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 22227
Joined: Sun, 14. Nov 04, 23:26
x4

Post by Cycrow » Fri, 20. Jan 06, 14:43

waits and interupts r simlar, the main difference, is that a wait will halt the script until the wait time has elapsed, whereas an interupt just lets other scripts run but will return back to that script as soon as the queue is free.

when running multiple scripts, the scripts are put on a stack, the first one on the stack is run until it gets to an inturpt point, then the next one is run, and so on eventually returning back to the interup points to run the rest of the scripts

you just gotta remember it works the same way as windows does to run multiple programs, althou it appears you running ltos of programs, windows is only ever processing one program at a time
it just breaks the programs into blocks and process small chunks at a time to make it appear that multiple programs are running

User avatar
Red Spot
Posts: 3461
Joined: Fri, 4. Feb 05, 13:44
x3

Post by Red Spot » Fri, 20. Jan 06, 16:22

euclid wrote:
Red Spot wrote: initialization scripts (setup/init/al.plugin) -> dont use waits .. these scripts wait for the previous to finish before the next runs ..
When do they run? If you starting X3 or if you load a savegame? Also what determines the hierarchy (which runs first, second etc..)

they run when you start/load a game .. each and every time ..

what the exact hierarchy is I dont know ..
afaik it starts with the 'init....' onces (wich we should never need to use .. :!: )
than the 'setup....' and 'al.plugin.....' onces but wich of the 2 comes first I dont know (doesnt really matter anyway)
the hierarchy within the 'group' is alfabetical order .. (you wanna mess up your custom commands .. install a script called "setup.AAAAAA" and make it a never ending loop ... :roll: ......)

and as these type of scripts are there to set things up they should be able to run at the start of a game .. (not 5 minutes in game .. or so)
so you should take care to make your setup/al.plugin script runs quickly so any other setup/al.plugin script can be run ..

if you do feel the need your setup scripts needs to do much wich you cant 'rush' .. than you could run a script on 'null' (I pers. however try to avoid this as I have nothing to 'simply' interfear with that task once it runs)


G

Naffarin
Posts: 481
Joined: Sat, 3. Dec 05, 09:49
x3

Post by Naffarin » Fri, 20. Jan 06, 16:26

Red Spot wrote: if you do feel the need your setup scripts needs to do much wich you cant 'rush' .. than you could run a script on 'null' (I pers. however try to avoid this as I have nothing to 'simply' interfear with that task once it runs)


G
You can delete it by pressing del in the list of global tasks in the script console, but not much help in the scripting engine, that's true

User avatar
nuclear_eclipse
Posts: 1129
Joined: Thu, 2. Sep 04, 01:54
x3tc

Post by nuclear_eclipse » Fri, 20. Jan 06, 18:47

Scripts in X3 function almost exactly like multi-threaded Java programs, which also run on the 'cooperative multitasking' methodology (although the Java Runtime Environment actually uses cooperative forms for multiple threads of a single program and forced form between multiple Java programs).

One thing to always keep in mind is that the '@=wait XX ms' command has one major property, as with all high-level languages. The wait command will halt execution for AT LEAST xx milliseconds. It's quite possible for the script to request a 1ms wait and not receive execution again until at least 20ms or so due to the number of scripts on the stack.

The execution wait period is never guaranteed for anythin except a minimum wait period, and your script should NEVER rely on waiting for that minimum time. However, the accuracy of waits will increase as the length of the wait increases, but that is simply because by the time the wait expires, the script has longer time to reach the top of the execution stack, so has a better chance of being called again once the wait period expires.

In all, the only true way to wait for an EXACT period of time is to write a program in assembly language and have that runas the only program on the CPU. Only then can you guarantee an exact wait period, as you have total controll over processor flow. Since X3 scripts are about as far away from this situation as possible, the best we can ever hope for is a minimum wait time.

---

@wait xx ms - vs - @wait randomly between xx and yy ms

Based on the type of system we are working with, the only true reason to use the random form is to add a bit of 'natural' feel to the script if it is being used closely by the user. So if you want something to happen every so often, but not on a exact schedule, use the random wait. Otherwise, just use a normal wait. It's less taxing on the processor (no random # generating all the time) and it makes your script much more predictable.

---

As for how to waits to keep the engine running smoothly, I have found that at least having a 1ms wait for every 10 lines of code helps to keep my system running more smoothly, but this is only noticeable when there is a LOT of scripts on the stack that are constant-running scripts.

In general, I use a 10ms wait if I am just sticking a wait in to break up a piece of code. If I'm waiting on something to happen in the universe, like a ship docking, hotkey press, etc, I at least use a 80-100ms wait, as a tenth of a second seems instantaneous enough to most users. If the waiting routine is even less necessary, such as a background task,I will sometimes use 500ms waits or longer, depending on how important the task is.

---

I would basically say that as long as you have any sort of wait in your program, especially during loops, you will be just fine. I sincerely doubt that the use (or misuse) of waits really causes any of the bugs with autopilot or such. I personally think that is something based on the engine code itself.

User avatar
Burianek
Posts: 2981
Joined: Mon, 29. Dec 03, 03:29
x3tc

Post by Burianek » Sat, 21. Jan 06, 02:08

nuclear_eclipse wrote:@wait xx ms - vs - @wait randomly between xx and yy ms

Based on the type of system we are working with, the only true reason to use the random form is to add a bit of 'natural' feel to the script if it is being used closely by the user. So if you want something to happen every so often, but not on a exact schedule, use the random wait. Otherwise, just use a normal wait. It's less taxing on the processor (no random # generating all the time) and it makes your script much more predictable.
The only caveat I'd add to this is if you have a bunch of scripts that initialize and start some loop upon game load or some such, you might want to use wait random. If you use the regular wait, you might get multiple instances of the same script all trying to execute at the same moment every time the loop completes. It's probably better to let these stagger, so using random waits will distribute execution evenly over time.

(does that make sense? don't feel like I explained that very well)
"Nature's first green is gold" . . . stay golden.

User avatar
euclid
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 13298
Joined: Sun, 15. Feb 04, 20:12
x4

Post by euclid » Sat, 21. Jan 06, 04:38

Nuclear_eclipse, that was very interesting, thanks for the briefing.

So there is a chance that stacked scripts cause lag.

I'm not saying that bugs like the auto pilot are related to that. But what makes some sense to me (now) is that the amount of lag (or smootheness) varies with the savegame.

For example Ore Belt. I always had heavy lag there but at one stage I've decided to save there, fought a battle and died. Reloaded and the lag was almost gone.

We know that the savegame contains also the scripts and one would expect that they are precisely in the state when the game was saved. However it seems that saving a game and reloading reshuffles the 'stack' .

Does this make sense?

I think there is an issue here. It should be possible to optimize the wait commands in a hollistic way (taken into account all running scripts).

Burianek is right in saying ....
.....if you have a bunch of scripts that initialize and start some loop upon game load or some such, you might want to use wait random. If you use the regular wait, you might get multiple instances of the same script all trying to execute at the same moment every time the loop completes. It's probably better to let these stagger, so using random waits will distribute execution evenly over time.
That is one general rule of optimizing the smootheness of the game play.

Cheers Euclid

User avatar
moggy2
Posts: 5505
Joined: Wed, 6. Nov 02, 20:31
x3ap

Post by moggy2 » Sat, 21. Jan 06, 06:25

it should be noted that certain events can cause waits to end prematurely.

For example, in X2 I noticed that the player changing sectors would cause this, as would viewing the trade menu(d) of a player owned station. In these cases, a script continued as though it had completed it's wait.

I suspect, though I haven't checked, that loading the game has a similar effect.

AalaarDB
Posts: 2282
Joined: Thu, 29. Jan 04, 08:19
x3tc

Post by AalaarDB » Sat, 21. Jan 06, 09:34

Loading the game does not make the AL plugin time end prematurely. I am unsure about scripts.

User avatar
nuclear_eclipse
Posts: 1129
Joined: Thu, 2. Sep 04, 01:54
x3tc

Post by nuclear_eclipse » Sat, 21. Jan 06, 16:32

Well, I do know that some of my 90 second waits in the Syndicate campaign scripts do NOT end prematurely due to saving, as I have done that a few times. I would think they should have fixed an issue like that in X3 vs X2...

User avatar
Burianek
Posts: 2981
Joined: Mon, 29. Dec 03, 03:29
x3tc

Post by Burianek » Sat, 21. Jan 06, 21:05

moggy2 wrote:it should be noted that certain events can cause waits to end prematurely.

For example, in X2 I noticed that the player changing sectors would cause this, as would viewing the trade menu(d) of a player owned station. In these cases, a script continued as though it had completed it's wait.

I suspect, though I haven't checked, that loading the game has a similar effect.
This is correct. Simply selecting a ship that is currently running a wait command and going into the command console can abort a currently running wait. (I think) At any rate, you should plan that regular wait commands can and will get interrupted. If you want to make sure that your waits are never interrupted, it's easy, do this:

Code: Select all

021   $wait.time =  = random value from 480000 to 600000 - 1
022   while $wait.time > 0
023 @  $wait.time = wait $wait.time ms
024   end
you wrap the wait in a while loop. the return value of a wait command is the current amount of time left in the wait at the time of interruption (or completion). So if it gets interrupted prematurely, the while loop will restart the wait command with the remaining amount of time.
Cheers.

Oh and to answer the last two posts, loading / saving is NOT one of the tihings that will trigger an interrupt in waits. It has more to do with other commands being executed on an object, which really is only done if the player selects them or some such.
"Nature's first green is gold" . . . stay golden.

User avatar
Red Spot
Posts: 3461
Joined: Fri, 4. Feb 05, 13:44
x3

Post by Red Spot » Mon, 27. Feb 06, 16:09

wasnt sure about this before ..

but the priority in wich initialization scripts run is;
-init....
-setup....
-al.plugin...

(meaning you could do some sort of 'pre-setup' for your plugin in a setup-script .....)


G

Rheinlander
Posts: 126
Joined: Sat, 4. Mar 06, 07:51
x4

Post by Rheinlander » Fri, 10. Mar 06, 04:41

Just as an aside regarding the ore belt lag euclid had, that sounds more like the game building up a large amount of resources in the cache during play, which degrades performance over time, and then starting fresh with a clean cache and plenty of room to throw resources about. I've experienced it loads of times in loads of games, when performance got choppy when previously it had been smooth, quitting out and reloading the game usually cleared it up.

This thread's a fascinating read, I'm planning on trying to make some scripts in the future and it's good knowing the stuff that's been discussed here.

Post Reply

Return to “X³: Reunion - Scripts and Modding”