Prechádzať zdrojové kódy

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-kcunney

Kieran Cunney 13 rokov pred
rodič
commit
35743713d9
100 zmenil súbory, kde vykonal 5024 pridanie a 452 odobranie
  1. 1 0
      .gitignore
  2. 5 8
      gameplay-luagen/README.md
  3. 24 2
      gameplay-luagen/gameplay-luagen.vcxproj
  4. 2 0
      gameplay-luagen/gameplay-luagen.vcxproj.user
  5. 42 29
      gameplay-luagen/src/Generator.cpp
  6. 1 0
      gameplay-luagen/src/Generator.h
  7. 0 2
      gameplay/android/jni/Android.mk
  8. 26 4
      gameplay/gameplay.vcxproj
  9. 78 12
      gameplay/gameplay.vcxproj.filters
  10. 159 27
      gameplay/gameplay.xcodeproj/project.pbxproj
  11. 90 0
      gameplay/src/AIAgent.cpp
  12. 163 0
      gameplay/src/AIAgent.h
  13. 199 0
      gameplay/src/AIController.cpp
  14. 107 0
      gameplay/src/AIController.h
  15. 203 0
      gameplay/src/AIMessage.cpp
  16. 272 0
      gameplay/src/AIMessage.h
  17. 74 0
      gameplay/src/AIState.cpp
  18. 137 0
      gameplay/src/AIState.h
  19. 133 0
      gameplay/src/AIStateMachine.cpp
  20. 160 0
      gameplay/src/AIStateMachine.h
  21. 2 0
      gameplay/src/AudioSource.h
  22. 1 1
      gameplay/src/Base.h
  23. 5 0
      gameplay/src/Bundle.h
  24. 1 0
      gameplay/src/CheckBox.h
  25. 1 0
      gameplay/src/Container.h
  26. 1 0
      gameplay/src/Curve.h
  27. 1 0
      gameplay/src/DepthStencilTarget.h
  28. 40 39
      gameplay/src/Font.h
  29. 2 0
      gameplay/src/Form.h
  30. 1 0
      gameplay/src/FrameBuffer.h
  31. 19 3
      gameplay/src/Game.cpp
  32. 10 0
      gameplay/src/Game.h
  33. 4 0
      gameplay/src/Game.inl
  34. 1 0
      gameplay/src/Image.h
  35. 1 0
      gameplay/src/Joystick.h
  36. 1 0
      gameplay/src/Label.h
  37. 4 0
      gameplay/src/Material.h
  38. 2 0
      gameplay/src/MeshBatch.h
  39. 1 0
      gameplay/src/Model.h
  40. 31 2
      gameplay/src/Node.cpp
  41. 21 0
      gameplay/src/Node.h
  42. 3 0
      gameplay/src/ParticleEmitter.h
  43. 1 0
      gameplay/src/Properties.h
  44. 1 0
      gameplay/src/RadioButton.h
  45. 1 0
      gameplay/src/RenderState.h
  46. 1 0
      gameplay/src/RenderTarget.h
  47. 1 0
      gameplay/src/SceneLoader.h
  48. 7 0
      gameplay/src/ScriptController.cpp
  49. 1 0
      gameplay/src/Slider.h
  50. 2 0
      gameplay/src/SpriteBatch.h
  51. 1 0
      gameplay/src/TextBox.h
  52. 5 0
      gameplay/src/Texture.h
  53. 1 0
      gameplay/src/Theme.h
  54. 1 0
      gameplay/src/VertexAttributeBinding.h
  55. 1 0
      gameplay/src/VerticalLayout.h
  56. 6 0
      gameplay/src/gameplay.h
  57. 469 0
      gameplay/src/lua/lua_AIAgent.cpp
  58. 24 0
      gameplay/src/lua/lua_AIAgent.h
  59. 115 0
      gameplay/src/lua/lua_AIAgentListener.cpp
  60. 15 0
      gameplay/src/lua/lua_AIAgentListener.h
  61. 144 0
      gameplay/src/lua/lua_AIController.cpp
  62. 15 0
      gameplay/src/lua/lua_AIController.h
  63. 838 0
      gameplay/src/lua/lua_AIMessage.cpp
  64. 32 0
      gameplay/src/lua/lua_AIMessage.h
  65. 58 0
      gameplay/src/lua/lua_AIMessageParameterType.cpp
  66. 15 0
      gameplay/src/lua/lua_AIMessageParameterType.h
  67. 309 0
      gameplay/src/lua/lua_AIState.cpp
  68. 20 0
      gameplay/src/lua/lua_AIState.h
  69. 243 0
      gameplay/src/lua/lua_AIStateListener.cpp
  70. 18 0
      gameplay/src/lua/lua_AIStateListener.h
  71. 343 0
      gameplay/src/lua/lua_AIStateMachine.cpp
  72. 19 0
      gameplay/src/lua/lua_AIStateMachine.h
  73. 2 2
      gameplay/src/lua/lua_AudioSource.cpp
  74. 6 6
      gameplay/src/lua/lua_Bundle.cpp
  75. 1 1
      gameplay/src/lua/lua_CheckBox.cpp
  76. 2 2
      gameplay/src/lua/lua_Container.cpp
  77. 1 1
      gameplay/src/lua/lua_Curve.cpp
  78. 1 1
      gameplay/src/lua/lua_DepthStencilTarget.cpp
  79. 3 54
      gameplay/src/lua/lua_Font.cpp
  80. 0 202
      gameplay/src/lua/lua_FontGlyph.cpp
  81. 0 18
      gameplay/src/lua/lua_FontGlyph.h
  82. 0 1
      gameplay/src/lua/lua_FontText.cpp
  83. 3 3
      gameplay/src/lua/lua_Form.cpp
  84. 1 1
      gameplay/src/lua/lua_FrameBuffer.cpp
  85. 47 0
      gameplay/src/lua/lua_Game.cpp
  86. 1 0
      gameplay/src/lua/lua_Game.h
  87. 22 10
      gameplay/src/lua/lua_Global.cpp
  88. 1 0
      gameplay/src/lua/lua_Global.h
  89. 1 1
      gameplay/src/lua/lua_Image.cpp
  90. 86 0
      gameplay/src/lua/lua_Joint.cpp
  91. 2 0
      gameplay/src/lua/lua_Joint.h
  92. 1 1
      gameplay/src/lua/lua_Joystick.cpp
  93. 1 1
      gameplay/src/lua/lua_Label.cpp
  94. 5 5
      gameplay/src/lua/lua_Material.cpp
  95. 6 6
      gameplay/src/lua/lua_MeshBatch.cpp
  96. 1 1
      gameplay/src/lua/lua_Model.cpp
  97. 88 2
      gameplay/src/lua/lua_Node.cpp
  98. 2 0
      gameplay/src/lua/lua_Node.h
  99. 3 3
      gameplay/src/lua/lua_ParticleEmitter.cpp
  100. 1 1
      gameplay/src/lua/lua_Properties.cpp

+ 1 - 0
.gitignore

@@ -197,3 +197,4 @@ Thumbs.db
 /gameplay-samples/sample05-lua/android/project.properties
 
 /gameplay-internal
+/gameplay\android/proguard-project.txt

+ 5 - 8
gameplay-luagen/README.md

@@ -31,23 +31,20 @@ There are also prebuilt binaries in the gameplay/bin folder.
     end
 - Note: you can't pass an enum to a function that doesn't explicitly take an enum (i.e. Control::setTextColor, which takes an unsigned char). In these cases, you need to go look up the enum values and pass them directly.
 
+
 ## Unsupported Features
 - operators
 - templates
 - variable arguments
 - Lua doesn't support as many types as C++ so if there are functions that overload on parameters with types that overlap in Lua, the overloading won't work properly (i.e. char, short, int, long, float, double and all corresponding unsigned variants overlap in Lua).
 
-### To Do List
-- Get Mac OS X and iOS working.
-- Fix hierarchy inheritance
-- Fix memory leaks in gameplay-luagen and in generated code.
-    * Add "@script{create}" to the appropriate gameplay functions.
-    * Add "@script{own}" to array parameters that are owned by the function or class they are passed to?
-- Add a global function that implements casting for use from Lua scripts (i.e. to downcast from a Control to a Button).
 
-### Future Feature List
+### To Do List
+- ScriptTarget class (remove ScriptListener class).
 - Add support for users to generate bindings for their own classes.
 - Look into updating bindValue() to support binding to any Lua script function.
+- Add a global function that implements casting for use from Lua scripts (i.e. to downcast from a Control to a Button).
+- Currently ignored: there is one memory leak in gameplay-luagen that is very difficult to fix (it appears to be a locale related leak-something leaks the first time an ofstream is created-doesn't matter the ofstream).
 
 
 ## Disclaimer

+ 24 - 2
gameplay-luagen/gameplay-luagen.vcxproj

@@ -55,9 +55,13 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
+    <CustomBuildBeforeTargets>
+    </CustomBuildBeforeTargets>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -76,8 +80,17 @@
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <PreBuildEvent>
-      <Command>del /Q "$(ProjectDir)..\gameplay\src\lua\*"</Command>
+      <Command>
+      </Command>
     </PreBuildEvent>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
@@ -99,8 +112,17 @@
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <PreBuildEvent>
-      <Command>del /Q "$(ProjectDir)..\gameplay\src\lua\*"</Command>
+      <Command>
+      </Command>
     </PreBuildEvent>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Message>
+      </Message>
+    </CustomBuildStep>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 2 - 0
gameplay-luagen/gameplay-luagen.vcxproj.user

@@ -3,9 +3,11 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LocalDebuggerCommandArguments>"$(ProjectDir)xml/" "$(ProjectDir)../gameplay/src/lua/"</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>$(TargetPath)</LocalDebuggerCommand>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LocalDebuggerCommandArguments>"$(ProjectDir)xml/" "$(ProjectDir)../gameplay/src/lua/"</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerCommand>$(TargetPath)</LocalDebuggerCommand>
   </PropertyGroup>
 </Project>

+ 42 - 29
gameplay-luagen/src/Generator.cpp

@@ -2,8 +2,6 @@
 
 Generator* Generator::__instance = NULL;
 
-set<string> __warnings;
-
 // Warning flags.
 static bool __printTemplateWarning = false;
 static bool __printVarargWarning = false;
@@ -14,6 +12,7 @@ static string trim(const string& str);
 static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param::Kind& kind);
 static inline bool isWantedFileNormal(const string& s);
 static inline bool isNamespaceFile(const string& s);
+static inline bool isGeneratedBindingFile(const string& s);
 static bool getFileList(string directory, vector<string>& files, bool (*isWantedFile)(const string& s));
 static bool isReservedKeyword(string name);
 
@@ -103,12 +102,17 @@ bool Generator::isDerived(const ClassBinding& c, string classname)
 {
     for (unsigned int i = 0; i < c.derived.size(); i++)
     {
-        const string& derivedClassName = getIdentifier(c.derived[i]);
-        if (derivedClassName == classname || 
-            (_classes.find(derivedClassName) != _classes.end() &&
-            isDerived(_classes[derivedClassName], classname)))
-        {
-            return true;
+        // If the derived class is not in the ref ID table, then it
+        // is a hidden (protected, private, etc.) class, so don't consider it.
+        if (_refIds.find(c.derived[i]) != _refIds.end())
+        {
+            const string& derivedClassName = getIdentifier(c.derived[i]);
+            if (derivedClassName == classname || 
+                (_classes.find(derivedClassName) != _classes.end() &&
+                isDerived(_classes[derivedClassName], classname)))
+            {
+                return true;
+            }
         }
     }
     return false;
@@ -151,6 +155,18 @@ void Generator::run(string inDir, string outDir)
     // Set the output directory.
     _outDir = outDir;
 
+    // Get a list of all .cpp and .h files in the output directory so
+    // we can delete them before generating new bindings.
+    vector<string> oldBindingsFiles;
+    getFileList(outDir, oldBindingsFiles, isGeneratedBindingFile);
+
+    // Delete the old bindings.
+    for (unsigned int i = 0; i < oldBindingsFiles.size(); i++)
+    {
+        remove(oldBindingsFiles[i].c_str());
+    }
+
+
     // Get a list of the Doxygen XML files that specify a namespace.
     // Note: we must do this before adding the normal files so that
     // when we process the files sequentially, we process the namespaces
@@ -370,10 +386,6 @@ void Generator::getNamespace(XMLElement* nsNode, const string& name)
 
 void Generator::getClass(XMLElement* classNode, const string& name)
 {
-    // Check if we should ignore this class.
-    if (getScriptFlag(classNode) == "ignore")
-        return;
-
     // Get the ref id for the class.
     string refId = classNode->Attribute("id");
 
@@ -383,6 +395,10 @@ void Generator::getClass(XMLElement* classNode, const string& name)
     // Store the mapping between the ref id and the class's fully qualified name.
     Generator::getInstance()->setIdentifier(refId, classBinding.classname);
 
+    // Check if we should ignore this class.
+    if (getScriptFlag(classNode) == "ignore")
+        return;
+
     // Get the include header for the original class declaration.
     XMLElement* includeElement = classNode->FirstChildElement("includes");
     if (includeElement)
@@ -857,7 +873,6 @@ string Generator::getScriptFlag(XMLElement* e)
     return flag;
 }
 
-
 void Generator::getCreateFlag(XMLElement* e, FunctionBinding& b)
 {
     if (getScriptFlag(e) == "create")
@@ -1495,11 +1510,6 @@ void Generator::generateBindings()
         {
             string path = _outDir + string(LUA_GLOBAL_FILENAME) + string(".h");
             ofstream global(path.c_str());
-            if (!global)
-            {
-                GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
-                goto end;
-            }
             includeGuard = string(LUA_GLOBAL_FILENAME) + string("_H_");
             transform(includeGuard.begin(), includeGuard.end(), includeGuard.begin(), ::toupper);
             global << "#ifndef " << includeGuard << "\n";
@@ -1550,13 +1560,7 @@ void Generator::generateBindings()
         // Write out the implementation.
         {
             string path = _outDir + string(LUA_GLOBAL_FILENAME) + string(".cpp");
-            ofstream global(path.c_str());
-            if (!global)
-            {
-                GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
-                goto end;
-            }
-            
+            ofstream global(path.c_str());            
             global << "#include \"ScriptController.h\"\n";
             global << "#include \"" << LUA_GLOBAL_FILENAME << ".h\"\n";
             map<string, set<string> >::iterator iter = _includes.find(string(LUA_GLOBAL_FILENAME) + string(".h"));
@@ -1658,7 +1662,6 @@ void Generator::generateBindings()
         }
     }
 
-end:
     luaAllCpp << "}\n\n";
     if (bindingNS)
         luaAllCpp << "}\n\n";
@@ -1682,9 +1685,14 @@ void Generator::getAllDerived(set<string>& derived, string classname)
 {
     for (unsigned int i = 0, count = _classes[classname].derived.size(); i < count; i++)
     {
-        string derivedClassName = getIdentifier(_classes[classname].derived[i]);
-        derived.insert(derivedClassName);
-        getAllDerived(derived, derivedClassName);
+        // If the derived class is not in the ref ID table, then it
+        // is a hidden (protected, private, etc.) class, so don't include it.
+        if (_refIds.find(_classes[classname].derived[i]) != _refIds.end())
+        {
+            string derivedClassName = getIdentifier(_classes[classname].derived[i]);
+            derived.insert(derivedClassName);
+            getAllDerived(derived, derivedClassName);
+        }
     }
 }
 
@@ -1767,6 +1775,11 @@ static inline bool isNamespaceFile(const string& s)
     return false;
 }
 
+static inline bool isGeneratedBindingFile(const string& s)
+{
+    return ( (s.find(".cpp") == s.size() - 4) || (s.find(".h") == s.size() - 2) );
+}
+
 static bool getFileList(string directory, vector<string>& files, bool (*isWantedFile)(const string& s))
 {
 #ifdef WIN32

+ 1 - 0
gameplay-luagen/src/Generator.h

@@ -199,6 +199,7 @@ private:
     map<string, EnumBinding> _enums;
     map<string, vector<string> > _namespaces;
     map<string, TypedefBinding> _typedefs;
+    set<string> __warnings;
 };
 
 #endif

+ 0 - 2
gameplay/android/jni/Android.mk

@@ -142,7 +142,6 @@ LOCAL_SRC_FILES := \
     lua/lua_FileSystem.cpp \
     lua/lua_FlowLayout.cpp \
     lua/lua_Font.cpp \
-    lua/lua_FontGlyph.cpp \
     lua/lua_FontJustify.cpp \
     lua/lua_FontStyle.cpp \
     lua/lua_FontText.cpp \
@@ -226,7 +225,6 @@ LOCAL_SRC_FILES := \
     lua/lua_RenderTarget.cpp \
     lua/lua_Scene.cpp \
     lua/lua_SceneDebugFlags.cpp \
-    lua/lua_SceneLoader.cpp \
     lua/lua_ScreenDisplayer.cpp \
     lua/lua_ScriptController.cpp \
     lua/lua_Slider.cpp \

+ 26 - 4
gameplay/gameplay.vcxproj

@@ -16,6 +16,11 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\AbsoluteLayout.cpp" />
+    <ClCompile Include="src\AIAgent.cpp" />
+    <ClCompile Include="src\AIController.cpp" />
+    <ClCompile Include="src\AIMessage.cpp" />
+    <ClCompile Include="src\AIState.cpp" />
+    <ClCompile Include="src\AIStateMachine.cpp" />
     <ClCompile Include="src\Animation.cpp" />
     <ClCompile Include="src\AnimationClip.cpp" />
     <ClCompile Include="src\AnimationController.cpp" />
@@ -54,6 +59,14 @@
     <ClCompile Include="src\Layout.cpp" />
     <ClCompile Include="src\Light.cpp" />
     <ClCompile Include="src\lua\lua_AbsoluteLayout.cpp" />
+    <ClCompile Include="src\lua\lua_AIAgent.cpp" />
+    <ClCompile Include="src\lua\lua_AIAgentListener.cpp" />
+    <ClCompile Include="src\lua\lua_AIController.cpp" />
+    <ClCompile Include="src\lua\lua_AIMessage.cpp" />
+    <ClCompile Include="src\lua\lua_AIMessageParameterType.cpp" />
+    <ClCompile Include="src\lua\lua_AIState.cpp" />
+    <ClCompile Include="src\lua\lua_AIStateListener.cpp" />
+    <ClCompile Include="src\lua\lua_AIStateMachine.cpp" />
     <ClCompile Include="src\lua\lua_all_bindings.cpp" />
     <ClCompile Include="src\lua\lua_Animation.cpp" />
     <ClCompile Include="src\lua\lua_AnimationClip.cpp" />
@@ -89,7 +102,6 @@
     <ClCompile Include="src\lua\lua_FileSystem.cpp" />
     <ClCompile Include="src\lua\lua_FlowLayout.cpp" />
     <ClCompile Include="src\lua\lua_Font.cpp" />
-    <ClCompile Include="src\lua\lua_FontGlyph.cpp" />
     <ClCompile Include="src\lua\lua_FontJustify.cpp" />
     <ClCompile Include="src\lua\lua_FontStyle.cpp" />
     <ClCompile Include="src\lua\lua_FontText.cpp" />
@@ -173,7 +185,6 @@
     <ClCompile Include="src\lua\lua_RenderTarget.cpp" />
     <ClCompile Include="src\lua\lua_Scene.cpp" />
     <ClCompile Include="src\lua\lua_SceneDebugFlags.cpp" />
-    <ClCompile Include="src\lua\lua_SceneLoader.cpp" />
     <ClCompile Include="src\lua\lua_ScreenDisplayer.cpp" />
     <ClCompile Include="src\lua\lua_ScriptController.cpp" />
     <ClCompile Include="src\lua\lua_Slider.cpp" />
@@ -261,6 +272,11 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\AbsoluteLayout.h" />
+    <ClInclude Include="src\AIAgent.h" />
+    <ClInclude Include="src\AIController.h" />
+    <ClInclude Include="src\AIMessage.h" />
+    <ClInclude Include="src\AIState.h" />
+    <ClInclude Include="src\AIStateMachine.h" />
     <ClInclude Include="src\Animation.h" />
     <ClInclude Include="src\AnimationClip.h" />
     <ClInclude Include="src\AnimationController.h" />
@@ -299,6 +315,14 @@
     <ClInclude Include="src\Layout.h" />
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\lua\lua_AbsoluteLayout.h" />
+    <ClInclude Include="src\lua\lua_AIAgent.h" />
+    <ClInclude Include="src\lua\lua_AIAgentListener.h" />
+    <ClInclude Include="src\lua\lua_AIController.h" />
+    <ClInclude Include="src\lua\lua_AIMessage.h" />
+    <ClInclude Include="src\lua\lua_AIMessageParameterType.h" />
+    <ClInclude Include="src\lua\lua_AIState.h" />
+    <ClInclude Include="src\lua\lua_AIStateListener.h" />
+    <ClInclude Include="src\lua\lua_AIStateMachine.h" />
     <ClInclude Include="src\lua\lua_all_bindings.h" />
     <ClInclude Include="src\lua\lua_Animation.h" />
     <ClInclude Include="src\lua\lua_AnimationClip.h" />
@@ -334,7 +358,6 @@
     <ClInclude Include="src\lua\lua_FileSystem.h" />
     <ClInclude Include="src\lua\lua_FlowLayout.h" />
     <ClInclude Include="src\lua\lua_Font.h" />
-    <ClInclude Include="src\lua\lua_FontGlyph.h" />
     <ClInclude Include="src\lua\lua_FontJustify.h" />
     <ClInclude Include="src\lua\lua_FontStyle.h" />
     <ClInclude Include="src\lua\lua_FontText.h" />
@@ -418,7 +441,6 @@
     <ClInclude Include="src\lua\lua_RenderTarget.h" />
     <ClInclude Include="src\lua\lua_Scene.h" />
     <ClInclude Include="src\lua\lua_SceneDebugFlags.h" />
-    <ClInclude Include="src\lua\lua_SceneLoader.h" />
     <ClInclude Include="src\lua\lua_ScreenDisplayer.h" />
     <ClInclude Include="src\lua\lua_ScriptController.h" />
     <ClInclude Include="src\lua\lua_Slider.h" />

+ 78 - 12
gameplay/gameplay.vcxproj.filters

@@ -366,9 +366,6 @@
     <ClCompile Include="src\lua\lua_Font.cpp">
       <Filter>lua</Filter>
     </ClCompile>
-    <ClCompile Include="src\lua\lua_FontGlyph.cpp">
-      <Filter>lua</Filter>
-    </ClCompile>
     <ClCompile Include="src\lua\lua_FontText.cpp">
       <Filter>lua</Filter>
     </ClCompile>
@@ -540,9 +537,6 @@
     <ClCompile Include="src\lua\lua_Scene.cpp">
       <Filter>lua</Filter>
     </ClCompile>
-    <ClCompile Include="src\lua\lua_SceneLoader.cpp">
-      <Filter>lua</Filter>
-    </ClCompile>
     <ClCompile Include="src\lua\lua_ScreenDisplayer.cpp">
       <Filter>lua</Filter>
     </ClCompile>
@@ -744,6 +738,45 @@
     <ClCompile Include="src\ScriptListener.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\AIAgent.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\AIController.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\AIMessage.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\AIState.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\AIStateMachine.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIAgent.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIAgentListener.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIController.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIMessage.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIMessageParameterType.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIState.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIStateListener.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_AIStateMachine.cpp">
+      <Filter>lua</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
@@ -1106,9 +1139,6 @@
     <ClInclude Include="src\lua\lua_Font.h">
       <Filter>lua</Filter>
     </ClInclude>
-    <ClInclude Include="src\lua\lua_FontGlyph.h">
-      <Filter>lua</Filter>
-    </ClInclude>
     <ClInclude Include="src\lua\lua_FontText.h">
       <Filter>lua</Filter>
     </ClInclude>
@@ -1280,9 +1310,6 @@
     <ClInclude Include="src\lua\lua_Scene.h">
       <Filter>lua</Filter>
     </ClInclude>
-    <ClInclude Include="src\lua\lua_SceneLoader.h">
-      <Filter>lua</Filter>
-    </ClInclude>
     <ClInclude Include="src\lua\lua_ScreenDisplayer.h">
       <Filter>lua</Filter>
     </ClInclude>
@@ -1481,6 +1508,45 @@
     <ClInclude Include="src\ScriptListener.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\AIStateMachine.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\AIAgent.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\AIController.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\AIMessage.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\AIState.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIAgent.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIAgentListener.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIController.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIMessage.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIMessageParameterType.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIState.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIStateListener.h">
+      <Filter>lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_AIStateMachine.h">
+      <Filter>lua</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\gameplay-main-macosx.mm">

+ 159 - 27
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -40,6 +40,58 @@
 		426878AF153F4BB300844500 /* FlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 426878AB153F4BB300844500 /* FlowLayout.h */; };
 		4271C08E15337C8200B89DA7 /* Layout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4271C08D15337C8200B89DA7 /* Layout.cpp */; };
 		4271C08F15337C8200B89DA7 /* Layout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4271C08D15337C8200B89DA7 /* Layout.cpp */; };
