Jump to content

Recommended Posts

FNV Scripting: NX Variables

 

 

Required knowledge: references v. base forms; script variables (floats/integers/ref vars); get & set

Req knowledge for advanced use: strings, string variables, array variables, referring to a quest variable in dialog etc conditions

So… if you spend any time around the sexout sections on LL you’ll have seen the word ‘nx’ pop up. It’s an extra set of functions that comes with the NVSE Extender by prideslayer. The most common NX functions that we use are the NX variable functions.

An nx variable function…

  • lets you store game information on a reference
  • as an nx variable – EVFl (for floats and integers), or EVFo (for forms – refs, base forms, dynamic refs) with NX_Get or NX_Set
  • without needing to declare it in your script: as soon as you set it, it exists on the reference:

someRef.NX_SetEVFl “thenameyougiveit” someNumericValue/someFloat/someInteger
someRef.NX_SetEVFo “thenameyougiveit” someForm/someRef


“the name you give it” = the key

and being reference functions, NX_Set/GetEVF* functions can use implied reference syntax too

 

To make it a bit more concrete, if you wanted to keep track of how many drinks actors have had, you'd both create the variable "DrinksDrunk" and manipulate its value by setting it on the reference:

BuddyRef.NX_SetEVFl "DM:DrinksDrunk" 1

and the same for their favorite poison or favorite boozing buddy:

BuddyRef.NX_SetEVFo "DM:FavoriteDrink" Scotch
BuddyRef.NX_SetEVFo "DM:BestestFriendInTheWholeWorld" Buddy2Ref

            

  • knowing that it will stay on that reference in your save game, and only on that reference; it does not need anything in your mod once it exists, so you could uninstall the mod that set it and it’ll still be there
  • and if any mod wants to read that information, it just can, from the ref, as long it knows what the key is:

set somefloat/integer to someRef.NX_GetEVFl “whateverkeyithas”

set somescriptRef to someRef.NX_GetEVFo “whateverkeyithas”

 

like:

int iDrinkCount
ref favDrink
set iDrinkCount to BuddyRef.NX_GetEVFl "DM:DrinksDrunk"
set favDrink to BuddyRef.NX_GetEVFo "DM:FavoriteDrink"
if BuddyRef.GetItemCount favDrink > 0 ; we have booze
     BuddyRef.CIOS favDrink             ; drinking it
     BuddyRef.removeitem favDrink 1     ; one fewer than before
     set iDrinkCount to iDrinkCount + 1 
     BuddyRef.NX_SetEVFl "DM:DrinksDrunk" iDrinkCount ; keeping track
endif
if 10 < BuddyRef.NX_GetEVFl "DM:DrinksDrunk" ; might have overdone it
     BuddyRef.CIOS ReallyStinkingDrunkSpell
endif


A different mod that wants to read that information, does not need yours as a master to do it.

And you can do all this tracking on as many NPCs as you'd want.

 

 

ref BuddyRef

set BuddyRef to whoever


 

 

  • you can have as many nx vars on any ref as you want
  • and if you don’t need them anymore, you get rid of them like this:

someRef.NX_ClrEFVl “key”
someRef.NX_ClrEVFo “key”

or, getting rid of a bunch of them, you can do:
someRef.NX_ClrEVFl “partthatallkeysshare” 2
someRef.NX_ClrEVFo “partthatallkeysshare” 2

 

Our drinking mod started all keys with "DM", so a complete wipe of all drinking-related information on BuddyRef would look like:

BuddyRef.NX_ClrEVFl "DM:" 2
BuddyRef.NX_ClrEVFo "DM:" 2

leaving a clean slate and a clear conscience.

 

This means that you can have a whole bunch of custom variables sticking to whatever actor or thing you want in your game. No effect, no token, no quest script needed, just to store that information, and that reduces mod conflicts and makes mods able to communicate with each other without mastering & load order crap. If you want to store any kind of information about an actor, for instance – their sexual orientation, love interest, how pregnant they look, favorite pizza parlor – you just stick it on that actor, where you'll find it when you need it.
 
Good practice tip:
You never know, someone may think of using the exact same key for an nx variable as you without using it for the same thing. So most of us using it just have a bit at the front of the string that tells us what mod it’s from: “MyCleverModAcronym:restofthekey” etc.

Another good practice tip:
Because this really allows other mods to consult and do things with information that you store in an nx var, it's a good idea to clearly state which nx vars you use, especially if you use a lot. You can store them all in a dummy script in your mod, stick it in a spoiler to your op, add a text file to your download, whatever. (If you plan to use it for sexout, have a look at this thread.)

 

Update:
with NX12 comes the ability to store and retrieve strings as an EVST variable: NX_SetEVST, NX_GetEVST, and NX_ClrEVST. You can do this with both actual strings and string variables.

To continue our boozing example:
 

string_var sv_quote
...
BuddyRef.NX_SetEVST "DM:BoozeQuote" "Champagne for my real friends - real pain for my sham friends, ha ha!"
BuddyRef.NX_SetEVST "DM:DrunkType" "Aggressive"
...
if BuddyRef.GetItemCount favDrink > 0 ; we have booze
    BuddyRef.CIOS favDrink ; drinking it
    let sv_quote := BuddyRef.NX_GetEVST "DM:BoozeQuote"
    MessageEX "%z" sv_quote ; will pop up a message with the quote in it
...
endif
if 10 < BuddyRef.NX_GetEVFl "DM:DrinksDrunk"
..
   if eval BuddyRef.NX_GetEVST "DM:DrunkType" == "Aggressive"
      BuddyRef.startcombat playerref
   endif
