@kevL_s
Did you still have access to that area load time script I wrote that gives feedback on objects that can affect an area load? (I posted a version of it again below, just in case it helps to shed any light on any specific objects.)
It might give some clue about some specific objects. (E.g. VFXs can often be a culprit, like torches.)
In my experience, we are aiming for a load time report result less than 30s if possible. (This is what I currently have a PASS/FAIL set at. It is set as a guide only though.) However up to a minute may be acceptable in some circumstances. Anything over a minute is starting to go into danger zones and potential fails in my opinion. NB: A SP game will obviously load these areas quicker, but the report timing values also give a good indication of the stability of the area in general.
const string CCBLUE = "<color=CornFlowerBlue>";
const string CBLUE = "<color=Blue>";
const string CRED = "<color=Red>";
const string CORANGE = "<color=Orange>";
const string CDORANGE = "<color=DarkOrange>";
const string CGREEN = "<color=Green>";
////////////////////////////////////////////////////////////////////////////////////////////
// ESTIMATE LOAD TIME FOR AREAS FOR A MP GAME (ALLOWS 4s FOR UNDETECTABLE SOUND OBJECTS)
// SET iDetailedReport TO TRUE (1) IF YOU WANT OBJECT DETAILS FOR THE AREA CHECKS
// SET iPlayerAreaOnly TO TRUE (1) IF YOU WANT TO CHECK THE PLAYERS CURRENT AREA ONLY
// WARNING! NEVER ALTER iStartFrom VALUE AS IT IS USED INTERNALLY BY THIS FUNCTION.
// ALSO, IF YOUR AREAS ARE LARGE AND/OR HAVE MANY OBJECTS, THEN THE LOOPS MAY FAIL. THIS
// CAN BE MADE MORE RELAIBLE BY REDUCING THE NUMBER OF AREAS LOOPED IN THE LINE THAT READS
// int iStopAt = iStartFrom + 3; < REDUCE THE NUMBER "3" UNTIL YOU GET A FULL REPORT IF NEED BE!
// NB: THIS SCRIPT USES COLOUR CONSTANTS THAT YOU WOULD EITHER NEED TO SETUP OR REMOVE
////////////////////////////////////////////////////////////////////////////////////////////
void MPEstimateAreaLoadTime(int iPlayerAreaOnly = 0, int iDetailedReport = 0, object oPlayer = OBJECT_SELF, int iStartFrom = 0, int iFAILED = 0, string sFAILED = "");
void MPEstimateAreaLoadTime(int iPlayerAreaOnly = 0, int iDetailedReport = 0, object oPlayer = OBJECT_SELF, int iStartFrom = 0, int iFAILED = 0, string sFAILED = "")
{
float fLoadTime = 0.0;
// OBJECT LOAD TIMES (CHANGE AS EACH TEST IMPROVES)
float fCREINV = 0.07;
float fPLCINV = 0.15;
float fPLCUSE = 0.24;
float fDOORS = 0.11;
float fVFX = 0.05;
float fLIGHTS = 0.1;
int iPlayers = 0; int iPCs = 0;
object oFM = GetFirstFactionMember(oPlayer, FALSE);
while(oFM != OBJECT_INVALID)
{
if(GetIsPC(oFM)){fLoadTime = fLoadTime + 2.5; iPlayers = iPlayers + 1;}
else{fLoadTime = fLoadTime + 1.0; iPCs = iPCs + 1;}
oFM = GetNextFactionMember(oPlayer, FALSE);
}
int iREPORT = 1; int iQTYAREAS = iStartFrom;
int iQTYITEMS = 0;
if(iStartFrom == 0)
{
SendMessageToPC(oPlayer, CBLUE + "<<< STARTING MP AREA LOAD TIME REPORT FOR MODULE (ALLOWS 4s FOR SOUNDS) >>>");
SendMessageToPC(oPlayer, CBLUE + "<<< PLAYERS x " + IntToString(iPlayers) + " (PARTY MEMBERS x " + IntToString(iPCs) +") = " + FloatToString(fLoadTime, 4, 2) + "s >>>");
}
object oAreaPC = GetArea(oPlayer);
// CHANGE STARTFROM TO A VALUE WHERE AREA LOOP STARTS
// SET AT NUMBER OF AREAS TO COVER (USE MAX 3 - DECREASE IF NEEDED)
int iStopAt = iStartFrom + 1;
int iCount = 0;
object oAreaLoop = OBJECT_INVALID;
if(iPlayerAreaOnly == 1){oAreaLoop = GetArea(oPlayer);}
else
{
oAreaLoop = GetFirstArea();
}
// MAX AROUND 15 AT A TIME, SO USE 1, 21
while(oAreaLoop != OBJECT_INVALID)
{
iCount = iCount + 1;
// IGNORE THE FOLLOWING
int iIGNORE = 0;if(GetLocalInt(oAreaLoop, "IGNORELOOP")){iIGNORE = 1;}
// AREA DETAILS COLLECTION
if(iCount > iStartFrom && iCount <= iStopAt && !iIGNORE)
{
string sAreaTag = GetTag(oAreaLoop);
string sAreaName = GetName(oAreaLoop); // USE NAME AS NESEWERS TAG IS THREE AREAS!
string sAreaInfo = sAreaTag + " (TAG) " + sAreaName + " (NAME)";
DelayCommand(0.4, SendMessageToPC(oPlayer, IntToString(iCount) + ") TESTING AREA > " + sAreaInfo));
iQTYAREAS = iQTYAREAS + 1;
string sCOLOUR = CRED;
// AREA SPECIFIC TIMINGS
float fTOTAL = 0.0;
float fInvLoadTime = 0.0; int iQPI = 0; string sQPI = "";
float fUseLoadTime = 0.0; int iQPU = 0; string sQPU = "";
float fCreLoadTime = 0.0; int iQCI = 0; string sQCI = "";
float fDoorLoadTime = 0.0; int iQD = 0; string sQD = "";
float fLightLoadTime = 0.0; int iQL = 0; string sQL = "";
float fVFXLoadTime = 0.0; int iQV = 0; string sQV = "";
//float fSOUNDLoadTime = 0.0; int iQS = 0; // CANNOT DETECT
string sITEMREPORT = "";
string sINVREPORT = "";
string sUSEREPORT = "";
string sCREREPORT = "";
string sDOORREPORT = "";
string sLIGHTREPORT = "";
string sVFXREPORT = "";
string sSOUNDREPORT = "";
// FIND ALL ITEMS
object oItem = GetFirstObjectInArea(oAreaLoop);
while(oItem != OBJECT_INVALID)
{
int iTYPE = GetObjectType(oItem);
string sTAG = GetTag(oItem);
////////////////////////////////////////////////////////////////////////////////////////////
// ITEM CHECKS - BASIC STRAY ITEMS SHOULD NOT HAVE ANY UPON RELEASE!
////////////////////////////////////////////////////////////////////////////////////////////
if(iTYPE == OBJECT_TYPE_ITEM)
{
if(iDetailedReport){SendMessageToPC(oPlayer, CRED + "ERROR: ITEM FOUND IN AREA: " + sAreaInfo);}
iQTYITEMS = iQTYITEMS + 1;
sITEMREPORT = CRED + "AREA TOTAL ITEM OBJECTS > " + IntToString(iQTYITEMS);
iFAILED = 1;
}
////////////////////////////////////////////////////////////////////////////////////////////
// CREATURE CHECKS
////////////////////////////////////////////////////////////////////////////////////////////
if(iTYPE == OBJECT_TYPE_CREATURE)
{
if(GetFirstItemInInventory(oItem) != OBJECT_INVALID || GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oItem) != OBJECT_INVALID
|| GetItemInSlot(INVENTORY_SLOT_CHEST, oItem) != OBJECT_INVALID)
{
//if(iDetailedReport){SendMessageToPC(oPlayer, CORANGE + "CREATURE " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo);}
fCreLoadTime = fCreLoadTime + fCREINV; iQCI = iQCI + 1;
}
sCOLOUR = CRED; if(fCreLoadTime < 5.0){sCOLOUR = CORANGE;}
sCREREPORT = sCOLOUR + "AREA CREATURE OBJECTS (" + IntToString(iQCI) + ") LOAD TIME > " + FloatToString(fCreLoadTime, 4, 2);
}
////////////////////////////////////////////////////////////////////////////////////////////
// PLACEABLE CHECKS
////////////////////////////////////////////////////////////////////////////////////////////
else if(iTYPE == OBJECT_TYPE_PLACEABLE)
{
if(GetHasInventory(oItem))
{
if(iDetailedReport){SendMessageToPC(oPlayer, CORANGE + "INV PLACEABLE " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo);}
fInvLoadTime = fInvLoadTime + fPLCINV; iQPI = iQPI + 1;
sCOLOUR = CRED; if(fInvLoadTime < 15.0){sCOLOUR = CORANGE;}
sINVREPORT = sCOLOUR + "AREA INVENTORY OBJECTS (" + IntToString(iQPI) + ") LOAD TIME > " + FloatToString(fInvLoadTime, 4, 2);
}
else if(GetUseableFlag(oItem))
{
if(iDetailedReport){DelayCommand(0.1, SendMessageToPC(oPlayer, CDORANGE + "USE PLACEABLE " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo));}
fUseLoadTime = fUseLoadTime + fPLCUSE; iQPU = iQPU + 1;
sCOLOUR = CRED; if(fUseLoadTime < 15.0){sCOLOUR = CORANGE;}
sUSEREPORT = sCOLOUR + "AREA USEABLE OBJECTS (" + IntToString(iQPU) + ") LOAD TIME > " + FloatToString(fUseLoadTime, 4, 2);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// DOOR CHECKS
////////////////////////////////////////////////////////////////////////////////////////////
else if(iTYPE == OBJECT_TYPE_DOOR)
{
//if(iDetailedReport){SendMessageToPC(oPlayer, CORANGE + "DOOR " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo);}
fDoorLoadTime = fDoorLoadTime + fDOORS; iQD = iQD + 1;
sDOORREPORT = "AREA DOOR OBJECTS (" + IntToString(iQD) + ") LOAD TIME > " + FloatToString(fDoorLoadTime, 4, 2);
}
////////////////////////////////////////////////////////////////////////////////////////////
// LIGHT CHECKS
////////////////////////////////////////////////////////////////////////////////////////////
else if(iTYPE == OBJECT_TYPE_LIGHT)
{
//if(iDetailedReport){SendMessageToPC(oPlayer, CORANGE + "LIGHT " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo);}
fLightLoadTime = fLightLoadTime + fLIGHTS; iQL = iQL + 1;
sCOLOUR = CRED; if(fLightLoadTime < 10.0){sCOLOUR = CORANGE;}
sLIGHTREPORT = sCOLOUR + "AREA LIGHT OBJECTS (" + IntToString(iQL) + ") LOAD TIME > " + FloatToString(fLightLoadTime, 4, 2);
}
////////////////////////////////////////////////////////////////////////////////////////////
// VFX CHECKS
////////////////////////////////////////////////////////////////////////////////////////////
else if(iTYPE == OBJECT_TYPE_PLACED_EFFECT)
{
//if(iDetailedReport){SendMessageToPC(oPlayer, CORANGE + "VFX " + "(" + (sTAG) + ") > FOUND IN AREA: " + sAreaInfo);}
fVFXLoadTime = fVFXLoadTime + fVFX; iQV = iQV + 1;
sCOLOUR = CRED; if(fVFXLoadTime < 10.0){sCOLOUR = CORANGE;}
sVFXREPORT = sCOLOUR + "AREA VFX OBJECTS (" + IntToString(iQV) + ") LOAD TIME > " + FloatToString(fVFXLoadTime, 4, 2);
}
oItem = GetNextObjectInArea(oAreaLoop);
} // END VALID OBJECT IN AREA
///////////////////////////////////////////////////////////////////////////////////////////////
// AREA TOTAL REPORTS
///////////////////////////////////////////////////////////////////////////////////////////////
// STRAY ITEMS
if(sITEMREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sITEMREPORT));}
// CREATURE OBJECTS
if(sCREREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sCREREPORT));}
// INVENTORY OBJECTS
if(sINVREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sINVREPORT));}
// INVENTORY OBJECTS
if(sUSEREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sUSEREPORT));}
// DOOR OBJECTS
if(sDOORREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sDOORREPORT));}
// VFX OBJECTS
if(sVFXREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sVFXREPORT));}
// LIGHT OBJECTS
if(sLIGHTREPORT != ""){DelayCommand(0.5, SendMessageToPC(oPlayer, sLIGHTREPORT));}
// SOUND OBJECTS
//if(sSOUNDREPORT != ""){SendMessageToPC(oPlayer, sLIGHTREPORT);}
// AREA TOTAL LOAD TIME (ALLOWING 5s FOR SOUND OBJECTS THAT CANNOT BE DETECTED)
fTOTAL = 4.0 + fLoadTime + fInvLoadTime + fUseLoadTime + fCreLoadTime + fDoorLoadTime + fLightLoadTime + fVFXLoadTime;
string sALERT = CRED + " FAIL !!!!"; if(fTOTAL < 30.0){sALERT = CGREEN + " PASS !!!!";}
// LIST ALL FAILED
else
{
sFAILED = sFAILED + "\n" + sAreaInfo + " : " + FloatToString(fTOTAL-4.0, 4, 2) + " TO " + FloatToString(fTOTAL, 4, 2) + "s ";
}
DelayCommand(0.51, SendMessageToPC(oPlayer, CCBLUE + "TOTAL ESTIMATED LOAD TIME FOR " + sAreaInfo + " : " + FloatToString(fTOTAL-4.0, 4, 2) + " TO " + FloatToString(fTOTAL, 4, 2) + "s " + sALERT));
} // END IF COUNT
else if(oAreaLoop != OBJECT_INVALID && iCount > iStopAt)
{
iREPORT = 0;
DelayCommand(0.2, MPEstimateAreaLoadTime(iPlayerAreaOnly, iDetailedReport, oPlayer, iStopAt, iFAILED, sFAILED)); oAreaLoop = OBJECT_INVALID; break;
}
if(iPlayerAreaOnly == 0)
{
oAreaLoop = GetNextArea();
}
else
{
oAreaLoop = OBJECT_INVALID;
}
} // END WHILE
// END REPORT (MODULE)
if(iREPORT == 1)
{
if(iFAILED == 0){DelayCommand(0.6, SendMessageToPC(oPlayer, CCBLUE + "<<< GOOD! NO STRAY ITEMS LEFT WITHIN MODULE! >>>"));}
else{DelayCommand(0.6,SendMessageToPC(oPlayer, CRED + "<<< BAD! STRAY ITEMS LEFT WITHIN MODULE! >>>"));}
DelayCommand(0.6, SendMessageToPC(oPlayer, CBLUE + "<<< " + IntToString(iQTYAREAS) + " AREAS CHECKED >>>"));
DelayCommand(0.6, SendMessageToPC(oPlayer, CBLUE + "<<< REPORT FINISHED >>>"));
DelayCommand(0.7, SendMessageToPC(oPlayer, CRED + sFAILED));
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// PATCH SCRIPT
////////////////////////////////////////////////////////////////////////////////////////////
void main(int iPlayerAreaOnly = 0, int iDetailedReport = 0)
{
object oPlayer = OBJECT_SELF;
//object oHost = GetTheGameHost();
object oHost = GetFirstPC();
object oArea = GetArea(oPlayer);
MPEstimateAreaLoadTime(iPlayerAreaOnly, iDetailedReport, oPlayer, 0);
}