TECHNICAL QUESTION: Using a VOID function vs ExecuteScript?

Hi All,

A question for all those out there that may be able to explain the pros and cons of using either of these methods to fire some code. i.e. I have many scripts that either use a void function call to do something, but sometimes I have also used the ExecuteScript function to do something instead.

In my own experience, I have found that sometimes I have had to use ExecuteScript because the void function with the same code did not fire as expected.

So basically, what’s the difference?

Does one take more resources, or is it more prioritised?

Thanks in advance, Lance.

1 Like

My experience is with NWN, not NWN2, so I may be off-base. These are fundamentally different. The void function call is still within the script or its compiled includes. The ExecuteScript runs a completely different script, unrelated to the script calling it.
So, if the function you want to run is in the script you are running or its includes, using the declared function call (whether it is a void or a returned variable) is best.
If the functions you want to run are not related to the script calling it, use ExecuteScript with the appropriate object calling it. Hope that helps?

Hi Mannast,

Thanks for responding. :slight_smile:

It’s similar in NWN2 … However, I have found some code calls simply will not run from a Void function call (even when all includes are in place), and had to resort to a ExecuteScript call instead.

That difference made me wonder what else may be going on. I guess the ExecuteScript is just more intendant and (perhaps?) more likely to fire in a tight spot? Resources, etc?

Cheers, Lance.


Do you have any examples of included functions that don’t call correctly? Maybe there’s something else going on. Calling an included function vs using ExecuteScript are pretty similar, just as mentioned above, except for where the called function resides. But NWscript does have its idiosyncrasies.

Are you sure they don’t run? I think I had to resort to ExecuteScript for timing issue (as in the function call was complete too early, as opposed to ExecuteScript only firing when called).
It’s been a long time, so I may mix things up there though.

Hi TG,

I think it may well be this, because the couple of examples I have appeared to be exceptions. Also, it is not that easy to give examples because of the sometimes complicated calls going on. However, the first instance I encountered (and probably the most curious) was when I picked up an item, I wanted to play a VFX on pick up. This was going to be a simple function call, but the VFX would not play unless it was called from an ExecuteScript. (Example below.)

However, this example is from one of my earliest pieces of coding, and so it may well just be something that I did at the time. Yet, iirc, I could not find anything obvious at all.

TIMING may well be the key point here … especially for some of my later scripts. However, the VFX not playing appears strange to me.

E.g. Using item tag switches, when I pick up an item with tag x to fire script x, the VFX inside script x does not play unless it is from a separate ExecuteScript.

Cheers, Lance.

one of the beauties of ExecuteScript() is that the calling script doesn’t need to be recompiled after changes are made to the executed script. (as long as the filename of the executed script stays the same)

what this means, among other things i guess, is that the .ncs of the calling script can remain very small, because it doesn’t need to compile all that extra code into it.

take a hypothetical example that’s going to require a lot of code …

say you want to call DetermineCombatRound() [a big function with a lot of bytecode] from three different places/scripts. You could make DetermineCombatRound() into a void main() function in a script called “dcr.nss”

Then in, say, creatures’ OnPerception, OnHeartbeat, OnDamaged, OnPhysicallyAttacked, etc Ai-scripts, instead of compiling DetermineCombatRound() into each of those .ncs files, just call ExecuteScript(“dcr”, OBJECT_SELF); instead

get it? One big script (dcr.nss) called by any number of much smaller scripts.

but i don’t like doing that since the stacktrace goes out the window …

however, it has been used to good effect by things like Kaedrin’s PrC pack. He basically overrides several module-level eventscripts, but instead of compiling his advanced functions into those scripts he just calls ExecuteScript() to invoke their functionality. This way those module-level eventscripts, once in place, no longer need to be re-edited or re-complied,

ps. you shouldn’t have to use ExecuteScript() … i’d bet that a judiciously placed DelayCommand() [etc] would solve those VFX issues …

pps. ExecuteScript() can also workaround some tmi (too many instructions) issues – but my opinion is that if you’re getting TMIs there’s something else that needs lookin’ at / imho

1 Like

Hi KevL,

