Jump to content

Fallout New Vegas GECK & Scripting Help 101


Recommended Posts

Now I got your attention, I know if you are even attempting scripting you aren't really a dummy. It's a matter of experience, if you've done any programming in any language you will pick it up quicker obviously, but in the end computers just do exactly what we tell them too they aren't smarter than people, they can just juggle numbers faster.

 

I'm not a professional programmer, I'm no expert at GECK, but I've poked with it for a few years of pain, so I've created this thread so some of us with a little more experience can share some gems and basic foundations for when writing your first scripts. Or just doing what many of us did when starting, pulling appart or modifing someone elses scripts.

 

There are different formats for things so what I do is not necessarily the way PrideSlayer or Zippy or Astymma would code something there's often more than one right way to do things and of course an infinate number of wrong ways :)

 

Look in the GECK Wiki at http://geck.bethsoft.com/index.php/Main_Page

Also read this thread too http://www.loverslab.com/showthread.php?tid=8808

 

So firstly if you other experienced guys can hopefully placemark a post each at the top of this thread so as we all think of things we can just edit the upper posts and save people wading through pages of discussion.

 

Secondly I'd like to ask the new people to refrain posting questions in this thread unless they are specific technical questions related to GECK usage not "my game is broken" posts and really have looked for answers or at least read the first and last pages of this thread, this is an answers/instructional thread.

 

Firstly install the latest beta of NVSE, it also gives you extra debug commands:

MessageEx and DebugPrint will save you hours of pulling your hair out. They can show you real time in the Console or on screen what variables are doing for integers, floatingpoints and references. Also look into scripts at how we use DebugPrint to show variables, MessageEx works the same but shows them on the game screen, but is a little laggy and will grind things to a halt if fired too often. Because it stays up for around 2 seconds it will get behind if you fire it more often than every 2 seconds. DebugPrint is better overall but needs to be turned on with SetDebug 1

http://nvse.silverlock.org/

 

Then install PrideSlayers NVSE Extender, it gives more advanced commands you may never use, but also fixes a few not working.

http://www.loverslab.com/topic/24656-nvse-extender-aka-nx/

 

Get GECK PowerUp and install it:

Otherwise you are flying Blind for the silliest of errors, it will tell you what type of error and which line it is on 99% of the time, it's not perfect but it's a heap better than just wondering why it won't save.

http://newvegas.nexusmods.com/downloads/file.php?id=41642

The GECK 1 4 PowerUp for Fallout New Vegas -a fork by PurplePigeon

Use this Forked version, NOT the original unforked version which is also somewhere on Nexus, it's out of date.

 

The GECKPowerup beta also allows you to directly edit ESM files, one thing you do have to do with ESM's is go into FNVEdit to delete things properly, GECK just marks them deleted.

After installing GECK PowerUp you need to start GECK from a NVSE Powerup Icon instead of the FNV GECK one, that was my problem for months after I first installed it, It's in the instructions somewhere. I start my GECK from

"D:\Games\SteamApps\common\fallout new vegas\nvse_loader.exe" -editor

instead of the GECK icon

 

Using Notepad find & change the following in your geckcustom.ini

 

bAllowMultipleMasterLoads=0

to

bAllowMultipleMasterLoads=1

 

You can't load any esm except FalloutNV.esm unless the value of this is 1.

 

If you have invisible walls in the World editor for multilevel buildings, you have to disable multibounds in your geckcustom.ini.

Find bUseMultiBounds=1 in the geckcustom.ini and change it to 0.

 

Also You can disable the annoying GECK Spell Checker under edit->enable spell checker.

 

If you run Windows 8.0 you will experience an issue with Conditions in effects being "invisible", they are there, the columns are all minimised and slid to the left, you can pull them out again but they reset every time you open/close an effect window. Windows 8.1 fixes this.

 

Next install FNVEdit and use it to check any new mod or update before uploading it, it will catch a few things GECK might miss telling you.

 

