I have a script which is very heavy, at the point it cause a stutter every time it runs.
This script essentially scan the whole cell and compare every "Static" object model path with a set of strings, to return the "type" of cell the player is currently in.
I already set the script to only run on cell change to avoid unnecessary runs, because if the cell is the same, so is the type of cell, obviously.
When the cell change is one of:
- interior->interior
- interior->exterior
- exterior->interior,
The problem is with cell changes exterior->exterior, as there's no loading screen and the stutter is noticeable.
The script is this one:
scn DMSGetCellType; Processes cell statics and music type to determine cell typeRef rLocationArray_Var aDataArray_Var aIterTypesArray_Var aIterPathRef rWalkShort iCountShort iMaxShort iMusicTypeShort iCellMusicTypeString_Var sKeyString_Var sTextBegin _Function { rLocation } Let sText := GetEditorID rLocation ForEach aIterTypes <- (sv_Split DMSMain.sENUMLOCATIONS, "|~|")[1:-2] ;Check if the cell type is in the location EditorID If Eval (( sv_Find *aIterTypes, sText ) >= 0 ) SetFunctionValue *aIterTypes Let iCount := 1 Break EndIf Loop If ( iCount ) ;Found the cell type in the EditorID? sv_Destruct sText Return ElseIf Eval !( Player.IsInInterior ) ;In exteriors count the trees Let iCount := GetNumRefs 30 If Eval ( iCount > 20 ) ;With many trees, go on with Forest and stop immediately. SetFunctionValue "Forest" Return EndIf EndIf Let aData := ar_Construct "StringMap" ForEach aIterTypes <- DMSMain.aCellTypesData Let aData[aIterTypes["Key"]] := 0 ;Initialize the keys Loop Let rWalk := GetFirstRef 28 While ( rWalk ) Let sText := rWalk.GetModelPath ForEach aIterTypes <- DMSMain.aCellTypesData ;All cell types ForEach aIterPath <- (*aIterTypes)[0] ;All substrings for this cell type to search in the model path Let aData[aIterTypes["Key"]] += (( sv_Find (*aIterPath), sText ) >= 0 ) ;<== BOTTLENECK. Count how many models match a cell type Loop Loop Let rWalk := GetNextRef Loop Let iCellMusicType := emcGetMusicType 1 ;World music Let sText := "NONE" ForEach aIterTypes <- aData Let iCount := (*aIterTypes) Let sKey := aIterTypes["Key"] Let iMusicType := DMSMain.aCellTypesData[sKey][1] Call DMSDebug ("DMS Debug | DMSGetCellType | Type > Count: " + sKey + " > (Music: " + $iMusicType + ") " + $iCount) If ( iCount > iMax ) If Eval ( iMusicType < 0 || iMusicType == iCellMusicType ) Let sText := sKey Let iMax := iCount EndIf EndIf Loop If Eval ( sText == "Cave" ) If Eval ( ar_HasKey aData "Oblivion" ) If Eval ( aData["Oblivion"] ) SetFunctionValue "Oblivion" sv_Destruct sText Return EndIf EndIf If Eval ( ar_HasKey aData "Mine" ) If Eval ( aData["Mine"] ) SetFunctionValue "Mine" sv_Destruct sText Return EndIf EndIf SetFunctionValue "Cave" Else SetFunctionValue sText EndIf sv_Destruct sText ReturnEnd
As you see, if there's a forest, the script stop immediately, else it will scan the whole cell, to find the cell type, which (example, in an exterior cell) could be a village.
Do you have any idea to make this script lighter, or break it in multiple pieces?
As as I you see, the bottleneck is when it scan all statics model paths (there are MANY models to scan, and must be compared with about about 10-15 possible substrings .