NVSE icon indicating copy to clipboard operation
NVSE copied to clipboard

Possible issue using eval with array functions

Open DRSSX4756 opened this issue 3 years ago • 10 comments

I'm seeing error reports that suggest an issue with the use of eval in conditions that contain array functions.

In the first example, a key contained in the 'svRole' string var passes the ar_haskey validity check when it shouldn't if eval 0 == ar_haskey SpunkVARZ.ar_PerksNeg, $svRole ... break ... elseif ... let rPerk := SpunkVARZ.ar_PerksNeg[svRole]

which results in the 'let' line correctly throwing the error "Array does not contain key". The issue is ofc that the script shouldn't gave gotten that far down.

Similarly, in the sexoutNG framework mod, if eval(Ar_Size arTodo) > 0 seems to evaluate to true despite the arToDo array not yet being populated, throwing errors later in the script. (Personally, I'd write that line like 'if eval 0 < ar_size arToDo, but I'll assume that eval has so far evaluated the entire line. Perhaps it now only evaluates what's between the parentheses, or perhaps it's related to the issue above.

DRSSX4756 avatar Jan 14 '21 21:01 DRSSX4756

Additionally, during one and the same game session, a multi-tier structure seems to disintegrate.

An array called 'thisact' is verified with ar_dump to contain two actor refs ** Dumping Array #690 ** Refs: 2 Owner 36: SexoutSpunk.esp [ 0.000000 ] : William (00000014) [ 1.000000 ] : Hooker (0012299D)

and added to a stringmap that is in turn added to an array: let thisactplus := ar_construct "stringmap" let thisactplus["actors"] := thisact let thisactplus["animdef"] := ar_animdef ar_append SpunkVARZ.ar_trackedActs thisactplus

A minute or so later, retrieving 'thisact' from within a loop foreach entry <- SpunkVARZ.ar_trackedacts let thisact := entry["value"]["actors"] throws Error in script 360248A7 (SpunkFuFindAct) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##thisact := entry["value"]["actors"]## (error wrapped in ##'s) Where thisact=uninitialized array, entry=array keys ["key", "value"] File: SexoutSpunk.esp Offset: 0x0084 Command: Let

At no point in between was the structure altered by any script of mine.

This attempt at retrieving 'thisact' is done in a UDF, called by an actor effect script. Since this actor effect script doesn't receive a valid array back back from the UDF, it triggers a deep dump of the ar_trackedActs structure. Interestingly enough, this is the result:

DD>> ===== Deep dump mode 2 - Depth= 0 - Array: [tracked acts] ===== DD>> [0][key] = 0 DD>> [0][value] = 36005E16 spunk spell end hook

The deep dump readout is skewed: ordinarily it would not contain 'key' and 'value', and in their stead would be the keys of the stringmap, followed by the keys of the 'thisact' array: DD>>[0][actors][0] = actorrefA DD>>[0][actors][1] = actorrefB I suspect this has something to do with array string elements not being read during string concats, among other things, attaching the relevant section of the deepdump script below. Yet that doesn't explain why the actor effect that calls the deep dump UDF is considered a value in any of this.

` foreach aEntry <- aArray ;=== Get key === ;=============== let sType := typeof aEntry["Key"] if eval (sType == "String") let sKey1 := "[" + aEntry["Key"] + "]"
else
let fNum := aEntry["Key"] let sKey1 := "[" + $fNum + "]" endif

  ;=== Get value ===
  ;=================
  let sType := typeof aEntry["Value"]  
  if eval (sType == "String")
    let sLine := sPrefix + sKey1 + " = '" + aEntry["Value"] + "'"
    printD "DD>> " + $sLine
  elseif eval (sType == "Number")
	let fNum := aEntry["Value"]
    let sLine := sPrefix + sKey1 + " = " + $fNum
    printD "DD>> " + $sLine
  elseif eval (sType == "Form")
    let xRef := aEntry["Value"]
    set sText to sv_Construct "%i %n" xRef xRef 
    let sLine := sPrefix + sKey1 + " = " + sText
    printD "DD>> " + $sLine
  else
    ; NA stuff
    if xDepth > 1     ; stops recursion at the last level initialized
      set xNextLevel to xMode * 100 + xLevel + 1
      let sText := sPrefix + sKey1

;;;; Uncomment the next line after the first successful compilation call SpunkFuDeepDump aEntry["Value"] , sText , xNextLevel, xDepth - 1 elseif xDepth == 1 && xMode == 2 let sLine := sPrefix + sKey1 + " . . ." printD "DD>> " + $sLine endif endif loop`

DRSSX4756 avatar Jan 15 '21 03:01 DRSSX4756

Some followup: the issue above with ar_haskey reporting a key exists in a stringmap when it doesn't continues in 6.0.2 if eval 0 == ar_haskey SpunkVARZ.ar_PerksNeg, $svRole

It also seems that GetInGrid no longer reports true when run against a ref var containing the playerref. Before, the following condition wouldn't have triggered if 'actor' contained the playerref, and it does now: if 0 == (GetInGrid actor, -1)

DRSSX4756 avatar Jan 17 '21 21:01 DRSSX4756

It seems the issue is a bit more complex as neither of the bugs embody themselves in a simple .esp test script. This is what I used:

scn TestScript

; first thing
begin menumode 4

string_var svStr
array_var avArr

let svStr := "ccc"
let avArr := ar_map "as"::1 "ab"::2
if eval 0 == (ar_hasKey avArr $svStr)
  print "no bug"
else
  print "bug"
endif

end

; second thing
begin gamemode

ref rPlayer
let rPlayer := playerRef

if 0 == (GetInGrid rPlayer, -1)
  print "bug"
else
  print "no bug"
endif

end

I've attached an esp with no external masters. If you find a way to reproduce the issue with an .esp that'd be great.

TestMod.esp.zip

korri123 avatar Jan 17 '21 22:01 korri123

I can confirm your test .esp doesn't return these functions as bugged, both with and without the mods installed that cause these error reports. However, that's in a fairly pristine testing environment. The users reporting these do so running a game from saves where these mods have been active for some time, with all sorts of data in the cosaves too. That, combined with the complexity of even a simple sexout setup, makes just providing an .esp where the bugs are bound to happen rather difficult.

The mods in question do have in common they're all dependent on and make heavy use of the NX plugin, and its logs show lines I haven't seen before, especially spamming "Received unknown message 20" - considering the xNVSE changelog says there was some work done on the plugin API, it might be worth a look. Although, tbh, I don't see how that could throw things like ar_haskey or getingrid out of whack in our mods specifically and not the test mod - nx remained installed when I ran that.

nvse_extender.log

DRSSX4756 avatar Jan 18 '21 02:01 DRSSX4756

I don't think it's related to the NX plugin. The message spam is because I added a main game loop (runs each frame) plugin message, and NX seems to log any plugin message it receives. Have you asked your users if they created a fresh cosave after upgrading to 6.0.2? Unfortunately it's extremely hard to figure out what the problem is until I run into it myself and I can examine closely what's happening under the hood using debugging tools. Since you don't seem to be available for isolating the issue (or seem to have had the issues yourself? only reports right?) there's not much I can do at the moment. Maybe the bug'll manifest itself in some other mod and the mod developer can point me in the right direction on how it happens.

korri123 avatar Jan 18 '21 02:01 korri123

In 6.0.4 there still seem to be issues of backward compatibility with data type usage particularly arrays and strings in many mods either legacy or ne. The user claims to be using 6.0.4. - see below.

Things I have personally noticed are strange behaviors in mods with rather complex data structs and those where arrays are passed as parameters to scripts designed as a function. Typically rather large script heavy mods.

In Spunk all the perks are in an Arrays based on the roles one for positive perks the other negative.

array_var ar_PerksPos array_var ar_PerksNeg

It builds these arrays in a script called SpunkFuArPopPerks which is called during the initialization process on game-load, so even if there were no values in a cosave it will start them from scratch - a fresh.

Spunk re-evaluates these perks with just about every act (call) which based on the role. It then conditionally adds or removes the perk to the player. (This is what spunk was attempting to do when the error occurs)

Here's a set of Errors:

Error in script 58051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkP := SpunkVarz.ar_PerksPos[sv_role]## (error wrapped in ##'s) Where rPerkP=uninitialized form (0), SpunkVarz.ar_PerksPos=array size 34, sv_role="rubber" File: SexoutSpunk.esp Offset: 0x0014 Command: Let Error in script 58051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkN := SpunkVarz.ar_PerksNeg[sv_role]## (error wrapped in ##'s) Where rPerkN=uninitialized form (0), SpunkVarz.ar_PerksNeg=array size 34, sv_role="rubber" File: SexoutSpunk.esp Offset: 0x002F Command: Let

This is the actual function failing: SpunkFuRemovePerk (actual code lines below)

let rPerkP := SpunkVARZ.ar_PerksPos[sv_role] let rPerkN := SpunkVARZ.ar_PerksNeg[sv_role]

if playerref.HasPerk rPerkP playerref.RemovePerk rPerkP endif if playerref.HasPerk rPerkN playerref.RemovePerk rPerkN endif

user's log attached.

SexoutSpunk-Log--2021-2-3-10-41-56.txt

Tommack63 avatar Feb 04 '21 20:02 Tommack63

The only realistic way for me to attempt to fix this is if the user uploads a save (.fos and .nvse) with a minimal load order (preferably that can be uploaded in a compressed file) where the issue occurs. I appreciate the detailed report, but unfortunately it doesn't give me a lot of hints on what's actually triggering the bug(s).

Edit: actually, it might give me an idea...

korri123 avatar Feb 05 '21 04:02 korri123

Below are some 6.0.9 nvse use from a log another user posted: I'm not sure if this is the same issue with the [ operator as before? I do know some mods have issues accessing (parsing) and rebuilding arrays from cosaves. i.e. I could never get spunk for instance to rebuild some particular mcm menus out of a cosave but can force it to rebuild them anew in initial form - invoking the script to do so - making spunk act like it's the first time installed. I attempted that thinking it may be a structural footprint in the save issue but subsequent save/loads suffered the same errors.

fallout root = C:\Program Files (x86)\Steam\steamapps\common\Fallout New Vegas
config path = C:\Program Files (x86)\Steam\steamapps\common\Fallout New Vegas\Data\NVSE\nvse_config.ini NVSE runtime: initialize (version = 6.0.9 040020D0 01D74D08EE0CF977) imagebase = 00400000 plugin directory = C:\Program Files (x86)\Steam\steamapps\common\Fallout New Vegas\Data\NVSE\Plugins
checking plugin C:\Program Files (x86)\Steam\steamapps\common\Fallout New Vegas\Data\NVSE\Plugins\jip_nvse.dll SetOpcodeBase 00002200 . . . .

init complete Hook_DirectInput8Create_Execute NVSE DLL DoPreLoadGameHook: quicksave.fos Reading mod list from co-save Loading array variables Loading strings plugin has data in save file but no handler NVSE DLL DoLoadGameHook: quicksave.fos NVSE DLL DoPostLoadGameHook: quicksave.fos NVSE DLL DoSaveGameHook: Soda Star - Save 10.fos saving to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\Soda Star - Save 10.nvse saving 2 plugins to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\Soda Star - Save 10.nvse NVSE DLL DoSaveGameHook: AUTOSAVE 2.fos saving to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\AUTOSAVE 2.nvse saving 2 plugins to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\AUTOSAVE 2.nvse Error in script 34051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkP := SpunkVarz.ar_PerksPos[sv_role]## (error wrapped in ##'s) Where rPerkP=uninitialized form (0), SpunkVarz.ar_PerksPos=array size 34, sv_role="kisser" File: SexoutSpunk.esp Offset: 0x0014 Command: Let Error in script 34051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkN := SpunkVarz.ar_PerksNeg[sv_role]## (error wrapped in ##'s) Where rPerkN=uninitialized form (0), SpunkVarz.ar_PerksNeg=array size 34, sv_role="kisser" File: SexoutSpunk.esp Offset: 0x002F Command: Let Error in script 34051E2F (SpunkQuEnjoy) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerk := SpunkVarz.ar_PerksPos[svRole]## (error wrapped in ##'s) Where rPerk=[id: 340512A3, edid: "SpunkPPRiding", name: "Giddyup Buttercup"], SpunkVarz.ar_PerksPos=array size 34, svRole="rubber" File: SexoutSpunk.esp Offset: 0x02C4 Command: Let Error in script 34051E2F (SpunkQuEnjoy) in mod SexoutSpunk.esp Array does not contain key

. . .

saving to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\AUTOSAVE 2.nvse saving 2 plugins to C:\Users\KVA\Documents\My Games\FalloutNV\Saves\AUTOSAVE 2.nvse Error in script 34051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkP := SpunkVarz.ar_PerksPos[sv_role]## (error wrapped in ##'s) Where rPerkP=uninitialized form (0), SpunkVarz.ar_PerksPos=array size 34, sv_role="kisser" File: SexoutSpunk.esp Offset: 0x0014 Command: Let Error in script 34051E30 (SpunkFuRemovePerk) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkN := SpunkVarz.ar_PerksNeg[sv_role]## (error wrapped in ##'s) Where rPerkN=uninitialized form (0), SpunkVarz.ar_PerksNeg=array size 34, sv_role="kisser" File: SexoutSpunk.esp Offset: 0x002F Command: Let Error in script 34051E2F (SpunkQuEnjoy) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerk := SpunkVarz.ar_PerksPos[svRole]## (error wrapped in ##'s) Where rPerk=[id: 340512A3, edid: "SpunkPPRiding", name: "Giddyup Buttercup"], SpunkVarz.ar_PerksPos=array size 34, svRole="rubber" File: SexoutSpunk.esp Offset: 0x02C4 Command: Let Error in script 34051E2F (SpunkQuEnjoy) in mod SexoutSpunk.esp Array does not contain key Operator := failed to evaluate to a valid result Script line approximation: Let ##rPerkObs := SpunkVarz.ar_PerksNeg[svRole]## (error wrapped in ##'s) Where rPerkObs=[id: 340512A2, edid: "SpunkPNRiding", name: "Saddle sore"], SpunkVarz.ar_PerksNeg=array size 34, svRole="rubber" File: SexoutSpunk.esp Offset: 0x02DF Command: Let NVSE DLL DoSaveGameHook: autosave.fos

Tommack63 avatar May 22 '21 17:05 Tommack63

Could you provide me with a zip file containing the save and cosave of the user, plus the .esm/.esp files? Also, are the issues happening on new saves as well? (created after xNVSE 6 release). The logs are informative to the scripter who is scripting the mod, not me particularly since the logs AFAIK are not the result of scripting errors.

korri123 avatar May 22 '21 23:05 korri123

Please test the recently released xNVSE 6.1.0

korri123 avatar Jun 04 '21 19:06 korri123