+		42789FCC15B0E83700866F5B /* AIAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC215B0E83700866F5B /* AIAgent.cpp */; };
+		42789FCD15B0E83700866F5B /* AIAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC215B0E83700866F5B /* AIAgent.cpp */; };
+		42789FCE15B0E83700866F5B /* AIAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC315B0E83700866F5B /* AIAgent.h */; };
+		42789FCF15B0E83700866F5B /* AIAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC315B0E83700866F5B /* AIAgent.h */; };
+		42789FD015B0E83700866F5B /* AIController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC415B0E83700866F5B /* AIController.cpp */; };
+		42789FD115B0E83700866F5B /* AIController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC415B0E83700866F5B /* AIController.cpp */; };
+		42789FD215B0E83700866F5B /* AIController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC515B0E83700866F5B /* AIController.h */; };
+		42789FD315B0E83700866F5B /* AIController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC515B0E83700866F5B /* AIController.h */; };
+		42789FD415B0E83700866F5B /* AIMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC615B0E83700866F5B /* AIMessage.cpp */; };
+		42789FD515B0E83700866F5B /* AIMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC615B0E83700866F5B /* AIMessage.cpp */; };
+		42789FD615B0E83700866F5B /* AIMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC715B0E83700866F5B /* AIMessage.h */; };
+		42789FD715B0E83700866F5B /* AIMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC715B0E83700866F5B /* AIMessage.h */; };
+		42789FD815B0E83700866F5B /* AIState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC815B0E83700866F5B /* AIState.cpp */; };
+		42789FD915B0E83700866F5B /* AIState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FC815B0E83700866F5B /* AIState.cpp */; };
+		42789FDA15B0E83700866F5B /* AIState.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC915B0E83700866F5B /* AIState.h */; };
+		42789FDB15B0E83700866F5B /* AIState.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FC915B0E83700866F5B /* AIState.h */; };
+		42789FDC15B0E83700866F5B /* AIStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FCA15B0E83700866F5B /* AIStateMachine.cpp */; };
+		42789FDD15B0E83700866F5B /* AIStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FCA15B0E83700866F5B /* AIStateMachine.cpp */; };
+		42789FDE15B0E83700866F5B /* AIStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FCB15B0E83700866F5B /* AIStateMachine.h */; };
+		42789FDF15B0E83700866F5B /* AIStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FCB15B0E83700866F5B /* AIStateMachine.h */; };
+		42789FF115B0E85500866F5B /* lua_AIAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE115B0E85500866F5B /* lua_AIAgent.cpp */; };
+		42789FF215B0E85500866F5B /* lua_AIAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE115B0E85500866F5B /* lua_AIAgent.cpp */; };
+		42789FF315B0E85500866F5B /* lua_AIAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE215B0E85500866F5B /* lua_AIAgent.h */; };
+		42789FF415B0E85500866F5B /* lua_AIAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE215B0E85500866F5B /* lua_AIAgent.h */; };
+		42789FF515B0E85500866F5B /* lua_AIAgentListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE315B0E85500866F5B /* lua_AIAgentListener.cpp */; };
+		42789FF615B0E85500866F5B /* lua_AIAgentListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE315B0E85500866F5B /* lua_AIAgentListener.cpp */; };
+		42789FF715B0E85500866F5B /* lua_AIAgentListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE415B0E85500866F5B /* lua_AIAgentListener.h */; };
+		42789FF815B0E85500866F5B /* lua_AIAgentListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE415B0E85500866F5B /* lua_AIAgentListener.h */; };
+		42789FF915B0E85500866F5B /* lua_AIController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE515B0E85500866F5B /* lua_AIController.cpp */; };
+		42789FFA15B0E85500866F5B /* lua_AIController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE515B0E85500866F5B /* lua_AIController.cpp */; };
+		42789FFB15B0E85500866F5B /* lua_AIController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE615B0E85500866F5B /* lua_AIController.h */; };
+		42789FFC15B0E85500866F5B /* lua_AIController.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE615B0E85500866F5B /* lua_AIController.h */; };
+		42789FFD15B0E85500866F5B /* lua_AIMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE715B0E85500866F5B /* lua_AIMessage.cpp */; };
+		42789FFE15B0E85500866F5B /* lua_AIMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE715B0E85500866F5B /* lua_AIMessage.cpp */; };
+		42789FFF15B0E85500866F5B /* lua_AIMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE815B0E85500866F5B /* lua_AIMessage.h */; };
+		4278A00015B0E85500866F5B /* lua_AIMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FE815B0E85500866F5B /* lua_AIMessage.h */; };
+		4278A00115B0E85500866F5B /* lua_AIMessageParameterType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE915B0E85500866F5B /* lua_AIMessageParameterType.cpp */; };
+		4278A00215B0E85500866F5B /* lua_AIMessageParameterType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FE915B0E85500866F5B /* lua_AIMessageParameterType.cpp */; };
+		4278A00315B0E85500866F5B /* lua_AIMessageParameterType.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEA15B0E85500866F5B /* lua_AIMessageParameterType.h */; };
+		4278A00415B0E85500866F5B /* lua_AIMessageParameterType.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEA15B0E85500866F5B /* lua_AIMessageParameterType.h */; };
+		4278A00515B0E85500866F5B /* lua_AIState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FEB15B0E85500866F5B /* lua_AIState.cpp */; };
+		4278A00615B0E85500866F5B /* lua_AIState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FEB15B0E85500866F5B /* lua_AIState.cpp */; };
+		4278A00715B0E85500866F5B /* lua_AIState.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEC15B0E85500866F5B /* lua_AIState.h */; };
+		4278A00815B0E85500866F5B /* lua_AIState.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEC15B0E85500866F5B /* lua_AIState.h */; };
+		4278A00915B0E85500866F5B /* lua_AIStateListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FED15B0E85500866F5B /* lua_AIStateListener.cpp */; };
+		4278A00A15B0E85500866F5B /* lua_AIStateListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FED15B0E85500866F5B /* lua_AIStateListener.cpp */; };
+		4278A00B15B0E85500866F5B /* lua_AIStateListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEE15B0E85500866F5B /* lua_AIStateListener.h */; };
+		4278A00C15B0E85500866F5B /* lua_AIStateListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FEE15B0E85500866F5B /* lua_AIStateListener.h */; };
+		4278A00D15B0E85500866F5B /* lua_AIStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FEF15B0E85500866F5B /* lua_AIStateMachine.cpp */; };
+		4278A00E15B0E85500866F5B /* lua_AIStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42789FEF15B0E85500866F5B /* lua_AIStateMachine.cpp */; };
+		4278A00F15B0E85500866F5B /* lua_AIStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FF015B0E85500866F5B /* lua_AIStateMachine.h */; };
+		4278A01015B0E85500866F5B /* lua_AIStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 42789FF015B0E85500866F5B /* lua_AIStateMachine.h */; };
 		428390991489D6E800E2B2F5 /* SceneLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 428390971489D6E800E2B2F5 /* SceneLoader.cpp */; };
 		4283909A1489D6E800E2B2F5 /* SceneLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 428390981489D6E800E2B2F5 /* SceneLoader.h */; };
 		42B7000015B08108002BB8C3 /* lua_ControlAlignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEA315B08108002BB8C3 /* lua_ControlAlignment.h */; };
@@ -88,10 +140,6 @@
 		42B7002B15B08108002BB8C3 /* lua_Font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FEB815B08108002BB8C3 /* lua_Font.cpp */; };
 		42B7002C15B08108002BB8C3 /* lua_Font.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEB915B08108002BB8C3 /* lua_Font.h */; };
 		42B7002D15B08108002BB8C3 /* lua_Font.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEB915B08108002BB8C3 /* lua_Font.h */; };
-		42B7002E15B08108002BB8C3 /* lua_FontGlyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FEBA15B08108002BB8C3 /* lua_FontGlyph.cpp */; };
-		42B7002F15B08108002BB8C3 /* lua_FontGlyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FEBA15B08108002BB8C3 /* lua_FontGlyph.cpp */; };
-		42B7003015B08108002BB8C3 /* lua_FontGlyph.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEBB15B08108002BB8C3 /* lua_FontGlyph.h */; };
-		42B7003115B08108002BB8C3 /* lua_FontGlyph.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEBB15B08108002BB8C3 /* lua_FontGlyph.h */; };
 		42B7003215B08108002BB8C3 /* lua_FontJustify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FEBC15B08108002BB8C3 /* lua_FontJustify.cpp */; };
 		42B7003315B08108002BB8C3 /* lua_FontJustify.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FEBC15B08108002BB8C3 /* lua_FontJustify.cpp */; };
 		42B7003415B08108002BB8C3 /* lua_FontJustify.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FEBD15B08108002BB8C3 /* lua_FontJustify.h */; };
@@ -424,10 +472,6 @@
 		42B7017B15B08109002BB8C3 /* lua_SceneDebugFlags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FF6015B08108002BB8C3 /* lua_SceneDebugFlags.cpp */; };
 		42B7017C15B08109002BB8C3 /* lua_SceneDebugFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FF6115B08108002BB8C3 /* lua_SceneDebugFlags.h */; };
 		42B7017D15B08109002BB8C3 /* lua_SceneDebugFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FF6115B08108002BB8C3 /* lua_SceneDebugFlags.h */; };
-		42B7017E15B08109002BB8C3 /* lua_SceneLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FF6215B08108002BB8C3 /* lua_SceneLoader.cpp */; };
-		42B7017F15B08109002BB8C3 /* lua_SceneLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FF6215B08108002BB8C3 /* lua_SceneLoader.cpp */; };
-		42B7018015B08109002BB8C3 /* lua_SceneLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FF6315B08108002BB8C3 /* lua_SceneLoader.h */; };
-		42B7018115B08109002BB8C3 /* lua_SceneLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FF6315B08108002BB8C3 /* lua_SceneLoader.h */; };
 		42B7018215B08109002BB8C3 /* lua_ScreenDisplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FF6415B08108002BB8C3 /* lua_ScreenDisplayer.cpp */; };
 		42B7018315B08109002BB8C3 /* lua_ScreenDisplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42B7FF6415B08108002BB8C3 /* lua_ScreenDisplayer.cpp */; };
 		42B7018415B08109002BB8C3 /* lua_ScreenDisplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 42B7FF6515B08108002BB8C3 /* lua_ScreenDisplayer.h */; };
@@ -1030,6 +1074,32 @@
 		426878AA153F4BB300844500 /* FlowLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FlowLayout.cpp; path = src/FlowLayout.cpp; sourceTree = SOURCE_ROOT; };
 		426878AB153F4BB300844500 /* FlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlowLayout.h; path = src/FlowLayout.h; sourceTree = SOURCE_ROOT; };
 		4271C08D15337C8200B89DA7 /* Layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Layout.cpp; path = src/Layout.cpp; sourceTree = SOURCE_ROOT; };
+		42789FC215B0E83700866F5B /* AIAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIAgent.cpp; path = src/AIAgent.cpp; sourceTree = SOURCE_ROOT; };
+		42789FC315B0E83700866F5B /* AIAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIAgent.h; path = src/AIAgent.h; sourceTree = SOURCE_ROOT; };
+		42789FC415B0E83700866F5B /* AIController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIController.cpp; path = src/AIController.cpp; sourceTree = SOURCE_ROOT; };
+		42789FC515B0E83700866F5B /* AIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIController.h; path = src/AIController.h; sourceTree = SOURCE_ROOT; };
+		42789FC615B0E83700866F5B /* AIMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIMessage.cpp; path = src/AIMessage.cpp; sourceTree = SOURCE_ROOT; };
+		42789FC715B0E83700866F5B /* AIMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIMessage.h; path = src/AIMessage.h; sourceTree = SOURCE_ROOT; };
+		42789FC815B0E83700866F5B /* AIState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIState.cpp; path = src/AIState.cpp; sourceTree = SOURCE_ROOT; };
+		42789FC915B0E83700866F5B /* AIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIState.h; path = src/AIState.h; sourceTree = SOURCE_ROOT; };
+		42789FCA15B0E83700866F5B /* AIStateMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AIStateMachine.cpp; path = src/AIStateMachine.cpp; sourceTree = SOURCE_ROOT; };
+		42789FCB15B0E83700866F5B /* AIStateMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIStateMachine.h; path = src/AIStateMachine.h; sourceTree = SOURCE_ROOT; };
+		42789FE115B0E85500866F5B /* lua_AIAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIAgent.cpp; path = src/lua/lua_AIAgent.cpp; sourceTree = SOURCE_ROOT; };
+		42789FE215B0E85500866F5B /* lua_AIAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIAgent.h; path = src/lua/lua_AIAgent.h; sourceTree = SOURCE_ROOT; };
+		42789FE315B0E85500866F5B /* lua_AIAgentListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIAgentListener.cpp; path = src/lua/lua_AIAgentListener.cpp; sourceTree = SOURCE_ROOT; };
+		42789FE415B0E85500866F5B /* lua_AIAgentListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIAgentListener.h; path = src/lua/lua_AIAgentListener.h; sourceTree = SOURCE_ROOT; };
+		42789FE515B0E85500866F5B /* lua_AIController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIController.cpp; path = src/lua/lua_AIController.cpp; sourceTree = SOURCE_ROOT; };
+		42789FE615B0E85500866F5B /* lua_AIController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIController.h; path = src/lua/lua_AIController.h; sourceTree = SOURCE_ROOT; };
+		42789FE715B0E85500866F5B /* lua_AIMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIMessage.cpp; path = src/lua/lua_AIMessage.cpp; sourceTree = SOURCE_ROOT; };
+		42789FE815B0E85500866F5B /* lua_AIMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIMessage.h; path = src/lua/lua_AIMessage.h; sourceTree = SOURCE_ROOT; };
+		42789FE915B0E85500866F5B /* lua_AIMessageParameterType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIMessageParameterType.cpp; path = src/lua/lua_AIMessageParameterType.cpp; sourceTree = SOURCE_ROOT; };
+		42789FEA15B0E85500866F5B /* lua_AIMessageParameterType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIMessageParameterType.h; path = src/lua/lua_AIMessageParameterType.h; sourceTree = SOURCE_ROOT; };
+		42789FEB15B0E85500866F5B /* lua_AIState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIState.cpp; path = src/lua/lua_AIState.cpp; sourceTree = SOURCE_ROOT; };
+		42789FEC15B0E85500866F5B /* lua_AIState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIState.h; path = src/lua/lua_AIState.h; sourceTree = SOURCE_ROOT; };
+		42789FED15B0E85500866F5B /* lua_AIStateListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIStateListener.cpp; path = src/lua/lua_AIStateListener.cpp; sourceTree = SOURCE_ROOT; };
+		42789FEE15B0E85500866F5B /* lua_AIStateListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIStateListener.h; path = src/lua/lua_AIStateListener.h; sourceTree = SOURCE_ROOT; };
+		42789FEF15B0E85500866F5B /* lua_AIStateMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_AIStateMachine.cpp; path = src/lua/lua_AIStateMachine.cpp; sourceTree = SOURCE_ROOT; };
+		42789FF015B0E85500866F5B /* lua_AIStateMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_AIStateMachine.h; path = src/lua/lua_AIStateMachine.h; sourceTree = SOURCE_ROOT; };
 		428390971489D6E800E2B2F5 /* SceneLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SceneLoader.cpp; path = src/SceneLoader.cpp; sourceTree = SOURCE_ROOT; };
 		428390981489D6E800E2B2F5 /* SceneLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneLoader.h; path = src/SceneLoader.h; sourceTree = SOURCE_ROOT; };
 		42B701F615B08177002BB8C3 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "../external-deps/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
@@ -1112,8 +1182,6 @@
 		42B7FEB715B08108002BB8C3 /* lua_FlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_FlowLayout.h; path = src/lua/lua_FlowLayout.h; sourceTree = SOURCE_ROOT; };
 		42B7FEB815B08108002BB8C3 /* lua_Font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_Font.cpp; path = src/lua/lua_Font.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FEB915B08108002BB8C3 /* lua_Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_Font.h; path = src/lua/lua_Font.h; sourceTree = SOURCE_ROOT; };
-		42B7FEBA15B08108002BB8C3 /* lua_FontGlyph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_FontGlyph.cpp; path = src/lua/lua_FontGlyph.cpp; sourceTree = SOURCE_ROOT; };
-		42B7FEBB15B08108002BB8C3 /* lua_FontGlyph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_FontGlyph.h; path = src/lua/lua_FontGlyph.h; sourceTree = SOURCE_ROOT; };
 		42B7FEBC15B08108002BB8C3 /* lua_FontJustify.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_FontJustify.cpp; path = src/lua/lua_FontJustify.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FEBD15B08108002BB8C3 /* lua_FontJustify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_FontJustify.h; path = src/lua/lua_FontJustify.h; sourceTree = SOURCE_ROOT; };
 		42B7FEBE15B08108002BB8C3 /* lua_FontStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_FontStyle.cpp; path = src/lua/lua_FontStyle.cpp; sourceTree = SOURCE_ROOT; };
@@ -1280,8 +1348,6 @@
 		42B7FF5F15B08108002BB8C3 /* lua_Scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_Scene.h; path = src/lua/lua_Scene.h; sourceTree = SOURCE_ROOT; };
 		42B7FF6015B08108002BB8C3 /* lua_SceneDebugFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_SceneDebugFlags.cpp; path = src/lua/lua_SceneDebugFlags.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FF6115B08108002BB8C3 /* lua_SceneDebugFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_SceneDebugFlags.h; path = src/lua/lua_SceneDebugFlags.h; sourceTree = SOURCE_ROOT; };
-		42B7FF6215B08108002BB8C3 /* lua_SceneLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_SceneLoader.cpp; path = src/lua/lua_SceneLoader.cpp; sourceTree = SOURCE_ROOT; };
-		42B7FF6315B08108002BB8C3 /* lua_SceneLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_SceneLoader.h; path = src/lua/lua_SceneLoader.h; sourceTree = SOURCE_ROOT; };
 		42B7FF6415B08108002BB8C3 /* lua_ScreenDisplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_ScreenDisplayer.cpp; path = src/lua/lua_ScreenDisplayer.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FF6515B08108002BB8C3 /* lua_ScreenDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua_ScreenDisplayer.h; path = src/lua/lua_ScreenDisplayer.h; sourceTree = SOURCE_ROOT; };
 		42B7FF6615B08108002BB8C3 /* lua_ScriptController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lua_ScriptController.cpp; path = src/lua/lua_ScriptController.cpp; sourceTree = SOURCE_ROOT; };
@@ -1622,6 +1688,16 @@
 			children = (
 				5BD52634150F822A004C9099 /* AbsoluteLayout.cpp */,
 				5BD52635150F822A004C9099 /* AbsoluteLayout.h */,
