Index: code/branches/gamestate/data/lua/Debugger.lua
===================================================================
--- code/branches/gamestate/data/lua/Debugger.lua	(revision 6659)
+++ code/branches/gamestate/data/lua/Debugger.lua	(revision 6660)
@@ -433,5 +433,5 @@
 
   -- Transform line endings to \n
-  text :gsub("\r\n", "\n") -- Windows to Unix
+  text:gsub("\r\n", "\n") -- Windows to Unix
   text:gsub("\r", "\n")   -- Mac to Unix
   if text[-1] ~= "\n" then
Index: code/branches/gamestate/data/lua/LuaStateInit.lua
===================================================================
--- code/branches/gamestate/data/lua/LuaStateInit.lua	(revision 6659)
+++ code/branches/gamestate/data/lua/LuaStateInit.lua	(revision 6660)
@@ -17,5 +17,5 @@
 dofile = function(filename)
   luaState:doFile(filename)
-  -- Required because the C++ function cannot return whatever might be on the stack
+  -- Required because if the file returns a table, it cannot be passed through the C++ function
   return LuaStateReturnValue -- C-injected global variable
 end
@@ -26,5 +26,5 @@
 include = function(filename)
   luaState:includeFile(filename)
-  -- Required because the C++ function cannot return whatever might be on the stack
+  -- Required because if the file returns a table, it cannot be passed through the C++ function
   return LuaStateReturnValue -- C-injected global variable
 end
@@ -44,10 +44,15 @@
     _LOADED = {}
   end
-  if not _LOADED[moduleName] then
+  if _LOADED[moduleName] == nil then
     -- save old value
     local _REQUIREDNAME_OLD = _REQUIREDNAME
     _REQUIREDNAME = moduleName
     luaState:doFile(moduleName .. ".lua")
-    _LOADED[moduleName] = LuaStateReturnValue
+    -- LuaStateReturnValue is required because if the file returns a table,
+    -- it cannot be passed through the C++ function
+    if LuaStateReturnValue == nil then -- C-injected global variable
+        LuaStateReturnValue = true
+    end
+    _LOADED[moduleName] = LuaStateReturnValue -- This entry must never be nil
     -- restore old value
     _REQUIREDNAME = _REQUIREDNAME_OLD
@@ -55,4 +60,36 @@
   return _LOADED[moduleName]
 end
+
+
+-- Include command line debugger for lua 5.1
+-- Note: It doesn't work if the IOConsole was started. Then we replace pause() with a warning
+if _VERSION ~= "Lua 5.0"  and not luaState:usingIOConsole() then
+  require("Debugger")
+else
+  -- Fallback pause function
+  pause = function()
+    logMessage(2, [["Warning: debug() called in Lua, but Debugger is not active.
+Do you have the IOConsole disabled and are you using Lua version 5.1?"]])
+  end
+end
+
+-- General error handler that gets called whenever an error happens at runtime
+errorHandler = function(err)
+  -- Display the error message
+  if type(err) == "string" then
+    logMessage(1, "Lua runtime error: "..err)
+  end
+
+  -- Start debugger if possible
+  if _LOADED and _LOADED["Debugger"] ~= nil then
+    pause()
+  else
+    -- Fallback: print stack trace
+    debug.traceback(nil, "", 2)
+  end
+  return err -- Hello Lua debugger user! Please type 'set 2' to get to the
+             -- actual position in the stack where the error occurred
+end
+
 
 -- Convenience function for console commands
@@ -71,7 +108,2 @@
   return orxonox.SettingsConfigFile:getInstance():tconfig(section, entry, value)
 end
-
--- Include command line debugger for lua 5.1
-if _VERSION ~= "Lua 5.0" then
-  require("Debugger")
-end
Index: code/branches/gamestate/src/libraries/core/LuaState.cc
===================================================================
--- code/branches/gamestate/src/libraries/core/LuaState.cc	(revision 6659)
+++ code/branches/gamestate/src/libraries/core/LuaState.cc	(revision 6660)
@@ -37,4 +37,7 @@
 
 #include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "IOConsole.h"
 #include "Resource.h"
 #include "ToluaBindCore.h"
@@ -54,4 +57,5 @@
         // Create new lua state and configure it
         luaState_ = lua_open();
+        Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_);
 #if LUA_VERSION_NUM == 501
         luaL_openlibs(luaState_);
@@ -78,5 +82,8 @@
 
         // Parse init script
-        this->doFile("LuaStateInit.lua");
+        if (!this->doFile("LuaStateInit.lua"))
+            ThrowException(InitialisationFailed, "Running LuaStateInit.lua failed");
+
+        luaStateGuard.Dismiss();
     }
 
@@ -96,14 +103,17 @@
     }
 
-    void LuaState::includeFile(const std::string& filename)
+    bool LuaState::includeFile(const std::string& filename)
     {
         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
         if (sourceInfo != NULL)
-            this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot include file '" << filename << "'." << std::endl;
-    }
-
-    void LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+            return this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot include file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     {
         // Parse string with provided include parser (otherwise don't preparse at all)
@@ -121,5 +131,5 @@
         }
 
