Splicer 10 Posted January 6, 2010 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
shuko 59 Posted January 6, 2010 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. 1 Share this post Link to post Share on other sites
Splicer 10 Posted January 6, 2010 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
AliMag 0 Posted January 6, 2010 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
shuko 59 Posted January 6, 2010 (edited) 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 January 8, 2010 by Shuko Share this post Link to post Share on other sites
Murklor 10 Posted January 6, 2010 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
Splicer 10 Posted January 6, 2010 Hi guys, Super! Your explanation/examples make this crystal clear! THANK YOU SO MUCH!!! My best, Splicer. Share this post Link to post Share on other sites
sbsmac 0 Posted January 6, 2010 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
zonekiller 175 Posted January 7, 2010 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
Splicer 10 Posted January 8, 2010 a spawned script will run at the same time as the script that spawned ita 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
zonekiller 175 Posted January 8, 2010 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
tcp 10 Posted January 8, 2010 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
Deadfast 43 Posted January 8, 2010 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
sbsmac 0 Posted January 8, 2010 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
Synide 0 Posted January 8, 2010 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
sbsmac 0 Posted January 8, 2010 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
Synide 0 Posted January 8, 2010 (edited) 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 January 8, 2010 by Synide Share this post Link to post Share on other sites
sbsmac 0 Posted January 8, 2010 (edited) ..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 January 8, 2010 by sbsmac Share this post Link to post Share on other sites
Synide 0 Posted January 8, 2010 lol, yeah ok fair enough... Share this post Link to post Share on other sites
McArcher 0 Posted January 8, 2010 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
tcp 10 Posted January 8, 2010 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
shuko 59 Posted January 8, 2010 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