+				42789FC215B0E83700866F5B /* AIAgent.cpp */,
+				42789FC315B0E83700866F5B /* AIAgent.h */,
+				42789FC415B0E83700866F5B /* AIController.cpp */,
+				42789FC515B0E83700866F5B /* AIController.h */,
+				42789FC615B0E83700866F5B /* AIMessage.cpp */,
+				42789FC715B0E83700866F5B /* AIMessage.h */,
+				42789FC815B0E83700866F5B /* AIState.cpp */,
+				42789FC915B0E83700866F5B /* AIState.h */,
+				42789FCA15B0E83700866F5B /* AIStateMachine.cpp */,
+				42789FCB15B0E83700866F5B /* AIStateMachine.h */,
 				42CD0DB1147D8FF50000361E /* Animation.cpp */,
 				42CD0DB2147D8FF50000361E /* Animation.h */,
 				42CD0DB3147D8FF50000361E /* AnimationClip.cpp */,
@@ -1851,10 +1927,26 @@
 		42B7FE7115B080EE002BB8C3 /* lua */ = {
 			isa = PBXGroup;
 			children = (
-				42B7FE7215B08108002BB8C3 /* lua_AbsoluteLayout.cpp */,
-				42B7FE7315B08108002BB8C3 /* lua_AbsoluteLayout.h */,
 				42B7FE7415B08108002BB8C3 /* lua_all_bindings.cpp */,
 				42B7FE7515B08108002BB8C3 /* lua_all_bindings.h */,
+				42B7FE7215B08108002BB8C3 /* lua_AbsoluteLayout.cpp */,
+				42B7FE7315B08108002BB8C3 /* lua_AbsoluteLayout.h */,
+				42789FE115B0E85500866F5B /* lua_AIAgent.cpp */,
+				42789FE215B0E85500866F5B /* lua_AIAgent.h */,
+				42789FE315B0E85500866F5B /* lua_AIAgentListener.cpp */,
+				42789FE415B0E85500866F5B /* lua_AIAgentListener.h */,
+				42789FE515B0E85500866F5B /* lua_AIController.cpp */,
+				42789FE615B0E85500866F5B /* lua_AIController.h */,
+				42789FE715B0E85500866F5B /* lua_AIMessage.cpp */,
+				42789FE815B0E85500866F5B /* lua_AIMessage.h */,
+				42789FE915B0E85500866F5B /* lua_AIMessageParameterType.cpp */,
+				42789FEA15B0E85500866F5B /* lua_AIMessageParameterType.h */,
+				42789FEB15B0E85500866F5B /* lua_AIState.cpp */,
+				42789FEC15B0E85500866F5B /* lua_AIState.h */,
+				42789FED15B0E85500866F5B /* lua_AIStateListener.cpp */,
+				42789FEE15B0E85500866F5B /* lua_AIStateListener.h */,
+				42789FEF15B0E85500866F5B /* lua_AIStateMachine.cpp */,
+				42789FF015B0E85500866F5B /* lua_AIStateMachine.h */,
 				42B7FE7615B08108002BB8C3 /* lua_Animation.cpp */,
 				42B7FE7715B08108002BB8C3 /* lua_Animation.h */,
 				42B7FE7815B08108002BB8C3 /* lua_AnimationClip.cpp */,
@@ -1923,8 +2015,6 @@
 				42B7FEB715B08108002BB8C3 /* lua_FlowLayout.h */,
 				42B7FEB815B08108002BB8C3 /* lua_Font.cpp */,
 				42B7FEB915B08108002BB8C3 /* lua_Font.h */,
-				42B7FEBA15B08108002BB8C3 /* lua_FontGlyph.cpp */,
-				42B7FEBB15B08108002BB8C3 /* lua_FontGlyph.h */,
 				42B7FEBC15B08108002BB8C3 /* lua_FontJustify.cpp */,
 				42B7FEBD15B08108002BB8C3 /* lua_FontJustify.h */,
 				42B7FEBE15B08108002BB8C3 /* lua_FontStyle.cpp */,
@@ -2091,8 +2181,6 @@
 				42B7FF5F15B08108002BB8C3 /* lua_Scene.h */,
 				42B7FF6015B08108002BB8C3 /* lua_SceneDebugFlags.cpp */,
 				42B7FF6115B08108002BB8C3 /* lua_SceneDebugFlags.h */,
-				42B7FF6215B08108002BB8C3 /* lua_SceneLoader.cpp */,
-				42B7FF6315B08108002BB8C3 /* lua_SceneLoader.h */,
 				42B7FF6415B08108002BB8C3 /* lua_ScreenDisplayer.cpp */,
 				42B7FF6515B08108002BB8C3 /* lua_ScreenDisplayer.h */,
 				42B7FF6615B08108002BB8C3 /* lua_ScriptController.cpp */,
@@ -2359,7 +2447,6 @@
 				42B7002415B08108002BB8C3 /* lua_FileSystem.h in Headers */,
 				42B7002815B08108002BB8C3 /* lua_FlowLayout.h in Headers */,
 				42B7002C15B08108002BB8C3 /* lua_Font.h in Headers */,
-				42B7003015B08108002BB8C3 /* lua_FontGlyph.h in Headers */,
 				42B7003415B08108002BB8C3 /* lua_FontJustify.h in Headers */,
 				42B7003815B08108002BB8C3 /* lua_FontStyle.h in Headers */,
 				42B7003C15B08108002BB8C3 /* lua_FontText.h in Headers */,
@@ -2443,7 +2530,6 @@
 				42B7017415B08109002BB8C3 /* lua_RenderTarget.h in Headers */,
 				42B7017815B08109002BB8C3 /* lua_Scene.h in Headers */,
 				42B7017C15B08109002BB8C3 /* lua_SceneDebugFlags.h in Headers */,
-				42B7018015B08109002BB8C3 /* lua_SceneLoader.h in Headers */,
 				42B7018415B08109002BB8C3 /* lua_ScreenDisplayer.h in Headers */,
 				42B7018815B08109002BB8C3 /* lua_ScriptController.h in Headers */,
 				42B7018C15B08109002BB8C3 /* lua_Slider.h in Headers */,
@@ -2473,6 +2559,19 @@
 				42B701EC15B08109002BB8C3 /* lua_VertexFormatElement.h in Headers */,
 				42B701F015B08109002BB8C3 /* lua_VertexFormatUsage.h in Headers */,
 				42B701F415B08109002BB8C3 /* lua_VerticalLayout.h in Headers */,
+				42789FCE15B0E83700866F5B /* AIAgent.h in Headers */,
+				42789FD215B0E83700866F5B /* AIController.h in Headers */,
+				42789FD615B0E83700866F5B /* AIMessage.h in Headers */,
+				42789FDA15B0E83700866F5B /* AIState.h in Headers */,
+				42789FDE15B0E83700866F5B /* AIStateMachine.h in Headers */,
+				42789FF315B0E85500866F5B /* lua_AIAgent.h in Headers */,
+				42789FF715B0E85500866F5B /* lua_AIAgentListener.h in Headers */,
+				42789FFB15B0E85500866F5B /* lua_AIController.h in Headers */,
+				42789FFF15B0E85500866F5B /* lua_AIMessage.h in Headers */,
+				4278A00315B0E85500866F5B /* lua_AIMessageParameterType.h in Headers */,
+				4278A00715B0E85500866F5B /* lua_AIState.h in Headers */,
+				4278A00B15B0E85500866F5B /* lua_AIStateListener.h in Headers */,
+				4278A00F15B0E85500866F5B /* lua_AIStateMachine.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2610,7 +2709,6 @@
 				42B7002515B08108002BB8C3 /* lua_FileSystem.h in Headers */,
 				42B7002915B08108002BB8C3 /* lua_FlowLayout.h in Headers */,
 				42B7002D15B08108002BB8C3 /* lua_Font.h in Headers */,
-				42B7003115B08108002BB8C3 /* lua_FontGlyph.h in Headers */,
 				42B7003515B08108002BB8C3 /* lua_FontJustify.h in Headers */,
 				42B7003915B08108002BB8C3 /* lua_FontStyle.h in Headers */,
 				42B7003D15B08108002BB8C3 /* lua_FontText.h in Headers */,
@@ -2694,7 +2792,6 @@
 				42B7017515B08109002BB8C3 /* lua_RenderTarget.h in Headers */,
 				42B7017915B08109002BB8C3 /* lua_Scene.h in Headers */,
 				42B7017D15B08109002BB8C3 /* lua_SceneDebugFlags.h in Headers */,
-				42B7018115B08109002BB8C3 /* lua_SceneLoader.h in Headers */,
 				42B7018515B08109002BB8C3 /* lua_ScreenDisplayer.h in Headers */,
 				42B7018915B08109002BB8C3 /* lua_ScriptController.h in Headers */,
 				42B7018D15B08109002BB8C3 /* lua_Slider.h in Headers */,
@@ -2724,6 +2821,19 @@
 				42B701ED15B08109002BB8C3 /* lua_VertexFormatElement.h in Headers */,
 				42B701F115B08109002BB8C3 /* lua_VertexFormatUsage.h in Headers */,
 				42B701F515B08109002BB8C3 /* lua_VerticalLayout.h in Headers */,
+				42789FCF15B0E83700866F5B /* AIAgent.h in Headers */,
+				42789FD315B0E83700866F5B /* AIController.h in Headers */,
+				42789FD715B0E83700866F5B /* AIMessage.h in Headers */,
+				42789FDB15B0E83700866F5B /* AIState.h in Headers */,
+				42789FDF15B0E83700866F5B /* AIStateMachine.h in Headers */,
+				42789FF415B0E85500866F5B /* lua_AIAgent.h in Headers */,
+				42789FF815B0E85500866F5B /* lua_AIAgentListener.h in Headers */,
+				42789FFC15B0E85500866F5B /* lua_AIController.h in Headers */,
+				4278A00015B0E85500866F5B /* lua_AIMessage.h in Headers */,
+				4278A00415B0E85500866F5B /* lua_AIMessageParameterType.h in Headers */,
+				4278A00815B0E85500866F5B /* lua_AIState.h in Headers */,
+				4278A00C15B0E85500866F5B /* lua_AIStateListener.h in Headers */,
+				4278A01015B0E85500866F5B /* lua_AIStateMachine.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2920,7 +3030,6 @@
 				42B7002215B08108002BB8C3 /* lua_FileSystem.cpp in Sources */,
 				42B7002615B08108002BB8C3 /* lua_FlowLayout.cpp in Sources */,
 				42B7002A15B08108002BB8C3 /* lua_Font.cpp in Sources */,
-				42B7002E15B08108002BB8C3 /* lua_FontGlyph.cpp in Sources */,
 				42B7003215B08108002BB8C3 /* lua_FontJustify.cpp in Sources */,
 				42B7003615B08108002BB8C3 /* lua_FontStyle.cpp in Sources */,
 				42B7003A15B08108002BB8C3 /* lua_FontText.cpp in Sources */,
@@ -3004,7 +3113,6 @@
 				42B7017215B08109002BB8C3 /* lua_RenderTarget.cpp in Sources */,
 				42B7017615B08109002BB8C3 /* lua_Scene.cpp in Sources */,
 				42B7017A15B08109002BB8C3 /* lua_SceneDebugFlags.cpp in Sources */,
-				42B7017E15B08109002BB8C3 /* lua_SceneLoader.cpp in Sources */,
 				42B7018215B08109002BB8C3 /* lua_ScreenDisplayer.cpp in Sources */,
 				42B7018615B08109002BB8C3 /* lua_ScriptController.cpp in Sources */,
 				42B7018A15B08109002BB8C3 /* lua_Slider.cpp in Sources */,
@@ -3034,6 +3142,19 @@
 				42B701EA15B08109002BB8C3 /* lua_VertexFormatElement.cpp in Sources */,
 				42B701EE15B08109002BB8C3 /* lua_VertexFormatUsage.cpp in Sources */,
 				42B701F215B08109002BB8C3 /* lua_VerticalLayout.cpp in Sources */,
+				42789FCC15B0E83700866F5B /* AIAgent.cpp in Sources */,
+				42789FD015B0E83700866F5B /* AIController.cpp in Sources */,
+				42789FD415B0E83700866F5B /* AIMessage.cpp in Sources */,
+				42789FD815B0E83700866F5B /* AIState.cpp in Sources */,
+				42789FDC15B0E83700866F5B /* AIStateMachine.cpp in Sources */,
+				42789FF115B0E85500866F5B /* lua_AIAgent.cpp in Sources */,
+				42789FF515B0E85500866F5B /* lua_AIAgentListener.cpp in Sources */,
+				42789FF915B0E85500866F5B /* lua_AIController.cpp in Sources */,
+				42789FFD15B0E85500866F5B /* lua_AIMessage.cpp in Sources */,
+				4278A00115B0E85500866F5B /* lua_AIMessageParameterType.cpp in Sources */,
+				4278A00515B0E85500866F5B /* lua_AIState.cpp in Sources */,
+				4278A00915B0E85500866F5B /* lua_AIStateListener.cpp in Sources */,
+				4278A00D15B0E85500866F5B /* lua_AIStateMachine.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3166,7 +3287,6 @@
 				42B7002315B08108002BB8C3 /* lua_FileSystem.cpp in Sources */,
 				42B7002715B08108002BB8C3 /* lua_FlowLayout.cpp in Sources */,
 				42B7002B15B08108002BB8C3 /* lua_Font.cpp in Sources */,
-				42B7002F15B08108002BB8C3 /* lua_FontGlyph.cpp in Sources */,
 				42B7003315B08108002BB8C3 /* lua_FontJustify.cpp in Sources */,
 				42B7003715B08108002BB8C3 /* lua_FontStyle.cpp in Sources */,
 				42B7003B15B08108002BB8C3 /* lua_FontText.cpp in Sources */,
@@ -3250,7 +3370,6 @@
 				42B7017315B08109002BB8C3 /* lua_RenderTarget.cpp in Sources */,
 				42B7017715B08109002BB8C3 /* lua_Scene.cpp in Sources */,
 				42B7017B15B08109002BB8C3 /* lua_SceneDebugFlags.cpp in Sources */,
-				42B7017F15B08109002BB8C3 /* lua_SceneLoader.cpp in Sources */,
 				42B7018315B08109002BB8C3 /* lua_ScreenDisplayer.cpp in Sources */,
 				42B7018715B08109002BB8C3 /* lua_ScriptController.cpp in Sources */,
 				42B7018B15B08109002BB8C3 /* lua_Slider.cpp in Sources */,
@@ -3280,6 +3399,19 @@
 				42B701EB15B08109002BB8C3 /* lua_VertexFormatElement.cpp in Sources */,
 				42B701EF15B08109002BB8C3 /* lua_VertexFormatUsage.cpp in Sources */,
 				42B701F315B08109002BB8C3 /* lua_VerticalLayout.cpp in Sources */,
+				42789FCD15B0E83700866F5B /* AIAgent.cpp in Sources */,
+				42789FD115B0E83700866F5B /* AIController.cpp in Sources */,
+				42789FD515B0E83700866F5B /* AIMessage.cpp in Sources */,
+				42789FD915B0E83700866F5B /* AIState.cpp in Sources */,
+				42789FDD15B0E83700866F5B /* AIStateMachine.cpp in Sources */,
+				42789FF215B0E85500866F5B /* lua_AIAgent.cpp in Sources */,
+				42789FF615B0E85500866F5B /* lua_AIAgentListener.cpp in Sources */,
+				42789FFA15B0E85500866F5B /* lua_AIController.cpp in Sources */,
+				42789FFE15B0E85500866F5B /* lua_AIMessage.cpp in Sources */,
+				4278A00215B0E85500866F5B /* lua_AIMessageParameterType.cpp in Sources */,
+				4278A00615B0E85500866F5B /* lua_AIState.cpp in Sources */,
+				4278A00A15B0E85500866F5B /* lua_AIStateListener.cpp in Sources */,
+				4278A00E15B0E85500866F5B /* lua_AIStateMachine.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3432,7 +3564,7 @@
 					"\"$(SRCROOT)/../external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"$(SRCROOT)/../external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
 					"\"$(SRCROOT)/../external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
-					"\"$(SRCROOT)/../external-deps/lua/lib/ios/armv7\"",
+					"\"$(SRCROOT)/../external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
 				);
 				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				ONLY_ACTIVE_ARCH = YES;

+ 90 - 0
gameplay/src/AIAgent.cpp

@@ -0,0 +1,90 @@
+#include "Base.h"
+#include "AIAgent.h"
+#include "Node.h"
+
+namespace gameplay
+{
+
+AIAgent::AIAgent()
+    : _stateMachine(NULL), _node(NULL), _enabled(true), _next(NULL)
+{
+    _stateMachine = new AIStateMachine(this);
+}
+
+AIAgent::~AIAgent()
+{
+    SAFE_DELETE(_stateMachine);
+}
+
+AIAgent* AIAgent::create()
+{
+    return new AIAgent();
+}
+
+const char* AIAgent::getId() const
+{
+    if (_node)
+        return _node->getId();
+
+    return "";
+}
+
+Node* AIAgent::getNode() const
+{
+    return _node;
+}
+
+AIStateMachine* AIAgent::getStateMachine()
+{
+    return _stateMachine;
+}
+
+bool AIAgent::isEnabled() const
+{
+    return (_node && _enabled);
+}
+
+void AIAgent::setEnabled(bool enabled)
+{
+    _enabled = enabled;
+}
+
+void AIAgent::setListener(Listener* listener)
+{
+    _listener = listener;
+}
+
+void AIAgent::update(float elapsedTime)
+{
+    _stateMachine->update(elapsedTime);
+}
+
+bool AIAgent::processMessage(AIMessage* message)
+{
+    // Handle built-in message types.
+    switch (message->_messageType)
+    {
+    case AIMessage::MESSAGE_TYPE_STATE_CHANGE:
+        {
+            // Change state message
+            const char* stateId = message->getString(0);
+            if (stateId)
+            {
+                AIState* state = _stateMachine->getState(stateId);
+                if (state)
+                    _stateMachine->setStateInternal(state);
+            }
+        }
+        break;
+    }
+
+    // Dispatch message to registered listener.
+    if (_listener && _listener->messageReceived(message))
+        return true;
+    
+    // TODO: Fire script listener
+    
+    return false;
+}
+
+}

+ 163 - 0
gameplay/src/AIAgent.h

@@ -0,0 +1,163 @@
+#ifndef AIAGENT_H_
+#define AIAGENT_H_
+
+#include "Ref.h"
+#include "AIStateMachine.h"
+#include "AIMessage.h"
+
+namespace gameplay
+{
+
+class Node;
+
+/**
+ * Defines an AI agent that can be added to nodes in a scene.
+ *
+ * Agents represent a unit of intelligence in a game and can be used
+ * to program logic for a character or object in a game, using constrcuts
+ * such as state machines. By default, an AIAgent has an empty state 
+ * machine.
+ */
+class AIAgent : public Ref
+{
+    friend class Node;
+    friend class AIController;
+
+public:
+
+    /**
+     * Interface for listening to AIAgent events.
+     */
+    class Listener
+    {
+    public:
+
+        /**
+         * Virtual destructor.
+         */
+        virtual ~Listener() { };
+
+        /**
+         * Called when a new message is sent to the AIAgent.
+         *
+         * Both global/broadcast messages and messages sent explicitly to the
+         * AIAgent are sent through this method. Returning true from this method
+         * will mark the message as handled and it will dispose of the message
+         * and prevent any other possible recipients from receiving the message.
+         * Alternatively, returning false allows the message to continue being
+         * routed though the AI system.
+         *
+         * @param message The message received.
+         *
+         * @return true to mark the message as handled, false otherwise.
+         */
+        virtual bool messageReceived(AIMessage* message) = 0;
+    };
+
+    /**
+     * Creates a new AIAgent.
+     *
+     * @return A new AIAgent.
+     */
+    static AIAgent* create();
+
+    /**
+     * Returns the identifier for the AIAgent.
+     *
+     * @return The identifier for the agent.
+     */
+    const char* getId() const;
+
+    /**
+     * Returns the Node this AIAgent is assigned to.
+     *
+     * @return The Node this agent is assigned to.
+     */
+    Node* getNode() const;
+
+    /**
+     * Returns the state machine for the AIAgent.
+     *
+     * @return The agent's state machine.
+     */
+    AIStateMachine* getStateMachine();
+
+    /**
+     * Determines if this AIAgent is currently enabled.
+     *
+     * Agents are always disabled until they have been associated
+     * with a valid Node though Node::setAgent(AIAgent*). In addition,
+     * an AIAgent can be explicitly enabled or disabled using the
+     * setEnabled(bool) method.
+     *
+     * @return true if the agent is enabled, false otherwise.
+     */
+    bool isEnabled() const;
+
+    /**
+     * Sets whether this AIAgent is enabled.
+     *
+     * By default, AIAgents are enabled and they can receive messages and state
+     * changes. When disabled, AIAgents stop receiving messages and their state
+     * machines are halted until they are re-enabled.
+     *
+     * @param enabled true if the AIAgent should be enabled, false otherwise.
+     */
+    void setEnabled(bool enabled);
+
+    /**
+     * Sets an event listener for this AIAgent.
+     *
+     * @param listener The new AIAgent listener, or NULL to remove any existing listener.
+     */
+    void setListener(Listener* listener);
+
+private:
+
+    /**
+     * Constructor.
+     */
+    AIAgent();
+
+    /**
+     * Destructor.
+     *
+     * Hidden, use SAFE_RELEASE instead.
+     */
+    virtual ~AIAgent();
+
+    /**
+     * Hidden copy constructor.
+     */
+    AIAgent(const AIAgent&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    AIAgent& operator=(const AIAgent&);
+
+    /**
+     * Called by the AIController to process a message for the AIAgent.
+     *
+     * @param message The message to be processed.
+     *
+     * @return true if the message was handled, false otherwise.
+     */
+    bool processMessage(AIMessage* message);
+
+    /**
+     * Called once per frame by the AIController to update the agent.
+     */
+    void update(float elapsedTime);
+
+    AIStateMachine* _stateMachine;
+    Node* _node;
+    bool _enabled;
+    Listener* _listener;
+    AIAgent* _next;
+
+};
+
+}
+
+#endif

+ 199 - 0
gameplay/src/AIController.cpp

@@ -0,0 +1,199 @@
+#include "Base.h"
+#include "AIController.h"
+#include "Game.h"
+
+// TODO:
+//
+// 1) Is std::string OK for message sender/receiver?
+// 2) Is AIMessage ok and is "dobule" ok for message parameters?
+// 3) Design of creating and deleting message (AIController deletes them)??
+// 4) Is setListener(Listener*) OK for AIState and AIStateMachine, or do we need addListener(Listener*)???
+
+// TODO: Add a way to snif messages on AIController??
+
+// TODO: only dispatch messages to agents that are in this list AND enabled. If not in the list, discard the message (and log) and if they are in the list and DISABLED, just hold on to the message until they are re-enabled.
+
+namespace gameplay
+{
+
+AIController::AIController()
+    : _paused(false), _firstMessage(NULL), _firstAgent(NULL)
+{
+}
+
+AIController::~AIController()
+{
+}
+
+void AIController::initialize()
+{
+}
+
+void AIController::finalize()
+{
+    // Remove all agents
+    AIAgent* agent = _firstAgent;
+    while (agent)
+    {
+        AIAgent* temp = agent;
+        agent = agent->_next;
+        SAFE_RELEASE(temp);
+    }
+    _firstAgent = NULL;
+
+    // Remove all messages
+    AIMessage* message = _firstMessage;
+    while (message)
+    {
+        AIMessage* temp = message;
+        message = message->_next;
+        SAFE_DELETE(temp);
+    }
+    _firstMessage = NULL;
+}
+
+void AIController::pause()
+{
+    _paused = true;
+}
+
+void AIController::resume()
+{
+    _paused = false;
+}
+
+void AIController::sendMessage(AIMessage* message, float delay)
+{
+    if (delay <= 0)
+    {
+        // Send instantly
+        if (message->getReceiver() == NULL || strlen(message->getReceiver()) == 0)
+        {
+            // Broadcast message to all agents
+            AIAgent* agent = _firstAgent;
+            while (agent)
+            {
+                if (agent->processMessage(message))
+                    break; // message consumed by this agent - stop bubbling
+                agent = agent->_next;
+            }
+        }
+        else
+        {
+            // Single recipient
+            AIAgent* agent = findAgent(message->getReceiver());
+            if (agent)
+            {
+                agent->processMessage(message);
+            }
+            else
+            {
+                GP_WARN("Failed to locate AIAgent for message recipient: %s", message->getReceiver());
+            }
+        }
+
+        // Delete the message, since it is finished being processed
+        SAFE_DELETE(message);
+    }
+    else
+    {
+        // Queue for later delivery
+        if (_firstMessage)
+            message->_next = _firstMessage;
+        _firstMessage = message;
+    }
+}
+
+void AIController::update(float elapsedTime)
+{
+    if (_paused)
+        return;
+
+    static Game* game = Game::getInstance();
+
+    // Send all pending messages that have expired
+    AIMessage* prevMsg = NULL;
+    AIMessage* msg = _firstMessage;
+    while (msg)
+    {
+        // If the message delivery time has expired, send it (this also deletes it)
+        if (msg->getDeliveryTime() >= game->getGameTime())
+        {
+            // Link the message out of our list
+            if (prevMsg)
+                prevMsg->_next = msg->_next;
+
+            AIMessage* temp = msg;
+            msg = msg->_next;
+            temp->_next = NULL;
+            sendMessage(temp);
+        }
+        else
+        {
+            prevMsg = msg;
+            msg = msg->_next;
+        }
+    }
+
+    // Update all enabled agents
+    AIAgent* agent = _firstAgent;
+    while (agent)
+    {
+        if (agent->isEnabled())
+            agent->update(elapsedTime);
+
+        agent = agent->_next;
+    }
+}
+
+void AIController::addAgent(AIAgent* agent)
+{
+    agent->addRef();
+
+    if (_firstAgent)
+        agent->_next = _firstAgent;
+
+    _firstAgent = agent;
+}
+
+void AIController::removeAgent(AIAgent* agent)
+{
+    // Search our linked list of agents and link this agent out.
+    AIAgent* prevAgent = NULL;
+    AIAgent* itr = _firstAgent;
+    while (itr)
+    {
+        if (itr == agent)
+        {
+            if (prevAgent)
+                prevAgent->_next = agent->_next;
+            else
+                _firstAgent = agent->_next;
+
+            agent->_next = NULL;
+            agent->release();
+            break;
+        }
+
+        prevAgent = itr;
+        itr = itr->_next;
+    }
+}
+
+AIAgent* AIController::findAgent(const char* id) const
+{
+    GP_ASSERT(id);
+
+    AIAgent* agent = _firstAgent;
+    while (agent)
+    {
+        if (strcmp(id, agent->getId()) == 0)
+            return agent;
+
+        agent = agent->_next;
+    }
+
+    return NULL;
+}
+
+}

+ 107 - 0
gameplay/src/AIController.h

@@ -0,0 +1,107 @@
+#ifndef AICONTROLLER_H_
+#define AICONTROLLER_H_
+
+#include "AIAgent.h"
+#include "AIMessage.h"
+
+namespace gameplay
+{
+
+/**
+ * The AIController facilitates state machine execution and message passing
+ * between AI objects in the game. This class is generally not interfaced
+ * with directly.
+ */
+class AIController
+{
+    friend class Game;
+    friend class Node;
+
+public:
+
+    /**
+     * Routes the secified message to its intended recipient(s).
+     *
+     * Messages are arbitrary packets of data that are sent either to a single or to multiple
+     * recipients in the game.
+     *
+     * Once the specified message has been delivered, it is automatically destroyed by the AIController.
+     * For this reason, AIMessage pointers should NOT be held or explicity destroyed by any code after
+     * they are sent through the AIController.
+     *
+     * @param message The message to send.
+     * @param delay The delay (in milliseconds) to wait before sending the message.
+     */
+    void sendMessage(AIMessage* message, float delay = 0);
+
+    /**
+     * Searches for an AIAgent that is registered with the AIController with the specified ID.
+     *
+     * @param id ID of the agent to find.
+     *
+     * @return The first agent matching the specified ID, or NULL if no matching agent could be found.
+     */
+    AIAgent* findAgent(const char* id) const;
+
+private:
+
+    /**
+     * Constructor.
+     */
+    AIController();
+
+    /**
+     * Destructor.
+     */
+    ~AIController();
+
+    /**
+     * Hidden copy constructor.
+     */
+    AIController(const AIController&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    AIController& operator=(const AIController&);
+
+    /**
+     * Called during startup to initialize the AIController.
+     */
+    void initialize();
+
+    /**
+     * Called during shutdown to finalize the AIController.
+     */
+    void finalize();
+
+    /**
+     * Pauses the AIController.
+     */
+    void pause();
+
+    /**
+     * Resumes the AIController.
+     */
+    void resume();
+
+    /**
+     * Called each frame to update the AIController.
+     *
+     * @param elapsedTime The elapsed time, in milliseconds.
+     */
+    void update(float elapsedTime);
+
+    void addAgent(AIAgent* agent);
+
+    void removeAgent(AIAgent* agent);
+
+    bool _paused;
+    AIMessage* _firstMessage;
+    AIAgent* _firstAgent;
+
+};
+
+}
+
+#endif

+ 203 - 0
gameplay/src/AIMessage.cpp

@@ -0,0 +1,203 @@
+#include "Base.h"
+#include "AIMessage.h"
+
+namespace gameplay
+{
+
+AIMessage::AIMessage()
+    : _id(0), _deliveryTime(0), _parameters(NULL), _parameterCount(0), _messageType(MESSAGE_TYPE_CUSTOM), _next(NULL)
+{
+}
+
+AIMessage::~AIMessage()
+{
+    SAFE_DELETE_ARRAY(_parameters);
+}
+
+AIMessage* AIMessage::create(unsigned int id, const char* sender, const char* receiver, unsigned int parameterCount)
+{
+    AIMessage* message = new AIMessage();
+    message->_id = id;
+    message->_sender = sender;
+    message->_receiver = receiver;
+    message->_parameterCount = parameterCount;
+    if (parameterCount > 0)
+        message->_parameters = new AIMessage::Parameter[parameterCount];
+    return message;
+}
+
+unsigned int AIMessage::getId() const
+{
+    return _id;
+}
+
+const char* AIMessage::getSender() const
+{
+    return _sender.c_str();
+}
+
+const char* AIMessage::getReceiver() const
+{
+    return _receiver.c_str();
+}
+
+double AIMessage::getDeliveryTime() const
+{
+    return _deliveryTime;
+}
+
+int AIMessage::getInt(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::INTEGER);
+
+    return _parameters[index].intValue;
+}
+
+void AIMessage::setInt(unsigned int index, int value)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    clearParameter(index);
+
+    _parameters[index].intValue = value;
+    _parameters[index].type = AIMessage::INTEGER;
+}
+
+long AIMessage::getLong(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::LONG);
+
+    return _parameters[index].longValue;
+}
+
+void AIMessage::setLong(unsigned int index, long value)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    clearParameter(index);
+
+    _parameters[index].longValue = value;
+    _parameters[index].type = AIMessage::LONG;
+}
+
+float AIMessage::getFloat(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::FLOAT);
+
+    return _parameters[index].floatValue;
+}
+
+void AIMessage::setFloat(unsigned int index, float value)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    clearParameter(index);
+
+    _parameters[index].floatValue = value;
+    _parameters[index].type = AIMessage::FLOAT;
+}
+
+double AIMessage::getDouble(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::DOUBLE);
+
+    return _parameters[index].doubleValue;
+}
+
+void AIMessage::setDouble(unsigned int index, double value)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    clearParameter(index);
+
+    _parameters[index].doubleValue = value;
+    _parameters[index].type = AIMessage::DOUBLE;
+}
+
+bool AIMessage::getBoolean(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::BOOLEAN);
+
+    return _parameters[index].boolValue;
+}
+
+void AIMessage::setBoolean(unsigned int index, bool value)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    clearParameter(index);
+
+    _parameters[index].boolValue = value;
+    _parameters[index].type = AIMessage::BOOLEAN;
+}
+
+const char* AIMessage::getString(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(_parameters[index].type == AIMessage::STRING);
+
+    return _parameters[index].stringValue;
+}
+
+void AIMessage::setString(unsigned int index, const char* value)
+{
+    GP_ASSERT(index < _parameterCount);
+    GP_ASSERT(value);
+
+    clearParameter(index);
+
+    // Copy the string into our parameter
+    size_t len = strlen(value);
+    char* buffer = new char[len + 1];
+    strcpy(buffer, value);
+    _parameters[index].stringValue = buffer;
+    _parameters[index].type = AIMessage::STRING;
+}
+
+unsigned int AIMessage::getParameterCount() const
+{
+    return _parameterCount;
+}
+
+AIMessage::ParameterType AIMessage::getParameterType(unsigned int index) const
+{
+    GP_ASSERT(index < _parameterCount);
+
+    return _parameters[index].type;
+}
+
+void AIMessage::clearParameter(unsigned int index)
+{
+    GP_ASSERT(index < _parameterCount);
+
+    _parameters[index].clear();
+}
+
+AIMessage::Parameter::Parameter()
+    : type(UNDEFINED)
+{
+}
+
+AIMessage::Parameter::~Parameter()
+{
+    clear();
+}
+
+void AIMessage::Parameter::clear()
+{
+    switch (type)
+    {
+    case AIMessage::STRING:
+        SAFE_DELETE_ARRAY(stringValue);
+        break;
+    }
+
+    type = AIMessage::UNDEFINED;
+}
+
+}

