diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
index a1841c568a..c9e57ce7b3 100644
--- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs
+++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs
@@ -26,8 +26,8 @@
*/
using System;
+using System.Diagnostics;
using System.Text;
-
using OpenMetaverse;
using OpenMetaverse.StructuredData;
@@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics
sb.Append(Environment.NewLine);
sb.Append(
string.Format(
- "Allocated to OpenSim : {0} MB" + Environment.NewLine,
+ "Allocated to OpenSim objects: {0} MB\n",
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
+ sb.Append(
+ string.Format(
+ "Process memory : {0} MB\n",
+ Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
return sb.ToString();
}
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index efa4a7ba87..31fa101e50 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -81,12 +81,15 @@ namespace OpenSim.Framework
private static uint nextXferID = 5000;
private static Random randomClass = new Random();
+
// Get a list of invalid file characters (OS dependent)
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
private static object XferLock = new object();
- /// Thread pool used for Util.FireAndForget if
- /// FireAndForgetMethod.SmartThreadPool is used
+
+ ///
+ /// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
+ ///
private static SmartThreadPool m_ThreadPool;
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 6fba2493d4..e955a58527 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -503,7 +503,11 @@ namespace OpenSim
string currentCommand;
while ((currentCommand = readFile.ReadLine()) != null)
{
- if (currentCommand != String.Empty)
+ currentCommand = currentCommand.Trim();
+ if (!(currentCommand == ""
+ || currentCommand.StartsWith(";")
+ || currentCommand.StartsWith("//")
+ || currentCommand.StartsWith("#")))
{
m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
m_console.RunCommand(currentCommand);
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index c303d6db1c..61d604ff3d 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -26,8 +26,10 @@
*/
using System;
+using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Security;
using log4net;
@@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private delegate void LookupUUIDS(List uuidLst);
-
public Scene Scene { get; private set; }
public IUserManagement UserManager { get; private set; }
@@ -876,98 +876,77 @@ namespace OpenSim.Region.CoreModules.World.Estate
if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
return;
- Dictionary SceneData = new Dictionary();
+ Dictionary sceneData = null;
List uuidNameLookupList = new List();
if (reportType == 1)
{
- SceneData = Scene.PhysicsScene.GetTopColliders();
+ sceneData = Scene.PhysicsScene.GetTopColliders();
}
else if (reportType == 0)
{
- SceneData = Scene.SceneGraph.GetTopScripts();
+ IScriptModule scriptModule = Scene.RequestModuleInterface();
+
+ if (scriptModule != null)
+ sceneData = scriptModule.GetObjectScriptsExecutionTimes();
}
List SceneReport = new List();
- lock (SceneData)
+ if (sceneData != null)
{
- foreach (uint obj in SceneData.Keys)
+ var sortedSceneData
+ = sceneData.Select(
+ item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
+
+ sortedSceneData.OrderBy(item => item.Measurement);
+
+ int items = 0;
+
+ foreach (var entry in sortedSceneData)
{
- SceneObjectPart prt = Scene.GetSceneObjectPart(obj);
- if (prt != null)
+ // The object may have been deleted since we received the data.
+ if (entry.Part == null)
+ continue;
+
+ // Don't show scripts that haven't executed or where execution time is below one microsecond in
+ // order to produce a more readable report.
+ if (entry.Measurement < 0.001)
+ continue;
+
+ items++;
+ SceneObjectGroup so = entry.Part.ParentGroup;
+
+ LandStatReportItem lsri = new LandStatReportItem();
+ lsri.LocationX = so.AbsolutePosition.X;
+ lsri.LocationY = so.AbsolutePosition.Y;
+ lsri.LocationZ = so.AbsolutePosition.Z;
+ lsri.Score = entry.Measurement;
+ lsri.TaskID = so.UUID;
+ lsri.TaskLocalID = so.LocalId;
+ lsri.TaskName = entry.Part.Name;
+ lsri.OwnerName = UserManager.GetUserName(so.OwnerID);
+
+ if (filter.Length != 0)
{
- SceneObjectGroup sog = prt.ParentGroup;
- LandStatReportItem lsri = new LandStatReportItem();
- lsri.LocationX = sog.AbsolutePosition.X;
- lsri.LocationY = sog.AbsolutePosition.Y;
- lsri.LocationZ = sog.AbsolutePosition.Z;
- lsri.Score = SceneData[obj];
- lsri.TaskID = sog.UUID;
- lsri.TaskLocalID = sog.LocalId;
- lsri.TaskName = sog.GetPartName(obj);
- lsri.OwnerName = "waiting";
- lock (uuidNameLookupList)
- uuidNameLookupList.Add(sog.OwnerID);
-
- if (filter.Length != 0)
+ if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
{
- if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
- {
- }
- else
- {
- continue;
- }
}
-
- SceneReport.Add(lsri);
+ else
+ {
+ continue;
+ }
}
+
+ SceneReport.Add(lsri);
+
+ if (items >= 100)
+ break;
}
}
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
-
- if (uuidNameLookupList.Count > 0)
- LookupUUID(uuidNameLookupList);
}
- private static void LookupUUIDSCompleted(IAsyncResult iar)
- {
- LookupUUIDS icon = (LookupUUIDS)iar.AsyncState;
- icon.EndInvoke(iar);
- }
-
- private void LookupUUID(List uuidLst)
- {
- LookupUUIDS d = LookupUUIDsAsync;
-
- d.BeginInvoke(uuidLst,
- LookupUUIDSCompleted,
- d);
- }
-
- private void LookupUUIDsAsync(List uuidLst)
- {
- UUID[] uuidarr;
-
- lock (uuidLst)
- {
- uuidarr = uuidLst.ToArray();
- }
-
- for (int i = 0; i < uuidarr.Length; i++)
- {
- // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
-
- IUserManagement userManager = Scene.RequestModuleInterface();
- if (userManager != null)
- userManager.GetUserName(uuidarr[i]);
-
- // we drop it. It gets cached though... so we're ready for the next request.
- // diva commnent 11/21/2010: uh?!? wft?
- // justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume.
- }
- }
#endregion
#region Outgoing Packets
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 18c45dde6e..9cab2e185b 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using OpenMetaverse;
namespace OpenSim.Region.Framework.Interfaces
@@ -74,5 +75,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// Starts the processing threads.
///
void StartProcessing();
+
+ ///
+ /// Get the execution times of all scripts in each object.
+ ///
+ ///
+ /// A dictionary where the key is the root object ID of a linkset
+ /// and the value is a representative execution time in milliseconds of all scripts in that linkset.
+ ///
+ Dictionary GetObjectScriptsExecutionTimes();
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index bc3400a7a5..5c542d65a2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -733,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
#endregion
#region Get Methods
+
///
/// Get the controlling client for the given avatar, if there is one.
///
@@ -1074,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes
return Entities.GetEntities();
}
- public Dictionary GetTopScripts()
- {
- Dictionary topScripts = new Dictionary();
-
- EntityBase[] EntityList = GetEntities();
- int limit = 0;
- foreach (EntityBase ent in EntityList)
- {
- if (ent is SceneObjectGroup)
- {
- SceneObjectGroup grp = (SceneObjectGroup)ent;
- if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
- {
- if (grp.scriptScore >= 0.01)
- {
- topScripts.Add(grp.LocalId, grp.scriptScore);
- limit++;
- if (limit >= 100)
- {
- break;
- }
- }
- grp.scriptScore = 0;
- }
- }
- }
-
- return topScripts;
- }
-
#endregion
#region Other Methods
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 878476e5c9..afb5ccfae5 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes
get { return RootPart.VolumeDetectActive; }
}
- public float scriptScore;
-
private Vector3 lastPhysGroupPos;
private Quaternion lastPhysGroupRot;
@@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes
public void AddScriptLPS(int count)
{
- if (scriptScore + count >= float.MaxValue - count)
- scriptScore = 0;
-
- scriptScore += (float)count;
- SceneGraph d = m_scene.SceneGraph;
- d.AddToScriptLPS(count);
+ m_scene.SceneGraph.AddToScriptLPS(count);
}
public void AddActiveScriptCount(int count)
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 8762642903..b04f6b6624 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -78,12 +78,38 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
///
string State { get; set; }
+ ///
+ /// Time the script was last started
+ ///
+ DateTime TimeStarted { get; }
+
+ ///
+ /// Tick the last measurement period was started.
+ ///
+ long MeasurementPeriodTickStart { get; }
+
+ ///
+ /// Ticks spent executing in the last measurement period.
+ ///
+ long MeasurementPeriodExecutionTime { get; }
+
IScriptEngine Engine { get; }
UUID AppDomain { get; set; }
string PrimName { get; }
string ScriptName { get; }
UUID ItemID { get; }
UUID ObjectID { get; }
+
+ ///
+ /// UUID of the root object for the linkset that the script is in.
+ ///
+ UUID RootObjectID { get; }
+
+ ///
+ /// Local id of the root object for the linkset that the script is in.
+ ///
+ uint RootLocalID { get; }
+
uint LocalID { get; }
UUID AssetID { get; }
Queue EventQueue { get; }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 968351b450..6e367421c0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -164,6 +164,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public uint LocalID { get; private set; }
+ public UUID RootObjectID { get; private set; }
+
+ public uint RootLocalID { get; private set; }
+
public UUID AssetID { get; private set; }
public Queue EventQueue { get; private set; }
@@ -172,6 +176,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public TaskInventoryItem ScriptTask { get; private set; }
+ public DateTime TimeStarted { get; private set; }
+
+ public long MeasurementPeriodTickStart { get; private set; }
+
+ public long MeasurementPeriodExecutionTime { get; private set; }
+
+ public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute;
+
public void ClearQueue()
{
m_TimerQueued = false;
@@ -190,6 +202,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
Engine = engine;
LocalID = part.LocalId;
ObjectID = part.UUID;
+ RootLocalID = part.ParentGroup.LocalId;
+ RootObjectID = part.ParentGroup.UUID;
ItemID = itemID;
AssetID = assetID;
PrimName = primName;
@@ -458,6 +472,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
Running = true;
+ TimeStarted = DateTime.Now;
+ MeasurementPeriodTickStart = Util.EnvironmentTickCount();
+ MeasurementPeriodExecutionTime = 0;
+
if (EventQueue.Count > 0)
{
if (m_CurrentWorkItem == null)
@@ -710,8 +728,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_EventStart = DateTime.Now;
m_InEvent = true;
+ int start = Util.EnvironmentTickCount();
+
+ // Reset the measurement period when we reach the end of the current one.
+ if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod)
+ MeasurementPeriodTickStart = start;
+
m_Script.ExecuteEvent(State, data.EventName, data.Params);
+ MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start;
+
m_InEvent = false;
m_CurrentEvent = String.Empty;
@@ -720,7 +746,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
// This will be the very first event we deliver
// (state_entry) in default state
//
-
SaveState(m_Assembly);
m_SaveState = false;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 105d97da47..3697f78c83 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1083,7 +1083,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (!m_PrimObjects[localID].Contains(itemID))
m_PrimObjects[localID].Add(itemID);
-
}
if (!m_Assemblies.ContainsKey(assetID))
@@ -1891,6 +1890,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
}
}
+ public Dictionary GetObjectScriptsExecutionTimes()
+ {
+ long tickNow = Util.EnvironmentTickCount();
+ Dictionary topScripts = new Dictionary();
+
+ lock (m_Scripts)
+ {
+ foreach (IScriptInstance si in m_Scripts.Values)
+ {
+ if (!topScripts.ContainsKey(si.LocalID))
+ topScripts[si.RootLocalID] = 0;
+
+// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
+// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond);
+
+ // Execution time of the script adjusted by it's measurement period to make scripts started at
+ // different times comparable.
+// float adjustedExecutionTime
+// = (float)si.MeasurementPeriodExecutionTime
+// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
+// / TimeSpan.TicksPerMillisecond;
+
+ long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
+
+ // Avoid divide by zerp
+ if (ticksElapsed == 0)
+ ticksElapsed = 1;
+
+ // Scale execution time to the ideal 55 fps frame time for these reasons.
+ //
+ // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
+ // 'script execution time per frame', which is the original purpose of this value.
+ //
+ // 2) Giving the raw execution times is misleading since scripts start at different times, making
+ // it impossible to compare scripts.
+ //
+ // 3) Scaling the raw execution time to the time that the script has been running is better but
+ // is still misleading since a script that has just been rezzed may appear to have been running
+ // for much longer.
+ //
+ // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
+ // since the figure does not represent actual execution time and very hard running scripts will
+ // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
+ float adjustedExecutionTime
+ = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
+
+ topScripts[si.RootLocalID] += adjustedExecutionTime;
+ }
+ }
+
+ return topScripts;
+ }
+
public void SuspendScript(UUID itemID)
{
// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID);
diff --git a/bin/ScriptEngines/Default.lsl b/bin/ScriptEngines/Default.lsl
deleted file mode 100644
index ade855d98f..0000000000
--- a/bin/ScriptEngines/Default.lsl
+++ /dev/null
@@ -1,104 +0,0 @@
-// autogenerated by generate_default_lsl.rb
-integer touch_count = 0;
-
-default {
- touch_start(integer total_number) {
- float angle45 = PI/4.0; // 45 degrees
- float angle30 = PI/6.0; // 30 degrees
- float sqrt2 = llSqrt(2.0);
- if((llFabs(-1.5) != 1.5) || (llFabs(10.4) != 10.4)) {
- llShout(0, "Houston, we have a big problem! llFabs() does not work! Need it for other tests!");
- }
- llSetText("This is a text by llSetText", <1,0,0>, 1);
- llWhisper(0, "llWhispering a few random numbers between 0 and 100: " + llFrand(100) + "," + llFrand(100) + "," + llFrand(100) + "," + llFrand(100));
- llShout(0, "llShouting the unix time: " + llGetUnixTime() + ", and region corner: " + llGetRegionCorner());
- llShout(1, "Shouting a random number between 0 and 100 on the channel#1: " + llFrand(100));
- if (llAbs(-1) != 1) {
- llSay(0, "Assert failed: llAbs(-1) != 1");
- }
- if (llAbs(10) != 10) {
- llSay(0, "Assert failed: llAbs(10) != 10");
- }
- if (llFabs((llCos(angle45) - sqrt2/2.0) - 0) > 0.000001) {
- llSay(0, "Assert failed: (llCos(angle45) - sqrt2/2.0) differs from 0 by more than 0.000001");
- llSay(0, " --> The actual result: " + (llCos(angle45) - sqrt2/2.0));
- }
- if (llFabs((llSin(angle30) - 0.5) - 0) > 0.000001) {
- llSay(0, "Assert failed: (llSin(angle30) - 0.5) differs from 0 by more than 0.000001");
- llSay(0, " --> The actual result: " + (llSin(angle30) - 0.5));
- }
- if (llFabs((llAtan2(1, 1)*4 - PI) - 0) > 0.000001) {
- llSay(0, "Assert failed: (llAtan2(1, 1)*4 - PI) differs from 0 by more than 0.000001");
- llSay(0, " --> The actual result: " + (llAtan2(1, 1)*4 - PI));
- }
- if (llFabs((llTan(PI)) - 0) > 0.000001) {
- llSay(0, "Assert failed: (llTan(PI)) differs from 0 by more than 0.000001");
- llSay(0, " --> The actual result: " + (llTan(PI)));
- }
- if (llFloor(2.4) != 2) {
- llSay(0, "Assert failed: llFloor(2.4) != 2");
- }
- if (llCeil(2.4) != 3) {
- llSay(0, "Assert failed: llCeil(2.4) != 3");
- }
- if (llRound(2.4) != 2) {
- llSay(0, "Assert failed: llRound(2.4) != 2");
- }
- if (llFloor(2.5) != 2) {
- llSay(0, "Assert failed: llFloor(2.5) != 2");
- }
- if (llCeil(2.5) != 3) {
- llSay(0, "Assert failed: llCeil(2.5) != 3");
- }
- if (llRound(2.5) != 3) {
- llSay(0, "Assert failed: llRound(2.5) != 3");
- }
- if (llFloor(2.51) != 2) {
- llSay(0, "Assert failed: llFloor(2.51) != 2");
- }
- if (llCeil(2.51) != 3) {
- llSay(0, "Assert failed: llCeil(2.51) != 3");
- }
- if (llRound(2.51) != 3) {
- llSay(0, "Assert failed: llRound(2.51) != 3");
- }
- if (llFloor(3.49) != 3) {
- llSay(0, "Assert failed: llFloor(3.49) != 3");
- }
- if (llCeil(3.49) != 4) {
- llSay(0, "Assert failed: llCeil(3.49) != 4");
- }
- if (llRound(3.49) != 3) {
- llSay(0, "Assert failed: llRound(3.49) != 3");
- }
- if (llFloor(3.5000001) != 3) {
- llSay(0, "Assert failed: llFloor(3.5000001) != 3");
- }
- if (llCeil(3.5000001) != 4) {
- llSay(0, "Assert failed: llCeil(3.5000001) != 4");
- }
- if (llRound(3.5000001) != 4) {
- llSay(0, "Assert failed: llRound(3.5000001) != 4");
- }
- if (llFloor(3.51) != 3) {
- llSay(0, "Assert failed: llFloor(3.51) != 3");
- }
- if (llCeil(3.51) != 4) {
- llSay(0, "Assert failed: llCeil(3.51) != 4");
- }
- if (llRound(3.51) != 4) {
- llSay(0, "Assert failed: llRound(3.51) != 4");
- }
- if ((llFabs(0-llPow(2, 16))) != 65536) {
- llSay(0, "Assert failed: (llFabs(0-llPow(2, 16))) != 65536");
- }
- if (llMD5String("Hello, Avatar!",0) != "112abd47ceaae1c05a826828650434a6") {
- llSay(0, "Assert failed: llMD5String('Hello, Avatar!',0) != '112abd47ceaae1c05a826828650434a6'");
- }
- if (llModPow(2, 16, 37) != 9) {
- llSay(0, "Assert failed: llModPow(2, 16, 37) != 9");
- }
- touch_count++;
- llSay(0, "Object was touched. Touch count: " + touch_count);
- }
-}
diff --git a/bin/shutdown_commands.txt b/bin/shutdown_commands.txt
index ec76ec276d..4397749d23 100644
--- a/bin/shutdown_commands.txt
+++ b/bin/shutdown_commands.txt
@@ -1 +1,3 @@
-backup
+; You can place simulator console commands here to execute when the simulator is shut down
+; e.g. show stats
+; Lines starting with ; are comments
diff --git a/bin/startup_commands.txt b/bin/startup_commands.txt
new file mode 100644
index 0000000000..1abfa64c87
--- /dev/null
+++ b/bin/startup_commands.txt
@@ -0,0 +1,3 @@
+; You can place region console commands here to execute once the simulator has finished starting up
+; e.g. show stats
+; Lines start with ; are comments.
diff --git a/bin/startup_commands.txt.example b/bin/startup_commands.txt.example
deleted file mode 100644
index 3dba4b378d..0000000000
--- a/bin/startup_commands.txt.example
+++ /dev/null
@@ -1,4 +0,0 @@
-terrain load-tile f32 islandterrain_1024x512.raw 512 1024 1000 1000
-terrain multiply 0.1
-terrain add 5
-