endif


With NVSE4+ come a whole slew of string var functions that allow you store, modify and retrieve strings on the fly. In combination with the ToString function (short: $), which allows you to pass string vars to functions that would otherwise expect an actual string, this means you can create nx keys dynamically, and in the case of EVST, values too. This means you can do something like:
 

string_var sv_fightoutcome
string_var sv_nxkey
int iFightNum
int iIsFighting
float fTimer

if BuddyRef.GetCombatTarget == playerref
    set iFightNum to iFightNum + 1 ;(or: let iFightNum += 1)
    set iIsFighting to 1
endif

if eval iIsFighting && (ftimer += GetSecondsPassed) > 30
   BuddyRef.StopCombat
endif

if iIsFighting && 0 == BuddyRef.IsInCombat
   set iIsFighting to 0
   if playerref.GetAV Health > BuddyRef.GetAV Health
       let sv_fightoutcome := "Lost"
   else
       let sv_fightoutcome := "Won"
   endif
   let sv_nxkey := "DM:Fight:" + $iFightNum + ":Score"  ; creates a string that'll be like "DM:Fight:1:Score", "DM:Fight:2:Score" etc)
   BuddyRef.NX_SetEVST $sv_nxkey $sv_fightoutcome
endif


Also new to NX12 are functions that return the nx information on an actor in a stringmap, with the nx keys in the stringmap's keys and the values in the stringmap values: NX_GetEVFlAr, NX_GetEVFoAr, and NX_GetEVStAr
 

Let's say you've had a few bar fights, buddyref's won and lost some, to return that data, you'd go:

array_var ar_results
let ar_results := BuddyRef.NX_GetEVStAr "DM:Fight"
ar_dump ar_results

and that ar_dump readout will look like:
[DM:Fight:1:Score] : Won
[DM:Fight:2:Score] : Lost
etc


You'll need to know a few things about arrays and foreach loops to do something with that data; hopefully I can write a couple of things about that later.

 

Update:

It's been talked about a lot and now it's here: nx EVFL vars can now be consulted in dialog/quest/anim conditions. (Only EVFLs because such conditions only have numbers for values.)

You start out by sticking a string var in a quest script, and setting that to the nx key you want it to represent. In line with the previous examples I chose "DM:DrinksDrunk":

post-18170-0-37980300-1391025154_thumb.jpg

Attach that to a quest, obviously. Note that a quest doesn't need to be enabled to just hold a variable, but in this case I'm setting the var in the same script, so I enable it to make that work. (I could've added let DSTestQst.sv_drinksdrunk := "DM:DrinksDrunk" to some other script and done the same thing.)

post-18170-0-11484700-1391025279_thumb.jpg

Since we have a quest going already, let's continue to test it with dialog conditions. As you can see I made a topic, and a line that I want to depend on a EVFL having a value of 1.

I add a condition, and pick NX_GetQVEVFL for the condition function. A window pops up that looks a lot like the one you'll see if you check a regular quest variable.

post-18170-0-63373900-1391025675_thumb.jpg

Pick the quest that has the quest script with the string variable in it in the dropdown menu. To actually pick the variable, you need the enter the index number for it. If it's the first variable in the script, it'll be 1. Whenever you're not sure what index number your string variable has, you can look that up in FNVEdit:

post-18170-0-30122400-1391025830_thumb.jpg

Note - and this is true for all quest variables - that you shouldn't go around rearranging quest variables after you've already made saves with it active; you can append new ones to the end of the variables list of a script, but not shuffle them around. (Well, you can, if you don't care about fielding bug reports.)

And as you can see in the next screenies, you can easily change the nx var on the actor in the result script, and the next line will detect the change.

 

post-18170-0-28653700-1391026117_thumb.jpg post-18170-0-98536500-1391026131_thumb.jpg

 

(Kudos to jaam for creating that one, as well as the EVST and array vars, and explaining the process.)

Share this post


Link to post
Guest carywinton

The genius of DoctaSax at work here. I can see a great many possibilities for using the nx variables and how this would make the overhead of the game and any associated mods much lower, excellent post. I shall read up on some more related aspects of variables and declarations to see where this might fit in with my current project. :D

Share this post


Link to post

The credit should to go pride - and throw some jaam's way for updating nvse too.

I just thought explaining it simply and outside of a sexout context could better highlight the possibilities of it for fnv modding in general, and get more modders interested. Like the required knowlege bit suggests, it's really quite simple to use - it just needs a certain "aha" moment in order to really get it, and maybe this can help with that.

 

Share this post


Link to post
Guest carywinton

The credit should to go pride - and throw some jaam's way for updating nvse too.

I just thought explaining it simply and outside of a sexout context could better highlight the possibilities of it for fnv modding in general, and get more modders interested. Like the required knowlege bit suggests, it's really quite simple to use - it just needs a certain "aha" moment in order to really get it, and maybe this can help with that.

Not only is it an "aha" moment, I saw some light at the end of a conversation/dialog tunnel for it's use. Dialog is one of the major issues with Gamebryo based games, darn near all of them have conflicts, does not matter who's mod or how well done, dialog especially, the opener, "Greeting" can be a real pain in the ass.

 

I read over Halstroms post on this, the link you referenced, good stuff. I will be sure to give Pride due Kudos on this.

Share this post


Link to post

Hm, well "greeting", even if flagged as conflicting in FNVEdit, doesn't really cause problems if attached to a new quest - all of that merges quite well in-game if you choose your quest priority and conditions wisely. The only thing I keep banging on about is the addtopic bug :)

Share this post


Link to post

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...