Jump to content
Sign in to follow this  
Splicer

How and when to use spawn vs execVM.

Recommended Posts

Hi,

I've read in the http://community.bistudio.com/wiki/Category:Scripting_Commands_ArmA2 the info on the commands spawn and execVM.

I understand that execVM is used to call and run a script.

I read somewhere that if a script will be used/called many times it is advisable to compile the script and store/cache it in memory so the engine doesn't have to access the hard drive every time such script is to be run, in turn increasing game efficiency and performance.

I searched in the forum for an example of the use of the spawn command (in layman terms), but I only found threads about spawning units/objects/etc.

I would be extremely grateful if anybody could explain to me how to use the spawn command (vs execVM) with a simple example/case.

Thank you much in advance. Splicer.

Share this post


Link to post
Share on other sites

Spawn and execvm are exactly the same thing. Spawn takes the code directly and execvm takes an external file from it read the code.

If you are going to call a script many times, do this:

myStuff = compile preprocessfile "script.sqf";

Then you can call that script with:

call myStuff

That way the engine doesnt need to read and compile the script each time, as it's already loaded in the myStuff variable.

  • Like 1

Share this post


Link to post
Share on other sites

call myStuff

Hi shk,

Thanks much for explaining this to me! :notworthy:

One more question if you don't mind.

