فهرست منبع

Added physics stresstest example.

Lasse Öörni 13 سال پیش
والد
کامیت
5e7387b695
4فایلهای تغییر یافته به همراه516 افزوده شده و 34 حذف شده
  1. 470 0
      Bin/Data/Scripts/Physics.as
  2. 1 0
      Bin/Physics.bat
  3. 44 33
      Docs/GettingStarted.dox
  4. 1 1
      Readme.txt

+ 470 - 0
Bin/Data/Scripts/Physics.as

@@ -0,0 +1,470 @@
+#include "Scripts/Utilities/Network.as"
+
+Scene@ testScene;
+Camera@ camera;
+Node@ cameraNode;
+PostProcess@ edgeFilter;
+PostProcess@ bloom;
+
+float yaw = 0.0;
+float pitch = 0.0;
+int drawDebug = 0;
+
+Text@ downloadsText;
+
+void Start()
+{
+    if (!engine.headless)
+    {
+        InitConsole();
+        InitUI();
+    }
+    else
+        OpenConsoleWindow();
+
+    ParseNetworkArguments();
+
+    InitScene();
+
+    SubscribeToEvent("Update", "HandleUpdate");
+    SubscribeToEvent("KeyDown", "HandleKeyDown");
+    SubscribeToEvent("MouseMove", "HandleMouseMove");
+    SubscribeToEvent("MouseButtonDown", "HandleMouseButtonDown");
+    SubscribeToEvent("MouseButtonUp", "HandleMouseButtonUp");
+    SubscribeToEvent("PostRenderUpdate", "HandlePostRenderUpdate");
+    SubscribeToEvent("SpawnBox", "HandleSpawnBox");
+
+    network.RegisterRemoteEvent("SpawnBox");
+
+    if (runServer)
+    {
+        network.StartServer(serverPort);
+        SubscribeToEvent("ClientConnected", "HandleClientConnected");
+
+        // Disable physics interpolation to ensure clients get sent physically correct transforms
+        testScene.physicsWorld.interpolation = false;
+
+        // Test package download by adding all package files in the cache as requirements for the scene
+        Array<PackageFile@> packages = cache.packageFiles;
+        for (uint i = 0; i < packages.length; ++i)
+            testScene.AddRequiredPackageFile(packages[i]);
+    }
+    if (runClient)
+    {
+        // Test package download. Remove existing Data.pak from resource cache so that it will be downloaded
+        // However, be sure to add the Data directory so that resource requests do not fail in the meanwhile
+        String packageName = fileSystem.programDir + "Data.pak";
+        cache.RemovePackageFile(packageName, false);
+        cache.AddResourceDir(fileSystem.programDir + "Data");
+
+        network.packageCacheDir = fileSystem.programDir;
+        network.Connect(serverAddress, serverPort, testScene);
+    }
+}
+
+void InitConsole()
+{
+    XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
+
+    engine.CreateDebugHud();
+    debugHud.style = uiStyle;
+    debugHud.mode = DEBUGHUD_SHOW_ALL;
+
+    engine.CreateConsole();
+    console.style = uiStyle;
+}
+
+void InitUI()
+{
+    XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
+
+    Cursor@ newCursor = Cursor("Cursor");
+    newCursor.style = uiStyle;
+    newCursor.position = IntVector2(graphics.width / 2, graphics.height / 2);
+    ui.cursor = newCursor;
+    if (GetPlatform() == "Android")
+        ui.cursor.visible = false;
+
+    downloadsText = Text();
+    downloadsText.SetAlignment(HA_CENTER, VA_CENTER);
+    downloadsText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 20);
+    ui.root.AddChild(downloadsText);
+}
+
+void InitScene()
+{
+    testScene = Scene("TestScene");
+
+    // Enable access to this script file & scene from the console
+    script.defaultScene = testScene;
+    script.defaultScriptFile = scriptFile;
+
+    // Create the camera outside the scene so it is unaffected by scene load/save
+    cameraNode = Node();
+    camera = cameraNode.CreateComponent("Camera");
+    cameraNode.position = Vector3(0, 2, -20);
+
+    if (!engine.headless)
+    {
+        edgeFilter = PostProcess();
+        edgeFilter.parameters = cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml");
+        edgeFilter.active = false; // Start out disabled
+
+        bloom = PostProcess();
+        bloom.parameters = cache.GetResource("XMLFile", "PostProcess/Bloom.xml");
+        bloom.active = false;
+
+        renderer.viewports[0] = Viewport(testScene, camera);
+        renderer.viewports[0].AddPostProcess(edgeFilter);
+        renderer.viewports[0].AddPostProcess(bloom);
+    }
+    
+    if (runClient)
+        return;
+
+    PhysicsWorld@ world = testScene.CreateComponent("PhysicsWorld");
+    testScene.CreateComponent("Octree");
+    testScene.CreateComponent("DebugRenderer");
+
+    Node@ zoneNode = testScene.CreateChild("Zone");
+    Zone@ zone = zoneNode.CreateComponent("Zone");
+    zone.ambientColor = Color(0.15, 0.15, 0.15);
+    zone.fogColor = Color(0.5, 0.5, 0.7);
+    zone.fogStart = 100.0;
+    zone.fogEnd = 300.0;
+    zone.boundingBox = BoundingBox(-1000, 1000);
+
+    {
+        Node@ lightNode = testScene.CreateChild("GlobalLight");
+        lightNode.direction = Vector3(0.3, -0.5, 0.425);
+
+        Light@ light = lightNode.CreateComponent("Light");
+        light.lightType = LIGHT_DIRECTIONAL;
+        light.castShadows = true;
+        light.shadowBias = BiasParameters(0.0001, 0.5);
+        light.shadowCascade = CascadeParameters(10.0, 50.0, 200.0, 0.0, 0.8);
+        light.specularIntensity = 0.5;
+    }
+
+    {
+        Node@ objectNode = testScene.CreateChild("Floor");
+        objectNode.position = Vector3(0, -0.5, 0);
+        objectNode.scale = Vector3(500, 1, 500);
+
+        StaticModel@ object = objectNode.CreateComponent("StaticModel");
+        object.model = cache.GetResource("Model", "Models/Box.mdl");
+        object.material = cache.GetResource("Material", "Materials/StoneTiled.xml");
+
+        RigidBody@ body = objectNode.CreateComponent("RigidBody");
+        CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
+        shape.SetBox(Vector3(1, 1, 1));
+    }
+
+    for (uint i = 0; i < 1000; ++i)
+    {
+        Node@ objectNode = testScene.CreateChild("Box");
+        objectNode.position = Vector3(0, i * 2 + 100, 0);
+        objectNode.SetScale(1);
+
+        StaticModel@ object = objectNode.CreateComponent("StaticModel");
+        object.model = cache.GetResource("Model", "Models/Box.mdl");
+        object.material = cache.GetResource("Material", "Materials/Stone.xml");
+        object.castShadows = true;
+
+        RigidBody@ body = objectNode.CreateComponent("RigidBody");
+        body.mass = 10.0;
+        body.friction = 1.0;
+        // When object count is high, disabling collision events gives a significant performance increase
+        body.collisionEventMode = COLLISION_NEVER;
+        CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
+        shape.SetBox(Vector3(1, 1, 1));
+    }
+
+    for (uint i = 0; i < 50; ++i)
+    {
+        Node@ objectNode = testScene.CreateChild("Mushroom");
+        objectNode.position = Vector3(Random() * 400 - 200, 0, Random() * 400 - 200);
+        objectNode.rotation = Quaternion(0, Random(360.0), 0);
+        objectNode.SetScale(5);
+
+        StaticModel@ object = objectNode.CreateComponent("StaticModel");
+        object.model = cache.GetResource("Model", "Models/Mushroom.mdl");
+        object.material = cache.GetResource("Material", "Materials/Mushroom.xml");
+        object.castShadows = true;
+
+        RigidBody@ body = objectNode.CreateComponent("RigidBody");
+        CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
+        shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0);
+    }
+}
+
+void HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    float timeStep = eventData["TimeStep"].GetFloat();
+
+    if (ui.focusElement is null)
+    {
+        float speedMultiplier = 1.0;
+        if (input.keyDown[KEY_LSHIFT])
+            speedMultiplier = 5.0;
+        if (input.keyDown[KEY_LCTRL])
+            speedMultiplier = 0.1;
+
+        if (input.keyDown['W'])
+            cameraNode.TranslateRelative(Vector3(0, 0, 10) * timeStep * speedMultiplier);
+        if (input.keyDown['S'])
+            cameraNode.TranslateRelative(Vector3(0, 0, -10) * timeStep * speedMultiplier);
+        if (input.keyDown['A'])
+            cameraNode.TranslateRelative(Vector3(-10, 0, 0) * timeStep * speedMultiplier);
+        if (input.keyDown['D'])
+            cameraNode.TranslateRelative(Vector3(10, 0, 0) * timeStep * speedMultiplier);
+    }
+
+    // Update package download status
+    if (network.serverConnection !is null)
+    {
+        Connection@ connection = network.serverConnection;
+        if (connection.numDownloads > 0)
+        {
+            downloadsText.text = "Downloads: " + connection.numDownloads + " Current download: " +
+                connection.downloadName + " (" + int(connection.downloadProgress * 100.0) + "%)";
+        }
+        else if (!downloadsText.text.empty)
+            downloadsText.text = "";
+    }
+}
+
+void HandleKeyDown(StringHash eventType, VariantMap& eventData)
+{
+    int key = eventData["Key"].GetInt();
+
+    if (key == KEY_ESC)
+    {
+        if (ui.focusElement is null)
+            engine.Exit();
+        else
+            console.visible = false;
+    }
+    
+    if (key == KEY_F1)
+        console.Toggle();
+
+    if (ui.focusElement is null)
+    {
+        if (key == '1')
+            renderer.renderMode = RenderMode((renderer.renderMode + 1) % 3);
+        
+        if (key == '2')
+        {
+            int quality = renderer.textureQuality;
+            ++quality;
+            if (quality > 2)
+                quality = 0;
+            renderer.textureQuality = quality;
+        }
+
+        if (key == '3')
+        {
+            int quality = renderer.materialQuality;
+            ++quality;
+            if (quality > 2)
+                quality = 0;
+            renderer.materialQuality = quality;
+        }
+
+        if (key == '4')
+            renderer.specularLighting = !renderer.specularLighting;
+
+        if (key == '5')
+            renderer.drawShadows = !renderer.drawShadows;
+
+        if (key == '6')
+        {
+            int size = renderer.shadowMapSize;
+            size *= 2;
+            if (size > 2048)
+                size = 512;
+            renderer.shadowMapSize = size;
+        }
+
+        if (key == '7')
+            renderer.shadowQuality = renderer.shadowQuality + 1;
+
+        if (key == '8')
+        {
+            bool occlusion = renderer.maxOccluderTriangles > 0;
+            occlusion = !occlusion;
+            renderer.maxOccluderTriangles = occlusion ? 5000 : 0;
+        }
+
+        if (key == '9')
+            renderer.dynamicInstancing = !renderer.dynamicInstancing;
+
+        if (key == ' ')
+        {
+            drawDebug++;
+            if (drawDebug > 2)
+                drawDebug = 0;
+        }
+
+        if (key == 'O')
+            camera.orthographic = !camera.orthographic;
+
+        if (key == 'B')
+            bloom.active = !bloom.active;
+
+        if (key == 'F')
+            edgeFilter.active = !edgeFilter.active;
+
+        if (key == 'T')
+            debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
+
+        if (key == KEY_F5)
+        {
+            File@ xmlFile = File(fileSystem.programDir + "Data/Scenes/Physics.xml", FILE_WRITE);
+            testScene.SaveXML(xmlFile);
+        }
+
+        if (key == KEY_F7)
+        {
+            File@ xmlFile = File(fileSystem.programDir + "Data/Scenes/Physics.xml", FILE_READ);
+            if (xmlFile.open)
+                testScene.LoadXML(xmlFile);
+        }
+    }
+}
+
+void HandleMouseMove(StringHash eventType, VariantMap& eventData)
+{
+    if (eventData["Buttons"].GetInt() & MOUSEB_RIGHT != 0)
+    {
+        int mousedx = eventData["DX"].GetInt();
+        int mousedy = eventData["DY"].GetInt();
+        yaw += mousedx / 10.0;
+        pitch += mousedy / 10.0;
+        if (pitch < -90.0)
+            pitch = -90.0;
+        if (pitch > 90.0)
+            pitch = 90.0;
+
+        cameraNode.rotation = Quaternion(pitch, yaw, 0);
+    }
+}
+
+void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
+{
+    int button = eventData["Button"].GetInt();
+    if (button == MOUSEB_RIGHT)
+        ui.cursor.visible = false;
+
+    // Test either creating a new physics object or painting a decal (SHIFT down)
+    if (button == MOUSEB_LEFT && ui.GetElementAt(ui.cursorPosition, true) is null && ui.focusElement is null)
+    {
+        if (!input.qualifierDown[QUAL_SHIFT])
+        {
+            VariantMap eventData;
+            eventData["Pos"] = cameraNode.position;
+            eventData["Rot"] = cameraNode.rotation;
+    
+            // If we are the client, send the spawn command as a remote event, else send locally
+            if (runClient)
+            {
+                if (network.serverConnection !is null)
+                    network.serverConnection.SendRemoteEvent("SpawnBox", true, eventData);
+            }
+            else
+                SendEvent("SpawnBox", eventData);
+        }
+        else
+        {
+            IntVector2 pos = ui.cursorPosition;
+            if (ui.GetElementAt(pos, true) is null && testScene.octree !is null)
+            {
+                Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
+                RayQueryResult result = testScene.octree.RaycastSingle(cameraRay, RAY_TRIANGLE, 250.0, DRAWABLE_GEOMETRY);
+                if (result.drawable !is null)
+                {
+                    Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
+                    DecalSet@ decal = result.drawable.node.GetComponent("DecalSet");
+                    if (decal is null)
+                    {
+                        decal = result.drawable.node.CreateComponent("DecalSet");
+                        decal.material = cache.GetResource("Material", "Materials/UrhoDecal.xml");
+                        // Increase max. vertices/indices if the target is skinned
+                        if (result.drawable.typeName == "AnimatedModel")
+                        {
+                            decal.maxVertices = 2048;
+                            decal.maxIndices = 4096;
+                        }
+                    }
+                    decal.AddDecal(result.drawable, rayHitPos, cameraNode.worldRotation, 0.5, 1.0, 1.0, Vector2(0, 0),
+                        Vector2(1, 1));
+                }
+            }
+        }
+    }
+}
+
+void HandleSpawnBox(StringHash eventType, VariantMap& eventData)
+{
+    Vector3 position = eventData["Pos"].GetVector3();
+    Quaternion rotation = eventData["Rot"].GetQuaternion();
+
+    Node@ newNode = testScene.CreateChild();
+    newNode.position = position;
+    newNode.rotation = rotation;
+    newNode.SetScale(0.2);
+
+    RigidBody@ body = newNode.CreateComponent("RigidBody");
+    body.mass = 1.0;
+    body.friction = 1.0;
+    body.linearVelocity = rotation * Vector3(0.0, 1.0, 10.0);
+
+    CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
+    shape.SetBox(Vector3(1, 1, 1));
+
+    StaticModel@ object = newNode.CreateComponent("StaticModel");
+    object.model = cache.GetResource("Model", "Models/Box.mdl");
+    object.material = cache.GetResource("Material", "Materials/StoneSmall.xml");
+    object.castShadows = true;
+    object.shadowDistance = 150.0;
+    object.drawDistance = 200.0;
+}
+
+void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
+{
+    if (eventData["Button"].GetInt() == MOUSEB_RIGHT)
+        ui.cursor.visible = true;
+}
+
+void HandlePostRenderUpdate()
+{
+    if (engine.headless)
+        return;
+
+    // Draw rendering debug geometry without depth test to see the effect of occlusion
+    if (drawDebug == 1)
+        renderer.DrawDebugGeometry(false);
+    if (drawDebug == 2)
+        testScene.physicsWorld.DrawDebugGeometry(true);
+
+    IntVector2 pos = ui.cursorPosition;
+    if (ui.GetElementAt(pos, true) is null && testScene.octree !is null)
+    {
+        Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
+        RayQueryResult result = testScene.octree.RaycastSingle(cameraRay, RAY_TRIANGLE, 250.0, DRAWABLE_GEOMETRY);
+        if (result.drawable !is null)
+        {
+            Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result.distance;
+            testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
+                Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
+        }
+    }
+}
+
+void HandleClientConnected(StringHash eventType, VariantMap& eventData)
+{
+    Connection@ connection = eventData["Connection"].GetConnection();
+    connection.scene = testScene; // Begin scene replication to the client
+    connection.logStatistics = true;
+}