+ 272 - 0
gameplay/src/AIMessage.h

@@ -0,0 +1,272 @@
+#ifndef AIMESSAGE_H_
+#define AIMESSAGE_H_
+
+namespace gameplay
+{
+
+/**
+ * Defines a simple, flexible message structure used for passing messages through
+ * the AI system.
+ *
+ * Messages can store an arbitrary number of parameters. For the sake of simplicity,
+ * each parameter is stored as type double, which is flexible enough to store most
+ * data that needs to be passed.
+ */
+class AIMessage
+{
+    friend class AIAgent;
+    friend class AIController;
+    friend class AIStateMachine;
+
+public:
+
+    /**
+     * Enumeration of supported AIMessage parameter types.
+     */
+    enum ParameterType
+    {
+        UNDEFINED,
+        INTEGER,
+        LONG,
+        FLOAT,
+        DOUBLE,
+        BOOLEAN,
+        STRING
+    };
+
+    /** 
+     * Destructor.
+     */
+    ~AIMessage();
+
+    /**
+     * Creates a new message.
+     *
+     * Once a message is constructed and populated with data, it can be routed to its
+     * intended recipient(s) by calling AIController::sendMessage(AIMessage*). The
+     * AIController will then handle scheduling and delivery of the message and it will
+     * also destroy the message after it has been successfully delivered. For this reason,
+     * once a message has been sent through AIController, it is unsafe to use or destroy
+     * the message pointer.
+     *
+     * @param id The message ID.
+     * @param sender AIAgent sender ID (can be empty or null for an annoymous message).
+     * @param receiver AIAgent receiver ID (can be empty or null for a broadcast message).
+     * @param parameterCount Number of parameters for this message.
+     *
+     * @return A new AIMessage.
+     */
+    static AIMessage* create(unsigned int id, const char* sender, const char* receiver, unsigned int paramterCount);
+
+    /**
+     * Returns the message ID.
+     *
+     * @return The message ID.
+     */
+    unsigned int getId() const;
+
+    /**
+     * Returns the sender for the message.
+     *
+     * @return The message sender ID.
+     */
+    const char* getSender() const;
+
+    /**
+     * Returns the receiver for the message.
+     *
+     * @return The message receiver.
+     */
+    const char* getReceiver() const;
+
+    /**
+     * Returns the value of the specified parameter as an integer.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    int getInt(unsigned int index) const;
+
+    /**
+     * Sets an integer parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setInt(unsigned int index, int value);
+
+    /**
+     * Returns the value of the specified parameter as a long integer.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    long getLong(unsigned int index) const;
+
+    /**
+     * Sets a long integer parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setLong(unsigned int index, long value);
+
+    /**
+     * Returns the value of the specified parameter as a float.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    float getFloat(unsigned int index) const;
+
+    /**
+     * Sets a float parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setFloat(unsigned int index, float value);
+
+    /**
+     * Returns the value of the specified parameter as a double.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    double getDouble(unsigned int index) const;
+
+    /**
+     * Sets a double parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setDouble(unsigned int index, double value);
+
+    /**
+     * Returns the value of the specified parameter as a boolean.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    bool getBoolean(unsigned int index) const;
+
+    /**
+     * Sets a long parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setBoolean(unsigned int index, bool value);
+
+    /**
+     * Returns the value of the specified parameter as a string.
+     *
+     * @param index Index of the paramter to get.
+     *
+     * @return The parameter value.
+     */
+    const char* getString(unsigned int index) const;
+
+    /**
+     * Sets a string parameter.
+     *
+     * @param index Index of the parameter to set.
+     * @param value The parameter value.
+     */
+    void setString(unsigned int index, const char* value);
+
+    /**
+     * Returns the number of parameters for this message.
+     * 
+     * @return The number of message parameters.
+     */
+    unsigned int getParameterCount() const;
+
+    /** 
+     * Returns the type of the specified parameter.
+     *
+     * @param index Index of the parameter to query.
+     *
+     * @return The parameter type.
+     */
+    ParameterType getParameterType(unsigned int index) const;
+
+private:
+
+    /**
+     * Internal message type enumeration.
+     */
+    enum MessageType
+    {
+        MESSAGE_TYPE_STATE_CHANGE,
+        MESSAGE_TYPE_CUSTOM
+    };
+
+    /**
+     * Defines a flexible message parameter.
+     */
+    struct Parameter
+    {
+        Parameter();
+
+        ~Parameter();
+
+        void clear();
+
+        union
+        {
+            int intValue;
+            long longValue;
+            float floatValue;
+            double doubleValue;
+            bool boolValue;
+            char* stringValue;
+        };
+
+        AIMessage::ParameterType type;
+    };
+
+    /**
+     * Constructor.
+     */
+    AIMessage();
+
+    /**
+     * Hidden copy construcotr.
+     */
+    AIMessage(const AIMessage&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    AIMessage& operator=(const AIMessage&);
+
+    /**
+     * Returns the delivery time for the message.
+     *
+     * @return The delivery time for the message, or zero if the message is not currently scheduled to be delivered.
+     */
+    double getDeliveryTime() const;
+
+    void clearParameter(unsigned int index);
+
+    unsigned int _id;
+    std::string _sender;
+    std::string _receiver;
+    double _deliveryTime;
+    Parameter* _parameters;
+    unsigned int _parameterCount;
+    MessageType _messageType;
+    AIMessage* _next;
+
+};
+
+}
+
+#endif

+ 74 - 0
gameplay/src/AIState.cpp

@@ -0,0 +1,74 @@
+#include "Base.h"
+#include "AIState.h"
+#include "AIStateMachine.h"
+
+namespace gameplay
+{
+
+AIState* AIState::_empty = NULL;
+
+AIState::AIState(const char* id)
+    : _id(id), _listener(NULL)
+{
+}
+
+AIState::~AIState()
+{
+}
+
+AIState* AIState::create(const char* id)
+{
+    return new AIState(id);
+}
+
+const char* AIState::getId() const
+{
+    return _id.c_str();
+}
+
+void AIState::setListener(Listener* listener)
+{
+    _listener = listener;
+}
+
+void AIState::enter(AIStateMachine* stateMachine)
+{
+    if (_listener)
+        _listener->stateEnter(stateMachine->getAgent(), this);
+
+    // TODO: Fire script event
+}
+
+void AIState::exit(AIStateMachine* stateMachine)
+{
+    if (_listener)
+        _listener->stateExit(stateMachine->getAgent(), this);
+
+    // TODO: Fire script event
+}
+
+void AIState::update(AIStateMachine* stateMachine, float elapsedTime)
+{
+    if (_listener)
+        _listener->stateUpdate(stateMachine->getAgent(), this, elapsedTime);
+
+    // TODO: Fire script event
+}
+
+AIState::Listener::~Listener()
+{
+}
+
+void AIState::Listener::stateEnter(AIAgent* agent, AIState* state)
+{
+}
+
+void AIState::Listener::stateExit(AIAgent* agent, AIState* state)
+{
+}
+
+void AIState::Listener::stateUpdate(AIAgent* agent, AIState* state, float elapsedTime)
+{
+}
+
+}

+ 137 - 0
gameplay/src/AIState.h

@@ -0,0 +1,137 @@
+#ifndef AISTATE_H_
+#define AISTATE_H_
+
+#include "Ref.h"
+
+namespace gameplay
+{
+
+class AIAgent;
+class AIStateMachine;
+
+/**
+ * Represents a single state in an AIStateMachine.
+ *
+ * An AIState encapsulates a state and unit of work within an AI
+ * state machine. Events can be programmed or scripted when the
+ * state is entered, exited and each frame/tick in its update event.
+ *
+ * 
+ */
+class AIState : public Ref
+{
+    friend class AIStateMachine;
+
+public:
+
+    /**
+     * Interface for listening to AIState events.
+     */
+    class Listener
+    {
+    public:
+
+        /**
+         * Virtual destructor.
+         */
+        virtual ~Listener();
+
+        /** 
+         * Called when a state is entered.
+         *
+         * @param agent The AIAgent this state event is for.
+         * @param state The state that was entered.
+         */
+        virtual void stateEnter(AIAgent* agent, AIState* state);
+
+        /**
+         * Called when a state is exited.
+         *
+         * @param agent The AIAgent this state event is for.
+         * @param state The state that was exited.
+         */
+        virtual void stateExit(AIAgent* agent, AIState* state);
+
+        /**
+         * Called once per frame when for a state when it is active.
+         *
+         * This method is normally where the logic for a state is implemented.
+         *
+         * @param agent The AIAgent this state event is for.
+         * @param state The active AIState.
+         * @param elapsedTime The elapsed time, in milliseconds.
+         */
+        virtual void stateUpdate(AIAgent* agent, AIState* state, float elapsedTime);
+    };
+
+    /**
+     * Creates a new AISTate.
+     *
+     * @param id The ID of the new AIState.
+     *
+     * @return The new AIState.
+     */
+    static AIState* create(const char* id);
+
+    /**
+     * Returns the ID of this state.
+     *
+     * @return The state ID.
+     */
+    const char* getId() const;
+
+    /**
+     * Sets a listener to dispatch state events to.
+     * 
+     * @param listener Listener to dispatch state events to, or NULL to disable event dispatching.
+     */
+    void setListener(Listener* listener);
+
+private:
+
+    /**
+     * Constructs a new AIState.
+     */
+    AIState(const char* id);
+
+    /**
+     * Destructor.
+     */
+    ~AIState();
+
+    /**
+     * Hidden copy constructor.
+     */
+    AIState(const AIState&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    AIState& operator=(const AIState&);
+
+    /**
+     * Called by AIStateMachine when this state is being entered.
+     */
+    void enter(AIStateMachine* stateMachine);
+
+    /**
+     * Called by AIStateMachine when this state is being exited.
+     */
+    void exit(AIStateMachine* stateMachine);
+
+    /**
+     * Called by AIStateMachine once per frame to update this state when it is active.
+     */
+    void update(AIStateMachine* stateMachine, float elapsedTime);
+
+    std::string _id;
+    Listener* _listener;
+
+    // The default/empty state.
+    static AIState* _empty;
+
+};
+
+}
+
+#endif

+ 133 - 0
gameplay/src/AIStateMachine.cpp

@@ -0,0 +1,133 @@
+#include "Base.h"
+#include "AIStateMachine.h"
+#include "AIAgent.h"
+#include "AIMessage.h"
+#include "Game.h"
+
+namespace gameplay
+{
+
+AIStateMachine::AIStateMachine(AIAgent* agent)
+    : _agent(agent)
+{
+    GP_ASSERT(agent);
+    if (AIState::_empty)
+        AIState::_empty->addRef();
+    else
+        AIState::_empty = new AIState("");
+    _currentState = AIState::_empty;
+}
+
+AIStateMachine::~AIStateMachine()
+{
+    // Release all states
+    for (std::list<AIState*>::iterator itr = _states.begin(); itr != _states.end(); ++itr)
+    {
+        (*itr)->release();
+    }
+    SAFE_RELEASE(AIState::_empty);
+}
+
+AIAgent* AIStateMachine::getAgent() const
+{
+    return _agent;
+}
+
+AIState* AIStateMachine::addState(const char* id)
+{
+    AIState* state = AIState::create(id);
+    _states.push_back(state);
+    return state;
+}
+
+void AIStateMachine::addState(AIState* state)
+{
+    state->addRef();
+    _states.push_back(state);
+}
+
+void AIStateMachine::removeState(AIState* state)
+{
+    std::list<AIState*>::iterator itr = std::find(_states.begin(), _states.end(), state);
+    if (itr != _states.end())
+    {
+        _states.erase(itr);
+        state->release();
+    }
+}
+
+AIState* AIStateMachine::getState(const char* id) const
+{
+    GP_ASSERT(id);
+
+    AIState* state;
+    for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
+    {
+        state = (*itr);
+
+        if (strcmp(id, state->getId()) == 0)
+            return state;
+    }
+
+    return NULL;
+}
+
+AIState* AIStateMachine::getActiveState() const
+{
+    return _currentState;
+}
+
+bool AIStateMachine::hasState(AIState* state) const
+{
+    GP_ASSERT(state);
+
+    return (std::find(_states.begin(), _states.end(), state) != _states.end());
+}
+
+AIState* AIStateMachine::setState(const char* id)
+{
+    AIState* state = getState(id);
+    if (state)
+        sendChangeStateMessage(state);
+    return state;
+}
+
+bool AIStateMachine::setState(AIState* state)
+{
+    if (hasState(state))
+    {
+        sendChangeStateMessage(state);
+        return true;
+    }
+
+    return false;
+}
+
+void AIStateMachine::sendChangeStateMessage(AIState* newState)
+{
+    AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
+    message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
+    message->setString(0, newState->getId());
+    Game::getInstance()->getAIController()->sendMessage(message);
+}
+
+void AIStateMachine::setStateInternal(AIState* state)
+{
+    GP_ASSERT(hasState(state));
+
+    // Fire the exit event for the current state
+    _currentState->exit(this);
+
+    // Set the new state
+    _currentState = state;
+
+    // Fire the enter event for the new state
+    _currentState->enter(this);
+}
+
+void AIStateMachine::update(float elapsedTime)
+{
+    _currentState->update(this, elapsedTime);
+}
+
+}

+ 160 - 0
gameplay/src/AIStateMachine.h

@@ -0,0 +1,160 @@
+#ifndef AISTATEMACHINE_H_
+#define AISTATEMACHINE_H_
+
+#include "AIState.h"
+
+namespace gameplay
+{
+
+class AIAgent;
+
+/**
+ * Defines a simple AI state machine that can be used to program logic
+ * for an AIAgent in a game.
+ *
+ * A state machine uses AIState objects to represent different states
+ * of an object in the game. The state machine provides access to the
+ * current state of an AI agent and it controls state changes as well.
+ * When a new state is set, the stateExited event will be called for the
+ * previous state, the stateEntered event will be called for the new state
+ * and then the stateUpdate event will begin to be called each frame
+ * while the new state is active.
+ *
+ * Communication of state changes is facilated through the AIMessage class.
+ * Messages are dispatched by the AIController and can be used for purposes
+ * other than state changes as well. Messages may be sent to the state
+ * machines of any other agents in a game and can contain any arbitrary
+ * information. This mechanism provides a simple, flexible and easily
+ * debuggable method for communicating between AI objects in a game.
+ */
+class AIStateMachine
+{
+    friend class AIAgent;
+
+public:
+
+    /**
+     * Returns the AIAgent that owns this state machine.
+     *
+     * @return The AIAgent that owns this state machine.
+     */
+    AIAgent* getAgent() const;
+
+    /**
+     * Creates and adds a new state to the state machine.
+     *
+     * @param id ID of the new state.
+     *
+     * @return The newly created and added state.
+     */
+    AIState* addState(const char* id);
+
+    /**
+     * Adds a state to the state machine.
+     *
+     * The specified state may be shared by other state machines.
+     * Its reference count is increased while it is held by
+     * this state machine.
+     *
+     * @param state The state to add.
+     */
+    void addState(AIState* state);
+
+    /**
+     * Removes a state from the state machine.
+     *
+     * @param state The state to remove.
+     */
+    void removeState(AIState* state);
+
+    /**
+     * Returns a state registered with this state machine.
+     *
+     * @param id The ID of the state to return.
+     *
+     * @return The state with the given ID, or NULL if no such state exists.
+     */
+    AIState* getState(const char* id) const;
+
+    /**
+     * Returns the active state for this state machine.
+     *
+     * @return The active state for this state machine.
+     */
+    AIState* getActiveState() const;
+
+    /**
+     * Changes the state of this state machine to the given state.
+     *
+     * If no state with the given ID exists within this state machine,
+     * this method does nothing.
+     *
+     * @param id The ID of the new state.
+     *
+     * @return The new state, or NULL if no matching state could be found.
+     */
+    AIState* setState(const char* id);
+
+    /**
+     * Changes the state of this state machine to the given state.
+     *
+     * If the given state is not registered with this state machine,
+     * this method does nothing.
+     *
+     * @param state The new state.
+     *
+     * @return true if the state is successfully changed, false otherwise.
+     */
+    bool setState(AIState* state);
+
+private:
+
+    /**
+     * Constructor.
+     */
+    AIStateMachine(AIAgent* agent);
+
+    /**
+     * Destructor.
+     */
+    ~AIStateMachine();
+
+    /**
+     * Hidden copy constructor.
+     */
+    AIStateMachine(const AIStateMachine&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    AIStateMachine& operator=(const AIStateMachine&);
+
+    /**
+     * Sends a message to change the state of this state machine.
+     */
+    void sendChangeStateMessage(AIState* newState);
+
+    /**
+     * Changes the active state of the state machine.
+     */
+    void setStateInternal(AIState* state);
+
+    /**
+     * Determines if the specified state exists within this state machine.
+     */
+    bool hasState(AIState* state) const;
+
+    /**
+     * Called by AIController to update the state machine each frame.
+     */
+    void update(float elapsedTime);
+
+    AIAgent* _agent;
+    AIState* _currentState;
+    std::list<AIState*> _states;
+
+};
+
+}
+
+#endif

+ 2 - 0
gameplay/src/AudioSource.h

@@ -40,6 +40,7 @@ public:
      * 
      * @param url The relative location on disk of the sound file or a URL specifying a Properties object defining an audio source.
      * @return The newly created audio source, or NULL if an audio source cannot be created.
+     * @script{create}
      */
     static AudioSource* create(const char* url);
 
@@ -48,6 +49,7 @@ public:
      * 
      * @param properties The properties object defining the audio source (must have namespace equal to 'audio').
      * @return The newly created audio source, or <code>NULL</code> if the audio source failed to load.
+     * @script{create}
      */
     static AudioSource* create(Properties* properties);
 

+ 1 - 1
gameplay/src/Base.h

@@ -115,7 +115,7 @@ extern void printError(const char* format, ...);
 #define SAFE_RELEASE(x) \
     if (x) \
     { \
-        x->release(); \
+        (x)->release(); \
         x = NULL; \
     }
 

+ 5 - 0
gameplay/src/Bundle.h

@@ -29,6 +29,7 @@ public:
      * release() method must be called. Note that calling release() does
      * NOT free any actual game objects created/returned from the Bundle
      * instance and those objects must be released separately.
+     * @script{create}
      */
     static Bundle* create(const char* path);
 
@@ -39,6 +40,7 @@ public:
      * @param id The ID of the scene to load (NULL to load the first scene).
      * 
      * @return The loaded scene, or NULL if the scene could not be loaded.
+     * @script{create}
      */
     Scene* loadScene(const char* id = NULL);
 
@@ -48,6 +50,7 @@ public:
      * @param id The ID of the node to load in the bundle.
      * 
      * @return The loaded node, or NULL if the node could not be loaded.
+     * @script{create}
      */
     Node* loadNode(const char* id);
 
@@ -57,6 +60,7 @@ public:
      * @param id The ID of the mesh to load.
      * 
      * @return The loaded mesh, or NULL if the mesh could not be loaded.
+     * @script{create}
      */
     Mesh* loadMesh(const char* id);
 
@@ -66,6 +70,7 @@ public:
      * @param id The ID of the font to load.
      * 
      * @return The loaded font, or NULL if the font could not be loaded.
+     * @script{create}
      */
     Font* loadFont(const char* id);
 

+ 1 - 0
gameplay/src/CheckBox.h

@@ -44,6 +44,7 @@ public:
      * @param style The control's style.
      *
      * @return The new check box.
+     * @script{create}
      */
     static CheckBox* create(const char* id, Theme::Style* style);
 

+ 1 - 0
gameplay/src/Container.h

@@ -72,6 +72,7 @@ public:
      * @param layoutType The container's layout type.
      *
      * @return The new container.
+     * @script{create}
      */
     static Container* create(const char* id, Theme::Style* style, Layout::Type layoutType = Layout::LAYOUT_ABSOLUTE);
 

+ 1 - 0
gameplay/src/Curve.h

@@ -280,6 +280,7 @@ public:
      * 
      * @param pointCount The number of points in the curve.
      * @param componentCount The number of float component values per key value.
+     * @script{create}
      */
     static Curve* create(unsigned int pointCount, unsigned int componentCount);
 

+ 1 - 0
gameplay/src/DepthStencilTarget.h

@@ -45,6 +45,7 @@ public:
      * @param height Height of the new DepthStencilTarget.
      *
      * @return A newly created DepthStencilTarget.
+     * @script{create}
      */
     static DepthStencilTarget* create(const char* id, Format format, unsigned int width, unsigned int height);
 

+ 40 - 39
gameplay/src/Font.h

@@ -54,28 +54,6 @@ public:
         ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
     };
 
-    /**
-     * Defines a font glyph within the texture map for a font.
-     */
-    class Glyph
-    {
-    public:
-        /**
-         * Glyph character code (decimal value).
-         */
-        unsigned int code;
-
-        /**
-         * Glyph width (in pixels).
-         */
-        unsigned int width;
-
-        /**
-         * Glyph texture coordinates.
-         */
-        float uvs[4];
-    };
-
     /**
      * Vertex coordinates, UVs and indices can be computed and stored in a Text object.
      * For static text labels that do not change frequently, this means these computations
@@ -129,26 +107,10 @@ public:
      * @param id An optional ID of the font resource within the bundle (NULL for the first/only resource).
      * 
      * @return The specified font.
+     * @script{create}
      */
     static Font* create(const char* path, const char* id = NULL);
 
-    /**
-     * Creates a font with the given characteristics from the specified glyph array and texture map.
-     *
-     * This method will create a new Font object regardless of whether another Font is already
-     * created with the same attributes.
-     *
-     * @param family The font family name.
-     * @param style The font style.
-     * @param size The font size.
-     * @param glyphs An array of font glyphs, defining each character in the font within the texture map.
-     * @param glyphCount The number of items in the glyph array.
-     * @param texture A texture map containing rendered glyphs.
-     * 
-     * @return The new Font.
-     */
-    static Font* create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture);
-
     /**
      * Returns the font size (max height of glyphs) in pixels.
      */
@@ -275,6 +237,27 @@ public:
 
 
 private:
+    /**
+     * Defines a font glyph within the texture map for a font.
+     */
+    class Glyph
+    {
+    public:
+        /**
+         * Glyph character code (decimal value).
+         */
+        unsigned int code;
+
+        /**
+         * Glyph width (in pixels).
+         */
+        unsigned int width;
+
+        /**
+         * Glyph texture coordinates.
+         */
+        float uvs[4];
+    };
 
     /**
      * Constructor.
@@ -296,6 +279,24 @@ private:
      */
     Font& operator=(const Font&);
 
+    /**
+     * Creates a font with the given characteristics from the specified glyph array and texture map.
+     *
+     * This method will create a new Font object regardless of whether another Font is already
+     * created with the same attributes.
+     *
+     * @param family The font family name.
+     * @param style The font style.
+     * @param size The font size.
+     * @param glyphs An array of font glyphs, defining each character in the font within the texture map.
+     * @param glyphCount The number of items in the glyph array.
+     * @param texture A texture map containing rendered glyphs.
+     * 
+     * @return The new Font.
+     * @script{create}
+     */
+    static Font* create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture);
+
     void getMeasurementInfo(const char* text, const Rectangle& area, unsigned int size, Justify justify, bool wrap, bool rightToLeft,
                             std::vector<int>* xPositions, int* yPosition, std::vector<unsigned int>* lineLengths);
 