You may also find FNVPlugin useful if you want to merge plugins easily.

 

So I'll start with my ideas on one of the basics, Variables.

 

If you want to share Variables across more than one script then one simple way is to create a Quest called MyModQuestVAR. You don't need to do anything other than tick the StartGame enabled box and hit ok, it doesn't need any dialogue or anything else.

 

Then create a script and call it something like MyModQuestVARScript, use the pull down box at the top to turn it into a Quest Script. In this create any Varibles you want to share across scripts or allow other people to read for other Mods.

 

If the you create variables inside an item or effect it is a seperate brandnew script for each item so when it first starts everything will be zero unless you pull in info from a VAR script. You do this by using the name of the VAR script with the variable. so the following in a script inside a Vertibird would check if the driver was drunk:

if MyModQuestVAR.fAlcoholLevel > 1

;Vertibird shutsdown if driver drunk over 1%

endif
Because in a Beer bottle script you would have something like:

Set MyModQuestVAR.fAlcoholLevel to MyModQuestVAR.fAlcoholLevel + .1 (they are German Beers  )
You should also want to look into NX_Variables using Prideslayers NVSE Extender as they are even better. Not as scary as you think and much more useful as they can be read by any plugin without needing the original plugin as a master. I suggest just learning to use the Set & Get as soon as you can.

 

http://www.loverslab.com/topic/22270-fnv-scripting-nx-variables/

 

If you don't need increments of less then 1 like .1 I would use an int Variable, I have been using shorts because I believed they were the same thing but have just been pointed out as otherwise by Prideslayer below, maybe they're the same in this Script language but they are indeed different in others.

 

Because there are float & integer type variables you have to be careful when they interact because integers will round off all decimal places involved. So what a lot of programmers do is start the Variables with lowercase letters or the whole word int, short, float or global. So fTimer would be a number with about 9 decimal places of accuracy while iTimer or sTimer is a rounded number with no decimal places. Integers just use a little less memory than FloatingPoints, but it's no big deal unless you use a lot of them. Boolleans don't exist in GECK scripting but people may tag them with a "b" such as bGotBigGunFlag which is either 0 or 1, but it would still be created as an int eg int bBigGunFlag.

 

Globals should start with g and are also FloatingPoint you can create them using the top GamePlay Tab > Globals, the main advantage to using Globals is they can be accessed by GECK effects and they don't change Index numbering. So I'd only use them for real important variables that you thought might need to be checked by non-scripted item conditions or other mods. But you can also check Quest Script variables too in Non-Scripted Effect conditions. They can also be read from any mod that has the mod containing them as a master except if you add or delete script variables any mod referencing them will get an Index error and need to resave their scripts, so generally only use them for variables used within the mod.

 

ref Variables are items, Characters etc so I always use an r on the front of them. this helps you notice silly mistakes incase you try and multiply a bullet reference instead of a bullet count into a number. It also helps you spot the difference between Functions(Commands) and Variables. I add a Z to the front of Actors so I use rZPlayer, because then if I want to do a mass replace of stuff to make a Veronica version of a Player Script I just change all the instances of ZPlayer otherwise it will replace other stuff you don't want swapped too like commands with the word Player in them.

 

Never start a Variable with a number or any item you create in GECK like 3MyGun, it only works in 99% of cases, the 1% it doesn't will drive you nuts, ending with a number fMyMagicBeer2 is fine, or f7My3Variable is fine too.

 

If you want to save turning off all those DLC esm's everytime you load in GECK, just delete all the .NAM files from your data folder. They don't do anything, they will replace though if you do a Steam Validate files.

 

You also need to run your mods through FNVEdit regularly too using the Check for Errors function. But it doesn't find all errors, I find PowerUp often finds things the FNVEdit doesn't and FNVEdit often finds things PowerUp doesn't, so a check of both might save a lot of issues. Also if you are working on an ESM, you can only fully delete items in FNVEdit.

Link to comment

 

