Anubis22 Posted October 28, 2017 Share Posted October 28, 2017 Hey everyone, I am currently working on a mod similar to SkyTweak. It is a lot more lightweight with a stronger focus on (combat-) balance and is designed to work on top of any load order, virtually conflict free. The mod is in it's last stages of refinement, but now I ran into a problem with the MCM menu script file. I am using the "State Option" method for addressing my ui elements, but I surpassed 128 states in the script and compiling will yield the following error:"SCRIPTS: error: Class SB_MCM_Script overflowed the named state count field(s) while linking. The class is marked as invalid. A programmer must adjust the bit field sizes" The MCM script got way too big for my taste anyway. I would love to split it up into several smaller scripts (for example one script for each MCM page).Is this possible and how could I do it?If not is there any solution except reverting back to the older non-State MCM format? Link to comment Share on other sites More sharing options...
foamyesque Posted October 28, 2017 Share Posted October 28, 2017 What on earth do you need 128+ states for? Link to comment Share on other sites More sharing options...
Anubis22 Posted October 28, 2017 Author Share Posted October 28, 2017 There are a lot of parameters involved in balancing the game, even if you do not go down to the lowest levels. For a quick reference just take a look at SkyTweak, which probably exceeds 200 easily. An example from my mod for Destruction Magic:- Toggle whether to adjust Destruction- Damage Multiplier- Damage Level Scaling- Cost Multiplier- Duration Multiplier- Experience Multiplier And you could add Level Scaling for Cost and Duration too. You have the same for the other magic schools and skills. It adds up, real quick.When using MCM with State Options every slider, checkbox and so on in your UI has a corresponding state in the script, hence why there are so many. Link to comment Share on other sites More sharing options...
foamyesque Posted October 28, 2017 Share Posted October 28, 2017 A state for every single option strikes me as major overkill. Have you considered, say, using one per page? You could, say, have one page for Destruction, and all your relevant code and variables set within a DestructionPage state. That keeps your OnWhatever events from turning into truly ridiculous spaghetti, but should keep your state count sane. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 29, 2017 Share Posted October 29, 2017 If I understand correctly, MCM allows 128 mod configuration entries (mods), 128 pages per mod, 128 option entries per page. Thus instead of having only one page with 128 option entries, you can break that down into multiple pages. The OnPageReset event (explained in the MCM documentation and included in the template script) is where you can determine which options are displayed on which page. Your states can remain unchanged, just change which page calls those options to display. A small example of multiple pages under one mod configuration entry Event OnPageReset(string page) If page == "" LoadCustomContent("") Else UnLoadCustomContent() EndIf If page == Pages[0] SetCursorFillMode(TOP_TO_BOTTOM) ; AddHeaderOption("Global Options") AddKeyMapOptionST("KeyMap_One", "$Modify Activation Key", KeyCodeOne) AddTextOptionST("KeyMap_One_Behavior","$Behavior",KMOBehave[KMOBehaveidx]) AddToggleOptionST("ManualSaveState","$Manual Save", ManualSave) SetCursorPosition(1) If FissActive == true FISSInterface fiss = FISSFactory.getFISS() If fiss AddToggleOptionST("SavePreset","$SavePreset",PresetSave,OPTION_FLAG_NONE) AddToggleOptionST("LoadPreset","$LoadPreset",PresetLoad,OPTION_FLAG_NONE) Else AddToggleOptionST("SavePreset","$SavePreset",PresetSave,OPTION_FLAG_DISABLED) AddToggleOptionST("LoadPreset","$LoadPreset",PresetLoad,OPTION_FLAG_DISABLED) EndIf Else AddToggleOptionST("SavePreset","$SavePreset",PresetSave,OPTION_FLAG_DISABLED) AddToggleOptionST("LoadPreset","$LoadPreset",PresetLoad,OPTION_FLAG_DISABLED) EndIf EndIf ;more pages removed for brevity EndEvent @foamyesqueThe state setup for MCM is designed for one state per option with different option events dedicated to the state setup. Thus it does not get to be as 'spaghetti' like as you'd think. Its more like a pie or a cake. Each state is a piece with the OnPageReset event being the icing tying it all together. Here is an example: A single option to make a 'carried' container weighted or weightless State Weightless0 Event OnSelectST() Int index = 0 WeightlesActive[index] = !WeightlesActive[index] SetToggleOptionValueST(WeightlesActive[index]) EndEvent Event OnDefaultST() Int index = 0 WeightlesActive[index] = false SetToggleOptionValueST(WeightlesActive[index]) EndEvent Event OnHighlightST() Int index = 0 If ComponentChoice[index] != 0 SetInfoText("$WeightlessInfo") EndIf EndEvent EndState and that is just one of 5 options for that one container. See earlier above for an OnPageReset example. Link to comment Share on other sites More sharing options...
foamyesque Posted October 29, 2017 Share Posted October 29, 2017 The spaghetti problem was in reference to a completely state-free implementation, where each event would need to do a comparison against every single possible option it could apply to to figure out which one it's processing. That gets really ugly quite quickly, hence the state-based system in MCM 2 in the first place. However, if a. there's more than 128 options that need states and b. Papyrus only allows 128 states total -- and the compiler error would suggest that -- then going back to the optionID layout might be the choice here... Link to comment Share on other sites More sharing options...
PeterMartyr Posted October 29, 2017 Share Posted October 29, 2017 I never done this, but papyrus is always extending something, & to create a simple test won't take long, but why don't you just extends you main MCM script. ScriptName MCMScriptMain Extends SKI_ConfigBase MCMPageTwo Property P2 Auto Event OnPageReset(string a_page) If a_page == Pages[0] Self.AddTextOptionST("StateName", "string a_text", "string a_value") ElseIf a_page == Pages[1] P2.PageTwo() EndIf EndEvent State StateName Event OnSelectST() Self.SetTextOptionValueST("Working") EndEvent EndState ScriptName MCMPageTwo Extends MCMScriptMain Function PageTwo() self.AddTextOptionST("PageTwoState", "string a_text", "string a_value") EndFunction State PageTwoState Event OnSelectST() Self.SetTextOptionValueST("Working") EndEvent EndState It compiled fine, but I obviously didn't create a test mod to see it in action, it should be possible to extend it. Who knows, what have got to lose, run some tests, if you don't get how to extends your scripts, look it up on the wiki. I You can beat the 128 States with State "" on dynamic statesExample of me use State "" in MCM, it look like old format doesn't it? Without integers, but using States Event OnInputOpenST() Int a_index String sResult = GetState() Int nClone = FDQMain.nCloneTypeID While(a_index < nClone) If(sResult == "INPUT_POSITION_X_STATE" + a_index) Float fTemp = FDQMain.fSetPositionX[a_index] SetInputDialogStartText(fTemp As Int) ElseIf(sResult == "INPUT_POSITION_Y_STATE" + a_index) Float fTemp = FDQMain.fSetPositionY[a_index] SetInputDialogStartText(fTemp As Int) ElseIf(sResult == "INPUT_ROTATION_Z_STATE" + a_index) Float fTemp = FDQMain.fSetAngleZ[a_index] SetInputDialogStartText(fTemp As Int) EndIf a_index +=1 EndWhile EndEventanother state "" where one Event serves multiple States with a delimiter I placed in the definition of States Names Int nIndex = 61 Int nCount While(nIndex > 30) nIndex -= 1 Int kSlotMask = Armor.GetMaskForSlot(nIndex) Form EquippedForm = PoupaREF.GetWornForm(kSlotMask) If(EquippedForm) self.AddTextOptionST("EquipForm_State" + "*" + nCount, EquippedForm.GetName(), (EquippedForm as Armor).GetArmorRating()) nCount += 1 EndIf EndWhile ********************************************************************************************** Event OnHighlightST() string[] sResult = StringUtil.Split(self.GetState(), "*") If(sResult[0] == "EquipForm_State") self.SetInfoText("Base CK Armor Rating for Item") EndIf EndSo yeah 128 is the limited, but doesn't mean you can't trick the compiler to get what you want with a minimum of Physical States So really it depends what you require from your MCM? I never had a the need to exceed 128, but I have needed to create Dynamic States with Loops. English is not 1st, but unlike others, I don't feel sorry about it. So no apology, here. :cool: Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 29, 2017 Share Posted October 29, 2017 Whether or not papyrus itself will not allow more than 128 states (never heard of such a limit myself), you can always create a second MCM quest in your mod. It would create another mod configuration entry (which would only be an issue if someone wants to use more than 128 mods with MCMs). Link to comment Share on other sites More sharing options...
foamyesque Posted October 29, 2017 Share Posted October 29, 2017 Whether or not papyrus itself will not allow more than 128 states (never heard of such a limit myself), you can always create a second MCM quest in your mod. It would create another mod configuration entry (which would only be an issue if someone wants to use more than 128 mods with MCMs). I haven't either. I'm actually going to be testing that later tonight just to see. But if there isn't such a limit, it makes me wonder what that compiler error would be caused by... Link to comment Share on other sites More sharing options...
IsharaMeradin Posted October 29, 2017 Share Posted October 29, 2017 I just checked on this. I created a script with 130+ simple states all with empty OnBeginState events. It compiled fine through SublimeText. But when I went to load the script in the CK it presented me with the error message that the OP indicated. I could not access the script in the CK until I reduced the number of states to 127 typed states and the always present empty state. Keep in mind this is not a compiler error. The compiler has no issues with the number of states. The Creation Kit itself has an issue with the number of states. The real question:Can a script with 128+ states that has been compiled outside of the CK function properly without issue within the game? Link to comment Share on other sites More sharing options...
Recommended Posts