+ 2 - 0
gameplay/src/Form.h

@@ -56,6 +56,7 @@ public:
      * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional). 
      * 
      * @param url The URL pointing to the Properties object defining the form. 
+     * @script{create}
      */
     static Form* create(const char* url);
 
@@ -67,6 +68,7 @@ public:
      * @param layoutType The form's layout type.
      *
      * @return The new Form.
+     * @script{create}
      */
     static Form* create(const char* id, Theme::Style* style, Layout::Type layoutType = Layout::LAYOUT_ABSOLUTE);
 

+ 1 - 0
gameplay/src/FrameBuffer.h

@@ -33,6 +33,7 @@ public:
      * @param height The height of the RenderTarget to be created and attached.
      *
      * @return A newly created FrameBuffer.
+     * @script{create}
      */
     static FrameBuffer* create(const char* id, unsigned int width, unsigned int height);
 

+ 19 - 3
gameplay/src/Game.cpp

@@ -22,8 +22,8 @@ Game::Game()
       _frameLastFPS(0), _frameCount(0), _frameRate(0), 
       _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
       _animationController(NULL), _audioController(NULL), 
-      _physicsController(NULL), _audioListener(NULL), _scriptController(NULL),
-      _scriptListeners(NULL)
+      _physicsController(NULL), _aiController(NULL), _audioListener(NULL), 
+      _gamepads(NULL), _timeEvents(NULL), _scriptController(NULL), _scriptListeners(NULL)
 {
     GP_ASSERT(__gameInstance == NULL);
     __gameInstance = this;
@@ -120,6 +120,9 @@ bool Game::startup()
     _physicsController = new PhysicsController();
     _physicsController->initialize();
 
+    _aiController = new AIController();
+    _aiController->initialize();
+
     loadGamepads();
     
     _scriptController = new ScriptController();
@@ -173,6 +176,7 @@ void Game::shutdown()
         GP_ASSERT(_animationController);
         GP_ASSERT(_audioController);
         GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
 
         Platform::signalShutdown();
         finalize();
@@ -198,6 +202,8 @@ void Game::shutdown()
 
         _physicsController->finalize();
         SAFE_DELETE(_physicsController);
+        _aiController->finalize();
+        SAFE_DELETE(_aiController);
 
         // Note: we do not clean up the script controller here
         // because users can call Game::exit() from a script.
@@ -219,11 +225,13 @@ void Game::pause()
         GP_ASSERT(_animationController);
         GP_ASSERT(_audioController);
         GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
         _state = PAUSED;
         _pausedTimeLast = Platform::getAbsoluteTime();
         _animationController->pause();
         _audioController->pause();
         _physicsController->pause();
+        _aiController->pause();
     }
 }
 
@@ -234,11 +242,13 @@ void Game::resume()
         GP_ASSERT(_animationController);
         GP_ASSERT(_audioController);
         GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
         _state = RUNNING;
         _pausedTimeTotal += Platform::getAbsoluteTime() - _pausedTimeLast;
         _animationController->resume();
         _audioController->resume();
         _physicsController->resume();
+        _aiController->resume();
     }
 }
 
@@ -261,6 +271,7 @@ void Game::frame()
         GP_ASSERT(_animationController);
         GP_ASSERT(_audioController);
         GP_ASSERT(_physicsController);
+        GP_ASSERT(_aiController);
 
         // Update Time.
         static double lastFrameTime = Game::getGameTime();
@@ -276,7 +287,10 @@ void Game::frame()
     
         // Update the physics.
         _physicsController->update(elapsedTime);
-        
+
+        // Update AI.
+        _aiController->update(elapsedTime);
+
         // Application Update.
         update(elapsedTime);
 
@@ -328,6 +342,7 @@ void Game::updateOnce()
     GP_ASSERT(_animationController);
     GP_ASSERT(_audioController);
     GP_ASSERT(_physicsController);
+    GP_ASSERT(_aiController);
 
     // Update Time.
     static double lastFrameTime = getGameTime();
@@ -338,6 +353,7 @@ void Game::updateOnce()
     // Update the internal controllers.
     _animationController->update(elapsedTime);
     _physicsController->update(elapsedTime);
+    _aiController->update(elapsedTime);
     _audioController->update(elapsedTime);
     _scriptController->update(elapsedTime);
 }

+ 10 - 0
gameplay/src/Game.h

@@ -9,6 +9,7 @@
 #include "AudioController.h"
 #include "AnimationController.h"
 #include "PhysicsController.h"
+#include "AIController.h"
 #include "AudioListener.h"
 #include "Rectangle.h"
 #include "Vector4.h"
@@ -219,6 +220,14 @@ public:
      */
     inline PhysicsController* getPhysicsController() const;
 