If the script needs to be fed with data (e.g., and array such as [value1, value2, etc.], should the data be contained between "call" and "myStuff"?

Or is there another command (instead of "call") that should be used?

Again, thank you so much shk!

Best, Splicer.

Share this post


Link to post
Share on other sites

Hi,

The same way you would call the script:

[parameters list] execVM "script.sqf";

or

[parameters list] call myStuff;

Cheers

Share this post


Link to post
Share on other sites

dataReturned = [datagiven1,given2] call myStuff;

Spawn can also be used to execute myStuff. Difference between spawn and call is that spawn starts a new thread, which runs besides the main game thread, thus not interrupting game flow and call in run in the one that it's called from. If call is run on the main thread (init.sqf, triggers, eventhandlers etc), it can not contain any waituntil/sleep etc which would stop the game. Call can sleep if it's used within a child thread (execvm, spawn).

Edited by Shuko

Share this post


Link to post
Share on other sites
Spawn and execvm are exactly the same thing.

Spawn can be used on internal functions. For example, you can have a dozen functions in a single sqf file running dozens instances of these functions using spawn. With execVM and sqf, you'd have a dozen files instead.

The difference between call and spawn is easy: call goes through your code line by line (ie it doesnt continue with what is after call until what is within call is done), spawn make a new instance and continues with what is after spawn in paralell with what is within spawn.

Share this post


Link to post
Share on other sites

Hi guys,

Super! Your explanation/examples make this crystal clear!

THANK YOU SO MUCH!!! :yay:

My best, Splicer.

Share this post


Link to post
Share on other sites
Spawn can also be used to execute myStuff. Difference between spawn and call is that spawn starts a new thread, which runs besides the main game thread, thus not interrupting game flow. Call on the other hand is run on the main thread, which means it can not contain any waituntil/sleep etc which would stop the game.

This isn't quite correct. Call simply executes the code 'in-line' with the current thread. waituntil/sleep etc are all perfectly possible inside called code as long as the calling context is a thread in its own right and interruptable. Some contexts are not interruptable (event-handlers for example).

Spawn creates a new (and interruptable) thread in its own right.

Share this post


Link to post
Share on other sites

a spawned script will run at the same time as the script that spawned it

a script will stop and wait till the called script is finished.

so if you need input into a script use call , if you want something to happen while

your script is running use spawn

ie

script telling unit to goto somewhere , new script telling unit to setdamage to 0 , you would use spawn

script wanting to tell a unit to go somewhere , new script to find that unit you would use call.

i dont know if that will make sence to you if not i can go into more detail...

Share this post


Link to post
Share on other sites
a spawned script will run at the same time as the script that spawned it

a script will stop and wait till the called script is finished.

so if you need input into a script use call , if you want something to happen while

your script is running use spawn

ie

script telling unit to goto somewhere , new script telling unit to setdamage to 0 , you would use spawn

script wanting to tell a unit to go somewhere , new script to find that unit you would use call.

i dont know if that will make sence to you if not i can go into more detail...

Hi ZoneKiller,

If I understand your examples correctly, one could say that spawn is to be used when the output of one of the 2 scripts does not depend on the other script to be done first (i.e., your example #1).

On the other hand, when the input of a script depends on the result of another script (i.e., your example #2), in such case the call command is to be used.

If the above is correct, then it's not clear to me why one couldn't use spawn for example #2. All that would happen is that the script would remain in memory idle until the AI reached its final destination to then be able to obtain its position.

Is this correct?

Thanks. Splicer.

Share this post


Link to post
Share on other sites

well you do understand it almost rig

using call

1st script

_man = _this select 0;

_man move getpos airport;

waituntil {_man distance airport < 100};

_plane = [airport] call maketheplane;

----script will wait here till the script that makes the plane has been finished ------

----if you used spawn the script would not wait and by now would be asking what F#$%i plane----

_man moveindriver _plane;

_man move flytosomewhere;

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

maketheplane script

_aiprort = _this select 0;

_plane = "A10" createVehicle position _airport;

_plane

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

Share this post


Link to post
Share on other sites

Did you already read this? http://community.bistudio.com/wiki/Function

Just one correction Zone: execVM will always spawn a new thread.

Use execVM for general scripts. It creates a seperate thread outside the game's main thread. You can also use execVM again within that script/thread to spawn another thread.

Use call for simple or constantly repeated functions. Usually, you will store the code in a variable (memory) ahead of time if it is high-priority code (rather than reading from file every time). A call can be used in the main game thread, but has the restriction of not using sleep.

Use spawn only when you need to execute code in a parallel thread that doesn't warrant a script of it's own.

Share this post


Link to post
Share on other sites

An important thing to note when using call is that the function cannot be interrupted - you can't you sleep or waitUntil.

_code =
{
    hint "1";
    sleep 1;
    hint "2";
};

call _code; //error

spawn _code; //works fine

Share this post


Link to post
Share on other sites

Deadfast- that isn't strictly correct. The restriction on sleep/waituntil is only present if the original execution context does not allow blocking. (Eg, event-handler, trigger, init-code etc.)

This code is completely legal....

pause={sleep 10;} ;

callingFunction ={

player sidechat format["before pause %1",time] ;

call pause;

player sidechat format["after pause %1",time] ;

} ;

[] spawn { call callingFunction;} ;

Share this post


Link to post
Share on other sites

lol, sbsmac... change your example to this...

pause={sleep 10;} ;

callingFunction ={
player sidechat format["before pause %1",time] ;
call pause;
player sidechat format["after pause %1",time] ;
};

call callingFunction;

[] spawn { call callingFunction;} ; 

...and your illustrating the exact same thing Deadfast's post illustrates.

If one sticks with the text from your first post (which was bang on) and Deadfast's code snippet that pretty much illustrates the call, spawn/execVM situation very well don't you think?

Share this post


Link to post
Share on other sites

Synide - I think you are missing the point I was trying to make. :) There is absolutely nothing inherent about 'call' that prevents you using sleep/waituntil inside it. Both deadfasts and your modified code above don't really illustrate anything because if called from a previously spawned context they will both work just fine !

A lot of people seem to think you can't _ever_ put a sleep statement inside a 'called' piece of code (regardless of context) - this just isn't correct.

Share this post


Link to post
Share on other sites

thats true... but you are not putting a sleep inside a call... your putting a sleep inside a spawn... it's irrelevant that inside the spawn you happen to be enclosing the sleep additionally within a 'call' piece of code. The salient point is that you HAD to wrap the sleep within a spawned thread context.

As I said, your first post was bang on the money with the description. Your just confusing noobs by adding the extra information.

Edited by Synide

Share this post


Link to post
Share on other sites

..which is precisely why I was pointing out the distinction between context and lexical scope.

There seem to be some people who believe that

pause={sleep 10;} ;

[] spawn {call pause;} ;

is invalid because, quote, "you can't use sleep inside called code"

Edited by sbsmac

Share this post


Link to post
Share on other sites

omg, I thought that execVM stores a compiled variant of the script somewhere in engine's cache memory in order not to compile it again..... I was wrong?

Share this post


Link to post
Share on other sites

Yes, you happen to be wrong. You can actually edit a script file (if you are working on an unpacked mission) mid-game and the next time it executes, it will use the changed code.

Also, I am with sbsmac on this one. A call can be used within the main game thread or, more often than not, within a child thread created by execVM or sometimes spawn. It inherits any limitations of the thread it was used from. Having said that, you wouldn't normally put a sleep within a call because it's meant for quick functions. It is was a complicated function you may want to use execVM with a script handle that can be used with scriptDone or spawn for the code while the main function uses waitUntil on a variable until is it !isNil or true.

Share this post


Link to post
Share on other sites

mac and tcp are both correct. I was too focused on init.sqf when replying, thus my post was not fully accurate.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×