MaddDreamer Posted November 27, 2017 Share Posted November 27, 2017 Hello, my portal i am scripting has a possible 729 destinations, this is kept track by a quest and for the first couple hundred destinations the script for my portal worked fine until i added the rest of the destinations in and all properties assigned; it has ceased to function.I figure this is due to the size of the script despite compiling with no errors but, im still learning about scripting. So my question is can states be put on multiple seperate scripts and used with a single parent? Link to comment Share on other sites More sharing options...
JonathanOstrus Posted November 27, 2017 Share Posted November 27, 2017 Without seeing the implementation and knowing the requirements to decide the destination you have it's hard to say what's going on. It sounds like you made 729 properties and have some sort of giant if tree to decide which one to go to. Is that about right? If you're doing some simple random jump then you could use an array. If memory serves, so long as the array entities are defined in CK and passed at design time then the size can be > 128. You just cannot manipulate the array other than referencing the existing entities. I'm not really sure I understand your question about the states. Scripts can have states yes. They are set internally to themselves. The scripts would have to be instanced on an object to be called directly from anywhere else. You can not set a state on ScriptB from ScriptA if that's what you're thinking of doing. You would have to have ScriptA call some function on ScriptB which then sets the state for ScriptB. Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 27, 2017 Author Share Posted November 27, 2017 Yes its one gaint if tree, each destination has a property and an if to go with it. Destinations are based off quest stages organized like an index, set by three more scripts connected to items. Item A sets stage x, (1-9), item B sets stage xy,(1-9),(1-9), item C sets stage xyz. Then depending on what the final stage is the portal would send the player to dungeon xyz. This worked fine for the first couple hundred but now the portal wont send me anywhere with the rest of the locations now included in both properties and ifs. The portal is a simple if tree, on activate if quest stage is 123 send to dungeon 123 elseif ect.. easy but 729 times makes it huge. The thought i had about the states was to break it up into smaller scripts but still connected to the portal. If i cant put a state from scriptA onto ScriptB, how can i have scriptA run ScriptB (or if possible scriptC)in order to send the player to the correct place Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 27, 2017 Author Share Posted November 27, 2017 If i set up a parent script with empty states and attach a child sript that overrides a certain stage, can i attach more child scripts to fill the other states with one parent or can i set this up to be one parent and and a child that also acts as a parent to the next child and that child is a parent to the next, as so down each child all "parent" functions are inharrited, ex: parent to child1/parent2 to child2/parent3 to child3/parent4? Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 27, 2017 Author Share Posted November 27, 2017 Or set parent with properties and child sends the player? Link to comment Share on other sites More sharing options...
JonathanOstrus Posted November 27, 2017 Share Posted November 27, 2017 (edited) The issue is the fact you're putting in 729 properties. There is an undocumented limit of how many can be on a script. It is unclear as to whether it's properties specifically, or a combination of properties and script scope variables, or both those and local function variables. I haven't done extensive testing but I think the limit is something like 512 which would sort of make sense from a programming viewpoint (power of 2 and all). If the if tree looks something like this:if questStage == 5 player.moveto(propertyDungeonSpawn3) elseif questStage ==6 player.moveto(propertyDungeonSpawn4) ... endif Then you could easily just put all the marker object refs of the spawn points into one giant array in CK then reference like thisif questStage == 5 player.moveto(propertyDungeonSpawns[3]) elseif questStage ==6 player.moveto(propertyDungeonSpawns[4]) ... endif Edit: Crap forgot that the compiler won't let you reference entities directly like this > 128. If you use a loop with a variable counter it does. So this wouldn't work. See below for different solution. Then you only need 2 properties, one for the quest you're comparing stage on, and the other for the list of marker refs. The biggest issue is that once the script is loaded in a game the array is baked into the save. So if you added more points to the list later you would have to use a new save that had never seen the mod. There are hacky ways to get around that, like adding an update script which calls a function on the script to add more entries to the array from within the script. Then an issue becomes a race condition if there are multiple updates to be added to make sure they're added in order since you're hard referencing entities. If all of the marker refs are persistent (typically they would be if you're accessing them via properties like you're trying to) you could also try using a formlist instead of an array. That may be more dynamically changeable from an update point of view. However keep in mind that form lists can only contain 1 of any given form id. You cannot have it listed multiple times. The other possible solution is splitting it up like you suggested into multiple scripts. If you have some hierarchy of logic where you can split it into a small subset of points it makes it easy. You would have a master script on your object (I'm going to assume this is a quest script from this point) and attach all the child scripts to the same object. Then you could do something like this:ScriptName MasterQuestScript extends Quest Function GoSomewhereMaster(int iQuestStage) if iQuestStage >= 5 && iQuestStage < 15 ; this gives us 10 stages (self as ChildScript1).GoSomewhereChild(iQuestStage) elseif iQuestStage >= 15 && iQuestStage < 25 ; yup another 10 (self as ChildScript2).GoSomewhereChild(iQuestStage) endif EndFunction It doesn't have to be done in small sets like 10, it could be 100. I just chose small numbers for illustrative purposes. I do suggest using an array of markers instead of individual properties though or you could potentially have save corruption due to an engine bug related to the string table. Each property adds a string to the table and when it exceeds some value (I don't know the exact number) the save becomes corrupted and cannot be loaded. Then have each of the child scripts do something like this:ScriptName ChildScript1 extends Quest ObjectReference[] Property SpawnMarkers Auto Function GoSomewhereChild (int iQuestStage) Actor PlayerRef = Game.GetPlayer() if iQuestStage == 5 PlayerRef.MoveTo(SpawnMarkers[0] elseif iQuestStage == 6 PlayerRef.MoveTo(SpawnMarkers[1] ... endif EndFunction Edited November 28, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 28, 2017 Author Share Posted November 28, 2017 Thank you for this, this is all an awesome point in the direction i was hoping for. Another question, i have my script attached to an activator, how much will i need to change for the function to work? Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 28, 2017 Author Share Posted November 28, 2017 Tis being the first time ive really had to deal with functions Link to comment Share on other sites More sharing options...
MaddDreamer Posted November 28, 2017 Author Share Posted November 28, 2017 For the form list option mentioned above, what will i need to do? folowing the examples, i get the compiling error that only arrays may be indexed Link to comment Share on other sites More sharing options...
JonathanOstrus Posted November 28, 2017 Share Posted November 28, 2017 For referencing formlists you would get an entry it like this: FormList.GetAt(int index starting at 0). Formlist page https://www.creationkit.com/index.php?title=FormList_ScriptGetAt page https://www.creationkit.com/index.php?title=GetAt_-_FormList Link to comment Share on other sites More sharing options...
Recommended Posts