-        this->doString(luaInput, sourceFileInfo);
+        bool returnValue = this->doString(luaInput, sourceFileInfo);
 
         if (sourceFileInfo != NULL)
@@ -129,16 +139,21 @@
                 this->sourceCodeMap_.erase(sourceFileInfo->filename);
         }
-    }
-
-    void LuaState::doFile(const std::string& filename)
+
+        return returnValue;
+    }
+
+    bool LuaState::doFile(const std::string& filename)
     {
         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
         if (sourceInfo != NULL)
-            this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
-        else
-            COUT(2) << "LuaState: Cannot do file '" << filename << "'." << std::endl;
-    }
-
-    void LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+            return this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot do file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     {
         // Save the old source file info
@@ -161,37 +176,69 @@
         }
 
-        int error = 0;
+        // Push custom error handler that uses the debugger
+        int errorHandler = 1;
+        lua_getglobal(this->luaState_, "errorHandler");
+        if (lua_isnil(this->luaState_, -1))
+        {
+            lua_pop(this->luaState_, 1);
+            errorHandler = 0;
+        }
+
 #if LUA_VERSION_NUM != 501
         LoadS ls;
         ls.s = code.c_str();
         ls.size = code.size();
-        error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str());
+        int error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str());
 #else
-        error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str());
+        int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str());
 #endif
 
-        // execute the chunk
+        switch (error)
+        {
+        case LUA_ERRSYNTAX: // Syntax error
+            COUT(1) << "Lua syntax error: " << lua_tostring(luaState_, -1) << std::endl;
+            break;
+        case LUA_ERRMEM:    // Memory allocation error
+            COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+            lua_pop(luaState_, 1);
+            break;
+        }
+
         if (error == 0)
-            error = lua_pcall(luaState_, 0, 1, 0);
+        {
+            // Execute the chunk in protected mode with an error handler function (stack index)
+            error = lua_pcall(luaState_, 0, 1, errorHandler);
+
+            switch (error)
+            {
+            case LUA_ERRRUN: // Runtime error
+                // Remove error string from stack (we already display the error in the
+                // 'errorHandler' Lua function in LuaStateInit.lua)
+                lua_pop(luaState_, 1);
+                break;
+            case LUA_ERRERR: // Error in the error handler
+                COUT(1) << "Lua error in error handler: " << lua_tostring(luaState_, -1) << std::endl;
+                break;
+            case LUA_ERRMEM: // Memory allocation error
+                COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+                lua_pop(luaState_, 1);
+                break;
+            }
+        }
+
         if (error != 0)
         {
-            std::string origin;
-            if (sourceFileInfo != NULL)
-                origin = " originating from " + sourceFileInfo_->filename;
-            COUT(1) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
-            // return value is true (not nil!)
-            lua_pushboolean(luaState_, 1);
-        }
-        if (lua_isnil(luaState_, -1))
-        {
-            // Nil return values cause problems
-            lua_pop(luaState_, 1);
-            lua_pushboolean(luaState_, 1);
-        }
-        // Push return value because it will get lost since the return value of this function is void
+            // Push a nil return value
+            lua_pushnil(luaState_);
+        }
+
+        // Set return value to a global variable because we cannot return a table in this function
+        // here. It would work for numbers, pointers and strings, but certainly not for Lua tables.
         lua_setglobal(luaState_, "LuaStateReturnValue");
 
         // Load the old info again
         sourceFileInfo_ = oldSourceFileInfo;
+
+        return (error == 0);
     }
 
@@ -230,4 +277,9 @@
     }
 
+    bool LuaState::usingIOConsole() const
+    {
+        return IOConsole::exists();
+    }
+
 #if LUA_VERSION_NUM != 501
     const char * LuaState::lua_Chunkreader(lua_State *L, void *data, size_t *size)
Index: code/branches/gamestate/src/libraries/core/LuaState.h
===================================================================
--- code/branches/gamestate/src/libraries/core/LuaState.h	(revision 6659)
+++ code/branches/gamestate/src/libraries/core/LuaState.h	(revision 6660)
@@ -71,9 +71,9 @@
         ~LuaState();
 
-        void doFile(const std::string& filename); // tolua_export
-        void doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+        bool doFile(const std::string& filename); // tolua_export
+        bool doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
 
-        void includeFile(const std::string& filename); // tolua_export
-        void includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+        bool includeFile(const std::string& filename); // tolua_export
+        bool includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
 
         void luaPrint(const std::string& str); // tolua_export
@@ -92,4 +92,6 @@
 
         Functor* createLuaFunctor(const std::string& code) { return new LuaFunctor(code, this); } // tolua_export
+        //! Tells about whether IOConsole was activated. The Lua debugger only works with a normal console.
+        bool usingIOConsole() const; // tolua_export
 
         static bool addToluaInterface(int (*function)(lua_State*), const std::string& name);