So firstly if you other experienced guys can placemark a post each at the top of this thread so as we all think of things we can just edit the upper posts and save people wading through pages of discussion.

 

You got it. Not that anyone reads the first post in any of my threads once before posting their question' date=' but I'm willing to keep trying. ;)

 

Now.. lets start arguing!

 

If you don't need increments of less then 1 like .1 I would use a short or int Variable (they are the same thing).

 

I always use floats or ints, never shorts. The less you have to type the better, and using a non-int "alias" in the geck language may lead you down a road to madness if you DO have experience in other languages. Don't expect a short to roll over at 32767 or 65535, it will roll over at 2-billion-something just like a regular signed int.

 

All numeric vars in the geck language are signed (can be negative).

 

I sometimes use hungarian notation as Hal mentions (the prefixes in front of variable names, like 'f' or 's') and other times not, it depends on my mood. I was taught to use so called 'systems hungarian' but have found 'applications hungarian' to be more useful. So you'll often see me using one, both, or neither at the same time. I'm at a transition period in my life.. old habits die hard.. etc. ;)

 

The difference is that you name for usage and functionality, not for actual datatype.

 

http://en.wikipedia.org/wiki/Hungarian_notation#Systems_vs._Applications_Hungarian

 

 

My tips:

 

1. Strive to always put constants on the LEFT. "if (0 == foo)" is preferable to "if (foo == 0)". More important in other languages. Comes from C. The first time you write "if (foo = 0)" when you meant "if (foo == 0)" you'll understand why.

 

2. Use parenthesis judiciously. You can almost never have too many.

 

3. Indent your code consistently. Makes bug hunting easier. Settle on using spaces or tabs (I heavily prefer spaces) and stick to it.

 

4. Declare all your variables at the top. If you declare them all over the place when you need them, you'll eventually regret it. I promise. Variables declared OUTSIDE the BEGIN blocks retain their value between runs, and in save games. Variables declared INSIDE a BEGIN block will be reset to 0 each time the script is run. (I have not thoroughly tested the last statement)

 

5. Make heavy use of the GECK WIKI, and verify what you read there before believing it. It's usually right, but it is occasionally wrong. Be suspicious of any pages that link you to the TES WIKI -- things have changed.

Link to comment

Will reserve a spot here:

 

Tips:

ALL OF WHAT PRIDESLAYER SAID :P

 

When naming variables, try to be consistent. You don't need to adhere to any naming scheme other than what you like but stay consistent with whatever you do choose to use. Personally I'm a Hungarian Camel Caser (int iMyCount, short sTheValue, ref rTheNPC, etc.)

 

Try to be explicit at all times rather than implicit. Assuming that version X treats something one way can burn you when version Y changes the default behavior. A good example is using a function without prefacing it with "Player.". While this may be assumed to be true, it can easily not be true depending on situation. So if you mean to run something on the player, be explicit and say so... never trust implicit compiler/interpreter behavior.

 

Just because you can change something doesn't mean you should. There are tons of globals and gamesettings that can be altered with almost no effort on your part... with horrible side effects and consequences for everyone else. Try to ALWAYS consider what repercussions your changes could have for other scripters and other modders. Always try to remember that your playstyle isn't more or less important than everyone else's playstyle. Be considerate in your choices whenever possible.

 

If you've created a mod and find yourself whining about how many bugs your users complain about and you end up spending a ton of time on support... well, stop putting so many bugs into your mods, hehe. Just remember one word... testing, testing, testing, testing, testing, testing, testing, testing, testing, testing, testing, TESTING. each hour spent testing will eliminate 5+ hours of support. Well worth the time and effort.

 

Document your mod somewhere... maybe not in the scripts themselves (due to size limits), but somewhere. Coming back to a mod you made two years ago can be harder than writing it from scratch, I know this one from experience. The more documentation you have, the easier maintaining a mod will be.

 