I checked for TMI, but never noticed anything. Of course, this may just be some kind of residual issue I was having when I had those sound issues with certain sound files not playing, especially when attached to VFXs.

So, maybe I can revisit those one or two scripts in the near future. However, I have just released v1.17E as a FINAL, yes you heard that correct … a final patch, because my wife just finished her xth play through and I have finished addressing all issues discovered.

Hopefully, I can put that aside now … but come back to it during my work with module 2. :wink:

And, if anybody should discover an issue of course.

Anyway, thanks for the info. :slight_smile:


1 Like

yeh we’ve heard that one before, Lance :wink:

1 Like

Pleeeeease let it be fully fixed now … I’m begging you all! I really don’t want to hear or see another problem with that gigantic effort.

Having done all the hak updates and replayed since many core changes made, this really should be the last fix required …

OK, I know … :frowning: I’ve said it before … but … but … pleeeease!

Cheers, Lance.

PS: Go on, I dare you to find a problem! :wink:

1 Like

move along, nothing to see here, please keep moving along …



I guess I am confused a little as to what situation you need these in. Forgive me if these seem simplistic or annoying. Do you have a specific script you are calling with the ExecuteScript that calls the function you can’t get to work in the main script? Or are you trying a command call with a scriptname and not a function? Or, I guess this might be a possibility, are you trying a function which needs some other type of type in front of it (some are “void” but others return variables and need their “int” , “string” or “float” or the calls fail.) Looks like you got it to work in one way or another, but if there is something we can simplify, I enjoy trying to look at it.

Hi Mannast,

Here is an example of when I had to use ExecuteScript: E.g. Using item tag switches, when I pick up an item with tag x to fire script x, the VFX inside script x does not play unless it is from a separate ExecuteScript. (Full example explained below.)

However, as you say, I have it working anyway … I was just curious as to why I could not get it to work from the same void script. It may be something to do with timing or the way switches work when executing tag based scripting.

By all means you could try to duplicate the issue I was having, but don’t worry too much, or spend unwarranted time, as it is purely academic as I have a solution that works anyway. It’s purely a curiosity on why I needed to do what I did to make it work.

The example expanded (Edited for clarity) …

  1. Create a script called scr_tag_gem that fires when the PC acquires an item.
  2. Create a placeable that when clicked, the PC acquires the item that fires scr_tag_gem.
  3. The script is supposed to play a VFX on the PC that acquires item from clicking placeable object.

Simply having the VFX fire within the scr_tag_gem did not work. I had to use ExecuteScript to fire another script to have the VFX play on the PC that acquired the item after clicking on the placeable object.

But this was some very early scripting I did, and I have not gone back to see if it was something I was doing wrong. However, this is not the only place I used ExecuteScript when I could not get something to fire from a void. It could be that I am missing something obvious.

Cheers, Lance.

Without actually seeing the scripts, I can only guess. My primary thought involves what object is calling the script. For example, the scr_tag_gem script is called by the module. All tag-based scripting are called by the module. So in the script, you need to define the oItem as the GetModuleItemAcquired() which triggered the module to call the event. Related, you define the oPC with the GetModuleItemAcquiredBy() function. So the script may be running fine, but it might not understand where to put the VFX. The ExecuteScript command is independent and you need to define the targets in the new script, so it skips the misunderstanding that the tag-based OnAcquire script is posing. Let me know if this seems to be on point or not. TheKrit had created a Tag-Based script template which setups all the calls needed for any module called event and defines the objects involved.

Hi Mannast,

When I have some time, I will try to put together a couple of scripts (from my own) to demonstrate directly. First, though, I will rewrite the scripts to see if they do work now with the VFX being directly called, as my code has undergone quite a few changes since I first encountered the result. Maybe it works as expected now I have made so many changes.

UPDATE: OK, so now my VFX DOES work as expected (from a void), so I guess my issue may well have been related to the VFX sound files issue I had a short while back. And my other instance where I used ExecuteScript may well be due to the reasons you posted in your last post.

Well, at least that answers that!

Thanks for showing an interest … and making me look over it again.

Cheers, Lance

1 Like