Haravikk Posted January 17, 2023 Share Posted January 17, 2023 I just want to confirm, since it's not mentioned explicitly on any wiki that I've seen (or I've been looking in the wrong places or have gone crosseyed from looking) but are Arrays in Fallout 4's version of papyrus passed by value (copied) or by reference (any variable pointing at the same array can change it for all variables)? I'm used to scripting in Skyrim where you could never really do much with arrays without re-creating them (and usually with PapyrusUtils since vanilla Skyrim at least didn't support expressions for array length) so I never really had much need to manipulate arrays I was given, as I'd just be creating a new one and returning it. But in Fallout 4 we have dynamically sized arrays, along with methods like Array.Add(), Array.Insert() etc. So I just wanted to confirm to make sure I haven't made a mistake, but am I correct in thinking that Arrays are passed by reference, so if I receive an array as an argument in a function and then add to it (using Array.Add or Array.Insert), the calling script will be able to access it? As a silly example (forgive typos): Int Function CountEquipped(Actor akActor, Int[] aiIndices, Form[] akFound = None) Int aiCount = 0 Int aiIndex = 0 While aiIndex < aiIndices.Length WornItem akWorn = akActor.GetWornItem(aiIndices[aiIndex]) If akWorn && akWorn.Item aiCount += 1 If akFound akFound.Add(akWorn.Item) EndIf EndIf aiIndex += 1 EndWhile Return aiCount EndFunction {Counts the number of equipped items on akActor found in slots listed in aiIndices, optionally adding each found item to akFound} Basically I just want to confirm that a function such as the above (which puts found items into akFound) should work, or if I need to find a way to convert them to return multiple values as a Var[] array or similar? Link to comment Share on other sites More sharing options...
RaidersClamoring Posted January 19, 2023 Share Posted January 19, 2023 Unfortunately they are passed by copy. Moreover and potentially even worse, they "new" keyword indicates they are created on the heap. And if this is the case, the only way to get that memory back, partially, is to clear(), or to let the game rebuild the heap. Simply exiting function- or script scope will not destroy the array. But it will terminate your access to it! Link to comment Share on other sites More sharing options...
niston Posted January 19, 2023 Share Posted January 19, 2023 Simply exiting function- or script scope will not destroy the array. I don't think that's true. Unless you use the compiler patch for structs in arrays and make complicated data structures with circular references, garbage collection will take care of it. Link to comment Share on other sites More sharing options...
SKKmods Posted January 20, 2023 Share Posted January 20, 2023 Function level variables or arrays will be cleaned up after the function exits. Script level variables or arrays should be cleaned up if/when the script clears EXCEPT non CONST scripts that can hold script level variables or arrays do not seem to clean up consistently (hanging scripts). Which is why attaching non CONST scripts to short lifecycle objects is bad. Therefore manually clearing script level properties, variables and arrays when they are done is a pro tip ya dont see that often. Link to comment Share on other sites More sharing options...
RaidersClamoring Posted January 20, 2023 Share Posted January 20, 2023 I don't think that's true. Unless you use the compiler patch for structs in arrays and make complicated data structures with circular references, garbage collection will take care of it. I'd love to be wrong. I suppose implementing a destructor for scope exit wouldn't be a problem on the C++ end. Link to comment Share on other sites More sharing options...
DlinnyLag Posted January 20, 2023 Share Posted January 20, 2023 (edited) Arrays defenitely passed by reference to a function. In other case my mod will never works. In my mod array object is created and passed to external function for modification.After external function finish caller uses changes made by external function. Edited January 20, 2023 by DlinnyLag Link to comment Share on other sites More sharing options...
DlinnyLag Posted January 20, 2023 Share Posted January 20, 2023 (edited) I just want to confirm, since it's not mentioned explicitly on any wiki that I've seen (or I've been looking in the wrong places or have gone crosseyed from looking) Please see Assigning/Passing Arrays section at https://www.creationkit.com/fallout4/index.php?title=Arrays_(Papyrus) Edited January 20, 2023 by DlinnyLag Link to comment Share on other sites More sharing options...
DlinnyLag Posted January 20, 2023 Share Posted January 20, 2023 (edited) Basically I just want to confirm that a function such as the above (which puts found items into akFound) should work, or if I need to find a way to convert them to return multiple values as a Var[] array or similar?If I understand your problem correctly then yes, elements added to akFound will be visible on the caller side.But in this particual case you could return newly created array instead of passing.Somethig like that: Form[] Function GetEquipped(Actor akActor, Int[] aiIndices) Form[] retVal = new Form[0] Int aiIndex = 0 While aiIndex < aiIndices.Length WornItem akWorn = akActor.GetWornItem(aiIndices[aiIndex]) If akWorn && akWorn.Item retVal.Add(akWorn.Item) EndIf aiIndex += 1 EndWhile Return retVal EndFunction The length of retuned array will be equal to your aiCount Edited January 20, 2023 by DlinnyLag Link to comment Share on other sites More sharing options...
Haravikk Posted January 20, 2023 Author Share Posted January 20, 2023 (edited) I just want to confirm, since it's not mentioned explicitly on any wiki that I've seen (or I've been looking in the wrong places or have gone crosseyed from looking) Please see Assigning/Passing Arrays section at https://www.creationkit.com/fallout4/index.php?title=Arrays_(Papyrus) Must have missed that somehow! However it only specifically shows setting an existing index (Array1[0] = 10), does the same rule hold true when using Array1.Add(10)? My actual case is proving complex to debug, I really need to add some very basic scripts just to test what behaviours might be broken (or misunderstood in my case), been a busy week though, I'll see if I can find time over the weekend. Basically I just want to confirm that a function such as the above (which puts found items into akFound) should work, or if I need to find a way to convert them to return multiple values as a Var[] array or similar?If I understand your problem correctly then yes, elements added to akFound will be visible on the caller side.But in this particual case you could return newly created array instead of passing. I should have said but the example was very much simplified compared to what I'm actually doing (to try and give a clearer idea of my question); in my actual case I have multiple arrays that I need to add entries to, ideally without having to return them somehow, so arguments will be the best way if that does in fact work. You're right that that specific example could just return the array, though my intention was that filling the array at all in the example is optional (no array needs to be passed if all you need is the total), also the array being passed in might not be empty (it may be passed between functions, each adding their own entries), which is part of what I'm actually doing (multiple functions adding their data to a set of arrays), at least, what my scripts are supposed to be doing. Edited January 20, 2023 by Haravikk Link to comment Share on other sites More sharing options...
DlinnyLag Posted January 20, 2023 Share Posted January 20, 2023 though my intention was that filling the array at all in the example is optional (no array needs to be passed if all you need is the total), also the array being passed in might not be empty (it may be passed between functions, each adding their own entries), which is part of what I'm actually doing (multiple functions adding their data to a set of arrays), at least, what my scripts are supposed to be doing. You can use F4DS if you have worries about built-in arrays functionality and F4SE usage is acceptable. Link to comment Share on other sites More sharing options...
Recommended Posts