Understand the block types and what functions can and should and can't and should NOT be used in each one. You can easily block thread execution with the wrong function and freeze a quest. Always give your code time to actually work. Many functions take longer than 1 pass (1 frame) to run. If in doubt, create stages and allow your script time to breathe.

 

NEVER NEVER NEVER use a local variable in a result script if you plan on it retaining a value. That includes quest stages, dialogue or any other small fragment of code that isn't in a script file. All of these scripts erase their variables after execution. Also, these fragment scripts act on top of other variables, replacing their scope. So if you have global named iMyCount and you declare int iMyCount in a fragment, you are blocking the global and replacing it with your variable while that fragment is running. Whenever possible, avoid using local variables in a fragment unless they're fire and forget variables that do not need to retain any information.

 

More to come...

Link to comment
  • 3 weeks later...
  • 2 weeks later...

True I think it would be great to have a ModdingSection.

Another one from me:

After installing GECK PowerUp you need to start GECK from a NVSE Powerup Icon instead of the FNV GECK one, that was my problem for months after I first installed it, I'ts in the instructions somewhere I start my GECK from
"D:\Games\SteamApps\common\fallout new vegas\nvse_loader.exe" -editor
instead of the GECK icon

Also learn to use these commands to debug
 

MessageEx "MyScript1: Script is running Ok at Point 1"; *** Put variations of this at Start & finish & a few key points in your script so you know if it is working and where it stops



MessageEx "MyScript1: %n's fVariable is at %2.3f" rZActor fMyVariable ; *** This will tell you on the screen what an Actor named rZActor's variable is at at this point in 2 digits to 3 decimal places.

There is also DebugPrint which does the same thing but it appears in the console instead, you get to the Console by the ~ "tilde" squiggle key. You need to turn DebugConsole on for each plugin using it though so you would use
 

SetDebug 1

DebugPrint "MyModNameMyScriptName: Code Running Ok Here, Variable at %3.2f percent" fMyVariable

Oh if you leave that "f" off the end of a DebugPrint or MessageEx variable, you will get slightly annoying CTD everytime it is excecuted :)

Link to comment
  • 3 weeks later...

I have another tip for you all:

 

You can use a quest stage to emulate a synchronous subroutine call.

 

http://geck.bethsoft.com/index.php/SetStage

 

The stage result script will be processed immediately after the SetStage call. The main script containing the SetStage call will be halted until the result script is finished. It is even possible to use the SetStage command inside a stage result script. In this case the new stage result script will run in place of the SetStage command and the old stage result script will continue after the new one has finished. Unlike Activate, it seems that any number of recursive SetStages are allowed (at least 250, tested from the same quest, are possible).

 

Note, however that when you use this approach, you need to create each quest stage twice, in GECK. In other words, first you need to create the stage itself (using right click, New), but then after it exists you need to create the stage again, for the purpose of the stage script. And, of course, you also need to create the quest in the first place. Here's an example of how to make this all happen:

 

First, you need an anonymous quest with repeatable stages, so, select "Quest" under Actor Data in the left panel of GECK's object window. Then right click over the right hand part f the object window and select New. This brings up a quest window.

 

Second, give your quest an ID.

 

You should also select "Allow repeated stages".

 

Hit "Ok" in the lower right and then open the quest up again by double clicking on its new ID in the top of the object window, it now exists!

 

Next go to the Quest Stages tab in your quest window and we will make two quest stages. Quest Stages each need a number between 1 and 255 to identify them. So, for this example:

 

Right click under 'Index' and create a quest stage and give it the number 10

Right click under 'Index' again and create another quest stage and give it the number 20

 

If you were to create a quest stage script right now, you would have problems. GECK problems. That means silent problems that you only notice later.

 

I always close the quest (hit "OK" in lower right corner) and then open it again. I do not know if this step is necessry.

 

Anways, now we need to create the quest stage script. To do that, select the Quest Stages tab again (since it got reset when we closed the quest), and then select quest stage 20. Then, under Quest Stage items, right click and select "New". You have to do this before your quest stage script can exist.

 