+    /** 
+     * Gets the AI controller for managing control of artifical
+     * intelligence associated with the game.
+     *
+     * @return The AI controller for this game.
+     */
+    inline AIController* getAIController() const;
+
     /**
      * Gets the script controller for managing control of Lua scripts
      * associated with the game.
@@ -530,6 +539,7 @@ private:
     AnimationController* _animationController;  // Controls the scheduling and running of animations.
     AudioController* _audioController;          // Controls audio sources that are playing in the game.
     PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
+    AIController* _aiController;                // Controls AI siulation.
     AudioListener* _audioListener;              // The audio listener in 3D space.
     std::vector<Gamepad*>* _gamepads;           // The connected gamepads.
     std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.

+ 4 - 0
gameplay/src/Game.inl

@@ -53,6 +53,10 @@ inline ScriptController* Game::getScriptController() const
 {
     return _scriptController;
 }
+inline AIController* Game::getAIController() const
+{
+    return _aiController;
+}
 
 template <class T>
 void Game::renderOnce(T* instance, void (T::*method)(void*), void* cookie)

+ 1 - 0
gameplay/src/Image.h

@@ -27,6 +27,7 @@ public:
      * 
      * @param path The path to the image file.
      * @return The newly created image.
+     * @script{create}
      */
     static Image* create(const char* path);
 

+ 1 - 0
gameplay/src/Joystick.h

@@ -23,6 +23,7 @@ public:
      * @param style The control's style.
      *
      * @return The new joystick.
+     * @script{create}
      */
     static Joystick* create(const char* id, Theme::Style* style);
     

+ 1 - 0
gameplay/src/Label.h

@@ -40,6 +40,7 @@ public:
      * @param style The control's style.
      *
      * @return The new label.
+     * @script{create}
      */
     static Label* create(const char*id, Theme::Style* style);
 

+ 4 - 0
gameplay/src/Material.h

@@ -35,6 +35,7 @@ public:
      * @param url The URL pointing to the Properties object defining the material.
      * 
      * @return A new Material.
+     * @script{create}
      */
     static Material* create(const char* url);
 
@@ -44,6 +45,7 @@ public:
      * @param materialProperties The properties object defining the 
      *      material (must have namespace equal to 'material').
      * @return A new Material.
+     * @script{create}
      */
     static Material* create(Properties* materialProperties);
 
@@ -56,6 +58,7 @@ public:
      * @param effect Effect for the new material.
      * 
      * @return A new Material.
+     * @script{create}
      */
     static Material* create(Effect* effect);
 
@@ -70,6 +73,7 @@ public:
      * @param defines New-line delimitted list of preprocessor defines.
      * 
      * @return A new Material.
+     * @script{create}
      */
     static Material* create(const char* vshPath, const char* fshPath, const char* defines = NULL);
 

+ 2 - 0
gameplay/src/MeshBatch.h

@@ -25,6 +25,7 @@ public:
      * @param growSize Amount to grow the batch by when it overflows (a value of zero prevents batch growing).
      *
      * @return A new mesh batch.
+     * @script{create}
      */
     static MeshBatch* create(const VertexFormat& vertexFormat, Mesh::PrimitiveType primitiveType, const char* materialPath, bool indexed, unsigned int initialCapacity = 1024, unsigned int growSize = 1024);
 
@@ -39,6 +40,7 @@ public:
      * @param growSize Amount to grow the batch by when it overflows (a value of zero prevents batch growing).
      *
      * @return A new mesh batch.
+     * @script{create}
      */
     static MeshBatch* create(const VertexFormat& vertexFormat, Mesh::PrimitiveType primitiveType, Material* material, bool indexed, unsigned int initialCapacity = 1024, unsigned int growSize = 1024);
 

+ 1 - 0
gameplay/src/Model.h

@@ -27,6 +27,7 @@ public:
 
     /**
      * Creates a new Model.
+     * @script{create}
      */
     static Model* create(Mesh* mesh);
 

+ 31 - 2
gameplay/src/Node.cpp

@@ -24,7 +24,7 @@ namespace gameplay
 Node::Node(const char* id)
     : _scene(NULL), _firstChild(NULL), _nextSibling(NULL), _prevSibling(NULL), _parent(NULL), _childCount(0),
     _nodeFlags(NODE_FLAG_VISIBLE), _camera(NULL), _light(NULL), _model(NULL), _form(NULL), _audioSource(NULL), _particleEmitter(NULL),