+ 1 - 0
Bin/Physics.bat

@@ -0,0 +1 @@
+Urho3D.exe Scripts/Physics.as %1 %2 %3 %4 %5 %6 %7 %8

+ 44 - 33
Docs/GettingStarted.dox

@@ -40,7 +40,7 @@ After the build is complete, the programs can be run from the Bin directory.
 
 To run from the Visual Studio debugger, set the Urho3D project as the startup project and enter its relative path and filename into Properties -> Debugging -> Command: ..\\Bin\\Urho3D.exe. Additionally, entering -w into Debugging -> Command Arguments is highly recommended. This enables startup in windowed mode: without it running into an exception or breakpoint will be obnoxious as the mouse cursor will likely be hidden.
 
-To actually make Urho3D.exe do something useful, it must be supplied with the name of the script file it should load and run. You can try for example the following arguments: Scripts/TestScene.as -w
+To actually make Urho3D.exe do something useful, it must be supplied with the name of the script file it should load and run. You can try for example the following arguments: Scripts/NinjaSnowWar.as -w
 
 To make the Urho3D examples start faster on Windows & Direct3D9 mode, run CompileAllShaders.bat from the Bin directory first.
 
@@ -83,7 +83,27 @@ The scripting language used is AngelScript (http://www.angelcode.com/angelscript
 
 On Android and iOS there are no command line options, so running the NinjaSnowWar example is hardcoded. This can be changed from the file Urho3D/Urho3D.cpp.
 
-Currently, five example application scripts exist:
+Currently eight example application scripts exist:
+
+\section Running_NinjaSnowWar NinjaSnowWar
+
+A third-person action game. To start, run NinjaSnowWar.bat in the Bin directory, or use the command Urho3D.exe Scripts/NinjaSnowWar.as
+
+Key and mouse controls:
+
+\verbatim
+WSAD        Move
+Left mouse  Attack
+Space       Jump
+F1          Toggle AngelScript console
+F2          Toggle physics debug geometry
+F3          Toggle profiling display
+F4          Toggle octree debug geometry
+\endverbatim
+
+If a joystick is connected, it can also be used for controlling the player character.
+
+NinjaSnowWar also supports client/server multiplayer. To start the server, run the command NinjaSnowWar.bat server (-headless switch can optionally given so that the server will not open a graphics window.) To connect to a server, specify the server address on the command line, for example NinjaSnowWar.bat 127.0.0.1
 
 \section Running_TestScene TestScene
 
@@ -105,50 +125,32 @@ T           Toggle profiling display
 O           Toggle orthographic camera
 F           Toggle FXAA edge filter
 B           Toggle bloom post-process
-P           Toggle scene animation (TestSceneOld only)
-L           Toggle camera light detached/attached (TestSceneOld only)
 \endverbatim
 
 TestScene also includes a network replication test, where clients can connect, move around as invisible cameras, and create new physics objects. For this, a server needs to be started with the command TestScene.bat server (-headless switch can optionally given so that the server will not open a graphics window) and clients can connect by specifying the server address on the command line, for example TestScene.bat 127.0.0.1
 
-There is also a variation of TestScene ported from Urho3D 1.0, TestSceneOld. It lacks networking features, but is provided for examining backward compatibility and performance. It can be run with TestSceneOld.bat or by using the command Urho3D.exe Scripts/TestSceneOld.as
-
-Yet another variation of TestScene demonstrates terrain rendering. To start, run Terrain.bat, or use the command Urho3D.exe Scripts/Terrain.as
-
-\section Running_NinjaSnowWar NinjaSnowWar
-
-A third-person action game. To start, run NinjaSnowWar.bat in the Bin directory, or use the command Urho3D.exe Scripts/NinjaSnowWar.as
-
-Key and mouse controls:
-
-\verbatim
-WSAD        Move
-Left mouse  Attack
-Space       Jump
-F1          Toggle AngelScript console
-F2          Toggle physics debug geometry
-F3          Toggle profiling display
-F4          Toggle octree debug geometry
-\endverbatim
+\section Running_Editor Editor
 
-If a joystick is connected, it can also be used for controlling the player character.
+%Scene editor application written in script. To start, run Editor.bat, or use the command Urho3D.exe Scripts/Editor.as
 
-NinjaSnowWar also supports client/server multiplayer. To start the server, run the command NinjaSnowWar.bat server (-headless switch can optionally given so that the server will not open a graphics window.) To connect to a server, specify the server address on the command line, for example NinjaSnowWar.bat 127.0.0.1
+For details on how to use the editor, see \ref EditorInstructions "Editor instructions."
 
-\section Running_Editor Editor
+\section Running_Terrain Terrain
 
-%Scene editor application written in script. To start, run Editor.bat, or use the command Urho3D.exe Scripts/Editor.as
+%Terrain rendering example. To start, run Terrain.bat, or use the command Urho3D.exe Scripts/Terrain.as. %Controls are the same as in TestScene.
 
-\section Running_Chat Chat
+\section Running_Physics Physics
 
-Simple client-server chat test application. To start, run Chat.bat or ChatServer.bat in the Bin directory, or use the command Urho3D.exe Scripts/Chat.as
+A stress test of 1000 moving physics objects, which also showcases the performance difference instancing can make. Run with Physics.bat, or use the command Urho3D.exe Scripts/Physics.as. %Controls as in TestScene.
 
-On the client, first type the server address to the text edit box and click "Connect." After connecting successfully you can start typing messages;
-either press return or click "Send" to send them. Press ESC to exit.
+\section Running_TestSceneOld TestSceneOld
 
-To connect automatically, the server address can also be given on the command line, for example Chat.bat 127.0.0.1
+A variation of TestScene ported from Urho3D 1.0. It lacks networking features, but is provided for examining backward compatibility and performance. Run with TestSceneOld.bat or by using the command Urho3D.exe Scripts/TestSceneOld.as. %Controls are like in TestScene, and additionally:
 
-For details on how to use the editor, see \ref EditorInstructions "Editor instructions."
+\verbatim
+P           Toggle scene animation
+L           Toggle camera light detached/attached
+\endverbatim
 
 \section Running_LightTest LightTest
 
@@ -171,6 +173,15 @@ F           Toggle FXAA edge filter
 R           Re-randomize light and object positions
 \endverbatim
 
+\section Running_Chat Chat
+
+Simple client-server chat test application. To start, run Chat.bat or ChatServer.bat in the Bin directory, or use the command Urho3D.exe Scripts/Chat.as
+
+On the client, first type the server address to the text edit box and click "Connect." After connecting successfully you can start typing messages;
+either press return or click "Send" to send them. Press ESC to exit.
+
+To connect automatically, the server address can also be given on the command line, for example Chat.bat 127.0.0.1
+
 \section Running_Commandline Command line options
 
 Urho3D.exe understands the following command line options:

+ 1 - 1
Readme.txt

@@ -144,7 +144,7 @@ breakpoint will be obnoxious as the mouse cursor will likely be hidden.
 
 To actually make Urho3D.exe do something useful, it must be supplied with the
 name of the script file it should load and run. You can try for example the
-following arguments: Scripts/TestScene.as -w
+following arguments: Scripts/NinjaSnowWar.as -w
 
 To make the Urho3D examples start faster on Windows & Direct3D9 mode, run 
 CompileAllShaders.bat from the Bin directory first.