Finally, when writing your quest stage script, you click the "Edit" button above the script, and when you are done and have hit "OK" in that edit window, you should "Compile Result" so that the changes happen. You need to be using geck powerup or any quest problems will prevent you from updating the result -- geck powerup will not prevent that but will give you an error message about something you need to fix.

 

Beware that geck powerup messages can appear behind your edit window. And you cannot select your edit window when they appear. So if GECK seems to freeze, try hitting Y a few times to page through the popups. (And then move your edit window so you can see the popups and try again.)

 

Note that quest stage scripts do not have "scn" lines (unlike quest scripts themselves). So any variable declarations in them need to go in the quest script. You also should refer to your quest by name in your stage script when you refer to names defined in your quest script.

 

And, remember to click "ok" on the quest when you are done. (But I do not think anyone will forget this part). You can also cancel out of script editing. (You can also edit directly in the little window that shows you the top of the script, this bypasses GECK powerup's issues with powerup messages being behind the script and seeming to freeze geck.)

 

Note that you need to "Compile Results" or your quest stage changes will not be saved. This will also give you geck powerup messages.

 

Finally, if you are going to use the quest stage as a subroutine, you need to finish the script by changing to a different stage. So, if our quest name was "example", the very last line of the stage script for 20 would be:

 

setstage example 10

 

This is like a "return" statement.

 

Note that 10 should probably not have a stage script.

 

Edit: and remember to test your script in the game! Every time you try something new in your script you should save your plugin and go into the game to test it. If you skip doing this then when you have problems you will have a bunch of different things that you do not fully understand, which makes finding your problems difficult.

Link to comment

How to use Dialogue as a Function:

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

 

Create a new dialogue topic (no need to assign it a quest).

Make sure this topic has NO name text (in FNVEdit the "FULL - Name" field should be blank).

 

Create 1 response for each result of the function that depends on conditionals. Make sure these responses also have no text for the speaker or responder. In the end script of each response put your result script for if the conditional is true.

 

Now, when you want to execute this function you have an NPC force speak the topic to the target using StartConversation.

 

An example would be if you want an NPC to perform an action based on their faction membership.

 

Another example might be a large list of quest variables that would determine an action by the NPC.

 

Another example might be variable actions based on the current quest stage of a quest.

 

Basically this technique works well when you want to do a set of results that are each determined by a condition that qualifies as a dialogue conditional. The advantage of the method is that you can run it against either speaker or target as needed on a wide array of varying conditionals by simply making an NPC speak a topic (no words will even need be spoken unless you want them to which is also an advantage... i.e. you can have your function results be both preceded and followed by dialogue).

 

If you want, the result script for each response can also do another StartConversation and so on so you end up with a multi-tiered function tree.

Link to comment
  • 3 months later...

I just saw mention of the GECK power up thingie in the OP. I had no idea that GECK power up thingie even existed...

 

*Bangs head against desk

 

Lol, I only modded FO3 (out of FO3 and FNV) previously and it's been a longggg time. So the other week I finally bought New Vegas off Steam when it was on sale. I ran into Sexout and got sucked into (just like being gay) making a mod for it.

 

Now I remembered how FO3 would save with like a

 

>=9

 

and then the code wouldn't run because of the bad spacing.

 

But the other day GECK decided it was fine if it saved a script with the wrong amount of endif's. Seriously... It saved with the wrong amount of if's WTF!! With my sloppy coding, I'm not even gonna admit how long it took me to figure out that was why my script wouldn't run. Good thing I'm not a code monkey for a living. I'm way too much of a turkey for that.

Link to comment

I will say flat out, it *really* helps if you do not code your scripts IN the geck. Use some other text editor like vim, ultraedit, whatever.. something with code folding and smart indenting and everything else.

 

Write your scripts in that text editor, then copy/paste them into the geck. This will save you a lot of agitation.

 

I go even a step beyond that now and run a local subversion repository and keep a revision history of all the scripts as text files so when something goes wrong I can go back and run a diff to find out exactly what I changed rather than trying to remember or *shudder* trying to use fnvedit to compare them.

Link to comment

Yeah, I hadn't touched Beth's tesscript games in a while, as lately, I'd been working with Skyrim and gotten used to Papyrus.

 

I'd honestly spent a lot more time on Oblivion than I did on Fallout 3 and its editor isn't as horrid as the GECK. Definitely gonna do my coding outside GECK for New Vegas from now on.

 

Edit:

 

*Starts googling vim and ultraedit.

Link to comment

I'd honestly spent a lot more time on Oblivion than I did on Fallout 3 and its editor isn't as horrid as the GECK

 

You must be joking. I cringe every time I have to open up the TESCK. I didn't do much of anything in the FO3 GECK, but the FONV GECK is like over 9000 times better than the oblivion CK. ;)

Link to comment

You must be joking. I cringe every time I have to open up the TESCK. I didn't do much of anything in the FO3 GECK' date=' but the FONV GECK is like over 9000 times better than the oblivion CK. ;)

[/quote']

 

Agreed, except for the few things that were ok in the TESCK but got fucked up in the geck :)

Progress, progress.

Link to comment
  • 4 weeks later...

Actor Refs

 

Here's what I've recently learned about Actor Ref's

 

Use GetSelf for Effect Scripts & Get Container for Object Scripts, a GetSelf in a Object script will compile and save fine but will crash the script in game unless it's directly in a NPC then it works ok, FNVEdit will show the error but PowerUp won't, you do need to Use GetSelf if the object script is attached to an Actor though.

 

Put your GetSelf or GetContainer only once on the first line you can in the script, run it ASAP, I've found it may take half a scan or repeats of the script to actually get the info. This means the first time the script runs it could run on a null ref instead of the actor, so something like GetDead will show the actor is dead.

 

I start my Actor based scripts with:

Begin GameMode



Set rZActor to GetContainer (or GetSelf)

if rZActor
Also while I remember GetDead seems to reset to dead temporarily going through doors even just opening containers, so use it with a short counter before acting on it.

 

When getting a new actors REF you need to use their REF from the game world in the render window, NOT their name in the NPC list, this of course means they need to be present in the gameworld somewhere, finding them isn't always easy.

 

EDIT: Just to confuse things, I've now discovered if an Object script is inside an NPC then you need to use GetSelf.

 

I also found quite a few functions don't return correct values for up to 10 seconds after game start on my PC, so all my mods check a timer in SCR has reached 10 before starting and make sure SCR has started before doing anything involving reading data. So I recommend most people give NV time to let all the other plugins settle before doing anything.

Link to comment

Also while I remember GetDead seems to reset to dead temporarily going through doors even just opening containers' date=' so use it with a short counter before acting on it.

 

When getting a new actors REF you need to use their REF from the game world in the render window, NOT their name in the NPC list, this of course means they need to be present in the gameworld somewhere, finding them isn't always easy.

[/quote']

 

Vanilla sometimes uses GetDeadCount + base form instead of GetDead + reference, for instance in "Run Goodsprings Run". Not sure which works best. I assume GetDeadCount can sometimes get borked up if an actor is resurrected, as a way of unfreezing them or a quest they play a part in. But it might not have the same trouble you describe.

 

Finding an actor's ref in the game world should be easy enough by right-clicking on the base form in the geck, and selecting "use info", then double-clicking on the cell it shows you (if at all).

Link to comment

I just discovered an exception to Object Scripts & GetSelf, if the Object script is inside an Actor then GetSelf is ok.

 

I'm not 100% sure but I also seem to have discovered that if you have 2 of the same object in an actors inventory, because any script in them is the same, the variables seem to overwrite each other :P

Link to comment
  • 1 month later...

I learned something new about variables today.

 

I was playing with the Powder Gang HPT mod, and I introduced some local variables into a dialog result script. Sometimes this worked as expected, and sometimes it didn't work at all. It was as if the variable wasn't even there, and could not be changed from zero. I was mystified. Then I found this link:

 

http://www.gameskyrim.com/issues-with-variables-dialogue-result-scripts-t48692.html

 

 

Also see here:

 

http://cs.elderscrolls.com/index.php/Result_scripts

 

I was completely unaware of this. I think there are some mods out there that use local variables in result scripts and which are running correctly purely by chance.

Link to comment

Just because it didn't work in Oblivion doesn't mean it doesn't work in NV... I thought the ability to declare vars in result scripts was a proper new feature for the geck. Anybody actually test that theory?

 

If you check my post on page 1 of this thread I already mentioned you should avoid local variables in a result script and for good reason:

 

1 - cannot retain a value, erased at end of snippet execution

2 - override any global variable of the same name during execution

3 - can override a local variable stored on an actor if they have a script assigned to their actor base that's located at the same storage index (i.e. first local in your script can accidentally override first local in actor's script)

 

Now there are ways to protect yourself from *some* of that... like initializing your local to a constant non-dynamic value before asigning it a dynamic non-constant value in the result script (i.e. declare int myInt, set myInt = 1 and THEN let myInt = some function return). That helps you avoid #3 above but you're still liable to be bitten by numbers 1 and 2. #1 isn't a big issue and if you need to store values, use quest variables instead. #2 can be avoided by a good naming convention for your locals.

 

TBH, you shouldn't use locals except in very specific circumstances in a result script... in almost every single case, a quest variable is a wiser, more stable choice.

Link to comment

Actually, you said: don't use it if you plan to retain the value. So 1 isn't much of a problem if like you said, it's a fire & forget thing. You also warned about 2, but that just depends on naming stuff properly.

 

It's 3 that's new to me.

 

I do see the occasional need for having a local var.

For instance, with the new calling version in Sexout, it's hard to pull off something like:

 set SexoutNG.fSurfaxeX to SexoutNG.fSurfaceX + 90 [/Code]

 

Works with the old calling version, not the new NX stuff (see my question about it in the API), so you either declare a local var in the result script to hold the fSurfaceX value for the duration of the result script or not use a result script to make your ng calls at all.

The formulas in my bed positioning tutorial also pretty much depend on declaring a few local vars when it comes to beds that aren't placed at right angles.

 

That trick with setting it to a constant first, does that work reliably for 3? Also, how does this play out for declaring a local ref instead of a float/int? Just set it to a form/ref from the fallout.esm?

Link to comment

In the GameSkyrim link I posted above, a example of defining local variables in a dialogue result script was given as follows:

 

Defined in the script:

 

short Player5s

short Player20s

short Player100s

short PlayerOwes

 

 

 

Commentary on the above:

 

The dialogue result script runs on the speaker. The variables you

define in the result script are either assigned to the quest or have

no assignment at all. Your variables might clutter some memory

somewhere but are not used otherwise.

 

Once the script is compiled it doesn't care about your names anymore,

your variables are numbered consecutively and the script uses those

numbers to access the variables: set Player5s to 42 in your case

would be translated to "set Variable #1 to 42"

 

If the NPC now has variables, then scripts that run on the NPC can

access those variables, regardless of the names you gave them in the

source code. E.g. when the NPC has the variables:

 

short var1

short var2

short var3

 

then your dialogue result script would use them this way:

 

var1 = Player5s

var2 = Player20s

var3 = Player100s

 

Variables that have no counterpart (e.g. PlayerOwes when the NPC has

only 3 variables) will permanently stay at 0 in the dialogue result

script. There even is a chance that some other values of the

speaker, commands in the speaker's script, or something seemingly

completely unrelated will be overwriten when you write to those

rogue variables.

 

The above seems to be what was happening to me. My NPC had a limited number of variables already assigned. I suppose I defined more than that number of local variables. I was susbsequently unable to utilize the extra variables in any way. Additionally, I was bashing the already defined variables. Who knows what, if any, effect this had on my game?

 

Anyway, I think that is what was happening.

Link to comment

Actually' date=' you said: don't use it if you plan to retain the value. So 1 isn't much of a problem if like you said, it's a fire & forget thing. You also warned about 2, but that just depends on naming stuff properly.

 

It's 3 that's new to me.

 

I do see the occasional need for having a local var.

For instance, with the new calling version in Sexout, it's hard to pull off something like:

 set SexoutNG.fSurfaxeX to SexoutNG.fSurfaceX + 90 [/Code]

 

Works with the old calling version, not the new NX stuff (see my question about it in the API), so you either declare a local var in the result script to hold the fSurfaceX value for the duration of the result script or not use a result script to make your ng calls at all.

The formulas in my bed positioning tutorial also pretty much depend on declaring a few local vars when it comes to beds that aren't placed at right angles.

 

That trick with setting it to a constant first, does that work reliably for 3? Also, how does this play out for declaring a local ref instead of a float/int? Just set it to a form/ref from the fallout.esm?

 

MtM and I went over this a lot in PMs and yes, it seems to work reliably to protect yourself from #3. As for references, you should be able to initialize them to zero (same as uninitialized) and if you can't, you can always initialize them to a control reference of some known insignificant reference like a static or marker somewhere unrelated to your task and one which you can check against.

Link to comment

In the GameSkyrim link I posted above' date=' a example of defining local variables in a dialogue result script was given as follows:

 

Defined in the script:

 

short Player5s

short Player20s

short Player100s

short PlayerOwes

 

 

 

Commentary on the above:

 

The dialogue result script runs on the speaker. The variables you

define in the result script are either assigned to the quest or have

no assignment at all. Your variables might clutter some memory

somewhere but are not used otherwise.

 

Once the script is compiled it doesn't care about your names anymore,

your variables are numbered consecutively and the script uses those

numbers to access the variables: set Player5s to 42 in your case

would be translated to "set Variable #1 to 42"

 

If the NPC now has variables, then scripts that run on the NPC can

access those variables, regardless of the names you gave them in the

source code. E.g. when the NPC has the variables:

 

short var1

short var2

short var3

 

then your dialogue result script would use them this way:

 

var1 = Player5s

var2 = Player20s

var3 = Player100s

 

Variables that have no counterpart (e.g. PlayerOwes when the NPC has

only 3 variables) will permanently stay at 0 in the dialogue result

script. There even is a chance that some other values of the

speaker, commands in the speaker's script, or something seemingly

completely unrelated will be overwriten when you write to those

rogue variables.

 

The above seems to be what was happening to me. My NPC had a limited number of variables already assigned. I suppose I defined more than that number of local variables. I was susbsequently unable to utilize the extra variables in any way. Additionally, I was bashing the already defined variables. Who knows what, if any, effect this had on my game?

 

Anyway, I think that is what was happening.

[/quote']

 

Yes, that was what I explained above as #3. It's extremely difficult to troubleshoot and can cause the most bizarre errors. As an example, someone was using a loop in a dialogue script to decrement a counter while clearing a list. Since the counter was the first variable it overrode the NPCs first variable in their actor script. Unfortunately, the decremented counter reaches 0 eventually and the first actor variable was whether they were hired or not as a companion... ugly and very hard to trace.

Link to comment

MtM and I went over this a lot in PMs and yes' date=' it seems to work reliably to protect yourself from #3. As for references, you should be able to initialize them to zero (same as uninitialized) and if you can't, you can always initialize them to a control reference of some known insignificant reference like a static or marker somewhere unrelated to your task and one which you can check against.

[/quote']

 

Good to know, this. Thanks!

I agree on using local vars sparingly, to be sure. But in the cases I mentioned earlier, having them is much easier than setting your calls in other scripts.

 

Edit: I don't see a ready answer in that other thread on whether or not the same is the case for quest stage result scripts. Can you shed a light on that?

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use