-    _collisionObject(NULL), _dirtyBits(NODE_DIRTY_ALL), _notifyHierarchyChanged(true), _userData(NULL)
+    _collisionObject(NULL), _agent(NULL), _dirtyBits(NODE_DIRTY_ALL), _notifyHierarchyChanged(true), _userData(NULL)
 {
     if (id)
     {
@@ -53,6 +53,8 @@ Node::~Node()
     SAFE_RELEASE(_form);
     SAFE_DELETE(_collisionObject);
 
+    setAgent(NULL);
+
     // Cleanup user data
     if (_userData)
     {
@@ -1088,10 +1090,37 @@ PhysicsCollisionObject* Node::setCollisionObject(Properties* properties)
         GP_ERROR("Failed to load collision object from properties object; required attribute 'type' is missing.");
         return NULL;
     }
-    
+
     return _collisionObject;
 }
 
+AIAgent* Node::getAgent() const
+{
+    return _agent;
+}
+
+void Node::setAgent(AIAgent* agent)
+{
+    if (agent != _agent)
+    {
+        if (_agent)
+        {
+            Game::getInstance()->getAIController()->removeAgent(_agent);
+            _agent->_node = NULL;
+            SAFE_RELEASE(_agent);
+        }
+
+        _agent = agent;
+
+        if (_agent)
+        {
+            _agent->addRef();
+            _agent->_node = this;
+            Game::getInstance()->getAIController()->addAgent(_agent);
+        }
+    }
+}
+
 NodeCloneContext::NodeCloneContext()
 {
 }

+ 21 - 0
gameplay/src/Node.h

@@ -11,6 +11,7 @@
 #include "PhysicsCollisionObject.h"
 #include "PhysicsCollisionShape.h"
 #include "BoundingBox.h"
+#include "AIAgent.h"
 
 namespace gameplay
 {
@@ -44,6 +45,7 @@ public:
      * Creates a new node with the specified ID.
      *
      * @param id The ID for the new node.
+     * @script{create}
      */
     static Node* create(const char* id = NULL);
 
@@ -557,6 +559,20 @@ public:
      */
     PhysicsCollisionObject* setCollisionObject(Properties* properties);
 
+    /**
+     * Returns the AI agent assigned to this node.
+     *
+     * @return The AI agent for this node.
+     */
+    AIAgent* getAgent() const;
+
+    /**
+     * Sets the AI agent for this node.
+     *
+     * @param agent The AI agent to set.
+     */
+    void setAgent(AIAgent* agent);
+
     /**
      * Returns the bounding sphere for the Node, in world space.
      *
@@ -753,6 +769,11 @@ protected:
      */
     PhysicsCollisionObject* _collisionObject;
     
+    /**
+     * Pointer to the AI agent attached to the Node.
+     */
+    AIAgent* _agent;
+
     /**
      * World Matrix representation of the Node.
      */

+ 3 - 0
gameplay/src/ParticleEmitter.h

@@ -161,6 +161,7 @@ public:
      * @param url The URL pointing to the Properties object defining the particle emitter.
      * 
      * @return An initialized ParticleEmitter.
+     * @script{create}
      */
     static ParticleEmitter* create(const char* url);
 
@@ -170,6 +171,7 @@ public:
      * @param properties The properties object defining the 
      *      particle emitter (must have namespace equal to 'particle').
      * @return The newly created particle emitter, or <code>NULL</code> if the particle emitter failed to load.
+     * @script{create}
      */
     static ParticleEmitter* create(Properties* properties);
 
@@ -179,6 +181,7 @@ public:
      * @param texturePath A path to the image to use as this ParticleEmitter's texture.
      * @param textureBlending The type of texture blending to be used for the particles emitted.
      * @param particleCountMax The maximum number of particles that can be alive at one time in this ParticleEmitter's system.
+     * @script{create}
      */
     static ParticleEmitter* create(const char* texturePath, TextureBlending textureBlending,  unsigned int particleCountMax);
 

+ 1 - 0
gameplay/src/Properties.h

@@ -150,6 +150,7 @@ public:
      * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional).
      * 
      * @param url The URL to create the properties from.
+     * @script{create}
      */
     static Properties* create(const char* url);
 

+ 1 - 0
gameplay/src/RadioButton.h

@@ -46,6 +46,7 @@ public:
      * @param style The control's style.
      *
      * @return The new radio button.
+     * @script{create}
      */
     static RadioButton* create(const char* id, Theme::Style* style);
 

+ 1 - 0
gameplay/src/RenderState.h

@@ -120,6 +120,7 @@ public:
 
         /**
          * Creates a new StateBlock with default render state settings.
+         * @script{create}
          */
         static StateBlock* create();
 

+ 1 - 0
gameplay/src/RenderTarget.h

@@ -25,6 +25,7 @@ public:
      * @param height The height of the new RenderTarget.
      *
      * @return A newly created RenderTarget.
+     * @script{create}
      */
     static RenderTarget* create(const char* id, unsigned int width, unsigned int height);
 

+ 1 - 0
gameplay/src/SceneLoader.h

@@ -12,6 +12,7 @@ namespace gameplay
 
 /**
  * Helper class for loading scenes from .scene files.
+ * @script{ignore}
  */
 class SceneLoader
 {

+ 7 - 0
gameplay/src/ScriptController.cpp

@@ -488,6 +488,10 @@ ScriptController::ScriptController() : _lua(NULL)
 
 ScriptController::~ScriptController()
 {
+    for (unsigned int i = 0; i < CALLBACK_COUNT; i++)
+    {
+        SAFE_DELETE(_callbacks[i]);
+    }
 }
 
 void ScriptController::initialize()
@@ -519,6 +523,9 @@ void ScriptController::finalizeGame()
     {
         executeFunction<void>(_callbacks[FINALIZE]->c_str());
     }
+
+    // Perform a full garbage collection cycle.
+    lua_gc(_lua, LUA_GCCOLLECT, 0);
 }
 
 void ScriptController::update(float elapsedTime)

+ 1 - 0
gameplay/src/Slider.h

@@ -42,6 +42,7 @@ public:
      * @param style The control's style.
      *
      * @return The new slider.
+     * @script{create}
      */
     static Slider* create(const char* id, Theme::Style* style);
 

+ 2 - 0
gameplay/src/SpriteBatch.h

@@ -52,6 +52,7 @@ public:
      * @param initialCapacity An optional initial capacity of the batch (number of sprites).
      * 
      * @return A new SpriteBatch for drawing sprites using the given texture.
+     * @script{create}
      */
     static SpriteBatch* create(const char* texturePath, Effect* effect = NULL, unsigned int initialCapacity = 0);
 
@@ -78,6 +79,7 @@ public:
      * @param initialCapacity An optional initial capacity of the batch (number of sprites).
      * 
      * @return A new SpriteBatch for drawing sprites using the given texture.
+     * @script{create}
      */
     static SpriteBatch* create(Texture* texture, Effect* effect = NULL, unsigned int initialCapacity = 0);
 

+ 1 - 0
gameplay/src/TextBox.h

@@ -46,6 +46,7 @@ public:
      * @param style The control's style.
      *
      * @return The new text box.
+     * @script{create}
      */
     static TextBox* create(const char* id, Theme::Style* style);
 

+ 5 - 0
gameplay/src/Texture.h

@@ -69,6 +69,7 @@ public:
          * @param texture The texture.
          *
          * @return The new sampler.
+         * @script{create}
          */
         static Sampler* create(Texture* texture);
 
@@ -79,6 +80,7 @@ public:
          * @param generateMipmaps True to force a full mipmap chain to be generated for the texture, false otherwise.
          *
          * @return The new sampler.
+         * @script{create}
          */
         static Sampler* create(const char* path, bool generateMipmaps = false);
 
@@ -138,16 +140,19 @@ public:
      * @param generateMipmaps true to auto-generate a full mipmap chain, false otherwise.
      * 
      * @return The new texture, or NULL if the texture could not be loaded/created.
+     * @script{create}
      */
     static Texture* create(const char* path, bool generateMipmaps = false);
 
     /**
      * Creates a texture from the given image.
+     * @script{create}
      */
     static Texture* create(Image* image, bool generateMipmaps = false);
 
     /**
      * Creates a texture from the given texture data.
+     * @script{create}
      */
     static Texture* create(Format format, unsigned int width, unsigned int height, unsigned char* data, bool generateMipmaps = false);
 

+ 1 - 0
gameplay/src/Theme.h

@@ -299,6 +299,7 @@ public:
      * (and "#<namespace-id>/<namespace-id>/.../<namespace-id>" is optional). 
      * 
      * @param url The URL pointing to the Properties object defining the theme. 
+     * @script{create}
      */
     static Theme* create(const char* url);
 

+ 1 - 0
gameplay/src/VertexAttributeBinding.h

@@ -46,6 +46,7 @@ public:
      * @param effect The effect.
      * 
      * @return A VertexAttributeBinding for the requested parameters.
+     * @script{create}
      */
     static VertexAttributeBinding* create(Mesh* mesh, Effect* effect);
 

+ 1 - 0
gameplay/src/VerticalLayout.h

@@ -20,6 +20,7 @@ public:
      * Create a VerticalLayout.
      *
      * @return a VerticalLayout object.
+     * @script{create}
      */
     static VerticalLayout* create();
 

+ 6 - 0
gameplay/src/gameplay.h

@@ -74,6 +74,12 @@
 #include "PhysicsGhostObject.h"
 #include "PhysicsCharacter.h"
 
+// AI
+#include "AIController.h"
+#include "AIAgent.h"
+#include "AIState.h"
+#include "AIStateMachine.h"
+
 // UI
 #include "Theme.h"
 #include "Control.h"

+ 469 - 0
gameplay/src/lua/lua_AIAgent.cpp

@@ -0,0 +1,469 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIAgent.h"
+#include "AIAgent.h"
+#include "Base.h"
+#include "Game.h"
+#include "Node.h"
+#include "Ref.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIAgent()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"addRef", lua_AIAgent_addRef},
+        {"getId", lua_AIAgent_getId},
+        {"getNode", lua_AIAgent_getNode},
+        {"getRefCount", lua_AIAgent_getRefCount},
+        {"getStateMachine", lua_AIAgent_getStateMachine},
+        {"isEnabled", lua_AIAgent_isEnabled},
+        {"release", lua_AIAgent_release},
+        {"setEnabled", lua_AIAgent_setEnabled},
+        {"setListener", lua_AIAgent_setListener},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_AIAgent_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("AIAgent", lua_members, NULL, lua_AIAgent__gc, lua_statics, scopePath);
+}
+
+static AIAgent* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIAgent");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIAgent' expected.");
+    return (AIAgent*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIAgent__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "AIAgent");
+                luaL_argcheck(state, userdata != NULL, 1, "'AIAgent' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    AIAgent* instance = (AIAgent*)object->instance;
+                    SAFE_RELEASE(instance);
+                }
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent__gc - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_addRef(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                instance->addRef();
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_addRef - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_getId(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                const char* result = instance->getId();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_getId - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_getNode(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getNode();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Node");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_getNode - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_getRefCount(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                unsigned int result = instance->getRefCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_getRefCount - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_getStateMachine(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getStateMachine();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIStateMachine");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_getStateMachine - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_isEnabled(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                bool result = instance->isEnabled();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_isEnabled - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_release(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIAgent* instance = getInstance(state);
+                instance->release();
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_release - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_setEnabled(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                bool param1 = ScriptUtil::luaCheckBool(state, 2);
+
+                AIAgent* instance = getInstance(state);
+                instance->setEnabled(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_setEnabled - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_setListener(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIAgent::Listener* param1 = ScriptUtil::getObjectPointer<AIAgent::Listener>(2, "AIAgentListener", false);
+
+                AIAgent* instance = getInstance(state);
+                instance->setListener(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgent_setListener - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgent_static_create(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            void* returnPtr = (void*)AIAgent::create();
+            if (returnPtr)
+            {
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "AIAgent");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 24 - 0
gameplay/src/lua/lua_AIAgent.h

@@ -0,0 +1,24 @@
+#ifndef LUA_AIAGENT_H_
+#define LUA_AIAGENT_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIAgent.
+int lua_AIAgent__gc(lua_State* state);
+int lua_AIAgent_addRef(lua_State* state);
+int lua_AIAgent_getId(lua_State* state);
+int lua_AIAgent_getNode(lua_State* state);
+int lua_AIAgent_getRefCount(lua_State* state);
+int lua_AIAgent_getStateMachine(lua_State* state);
+int lua_AIAgent_isEnabled(lua_State* state);
+int lua_AIAgent_release(lua_State* state);
+int lua_AIAgent_setEnabled(lua_State* state);
+int lua_AIAgent_setListener(lua_State* state);
+int lua_AIAgent_static_create(lua_State* state);
+
+void luaRegister_AIAgent();
+
+}
+
+#endif

+ 115 - 0
gameplay/src/lua/lua_AIAgentListener.cpp

@@ -0,0 +1,115 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIAgentListener.h"
+#include "AIAgent.h"
+#include "Base.h"
+#include "Game.h"
+#include "Node.h"
+#include "Ref.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIAgentListener()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"messageReceived", lua_AIAgentListener_messageReceived},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+    scopePath.push_back("AIAgent");
+
+    ScriptUtil::registerClass("AIAgentListener", lua_members, NULL, lua_AIAgentListener__gc, lua_statics, scopePath);
+}
+
+static AIAgent::Listener* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIAgentListener");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIAgentListener' expected.");
+    return (AIAgent::Listener*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIAgentListener__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "AIAgentListener");
+                luaL_argcheck(state, userdata != NULL, 1, "'AIAgentListener' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    AIAgent::Listener* instance = (AIAgent::Listener*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgentListener__gc - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIAgentListener_messageReceived(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIMessage* param1 = ScriptUtil::getObjectPointer<AIMessage>(2, "AIMessage", false);
+
+                AIAgent::Listener* instance = getInstance(state);
+                bool result = instance->messageReceived(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIAgentListener_messageReceived - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 15 - 0
gameplay/src/lua/lua_AIAgentListener.h

@@ -0,0 +1,15 @@
+#ifndef LUA_AIAGENTLISTENER_H_
+#define LUA_AIAGENTLISTENER_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIAgent::Listener.
+int lua_AIAgentListener__gc(lua_State* state);
+int lua_AIAgentListener_messageReceived(lua_State* state);
+
+void luaRegister_AIAgentListener();
+
+}
+
+#endif

+ 144 - 0
gameplay/src/lua/lua_AIController.cpp

@@ -0,0 +1,144 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIController.h"
+#include "AIController.h"
+#include "Base.h"
+#include "Game.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIController()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"findAgent", lua_AIController_findAgent},
+        {"sendMessage", lua_AIController_sendMessage},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("AIController", lua_members, NULL, NULL, lua_statics, scopePath);
+}
+
+static AIController* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIController");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIController' expected.");
+    return (AIController*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIController_findAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                AIController* instance = getInstance(state);
+                void* returnPtr = (void*)instance->findAgent(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIAgent");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIController_findAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIController_sendMessage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIMessage* param1 = ScriptUtil::getObjectPointer<AIMessage>(2, "AIMessage", false);
+
+                AIController* instance = getInstance(state);
+                instance->sendMessage(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIController_sendMessage - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                AIMessage* param1 = ScriptUtil::getObjectPointer<AIMessage>(2, "AIMessage", false);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 3);
+
+                AIController* instance = getInstance(state);
+                instance->sendMessage(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIController_sendMessage - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 15 - 0
gameplay/src/lua/lua_AIController.h

@@ -0,0 +1,15 @@
+#ifndef LUA_AICONTROLLER_H_
+#define LUA_AICONTROLLER_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIController.
+int lua_AIController_findAgent(lua_State* state);
+int lua_AIController_sendMessage(lua_State* state);
+
+void luaRegister_AIController();
+
+}
+
+#endif

+ 838 - 0
gameplay/src/lua/lua_AIMessage.cpp

@@ -0,0 +1,838 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIMessage.h"
+#include "AIMessage.h"
+#include "Base.h"
+#include "lua_AIMessageParameterType.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIMessage()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"getBoolean", lua_AIMessage_getBoolean},
+        {"getDouble", lua_AIMessage_getDouble},
+        {"getFloat", lua_AIMessage_getFloat},
+        {"getId", lua_AIMessage_getId},
+        {"getInt", lua_AIMessage_getInt},
+        {"getLong", lua_AIMessage_getLong},
+        {"getParameterCount", lua_AIMessage_getParameterCount},
+        {"getParameterType", lua_AIMessage_getParameterType},
+        {"getReceiver", lua_AIMessage_getReceiver},
+        {"getSender", lua_AIMessage_getSender},
+        {"getString", lua_AIMessage_getString},
+        {"setBoolean", lua_AIMessage_setBoolean},
+        {"setDouble", lua_AIMessage_setDouble},
+        {"setFloat", lua_AIMessage_setFloat},
+        {"setInt", lua_AIMessage_setInt},
+        {"setLong", lua_AIMessage_setLong},
+        {"setString", lua_AIMessage_setString},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_AIMessage_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("AIMessage", lua_members, NULL, lua_AIMessage__gc, lua_statics, scopePath);
+}
+
+static AIMessage* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIMessage");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIMessage' expected.");
+    return (AIMessage*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIMessage__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "AIMessage");
+                luaL_argcheck(state, userdata != NULL, 1, "'AIMessage' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    AIMessage* instance = (AIMessage*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage__gc - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getBoolean(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                bool result = instance->getBoolean(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getBoolean - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getDouble(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                double result = instance->getDouble(param1);
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getDouble - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getFloat(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                float result = instance->getFloat(param1);
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getFloat - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getId(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIMessage* instance = getInstance(state);
+                unsigned int result = instance->getId();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getId - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getInt(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                int result = instance->getInt(param1);
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getInt - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getLong(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                long result = instance->getLong(param1);
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getLong - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getParameterCount(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIMessage* instance = getInstance(state);
+                unsigned int result = instance->getParameterCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getParameterCount - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getParameterType(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                AIMessage::ParameterType result = instance->getParameterType(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_AIMessageParameterType(result));
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getParameterType - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getReceiver(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIMessage* instance = getInstance(state);
+                const char* result = instance->getReceiver();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getReceiver - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getSender(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIMessage* instance = getInstance(state);
+                const char* result = instance->getSender();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getSender - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_getString(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                AIMessage* instance = getInstance(state);
+                const char* result = instance->getString(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_getString - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setBoolean(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = ScriptUtil::luaCheckBool(state, 3);
+
+                AIMessage* instance = getInstance(state);
+                instance->setBoolean(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setBoolean - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setDouble(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                double param2 = (double)luaL_checknumber(state, 3);
+
+                AIMessage* instance = getInstance(state);
+                instance->setDouble(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setDouble - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setFloat(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                float param2 = (float)luaL_checknumber(state, 3);
+
+                AIMessage* instance = getInstance(state);
+                instance->setFloat(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setFloat - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setInt(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                AIMessage* instance = getInstance(state);
+                instance->setInt(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setInt - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setLong(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                long param2 = (long)luaL_checklong(state, 3);
+
+                AIMessage* instance = getInstance(state);
+                instance->setLong(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setLong - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_setString(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = ScriptUtil::getString(3, false);
+
+                AIMessage* instance = getInstance(state);
+                instance->setString(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_setString - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIMessage_static_create(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 4:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL) &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 1);
+
+                // Get parameter 2 off the stack.
+                const char* param2 = ScriptUtil::getString(2, false);
+
+                // Get parameter 3 off the stack.
+                const char* param3 = ScriptUtil::getString(3, false);
+
+                // Get parameter 4 off the stack.
+                unsigned int param4 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                void* returnPtr = (void*)AIMessage::create(param1, param2, param3, param4);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIMessage");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIMessage_static_create - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 32 - 0
gameplay/src/lua/lua_AIMessage.h

@@ -0,0 +1,32 @@
+#ifndef LUA_AIMESSAGE_H_
+#define LUA_AIMESSAGE_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIMessage.
+int lua_AIMessage__gc(lua_State* state);
+int lua_AIMessage_getBoolean(lua_State* state);
+int lua_AIMessage_getDouble(lua_State* state);
+int lua_AIMessage_getFloat(lua_State* state);
+int lua_AIMessage_getId(lua_State* state);
+int lua_AIMessage_getInt(lua_State* state);
+int lua_AIMessage_getLong(lua_State* state);
+int lua_AIMessage_getParameterCount(lua_State* state);
+int lua_AIMessage_getParameterType(lua_State* state);
+int lua_AIMessage_getReceiver(lua_State* state);
+int lua_AIMessage_getSender(lua_State* state);
+int lua_AIMessage_getString(lua_State* state);
+int lua_AIMessage_setBoolean(lua_State* state);
+int lua_AIMessage_setDouble(lua_State* state);
+int lua_AIMessage_setFloat(lua_State* state);
+int lua_AIMessage_setInt(lua_State* state);
+int lua_AIMessage_setLong(lua_State* state);
+int lua_AIMessage_setString(lua_State* state);
+int lua_AIMessage_static_create(lua_State* state);
+
+void luaRegister_AIMessage();
+
+}
+
+#endif

+ 58 - 0
gameplay/src/lua/lua_AIMessageParameterType.cpp

@@ -0,0 +1,58 @@
+#include "Base.h"
+#include "lua_AIMessageParameterType.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_AIMessageParameterType_UNDEFINED = "UNDEFINED";
+static const char* luaEnumString_AIMessageParameterType_INTEGER = "INTEGER";
+static const char* luaEnumString_AIMessageParameterType_LONG = "LONG";
+static const char* luaEnumString_AIMessageParameterType_FLOAT = "FLOAT";
+static const char* luaEnumString_AIMessageParameterType_DOUBLE = "DOUBLE";
+static const char* luaEnumString_AIMessageParameterType_BOOLEAN = "BOOLEAN";
+static const char* luaEnumString_AIMessageParameterType_STRING = "STRING";
+
+AIMessage::ParameterType lua_enumFromString_AIMessageParameterType(const char* s)
+{
+    if (strcmp(s, luaEnumString_AIMessageParameterType_UNDEFINED) == 0)
+        return AIMessage::UNDEFINED;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_INTEGER) == 0)
+        return AIMessage::INTEGER;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_LONG) == 0)
+        return AIMessage::LONG;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_FLOAT) == 0)
+        return AIMessage::FLOAT;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_DOUBLE) == 0)
+        return AIMessage::DOUBLE;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_BOOLEAN) == 0)
+        return AIMessage::BOOLEAN;
+    if (strcmp(s, luaEnumString_AIMessageParameterType_STRING) == 0)
+        return AIMessage::STRING;
+    GP_ERROR("Invalid enumeration value '%s' for enumeration AIMessage::ParameterType.", s);
+    return AIMessage::UNDEFINED;
+}
+
+const char* lua_stringFromEnum_AIMessageParameterType(AIMessage::ParameterType e)
+{
+    if (e == AIMessage::UNDEFINED)
+        return luaEnumString_AIMessageParameterType_UNDEFINED;
+    if (e == AIMessage::INTEGER)
+        return luaEnumString_AIMessageParameterType_INTEGER;
+    if (e == AIMessage::LONG)
+        return luaEnumString_AIMessageParameterType_LONG;
+    if (e == AIMessage::FLOAT)
+        return luaEnumString_AIMessageParameterType_FLOAT;
+    if (e == AIMessage::DOUBLE)
+        return luaEnumString_AIMessageParameterType_DOUBLE;
+    if (e == AIMessage::BOOLEAN)
+        return luaEnumString_AIMessageParameterType_BOOLEAN;
+    if (e == AIMessage::STRING)
+        return luaEnumString_AIMessageParameterType_STRING;
+    GP_ERROR("Invalid enumeration value '%d' for enumeration AIMessage::ParameterType.", e);
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_AIMessageParameterType.h

@@ -0,0 +1,15 @@
+#ifndef LUA_AIMESSAGEPARAMETERTYPE_H_
+#define LUA_AIMESSAGEPARAMETERTYPE_H_
+
+#include "AIMessage.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for AIMessage::ParameterType.
+AIMessage::ParameterType lua_enumFromString_AIMessageParameterType(const char* s);
+const char* lua_stringFromEnum_AIMessageParameterType(AIMessage::ParameterType e);
+
+}
+
+#endif

+ 309 - 0
gameplay/src/lua/lua_AIState.cpp

@@ -0,0 +1,309 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIState.h"
+#include "AIState.h"
+#include "AIStateMachine.h"
+#include "Base.h"
+#include "Game.h"
+#include "Ref.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIState()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"addRef", lua_AIState_addRef},
+        {"getId", lua_AIState_getId},
+        {"getRefCount", lua_AIState_getRefCount},
+        {"release", lua_AIState_release},
+        {"setListener", lua_AIState_setListener},
+        {NULL, NULL}
+    };
+    const luaL_Reg lua_statics[] = 
+    {
+        {"create", lua_AIState_static_create},
+        {NULL, NULL}
+    };
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("AIState", lua_members, NULL, lua_AIState__gc, lua_statics, scopePath);
+}
+
+static AIState* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIState");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIState' expected.");
+    return (AIState*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIState__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "AIState");
+                luaL_argcheck(state, userdata != NULL, 1, "'AIState' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    AIState* instance = (AIState*)object->instance;
+                    SAFE_RELEASE(instance);
+                }
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState__gc - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_addRef(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIState* instance = getInstance(state);
+                instance->addRef();
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_addRef - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_getId(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIState* instance = getInstance(state);
+                const char* result = instance->getId();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_getId - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_getRefCount(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIState* instance = getInstance(state);
+                unsigned int result = instance->getRefCount();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_getRefCount - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_release(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIState* instance = getInstance(state);
+                instance->release();
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_release - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_setListener(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIState::Listener* param1 = ScriptUtil::getObjectPointer<AIState::Listener>(2, "AIStateListener", false);
+
+                AIState* instance = getInstance(state);
+                instance->setListener(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_setListener - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIState_static_create(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(1, false);
+
+                void* returnPtr = (void*)AIState::create(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIState");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIState_static_create - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 20 - 0
gameplay/src/lua/lua_AIState.h

@@ -0,0 +1,20 @@
+#ifndef LUA_AISTATE_H_
+#define LUA_AISTATE_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIState.
+int lua_AIState__gc(lua_State* state);
+int lua_AIState_addRef(lua_State* state);
+int lua_AIState_getId(lua_State* state);
+int lua_AIState_getRefCount(lua_State* state);
+int lua_AIState_release(lua_State* state);
+int lua_AIState_setListener(lua_State* state);
+int lua_AIState_static_create(lua_State* state);
+
+void luaRegister_AIState();
+
+}
+
+#endif

+ 243 - 0
gameplay/src/lua/lua_AIStateListener.cpp

@@ -0,0 +1,243 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIStateListener.h"
+#include "AIState.h"
+#include "AIStateMachine.h"
+#include "Base.h"
+#include "Game.h"
+#include "Ref.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIStateListener()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"stateEnter", lua_AIStateListener_stateEnter},
+        {"stateExit", lua_AIStateListener_stateExit},
+        {"stateUpdate", lua_AIStateListener_stateUpdate},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+    scopePath.push_back("AIState");
+
+    ScriptUtil::registerClass("AIStateListener", lua_members, lua_AIStateListener__init, lua_AIStateListener__gc, lua_statics, scopePath);
+}
+
+static AIState::Listener* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIStateListener");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIStateListener' expected.");
+    return (AIState::Listener*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIStateListener__gc(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                void* userdata = luaL_checkudata(state, 1, "AIStateListener");
+                luaL_argcheck(state, userdata != NULL, 1, "'AIStateListener' expected.");
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
+                if (object->owns)
+                {
+                    AIState::Listener* instance = (AIState::Listener*)object->instance;
+                    SAFE_DELETE(instance);
+                }
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateListener__gc - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateListener__init(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            void* returnPtr = (void*)new AIState::Listener();
+            if (returnPtr)
+            {
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = true;
+                luaL_getmetatable(state, "AIStateListener");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateListener_stateEnter(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIAgent* param1 = ScriptUtil::getObjectPointer<AIAgent>(2, "AIAgent", false);
+
+                // Get parameter 2 off the stack.
+                AIState* param2 = ScriptUtil::getObjectPointer<AIState>(3, "AIState", false);
+
+                AIState::Listener* instance = getInstance(state);
+                instance->stateEnter(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateListener_stateEnter - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateListener_stateExit(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIAgent* param1 = ScriptUtil::getObjectPointer<AIAgent>(2, "AIAgent", false);
+
+                // Get parameter 2 off the stack.
+                AIState* param2 = ScriptUtil::getObjectPointer<AIState>(3, "AIState", false);
+
+                AIState::Listener* instance = getInstance(state);
+                instance->stateExit(param1, param2);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateListener_stateExit - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateListener_stateUpdate(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                (lua_type(state, 3) == LUA_TUSERDATA || lua_type(state, 3) == LUA_TTABLE || lua_type(state, 3) == LUA_TNIL) &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                AIAgent* param1 = ScriptUtil::getObjectPointer<AIAgent>(2, "AIAgent", false);
+
+                // Get parameter 2 off the stack.
+                AIState* param2 = ScriptUtil::getObjectPointer<AIState>(3, "AIState", false);
+
+                // Get parameter 3 off the stack.
+                float param3 = (float)luaL_checknumber(state, 4);
+
+                AIState::Listener* instance = getInstance(state);
+                instance->stateUpdate(param1, param2, param3);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateListener_stateUpdate - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 4).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 18 - 0
gameplay/src/lua/lua_AIStateListener.h

@@ -0,0 +1,18 @@
+#ifndef LUA_AISTATELISTENER_H_
+#define LUA_AISTATELISTENER_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIState::Listener.
+int lua_AIStateListener__gc(lua_State* state);
+int lua_AIStateListener__init(lua_State* state);
+int lua_AIStateListener_stateEnter(lua_State* state);
+int lua_AIStateListener_stateExit(lua_State* state);
+int lua_AIStateListener_stateUpdate(lua_State* state);
+
+void luaRegister_AIStateListener();
+
+}
+
+#endif

+ 343 - 0
gameplay/src/lua/lua_AIStateMachine.cpp

@@ -0,0 +1,343 @@
+#include "Base.h"
+#include "ScriptController.h"
+#include "lua_AIStateMachine.h"
+#include "AIAgent.h"
+#include "AIMessage.h"
+#include "AIStateMachine.h"
+#include "Base.h"
+#include "Game.h"
+
+namespace gameplay
+{
+
+void luaRegister_AIStateMachine()
+{
+    const luaL_Reg lua_members[] = 
+    {
+        {"addState", lua_AIStateMachine_addState},
+        {"getActiveState", lua_AIStateMachine_getActiveState},
+        {"getAgent", lua_AIStateMachine_getAgent},
+        {"getState", lua_AIStateMachine_getState},
+        {"removeState", lua_AIStateMachine_removeState},
+        {"setState", lua_AIStateMachine_setState},
+        {NULL, NULL}
+    };
+    const luaL_Reg* lua_statics = NULL;
+    std::vector<std::string> scopePath;
+
+    ScriptUtil::registerClass("AIStateMachine", lua_members, NULL, NULL, lua_statics, scopePath);
+}
+
+static AIStateMachine* getInstance(lua_State* state)
+{
+    void* userdata = luaL_checkudata(state, 1, "AIStateMachine");
+    luaL_argcheck(state, userdata != NULL, 1, "'AIStateMachine' expected.");
+    return (AIStateMachine*)((ScriptUtil::LuaObject*)userdata)->instance;
+}
+
+int lua_AIStateMachine_addState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                AIStateMachine* instance = getInstance(state);
+                void* returnPtr = (void*)instance->addState(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIState");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIState* param1 = ScriptUtil::getObjectPointer<AIState>(2, "AIState", false);
+
+                AIStateMachine* instance = getInstance(state);
+                instance->addState(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_addState - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateMachine_getActiveState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIStateMachine* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getActiveState();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIState");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_getActiveState - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateMachine_getAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                AIStateMachine* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAgent();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIAgent");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_getAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateMachine_getState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                AIStateMachine* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getState(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIState");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_getState - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateMachine_removeState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIState* param1 = ScriptUtil::getObjectPointer<AIState>(2, "AIState", false);
+
+                AIStateMachine* instance = getInstance(state);
+                instance->removeState(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_removeState - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_AIStateMachine_setState(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = ScriptUtil::getString(2, false);
+
+                AIStateMachine* instance = getInstance(state);
+                void* returnPtr = (void*)instance->setState(param1);
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIState");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIState* param1 = ScriptUtil::getObjectPointer<AIState>(2, "AIState", false);
+
+                AIStateMachine* instance = getInstance(state);
+                bool result = instance->setState(param1);
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_AIStateMachine_setState - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+}

+ 19 - 0
gameplay/src/lua/lua_AIStateMachine.h

@@ -0,0 +1,19 @@
+#ifndef LUA_AISTATEMACHINE_H_
+#define LUA_AISTATEMACHINE_H_
+
+namespace gameplay
+{
+
+// Lua bindings for AIStateMachine.
+int lua_AIStateMachine_addState(lua_State* state);
+int lua_AIStateMachine_getActiveState(lua_State* state);
+int lua_AIStateMachine_getAgent(lua_State* state);
+int lua_AIStateMachine_getState(lua_State* state);
+int lua_AIStateMachine_removeState(lua_State* state);
+int lua_AIStateMachine_setState(lua_State* state);
+
+void luaRegister_AIStateMachine();
+
+}
+
+#endif

+ 2 - 2
gameplay/src/lua/lua_AudioSource.cpp

@@ -752,7 +752,7 @@ int lua_AudioSource_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "AudioSource");
                     lua_setmetatable(state, -2);
                 }
@@ -773,7 +773,7 @@ int lua_AudioSource_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "AudioSource");
                     lua_setmetatable(state, -2);
                 }

+ 6 - 6
gameplay/src/lua/lua_Bundle.cpp

@@ -298,7 +298,7 @@ int lua_Bundle_loadFont(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Font");
                     lua_setmetatable(state, -2);
                 }
@@ -348,7 +348,7 @@ int lua_Bundle_loadMesh(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Mesh");
                     lua_setmetatable(state, -2);
                 }
@@ -398,7 +398,7 @@ int lua_Bundle_loadNode(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Node");
                     lua_setmetatable(state, -2);
                 }
@@ -444,7 +444,7 @@ int lua_Bundle_loadScene(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Scene");
                     lua_setmetatable(state, -2);
                 }
@@ -476,7 +476,7 @@ int lua_Bundle_loadScene(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Scene");
                     lua_setmetatable(state, -2);
                 }
@@ -558,7 +558,7 @@ int lua_Bundle_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Bundle");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_CheckBox.cpp

@@ -4507,7 +4507,7 @@ int lua_CheckBox_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "CheckBox");
                     lua_setmetatable(state, -2);
                 }

+ 2 - 2
gameplay/src/lua/lua_Container.cpp

@@ -4713,7 +4713,7 @@ int lua_Container_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Container");
                     lua_setmetatable(state, -2);
                 }
@@ -4751,7 +4751,7 @@ int lua_Container_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Container");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_Curve.cpp

@@ -544,7 +544,7 @@ int lua_Curve_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Curve");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_DepthStencilTarget.cpp

@@ -290,7 +290,7 @@ int lua_DepthStencilTarget_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "DepthStencilTarget");
                     lua_setmetatable(state, -2);
                 }

+ 3 - 54
gameplay/src/lua/lua_Font.cpp

@@ -8,7 +8,6 @@
 #include "Game.h"
 #include "Ref.h"
 #include "lua_FontJustify.h"
-#include "lua_FontStyle.h"
 
 namespace gameplay
 {
@@ -1607,7 +1606,7 @@ int lua_Font_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Font");
                     lua_setmetatable(state, -2);
                 }
@@ -1641,57 +1640,7 @@ int lua_Font_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
-                    luaL_getmetatable(state, "Font");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-            else
-            {
-                lua_pushstring(state, "lua_Font_static_create - Failed to match the given parameters to a valid function signature.");
-                lua_error(state);
-            }
-            break;
-        }
-        case 6:
-        {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL) &&
-                (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER &&
-                (lua_type(state, 4) == LUA_TUSERDATA || lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TNIL) &&
-                lua_type(state, 5) == LUA_TNUMBER &&
-                (lua_type(state, 6) == LUA_TUSERDATA || lua_type(state, 6) == LUA_TTABLE || lua_type(state, 6) == LUA_TNIL))
-            {
-                // Get parameter 1 off the stack.
-                const char* param1 = ScriptUtil::getString(1, false);
-
-                // Get parameter 2 off the stack.
-                Font::Style param2 = (Font::Style)lua_enumFromString_FontStyle(luaL_checkstring(state, 2));
-
-                // Get parameter 3 off the stack.
-                unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
-
-                // Get parameter 4 off the stack.
-                Font::Glyph* param4 = ScriptUtil::getObjectPointer<Font::Glyph>(4, "FontGlyph", false);
-
-                // Get parameter 5 off the stack.
-                int param5 = (int)luaL_checkint(state, 5);
-
-                // Get parameter 6 off the stack.
-                Texture* param6 = ScriptUtil::getObjectPointer<Texture>(6, "Texture", false);
-
-                void* returnPtr = (void*)Font::create(param1, param2, param3, param4, param5, param6);
-                if (returnPtr)
-                {
-                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                    object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Font");
                     lua_setmetatable(state, -2);
                 }
@@ -1711,7 +1660,7 @@ int lua_Font_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 1, 2 or 6).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
             lua_error(state);
             break;
         }

+ 0 - 202
gameplay/src/lua/lua_FontGlyph.cpp

@@ -1,202 +0,0 @@
-#include "Base.h"
-#include "ScriptController.h"
-#include "lua_FontGlyph.h"
-#include "Base.h"
-#include "Bundle.h"
-#include "FileSystem.h"
-#include "Font.h"
-#include "Game.h"
-#include "Ref.h"
-#include "lua_FontJustify.h"
-#include "lua_FontStyle.h"
-
-namespace gameplay
-{
-
-void luaRegister_FontGlyph()
-{
-    const luaL_Reg lua_members[] = 
-    {
-        {"code", lua_FontGlyph_code},
-        {"uvs", lua_FontGlyph_uvs},
-        {"width", lua_FontGlyph_width},
-        {NULL, NULL}
-    };
-    const luaL_Reg* lua_statics = NULL;
-    std::vector<std::string> scopePath;
-    scopePath.push_back("Font");
-
-    ScriptUtil::registerClass("FontGlyph", lua_members, lua_FontGlyph__init, lua_FontGlyph__gc, lua_statics, scopePath);
-}
-
-static Font::Glyph* getInstance(lua_State* state)
-{
-    void* userdata = luaL_checkudata(state, 1, "FontGlyph");
-    luaL_argcheck(state, userdata != NULL, 1, "'FontGlyph' expected.");
-    return (Font::Glyph*)((ScriptUtil::LuaObject*)userdata)->instance;
-}
-
-int lua_FontGlyph__gc(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                void* userdata = luaL_checkudata(state, 1, "FontGlyph");
-                luaL_argcheck(state, userdata != NULL, 1, "'FontGlyph' expected.");
-                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)userdata;
-                if (object->owns)
-                {
-                    Font::Glyph* instance = (Font::Glyph*)object->instance;
-                    SAFE_DELETE(instance);
-                }
-                
-                return 0;
-            }
-            else
-            {
-                lua_pushstring(state, "lua_FontGlyph__gc - Failed to match the given parameters to a valid function signature.");
-                lua_error(state);
-            }
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FontGlyph__init(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 0:
-        {
-            void* returnPtr = (void*)new Font::Glyph();
-            if (returnPtr)
-            {
-                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
-                object->instance = returnPtr;
-                object->owns = true;
-                luaL_getmetatable(state, "FontGlyph");
-                lua_setmetatable(state, -2);
-            }
-            else
-            {
-                lua_pushnil(state);
-            }
-
-            return 1;
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_FontGlyph_code(lua_State* state)
-{
-    // Validate the number of parameters.
-    if (lua_gettop(state) > 2)
-    {
-        lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
-        lua_error(state);
-    }
-
-    Font::Glyph* instance = getInstance(state);
-    if (lua_gettop(state) == 2)
-    {
-        // Get parameter 2 off the stack.
-        unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 2);
-
-        instance->code = param2;
-        return 0;
-    }
-    else
-    {
-        unsigned int result = instance->code;
-
-        // Push the return value onto the stack.
-        lua_pushunsigned(state, result);
-
-        return 1;
-    }
-}
-
-int lua_FontGlyph_uvs(lua_State* state)
-{
-    // Validate the number of parameters.
-    if (lua_gettop(state) > 2)
-    {
-        lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
-        lua_error(state);
-    }
-
-    Font::Glyph* instance = getInstance(state);
-    if (lua_gettop(state) == 2)
-    {
-        // Get parameter 2 off the stack.
-        float* param2 = ScriptUtil::getFloatPointer(2);
-
-        memcpy(instance->uvs, param2, sizeof(float) * 4);
-        return 0;
-    }
-    else
-    {
-        float* result = instance->uvs;
-
-        // Push the return value onto the stack.
-        lua_pushlightuserdata(state, result);
-        return 1;
-    }
-}
-
-int lua_FontGlyph_width(lua_State* state)
-{
-    // Validate the number of parameters.
-    if (lua_gettop(state) > 2)
-    {
-        lua_pushstring(state, "Invalid number of parameters (expected 1 or 2).");
-        lua_error(state);
-    }
-
-    Font::Glyph* instance = getInstance(state);
-    if (lua_gettop(state) == 2)
-    {
-        // Get parameter 2 off the stack.
-        unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 2);
-
-        instance->width = param2;
-        return 0;
-    }
-    else
-    {
-        unsigned int result = instance->width;
-
-        // Push the return value onto the stack.
-        lua_pushunsigned(state, result);
-
-        return 1;
-    }
-}
-
-}

+ 0 - 18
gameplay/src/lua/lua_FontGlyph.h

@@ -1,18 +0,0 @@
-#ifndef LUA_FONTGLYPH_H_
-#define LUA_FONTGLYPH_H_
-
-namespace gameplay
-{
-
-// Lua bindings for Font::Glyph.
-int lua_FontGlyph__gc(lua_State* state);
-int lua_FontGlyph__init(lua_State* state);
-int lua_FontGlyph_code(lua_State* state);
-int lua_FontGlyph_uvs(lua_State* state);
-int lua_FontGlyph_width(lua_State* state);
-
-void luaRegister_FontGlyph();
-
-}
-
-#endif

+ 0 - 1
gameplay/src/lua/lua_FontText.cpp

@@ -8,7 +8,6 @@
 #include "Game.h"
 #include "Ref.h"
 #include "lua_FontJustify.h"
-#include "lua_FontStyle.h"
 
 namespace gameplay
 {

+ 3 - 3
gameplay/src/lua/lua_Form.cpp

@@ -4835,7 +4835,7 @@ int lua_Form_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Form");
                     lua_setmetatable(state, -2);
                 }
@@ -4869,7 +4869,7 @@ int lua_Form_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Form");
                     lua_setmetatable(state, -2);
                 }
@@ -4907,7 +4907,7 @@ int lua_Form_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Form");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -613,7 +613,7 @@ int lua_FrameBuffer_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "FrameBuffer");
                     lua_setmetatable(state, -2);
                 }

+ 47 - 0
gameplay/src/lua/lua_Game.cpp

@@ -28,6 +28,7 @@ void luaRegister_Game()
         {"exit", lua_Game_exit},
         {"frame", lua_Game_frame},
         {"gamepadEvent", lua_Game_gamepadEvent},
+        {"getAIController", lua_Game_getAIController},
         {"getAccelerometerValues", lua_Game_getAccelerometerValues},
         {"getAnimationController", lua_Game_getAnimationController},
         {"getAudioController", lua_Game_getAudioController},
@@ -320,6 +321,52 @@ int lua_Game_gamepadEvent(lua_State* state)
     return 0;
 }
 
+int lua_Game_getAIController(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAIController();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Game_getAIController - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Game_getAccelerometerValues(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_Game.h

@@ -11,6 +11,7 @@ int lua_Game_displayKeyboard(lua_State* state);
 int lua_Game_exit(lua_State* state);
 int lua_Game_frame(lua_State* state);
 int lua_Game_gamepadEvent(lua_State* state);
+int lua_Game_getAIController(lua_State* state);
 int lua_Game_getAccelerometerValues(lua_State* state);
 int lua_Game_getAnimationController(lua_State* state);
 int lua_Game_getAudioController(lua_State* state);

+ 22 - 10
gameplay/src/lua/lua_Global.cpp

@@ -12,7 +12,7 @@ void luaRegister_lua_Global()
     ScriptUtil::registerFunction("printError", lua__printError);
 
     std::map<std::string, std::vector<std::string> > hierarchy;
-    hierarchy["AnimationClip::Listener"].push_back("classgameplay_1_1_script_listener");
+    hierarchy["AnimationClip::Listener"].push_back("ScriptListener");
     hierarchy["AnimationTarget"].push_back("Button");
     hierarchy["AnimationTarget"].push_back("CheckBox");
     hierarchy["AnimationTarget"].push_back("Container");
@@ -27,7 +27,6 @@ void luaRegister_lua_Global()
     hierarchy["AnimationTarget"].push_back("Slider");
     hierarchy["AnimationTarget"].push_back("TextBox");
     hierarchy["AnimationTarget"].push_back("Transform");
-    hierarchy["AnimationTarget"].push_back("classgameplay_1_1_theme_1_1_style_1_1_overlay");
     hierarchy["Button"].push_back("CheckBox");
     hierarchy["Button"].push_back("RadioButton");
     hierarchy["Container"].push_back("Form");
@@ -40,7 +39,7 @@ void luaRegister_lua_Global()
     hierarchy["Control"].push_back("RadioButton");
     hierarchy["Control"].push_back("Slider");
     hierarchy["Control"].push_back("TextBox");
-    hierarchy["Control::Listener"].push_back("classgameplay_1_1_script_listener");
+    hierarchy["Control::Listener"].push_back("ScriptListener");
     hierarchy["Label"].push_back("Button");
     hierarchy["Label"].push_back("CheckBox");
     hierarchy["Label"].push_back("RadioButton");
@@ -53,16 +52,18 @@ void luaRegister_lua_Global()
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsCharacter");
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsGhostObject");
     hierarchy["PhysicsCollisionObject"].push_back("PhysicsRigidBody");
-    hierarchy["PhysicsCollisionObject::CollisionListener"].push_back("classgameplay_1_1_script_listener");
+    hierarchy["PhysicsCollisionObject::CollisionListener"].push_back("ScriptListener");
     hierarchy["PhysicsConstraint"].push_back("PhysicsFixedConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsGenericConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsHingeConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsSocketConstraint");
     hierarchy["PhysicsConstraint"].push_back("PhysicsSpringConstraint");
-    hierarchy["PhysicsController::Listener"].push_back("classgameplay_1_1_script_listener");
+    hierarchy["PhysicsController::Listener"].push_back("ScriptListener");
     hierarchy["PhysicsGenericConstraint"].push_back("PhysicsFixedConstraint");
     hierarchy["PhysicsGenericConstraint"].push_back("PhysicsSpringConstraint");
     hierarchy["PhysicsGhostObject"].push_back("PhysicsCharacter");
+    hierarchy["Ref"].push_back("AIAgent");
+    hierarchy["Ref"].push_back("AIState");
     hierarchy["Ref"].push_back("AbsoluteLayout");
     hierarchy["Ref"].push_back("Animation");
     hierarchy["Ref"].push_back("AnimationClip");
@@ -109,10 +110,6 @@ void luaRegister_lua_Global()
     hierarchy["Ref"].push_back("Theme::ThemeImage");
     hierarchy["Ref"].push_back("VertexAttributeBinding");
     hierarchy["Ref"].push_back("VerticalLayout");
-    hierarchy["Ref"].push_back("classgameplay_1_1_material_parameter_1_1_method_binding");
-    hierarchy["Ref"].push_back("classgameplay_1_1_theme_1_1_image_list");
-    hierarchy["Ref"].push_back("classgameplay_1_1_theme_1_1_skin");
-    hierarchy["Ref"].push_back("classgameplay_1_1_theme_1_1_style_1_1_overlay");
     hierarchy["RenderState"].push_back("Material");
     hierarchy["RenderState"].push_back("Pass");
     hierarchy["RenderState"].push_back("Technique");
@@ -125,9 +122,22 @@ void luaRegister_lua_Global()
     hierarchy["Transform::Listener"].push_back("PhysicsCharacter");
     hierarchy["Transform::Listener"].push_back("PhysicsGhostObject");
     hierarchy["Transform::Listener"].push_back("PhysicsRigidBody");
-    hierarchy["Transform::Listener"].push_back("classgameplay_1_1_script_listener");
+    hierarchy["Transform::Listener"].push_back("ScriptListener");
     ScriptUtil::setGlobalHierarchy(hierarchy);
 
+    // Register enumeration AIMessage::ParameterType.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("AIMessage");
+        ScriptUtil::registerConstantString("UNDEFINED", "UNDEFINED", scopePath);
+        ScriptUtil::registerConstantString("INTEGER", "INTEGER", scopePath);
+        ScriptUtil::registerConstantString("LONG", "LONG", scopePath);
+        ScriptUtil::registerConstantString("FLOAT", "FLOAT", scopePath);
+        ScriptUtil::registerConstantString("DOUBLE", "DOUBLE", scopePath);
+        ScriptUtil::registerConstantString("BOOLEAN", "BOOLEAN", scopePath);
+        ScriptUtil::registerConstantString("STRING", "STRING", scopePath);
+    }
+
     // Register enumeration AnimationClip::Listener::EventType.
     {
         std::vector<std::string> scopePath;
@@ -848,6 +858,8 @@ static const char* enumStringEmpty = "";
 
 const char* lua_stringFromEnumGlobal(std::string& enumname, unsigned int value)
 {
+    if (enumname == "AIMessage::ParameterType")
+        return lua_stringFromEnum_AIMessageParameterType((AIMessage::ParameterType)value);
     if (enumname == "AnimationClip::Listener::EventType")
         return lua_stringFromEnum_AnimationClipListenerEventType((AnimationClip::Listener::EventType)value);
     if (enumname == "AudioSource::State")

+ 1 - 0
gameplay/src/lua/lua_Global.h

@@ -1,6 +1,7 @@
 #ifndef LUA_GLOBAL_H_
 #define LUA_GLOBAL_H_
 
+#include "lua_AIMessageParameterType.h"
 #include "lua_AnimationClipListenerEventType.h"
 #include "lua_AudioSourceState.h"
 #include "lua_CameraType.h"

+ 1 - 1
gameplay/src/lua/lua_Image.cpp

@@ -316,7 +316,7 @@ int lua_Image_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Image");
                     lua_setmetatable(state, -2);
                 }

+ 86 - 0
gameplay/src/lua/lua_Joint.cpp

@@ -38,6 +38,7 @@ void luaRegister_Joint()
         {"findNode", lua_Joint_findNode},
         {"getActiveCameraTranslationView", lua_Joint_getActiveCameraTranslationView},
         {"getActiveCameraTranslationWorld", lua_Joint_getActiveCameraTranslationWorld},
+        {"getAgent", lua_Joint_getAgent},
         {"getAnimation", lua_Joint_getAnimation},
         {"getAnimationPropertyComponentCount", lua_Joint_getAnimationPropertyComponentCount},
         {"getAnimationPropertyValue", lua_Joint_getAnimationPropertyValue},
@@ -108,6 +109,7 @@ void luaRegister_Joint()
         {"scaleY", lua_Joint_scaleY},
         {"scaleZ", lua_Joint_scaleZ},
         {"set", lua_Joint_set},
+        {"setAgent", lua_Joint_setAgent},
         {"setAnimationPropertyValue", lua_Joint_setAnimationPropertyValue},
         {"setAudioSource", lua_Joint_setAudioSource},
         {"setCamera", lua_Joint_setCamera},
@@ -1023,6 +1025,52 @@ int lua_Joint_getActiveCameraTranslationWorld(lua_State* state)
     return 0;
 }
 
+int lua_Joint_getAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Joint* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAgent();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIAgent");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Joint_getAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Joint_getAnimation(lua_State* state)
 {
     // Get the number of parameters.
@@ -4438,6 +4486,44 @@ int lua_Joint_set(lua_State* state)
     return 0;
 }
 
+int lua_Joint_setAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIAgent* param1 = ScriptUtil::getObjectPointer<AIAgent>(2, "AIAgent", false);
+
+                Joint* instance = getInstance(state);
+                instance->setAgent(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Joint_setAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Joint_setAnimationPropertyValue(lua_State* state)
 {
     // Get the number of parameters.

+ 2 - 0
gameplay/src/lua/lua_Joint.h

@@ -17,6 +17,7 @@ int lua_Joint_destroyAnimation(lua_State* state);
 int lua_Joint_findNode(lua_State* state);
 int lua_Joint_getActiveCameraTranslationView(lua_State* state);
 int lua_Joint_getActiveCameraTranslationWorld(lua_State* state);
+int lua_Joint_getAgent(lua_State* state);
 int lua_Joint_getAnimation(lua_State* state);
 int lua_Joint_getAnimationPropertyComponentCount(lua_State* state);
 int lua_Joint_getAnimationPropertyValue(lua_State* state);
@@ -87,6 +88,7 @@ int lua_Joint_scaleX(lua_State* state);
 int lua_Joint_scaleY(lua_State* state);
 int lua_Joint_scaleZ(lua_State* state);
 int lua_Joint_set(lua_State* state);
+int lua_Joint_setAgent(lua_State* state);
 int lua_Joint_setAnimationPropertyValue(lua_State* state);
 int lua_Joint_setAudioSource(lua_State* state);
 int lua_Joint_setCamera(lua_State* state);

+ 1 - 1
gameplay/src/lua/lua_Joystick.cpp

@@ -4471,7 +4471,7 @@ int lua_Joystick_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Joystick");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_Label.cpp

@@ -4338,7 +4338,7 @@ int lua_Label_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Label");
                     lua_setmetatable(state, -2);
                 }

+ 5 - 5
gameplay/src/lua/lua_Material.cpp

@@ -645,7 +645,7 @@ int lua_Material_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Material");
                     lua_setmetatable(state, -2);
                 }
@@ -666,7 +666,7 @@ int lua_Material_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Material");
                     lua_setmetatable(state, -2);
                 }
@@ -687,7 +687,7 @@ int lua_Material_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Material");
                     lua_setmetatable(state, -2);
                 }
@@ -721,7 +721,7 @@ int lua_Material_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Material");
                     lua_setmetatable(state, -2);
                 }
@@ -759,7 +759,7 @@ int lua_Material_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Material");
                     lua_setmetatable(state, -2);
                 }

+ 6 - 6
gameplay/src/lua/lua_MeshBatch.cpp

@@ -332,7 +332,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }
@@ -365,7 +365,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }
@@ -411,7 +411,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }
@@ -448,7 +448,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }
@@ -498,7 +498,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }
@@ -539,7 +539,7 @@ int lua_MeshBatch_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "MeshBatch");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_Model.cpp

@@ -784,7 +784,7 @@ int lua_Model_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Model");
                     lua_setmetatable(state, -2);
                 }

+ 88 - 2
gameplay/src/lua/lua_Node.cpp

@@ -37,6 +37,7 @@ void luaRegister_Node()
         {"findNode", lua_Node_findNode},
         {"getActiveCameraTranslationView", lua_Node_getActiveCameraTranslationView},
         {"getActiveCameraTranslationWorld", lua_Node_getActiveCameraTranslationWorld},
+        {"getAgent", lua_Node_getAgent},
         {"getAnimation", lua_Node_getAnimation},
         {"getAnimationPropertyComponentCount", lua_Node_getAnimationPropertyComponentCount},
         {"getAnimationPropertyValue", lua_Node_getAnimationPropertyValue},
@@ -106,6 +107,7 @@ void luaRegister_Node()
         {"scaleY", lua_Node_scaleY},
         {"scaleZ", lua_Node_scaleZ},
         {"set", lua_Node_set},
+        {"setAgent", lua_Node_setAgent},
         {"setAnimationPropertyValue", lua_Node_setAnimationPropertyValue},
         {"setAudioSource", lua_Node_setAudioSource},
         {"setCamera", lua_Node_setCamera},
@@ -1022,6 +1024,52 @@ int lua_Node_getActiveCameraTranslationWorld(lua_State* state)
     return 0;
 }
 
+int lua_Node_getAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Node* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getAgent();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "AIAgent");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Node_getAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Node_getAnimation(lua_State* state)
 {
     // Get the number of parameters.
@@ -4391,6 +4439,44 @@ int lua_Node_set(lua_State* state)
     return 0;
 }
 
+int lua_Node_setAgent(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                AIAgent* param1 = ScriptUtil::getObjectPointer<AIAgent>(2, "AIAgent", false);
+
+                Node* instance = getInstance(state);
+                instance->setAgent(param1);
+                
+                return 0;
+            }
+            else
+            {
+                lua_pushstring(state, "lua_Node_setAgent - Failed to match the given parameters to a valid function signature.");
+                lua_error(state);
+            }
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Node_setAnimationPropertyValue(lua_State* state)
 {
     // Get the number of parameters.
@@ -5742,7 +5828,7 @@ int lua_Node_static_create(lua_State* state)
             {
                 ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                 object->instance = returnPtr;
-                object->owns = false;
+                object->owns = true;
                 luaL_getmetatable(state, "Node");
                 lua_setmetatable(state, -2);
             }
@@ -5766,7 +5852,7 @@ int lua_Node_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Node");
                     lua_setmetatable(state, -2);
                 }

+ 2 - 0
gameplay/src/lua/lua_Node.h

@@ -17,6 +17,7 @@ int lua_Node_destroyAnimation(lua_State* state);
 int lua_Node_findNode(lua_State* state);
 int lua_Node_getActiveCameraTranslationView(lua_State* state);
 int lua_Node_getActiveCameraTranslationWorld(lua_State* state);
+int lua_Node_getAgent(lua_State* state);
 int lua_Node_getAnimation(lua_State* state);
 int lua_Node_getAnimationPropertyComponentCount(lua_State* state);
 int lua_Node_getAnimationPropertyValue(lua_State* state);
@@ -86,6 +87,7 @@ int lua_Node_scaleX(lua_State* state);
 int lua_Node_scaleY(lua_State* state);
 int lua_Node_scaleZ(lua_State* state);
 int lua_Node_set(lua_State* state);
+int lua_Node_setAgent(lua_State* state);
 int lua_Node_setAnimationPropertyValue(lua_State* state);
 int lua_Node_setAudioSource(lua_State* state);
 int lua_Node_setCamera(lua_State* state);

+ 3 - 3
gameplay/src/lua/lua_ParticleEmitter.cpp

@@ -2452,7 +2452,7 @@ int lua_ParticleEmitter_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "ParticleEmitter");
                     lua_setmetatable(state, -2);
                 }
@@ -2473,7 +2473,7 @@ int lua_ParticleEmitter_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "ParticleEmitter");
                     lua_setmetatable(state, -2);
                 }
@@ -2511,7 +2511,7 @@ int lua_ParticleEmitter_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "ParticleEmitter");
                     lua_setmetatable(state, -2);
                 }

+ 1 - 1
gameplay/src/lua/lua_Properties.cpp

@@ -1021,7 +1021,7 @@ int lua_Properties_static_create(lua_State* state)
                 {
                     ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
                     object->instance = returnPtr;
-                    object->owns = false;
+                    object->owns = true;
                     luaL_getmetatable(state, "Properties");
                     lua_setmetatable(state, -2);
                 }

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov