diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 00000000..972446b0
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,28 @@
+{
+    "configurations": [
+        {
+            "name": "Mac",
+            "includePath": ["/usr/include"],
+            "browse" : {
+                "limitSymbolsToIncludedHeaders" : true,
+                "databaseFilename" : ""
+            }
+        },
+        {
+            "name": "Linux",
+            "includePath": ["/usr/include"],
+            "browse" : {
+                "limitSymbolsToIncludedHeaders" : true,
+                "databaseFilename" : ""
+            }
+        },
+        {
+            "name": "Win32",
+            "includePath": ["c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", "src"],
+            "browse" : {
+                "limitSymbolsToIncludedHeaders" : true,
+                "databaseFilename" : ""
+            }
+        }
+    ]
+}
diff --git a/build/Lol (vs2015).sln b/build/Lol (vs2015).sln
index 22c0ffe0..d24d0a1d 100644
--- a/build/Lol (vs2015).sln	
+++ b/build/Lol (vs2015).sln	
@@ -66,6 +66,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B629
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "15_lolimgui", "..\doc\tutorial\15_lolimgui.vcxproj", "{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "14_lol_lua", "..\doc\tutorial\14_lol_lua.vcxproj", "{31B96262-1C41-43B9-BA38-27AA385B05DB}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|ORBIS = Debug|ORBIS
@@ -308,6 +310,18 @@ Global
 		{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|Win32.Build.0 = Release|Win32
 		{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.ActiveCfg = Release|x64
 		{81C83B42-D00A-4FA3-9A3D-80F9D46524BF}.Release|x64.Build.0 = Release|x64
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|ORBIS.ActiveCfg = Debug|ORBIS
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|ORBIS.Build.0 = Debug|ORBIS
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|Win32.Build.0 = Debug|Win32
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|x64.ActiveCfg = Debug|x64
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Debug|x64.Build.0 = Debug|x64
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|ORBIS.ActiveCfg = Release|ORBIS
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|ORBIS.Build.0 = Release|ORBIS
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|Win32.ActiveCfg = Release|Win32
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|Win32.Build.0 = Release|Win32
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|x64.ActiveCfg = Release|x64
+		{31B96262-1C41-43B9-BA38-27AA385B05DB}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -341,5 +355,6 @@ Global
 		{73F1A804-1116-46C3-922A-9C0ADEB33F52} = {4C4BD478-3767-4C27-BD91-DAAFE7CD03A2}
 		{B6297FF2-63D0-41EE-BE13-EFF720C9B0FA} = {1AFD580B-98B8-4689-B661-38C41132C60E}
 		{81C83B42-D00A-4FA3-9A3D-80F9D46524BF} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
+		{31B96262-1C41-43B9-BA38-27AA385B05DB} = {E74CF679-CA2A-47E9-B1F4-3779D6AC6B04}
 	EndGlobalSection
 EndGlobal
diff --git a/doc/samples/meshviewer/imgui.ini b/doc/samples/meshviewer/imgui.ini
new file mode 100644
index 00000000..0e0a9153
--- /dev/null
+++ b/doc/samples/meshviewer/imgui.ini
@@ -0,0 +1,10 @@
+[Debug]
+Pos=60,60
+Size=400,400
+Collapsed=0
+
+[Camera Setup]
+Pos=60,60
+Size=307,314
+Collapsed=0
+
diff --git a/doc/samples/meshviewer/scenesetup.cpp b/doc/samples/meshviewer/scenesetup.cpp
index 46806349..a86ff561 100644
--- a/doc/samples/meshviewer/scenesetup.cpp
+++ b/doc/samples/meshviewer/scenesetup.cpp
@@ -159,93 +159,83 @@ SceneSetupLuaObject::~SceneSetupLuaObject()
 //-----------------------------------------------------------------------------
 SceneSetupLuaObject* SceneSetupLuaObject::New(lua_State* l, int arg_nb)
 {
-    UNUSED(l);
     UNUSED(arg_nb);
-    LuaStack s(l);
-    LuaString n;
-    s >> n;
-    return new SceneSetupLuaObject(n());
+    auto s = LuaStack::Begin(l);
+    auto n = s.Get<String>();
+    return new SceneSetupLuaObject(n);
 }
 
 //-- Setup command ------------------------------------------------------------
 int SceneSetupLuaObject::AddLight(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaString t;
-    s >> o >> t;
-    o->m_setup->AddLight(FindValue<LightType>(t().C()));
-    return 0;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto t = s.Get<String>();
+    o->m_setup->AddLight(FindValue<LightType>(t.C()));
+    return s.End();
 }
 int SceneSetupLuaObject::SetupScene(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    s >> o;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
     o->m_setup->SetupScene();
-    return 0;
+    return s.End();
 }
 //-- main funcs ---------------------------------------------------------------
 int SceneSetupLuaObject::SetPosition(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaVec3 c;
-    s >> o >> c;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto c = s.Get<vec3>();
     o->m_setup->SetPosition(c);
-    return 0;
+    return s.End();
 }
 int SceneSetupLuaObject::SetLookAt(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaVec3 c;
-    s >> o >> c;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto c = s.Get<vec3>();
     o->m_setup->SetLookAt(c);
-    return 0;
+    return s.End();
 }
 int SceneSetupLuaObject::SetColor(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaColor c;
-    s >> o >> c;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto c = s.Get<vec4>();
     o->m_setup->SetColor(c);
-    return 0;
+    return s.End();
 }
 int SceneSetupLuaObject::Show(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaDisplay e;
-    s >> o >> e;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto e = s.GetEnum<SceneSetup::DisplayBase>();
     o->m_setup->Show(e);
-    return 0;
+    return s.End();
 }
 int SceneSetupLuaObject::Hide(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaDisplay e;
-    s >> o >> e;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto e = s.GetEnum<SceneSetup::DisplayBase>();
     o->m_setup->Hide(e);
-    return 0;
+    return s.End();
 }
 int SceneSetupLuaObject::Toggle(lua_State* l)
 {
-    LuaStack s(l);
-    LuaSSetupPtr o;
-    LuaDisplay e;
-    s >> o >> e;
+    auto s = LuaStack::Begin(l);
+    auto o = s.GetPtr<SceneSetupLuaObject>();
+    auto e = s.GetEnum<SceneSetup::DisplayBase>();
     o->m_setup->Toggle(e);
-    return 0;
+    return s.End();
 }
 
 //-----------------------------------------------------------------------------
-const LuaObjectLib* SceneSetupLuaObject::GetLib()
+const LuaObjectLibrary* SceneSetupLuaObject::GetLib()
 {
     typedef SceneSetupLuaObject SSLO;
-    static const LuaObjectLib lib = LuaObjectLib(
+    static const LuaObjectLibrary lib = LuaObjectLibrary(
         "SceneSetup",
         //Statics
         { { nullptr, nullptr } },
@@ -264,7 +254,7 @@ const LuaObjectLib* SceneSetupLuaObject::GetLib()
         },
         //Variables
         { { nullptr, nullptr, nullptr } });
-            return &lib;
+    return &lib;
 }
 
 //-----------------------------------------------------------------------------
@@ -273,7 +263,7 @@ SceneSetupLuaLoader::SceneSetupLuaLoader() : LuaLoader()
 {
     lua_State* l = GetLuaState();
 
-    LuaObjectDef::Register<SceneSetupLuaObject>(l);
+    LuaObjectHelper::Register<SceneSetupLuaObject>(l);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/doc/samples/meshviewer/scenesetup.h b/doc/samples/meshviewer/scenesetup.h
index 9b6ffc29..23694a7b 100644
--- a/doc/samples/meshviewer/scenesetup.h
+++ b/doc/samples/meshviewer/scenesetup.h
@@ -103,12 +103,10 @@ public:
     bool                        m_show_gizmo;
     bool                        m_show_lights;
 };
-typedef Lolua::VarEnum<SceneSetup::DisplayBase> LuaDisplay;
 
 //-----------------------------------------------------------------------------
 class SceneSetupLuaObject : public LuaObject
 {
-    typedef Lolua::VarPtr<SceneSetupLuaObject> LuaSSetupPtr;
 public:
     //-------------------------------------------------------------------------
     SceneSetupLuaObject(String& name);
@@ -116,7 +114,7 @@ public:
 
     //-------------------------------------------------------------------------
     static SceneSetupLuaObject* New(lua_State* l, int arg_nb);
-    static const LuaObjectLib* GetLib();
+    static const LuaObjectLibrary* GetLib();
 
     //-------------------------------------------------------------------------
 public:
diff --git a/doc/tutorial/14_lol_lua.cpp b/doc/tutorial/14_lol_lua.cpp
index 653354c6..412795e5 100644
--- a/doc/tutorial/14_lol_lua.cpp
+++ b/doc/tutorial/14_lol_lua.cpp
@@ -23,7 +23,6 @@ using namespace lol;
 //-----------------------------------------------------------------------------
 class DemoObject : public LuaObject
 {
-    typedef Lolua::VarPtr<DemoObject> LuaDemoObjectPtr;
 public:
     DemoObject() : LuaObject() {}
     virtual ~DemoObject() {}
@@ -37,47 +36,67 @@ public:
     //-------------------------------------------------------------------------
     static int AddFive(lua_State* l)
     {
-        LuaInt32 i; i.Get(l, 1);
+		auto stack = LuaStack::Begin(l);
+		int32_t i = stack.Get<int32_t>();
+
         i += 5;
-        return i.Return(l);
+
+        return (stack << i).End();
     }
-    static int AddTenInstance(lua_State* l)
+    
+    LOLUA_DECLARE_RETURN_METHOD_ARGS(AddTenInstance, GetPtr<DemoObject>(), AddTenMethod, Get<float>(), Get<int32_t>(), Get<int32_t>());
+    static int _AddTenInstance(lua_State* l)
     {
-        LuaStack stack(l);
-        LuaDemoObjectPtr obj;
-        LuaFloat f;
-        stack >> obj >> f;
-        f = obj->AddTenMethod(f);
-        return f.Return(l);
+        auto stack = LuaStack::Begin(l);
+        DemoObject* obj = stack.GetPtr<DemoObject>();
+        float f = stack.Get<float>();
+        int32_t i = stack.Get<int32_t>();
+        int32_t i2 = stack.Get<int32_t>();
+
+        f = obj->AddTenMethod(f, i, i2);
+
+        return (stack << f).End();
     }
-    float AddTenMethod(float f)
+
+    float AddTenMethod(float f, int32_t i, int32_t i2)
     {
+        UNUSED(i, i2);
         return (f + 10);
     }
 
     static int GetX(lua_State* l)
     {
-        LuaStack stack(l);
-        LuaDemoObjectPtr obj;
-        LuaInt32 i;
-        stack >> obj;
+        auto stack = LuaStack::Begin(l);
+        DemoObject* obj = stack.GetPtr<DemoObject>();
+        auto i = stack.Get<int32_t>();
+
         i = obj->m_x;
-        return stack << i;
+
+        return (stack << i).End();
     }
-    static int SetX(lua_State* l)
+
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SetX, GetPtr<DemoObject>(), SetXMethod, Get<int32_t>());
+    static int _SetX(lua_State* l)
     {
-        LuaStack stack(l);
-        LuaDemoObjectPtr obj;
-        LuaInt32 i;
-        stack >> obj >> i;
+        auto stack = LuaStack::Begin(l);
+        DemoObject* obj = stack.GetPtr<DemoObject>();
+        auto i = stack.Get<int32_t>();
+
         obj->m_x = i;
-        return 0;
+
+        return stack.End();
+    }
+
+    void SetXMethod(int32_t i)
+    {
+        m_x = i;
     }
 
+
     //-------------------------------------------------------------------------
-    static const LuaObjectLib* GetLib()
+    static const LuaObjectLibrary* GetLib()
     {
-        static const LuaObjectLib lib = LuaObjectLib(
+        static const LuaObjectLibrary lib = LuaObjectLibrary(
             "LoluaDemo",
             { { "AddFive", &DemoObject::AddFive } },
             { { "AddTenInstance", &DemoObject::AddTenInstance } },
@@ -91,9 +110,12 @@ public:
 //-----------------------------------------------------------------------------
 static int GlobalAddString(lua_State* l)
 {
-    LuaString s; s.Get(l, 1);
-    s() += "_added";
-    return s.Return(l);
+    auto stack = LuaStack::Begin(l);
+    auto s = stack.Get<String>();
+
+    s += "_added";
+
+    return (stack << s).End();
 }
 
 //-----------------------------------------------------------------------------
@@ -105,7 +127,7 @@ public:
         lua_State* l = GetLuaState();
 
         //Registering demo object
-        LuaObjectDef::Register<DemoObject>(l);
+        LuaObjectHelper::Register<DemoObject>(l);
 
         //Registering function
         LuaFunction add_string(l, "GlobalAddString", &GlobalAddString);
@@ -158,27 +180,33 @@ public:
         demo_loader->TestStuff();
 
         //Grab global test values
-        float testvalue_num = demo_loader->GetVar<float>("testvalue_num");
-        int32_t testvalue_int = demo_loader->GetVar<int32_t>("testvalue_int");
-        uint32_t testvalue_uint = demo_loader->GetVar<uint32_t>("testvalue_uint");
-        String testvalue_str = demo_loader->GetVar<String>("testvalue_str");
+        float testvalue_num = demo_loader->Get<float>("testvalue_num");
+        int32_t testvalue_int = demo_loader->Get<int32_t>("testvalue_int");
+        uint32_t testvalue_uint = demo_loader->Get<uint32_t>("testvalue_uint");
+        String testvalue_str = demo_loader->Get<String>("testvalue_str");
 
         //Grab string modified with function
-        String function_return = demo_loader->GetVar<String>("function_return");
+        String function_return = demo_loader->Get<String>("function_return");
 
         //Grab global values modified with DemoObject
-        int32_t loluademo_return = demo_loader->GetVar<int32_t>("loluademo_return");
-        int32_t loluademo_getx = demo_loader->GetVar<int32_t>("loluademo_getx");
-        float loluademo_inst_return = demo_loader->GetVar<float>("loluademo_inst_return");
+        int32_t loluademo_return = demo_loader->Get<int32_t>("loluademo_return");
+        int32_t loluademo_getx = demo_loader->Get<int32_t>("loluademo_getx");
+        float loluademo_inst_return = demo_loader->Get<float>("loluademo_inst_return");
         DemoObject* loluademo_inst = demo_loader->GetPtr<DemoObject>("loluademo_inst");
 
         msg::info("Lua Vars: \
             testvalue_num: %.2f, testvalue_int: %i, testvalue_uint: %i, testvalue_str: %s.\n",
             testvalue_num, testvalue_int, testvalue_uint, testvalue_str.C());
         msg::info("Lua Vars: \
-            function_return: %s, loluademo_return: %i, loluademo_inst_return: %.f, loluademo_getx: %i, loluademo_inst->m_x: %i.\n",
+            function_return: %s, loluademo_return: %i, loluademo_inst_return: %.2f, loluademo_getx: %i, loluademo_inst->m_x: %i.\n",
             function_return.C(), loluademo_return, loluademo_inst_return, loluademo_getx, loluademo_inst->m_x);
 
+#define /***/ _LOLUA_ARG_1(a00) (float)a00
+#define /***/ _LOLUA_ARG_2(a00, a01) _LOLUA_ARG_1(a00), _LOLUA_ARG_1(a01)
+#define /***/ _LOLUA_ARG_3(a00, a01, a02) _LOLUA_ARG_1(a00), _LOLUA_ARG_2(a01, a02)
+#define /***/ _LOLUA_ARG_4(a00, a01, a02, a03) _LOLUA_ARG_1(a00), _LOLUA_ARG_3(a01, a02, a03)
+        msg::info("_LOLUA_ARG_1: %f, %f, %f, %f\n", _LOLUA_ARG_4(0, 1, 2, 3));
+
         delete demo_loader;
 
         Ticker::Shutdown();
diff --git a/doc/tutorial/14_lol_lua.lua b/doc/tutorial/14_lol_lua.lua
index cea94073..0b0a0428 100644
--- a/doc/tutorial/14_lol_lua.lua
+++ b/doc/tutorial/14_lol_lua.lua
@@ -13,4 +13,4 @@ loluademo_return = LoluaDemo.AddFive(1);
 loluademo_inst = LoluaDemo.New();
 loluademo_inst:SetX(10);
 loluademo_getx = loluademo_inst:GetX();
-loluademo_inst_return = loluademo_inst:AddTenInstance(2.0);
+loluademo_inst_return = loluademo_inst:AddTenInstance(2.5, 4, 6);
diff --git a/doc/tutorial/imgui.ini b/doc/tutorial/imgui.ini
index c39d8823..f11877b3 100644
--- a/doc/tutorial/imgui.ini
+++ b/doc/tutorial/imgui.ini
@@ -4,12 +4,12 @@ Size=400,400
 Collapsed=0
 
 [testature]
-Pos=266,15
+Pos=187,98
 Size=494,359
 Collapsed=0
 
 [SO FUN !!]
-Pos=30,24
+Pos=16,24
 Size=113,99
 Collapsed=0
 
diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h
index 8f93def3..31198e37 100644
--- a/src/easymesh/easymesh.h
+++ b/src/easymesh/easymesh.h
@@ -392,7 +392,11 @@ public:
         - offset : useless
      */
     void AppendCog(int nbsides, float h, float d10, float d20, float d11,
-                   float d21, float d12, float d22, float sidemul=0.f, bool offset=false);
+                   float d21, float d12, float d22, float sidemul = 0.f, bool offset = false);
+    void AppendCog(int nbsides, float h, vec2 d0, vec2 d1, vec2 d2, float sidemul = 0.f, bool offset = false)
+    {
+        AppendCog(nbsides, h, d0.x, d0.y, d1.x, d1.y, d2.x, d2.y, sidemul, offset);
+    }
 
     //-------------------------------------------------------------------------
     //TODO : Mesh Bone operations
diff --git a/src/easymesh/easymeshlua.cpp b/src/easymesh/easymeshlua.cpp
index 258b3182..3c932b47 100644
--- a/src/easymesh/easymeshlua.cpp
+++ b/src/easymesh/easymeshlua.cpp
@@ -27,7 +27,7 @@ EasyMeshLuaLoader::EasyMeshLuaLoader() : LuaLoader()
     lua_State* l = GetLuaState();
 
     //Registering demo object
-    LuaObjectDef::Register<EasyMeshLuaObject>(l);
+    LuaObjectHelper::Register<EasyMeshLuaObject>(l);
 }
 
 //-----------------------------------------------------------------------------
@@ -81,17 +81,17 @@ EasyMeshLuaObject* EasyMeshLuaObject::New(lua_State* l, int arg_nb)
 {
     UNUSED(l);
     UNUSED(arg_nb);
-    LuaStack s(l);
-    LuaString n("", true);
-    s >> n;
-    return new EasyMeshLuaObject(n());
+    LuaStack s = LuaStack::Begin(l);
+    String str = s.Get<String>("");
+    return new EasyMeshLuaObject(str);
 }
 
 //-----------------------------------------------------------------------------
-const LuaObjectLib* EasyMeshLuaObject::GetLib()
+const LuaObjectLibrary* EasyMeshLuaObject::GetLib()
 {
-    typedef EasyMeshLuaObject EMLO;
-    static const LuaObjectLib lib = LuaObjectLib(
+#define EMLO EasyMeshLuaObject
+
+    static const LuaObjectLibrary lib = LuaObjectLibrary(
         "EasyMesh",
         //Statics
         { { nullptr, nullptr } },
@@ -182,6 +182,8 @@ const LuaObjectLib* EasyMeshLuaObject::GetLib()
         //Variables
         { { nullptr, nullptr, nullptr } });
     return &lib;
+
+#undef EMLO
 }
 
 //-----------------------------------------------------------------------------
diff --git a/src/easymesh/easymeshlua.h b/src/easymesh/easymeshlua.h
index 3632e2d4..6c786c55 100644
--- a/src/easymesh/easymeshlua.h
+++ b/src/easymesh/easymeshlua.h
@@ -18,7 +18,6 @@ namespace lol
 //-----------------------------------------------------------------------------
 class EasyMeshLuaObject : public LuaObject
 {
-    typedef Lolua::VarPtr<EasyMeshLuaObject> EzMeshPtr;
     EasyMesh m_instance;
 public:
     //-------------------------------------------------------------------------
@@ -28,610 +27,91 @@ public:
 
     //-------------------------------------------------------------------------
     static EasyMeshLuaObject* New(lua_State* l, int arg_nb);
-    static const LuaObjectLib* GetLib();
+    static const LuaObjectLibrary* GetLib();
+
+#define EMLO GetPtr<EasyMeshLuaObject>()
 
     //-------------------------------------------------------------------------
-    static int AppendCylinder(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 nsides;
-        LuaFloat h, d1, d2;
-        LuaBool dualside(false, true), smooth(false, true), close(false, true);
-        s >> m >> nsides >> h >> d1 >> d2 >> dualside >> smooth >> close;
-        m->m_instance.AppendCylinder(nsides, h, d1, d2, dualside, smooth, close);
-        return 0;
-    }
-    static int AppendSphere(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 ndivisions;
-        LuaFloat d;
-        s >> m >> ndivisions >> d;
-        m->m_instance.AppendSphere(ndivisions, d);
-        return 0;
-    }
-    static int AppendCapsule(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 ndivisions;
-        LuaFloat h, d;
-        s >> m >> ndivisions >> h >> d;
-        m->m_instance.AppendCapsule(ndivisions, h, d);
-        return 0;
-    }
-    static int AppendTorus(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 ndivisions;
-        LuaFloat d1, d2;
-        s >> m >> ndivisions >> d1 >> d2;
-        m->m_instance.AppendTorus(ndivisions, d1, d2);
-        return 0;
-    }
-    static int AppendBox(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaVec3 size;
-        LuaFloat chamf(0.f, true);
-        LuaBool smooth(false, true);
-        s >> m >> size >> chamf >> smooth;
-        m->m_instance.AppendBox(size, chamf, smooth);
-        return 0;
-    }
-    static int AppendStar(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 nbranches;
-        LuaFloat d1, d2;
-        LuaBool fade(false, true), fade2(false, true);
-        s >> m >> nbranches >> d1 >> d2 >> fade >> fade2;
-        m->m_instance.AppendStar(nbranches, d1, d2, fade, fade2);
-        return 0;
-    }
-    static int AppendExpandedStar(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 nbranches;
-        LuaFloat d1, d2, extrad(0.f, true);
-        s >> m >> nbranches >> d1 >> d2 >> extrad;
-        m->m_instance.AppendExpandedStar(nbranches, d1, d2, extrad);
-        return 0;
-    }
-    static int AppendDisc(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 nsides;
-        LuaFloat d;
-        LuaBool fade(false, true);
-        s >> m >> nsides >> d >> fade;
-        m->m_instance.AppendDisc(nsides, d, fade);
-        return 0;
-    }
-    static int AppendSimpleTriangle(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat d;
-        LuaBool fade(false, true);
-        s >> m >> d >> fade;
-        m->m_instance.AppendSimpleTriangle(d, fade);
-        return 0;
-    }
-    static int AppendSimpleQuad(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat size;
-        LuaBool fade(false, true);
-        s >> m >> size >> fade;
-        m->m_instance.AppendSimpleQuad(size, fade);
-        return 0;
-    }
-    static int AppendCog(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 nbsides;
-        LuaFloat h, sidemul(0.f, true);
-        LuaVec2 d0, d1, d2;
-        LuaBool offset(false, true);
-        s >> m >> nbsides >> h >> d0 >> d1 >> d2 >> sidemul >> offset;
-        m->m_instance.AppendCog(nbsides, h, d0().x, d0().y, d1().x, d1().y, d2().x, d2().y, sidemul, offset);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int TranslateX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat f;
-        s >> m >> f;
-        m->m_instance.TranslateX(f);
-        return 0;
-    }
-    static int TranslateY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat f;
-        s >> m >> f;
-        m->m_instance.TranslateY(f);
-        return 0;
-    }
-    static int TranslateZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat f;
-        s >> m >> f;
-        m->m_instance.TranslateZ(f);
-        return 0;
-    }
-    static int Translate(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaVec3 v;
-        s >> m >> v;
-        m->m_instance.Translate(v);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int RotateX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat a;
-        s >> m >> a;
-        m->m_instance.RotateX(a);
-        return 0;
-    }
-    static int RotateY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat a;
-        s >> m >> a;
-        m->m_instance.RotateY(a);
-        return 0;
-    }
-    static int RotateZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat a;
-        s >> m >> a;
-        m->m_instance.RotateZ(a);
-        return 0;
-    }
-    static int Rotate(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat a;
-        LuaVec3 v;
-        s >> m >> a >> v;
-        m->m_instance.Rotate(a, v);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int ScaleX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x;
-        s >> m >> x;
-        m->m_instance.ScaleX(x);
-        return 0;
-    }
-    static int ScaleY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat y;
-        s >> m >> y;
-        m->m_instance.ScaleY(y);
-        return 0;
-    }
-    static int ScaleZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat z;
-        s >> m >> z;
-        m->m_instance.ScaleZ(z);
-        return 0;
-    }
-    static int Scale(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaVec3 v;
-        s >> m >> v;
-        m->m_instance.Scale(v);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int RadialJitter(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat f;
-        s >> m >> f;
-        m->m_instance.RadialJitter(f);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int TaperX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat y, z, xoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> y >> z >> xoff >> abs;
-        m->m_instance.TaperX(y, z, xoff, abs);
-        return 0;
-    }
-    static int TaperY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, z, yoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> x >> z >> yoff >> abs;
-        m->m_instance.TaperY(x, z, yoff, abs);
-        return 0;
-    }
-    static int TaperZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, y, zoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> x >> y >> zoff >> abs;
-        m->m_instance.TaperZ(x, y, zoff, abs);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int TwistX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.TwistX(t, toff);
-        return 0;
-    }
-    static int TwistY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.TwistY(t, toff);
-        return 0;
-    }
-    static int TwistZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.TwistZ(t, toff);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int ShearX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat y, z, xoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> y >> z >> xoff >> abs;
-        m->m_instance.ShearX(y, z, xoff, abs);
-        return 0;
-    }
-    static int ShearY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, z, yoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> x >> z >> yoff >> abs;
-        m->m_instance.ShearY(x, z, yoff, abs);
-        return 0;
-    }
-    static int ShearZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, y, zoff(0.f, true);
-        LuaBool abs(true, true);
-        s >> m >> x >> y >> zoff >> abs;
-        m->m_instance.ShearZ(x, y, zoff, abs);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int StretchX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat y, z, xoff(0.f, true);
-        s >> m >> y >> z >> xoff;
-        m->m_instance.StretchX(y, z, xoff);
-        return 0;
-    }
-    static int StretchY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, z, yoff(0.f, true);
-        s >> m >> x >> z >> yoff;
-        m->m_instance.StretchY(x, z, yoff);
-        return 0;
-    }
-    static int StretchZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat x, y, zoff(0.f, true);
-        s >> m >> x >> y >> zoff;
-        m->m_instance.StretchZ(x, y, zoff);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int BendXY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendXY(t, toff);
-        return 0;
-    }
-    static int BendXZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendXZ(t, toff);
-        return 0;
-    }
-    static int BendYX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendYX(t, toff);
-        return 0;
-    }
-    static int BendYZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendYZ(t, toff);
-        return 0;
-    }
-    static int BendZX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendZX(t, toff);
-        return 0;
-    }
-    static int BendZY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat t, toff(0.f, true);
-        s >> m >> t >> toff;
-        m->m_instance.BendZY(t, toff);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int MirrorX(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.MirrorX();
-        return 0;
-    }
-    static int MirrorY(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.MirrorY();
-        return 0;
-    }
-    static int MirrorZ(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.MirrorZ();
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int LoopStart(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 loopnb;
-        s >> m >> loopnb;
-        m->m_instance.LoopStart(loopnb);
-        return 0;
-    }
-    static int LoopEnd(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.LoopEnd();
-        return 0;
-    }
-    static int OpenBrace(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.OpenBrace();
-        return 0;
-    }
-    static int CloseBrace(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.CloseBrace();
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int ToggleScaleWinding(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.ToggleScaleWinding();
-        return 0;
-    }
-    static int ToggleQuadWeighting(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.ToggleQuadWeighting();
-        return 0;
-    }
-    static int TogglePostBuildNormal(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.TogglePostBuildNormal();
-        return 0;
-    }
-    static int ToggleVerticeNoCleanup(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.ToggleVerticeNoCleanup();
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int VerticesMerge(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.VerticesMerge();
-        return 0;
-    }
-    static int VerticesSeparate(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.VerticesSeparate();
-        return 0;
-    }
-    static int VerticesCleanup(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        s >> m;
-        m->m_instance.VerticesCleanup();
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int Duplicate(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaVec3 ds(vec3(1.f));
-        s >> m >> ds;
-        m->m_instance.DupAndScale(ds, true);
-        return 0;
-    }
-    static int Smooth(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 pass, split_per_pass, smooth_per_pass;
-        s >> m >> pass >> split_per_pass >> smooth_per_pass;
-        m->m_instance.SmoothMesh(pass, split_per_pass, smooth_per_pass);
-        return 0;
-    }
-    static int SplitTriangles(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaInt32 pass;
-        s >> m >> pass;
-        m->m_instance.SplitTriangles(pass);
-        return 0;
-    }
-    static int Chamfer(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaFloat f;
-        s >> m >> f;
-        m->m_instance.Chamfer(f);
-        return 0;
-    }
-    //-------------------------------------------------------------------------
-    static int SetCurColor(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaColor c;
-        s >> m >> c;
-        m->m_instance.SetCurColor(c);
-        return 0;
-    }
-    static int SetCurColorA(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaColor c;
-        s >> m >> c;
-        m->m_instance.SetCurColorA(c);
-        return 0;
-    }
-    static int SetCurColorB(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaColor c;
-        m->m_instance.SetCurColorB(c);
-        return 0;
-    }
-    static int SetVertColor(lua_State* l)
-    {
-        LuaStack s(l);
-        EzMeshPtr m;
-        LuaColor c;
-        s >> m >> c;
-        m->m_instance.SetVertColor(c);
-        return 0;
-    }
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCylinder, EMLO, m_instance.AppendCylinder, Get<int32_t>(), Get<float>(), Get<float>(), Get<float>(), Get<bool>(false), Get<bool>(false), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSphere, EMLO, m_instance.AppendSphere, Get<int32_t>(), Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCapsule, EMLO, m_instance.AppendCapsule, Get<int32_t>(), Get<float>(), Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendTorus, EMLO, m_instance.AppendTorus, Get<int32_t>(), Get<float>(), Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendBox, EMLO, m_instance.AppendBox, Get<vec3>(), Get<float>(0.f), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendStar, EMLO, m_instance.AppendStar, Get<int32_t>(), Get<float>(), Get<float>(), Get<bool>(false), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendExpandedStar, EMLO, m_instance.AppendExpandedStar, Get<int32_t>(), Get<float>(), Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendDisc, EMLO, m_instance.AppendDisc, Get<int32_t>(), Get<float>(), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSimpleTriangle, EMLO, m_instance.AppendSimpleTriangle, Get<float>(), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendSimpleQuad, EMLO, m_instance.AppendSimpleQuad, Get<float>(), Get<bool>(false));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(AppendCog, EMLO, m_instance.AppendCog, Get<int32_t>(), Get<float>(), Get<vec2>(), Get<vec2>(), Get<vec2>(), Get<float>(0.f), Get<bool>(false));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateX, EMLO, m_instance.TranslateX, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateY, EMLO, m_instance.TranslateY, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TranslateZ, EMLO, m_instance.TranslateZ, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Translate, EMLO, m_instance.Translate, Get<vec3>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(RotateX, EMLO, m_instance.RotateX, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(RotateY, EMLO, m_instance.RotateY, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(RotateZ, EMLO, m_instance.RotateZ, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Rotate, EMLO, m_instance.Rotate, Get<float>(), Get<vec3>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleX, EMLO, m_instance.ScaleX, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleY, EMLO, m_instance.ScaleY, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ScaleZ, EMLO, m_instance.ScaleZ, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Scale, EMLO,  m_instance.Scale, Get<vec3>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(RadialJitter, EMLO, m_instance.RadialJitter, Get<float>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TaperX, EMLO, m_instance.TaperX, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TaperY, EMLO, m_instance.TaperY, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TaperZ, EMLO, m_instance.TaperZ, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TwistX, EMLO, m_instance.TwistX, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TwistY, EMLO, m_instance.TwistY, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(TwistZ, EMLO, m_instance.TwistZ, Get<float>(), Get<float>(0.f));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ShearX, EMLO, m_instance.ShearX, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ShearY, EMLO, m_instance.ShearY, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(ShearZ, EMLO, m_instance.ShearZ, Get<float>(), Get<float>(), Get<float>(0.f), Get<bool>(true));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(StretchX, EMLO, m_instance.StretchX, Get<float>(), Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(StretchY, EMLO, m_instance.StretchY, Get<float>(), Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(StretchZ, EMLO, m_instance.StretchZ, Get<float>(), Get<float>(), Get<float>(0.f));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendXY, EMLO, m_instance.BendXY, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendXZ, EMLO, m_instance.BendXZ, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendYX, EMLO, m_instance.BendYX, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendYZ, EMLO, m_instance.BendYZ, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendZX, EMLO, m_instance.BendZX, Get<float>(), Get<float>(0.f));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(BendZY, EMLO, m_instance.BendZY, Get<float>(), Get<float>(0.f));
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_VOID(MirrorX, EMLO, m_instance.MirrorX);
+    LOLUA_DECLARE_VOID_METHOD_VOID(MirrorY, EMLO, m_instance.MirrorY);
+    LOLUA_DECLARE_VOID_METHOD_VOID(MirrorZ, EMLO, m_instance.MirrorZ);
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(LoopStart, EMLO, m_instance.LoopStart, Get<int32_t>());
+    LOLUA_DECLARE_VOID_METHOD_VOID(LoopEnd, EMLO, m_instance.LoopEnd);
+    LOLUA_DECLARE_VOID_METHOD_VOID(OpenBrace, EMLO, m_instance.OpenBrace, Get<float>());
+    LOLUA_DECLARE_VOID_METHOD_VOID(CloseBrace, EMLO, m_instance.CloseBrace, Get<float>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_VOID(ToggleScaleWinding, EMLO, m_instance.ToggleScaleWinding);
+    LOLUA_DECLARE_VOID_METHOD_VOID(ToggleQuadWeighting, EMLO, m_instance.ToggleQuadWeighting);
+    LOLUA_DECLARE_VOID_METHOD_VOID(TogglePostBuildNormal, EMLO, m_instance.TogglePostBuildNormal);
+    LOLUA_DECLARE_VOID_METHOD_VOID(ToggleVerticeNoCleanup, EMLO, m_instance.ToggleVerticeNoCleanup);
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_VOID(VerticesMerge, EMLO, m_instance.VerticesMerge);
+    LOLUA_DECLARE_VOID_METHOD_VOID(VerticesSeparate, EMLO, m_instance.VerticesSeparate);
+    LOLUA_DECLARE_VOID_METHOD_VOID(VerticesCleanup, EMLO, m_instance.VerticesCleanup);
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Duplicate, EMLO, m_instance.DupAndScale, Get<vec3>(vec3(1.f)), Get<bool>(true));
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Smooth, EMLO, m_instance.SmoothMesh, Get<int32_t>(), Get<int32_t>(), Get<int32_t>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SplitTriangles, EMLO, m_instance.SplitTriangles, Get<int32_t>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(Chamfer, EMLO, m_instance.Chamfer, Get<float>());
+    //-------------------------------------------------------------------------
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColor, EMLO, m_instance.SetCurColor, Get<vec4>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColorA, EMLO, m_instance.SetCurColorA, Get<vec4>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SetCurColorB, EMLO, m_instance.SetCurColorB, Get<vec4>());
+    LOLUA_DECLARE_VOID_METHOD_ARGS(SetVertColor, EMLO, m_instance.SetVertColor, Get<vec4>());
+
     /*
     (csgu|csgunion)          { return token::T_CSGUNION; }
     (csgs|CsgSub)            { return token::T_CSGSUBSTRACT; }
@@ -640,6 +120,7 @@ public:
     (csgx|csgxor)            { return token::T_CSGXOR; }
     */
 
+    #undef EMLO
 };
 
 //-----------------------------------------------------------------------------
diff --git a/src/lolimgui.cpp b/src/lolimgui.cpp
index ab47cc89..70a612b1 100644
--- a/src/lolimgui.cpp
+++ b/src/lolimgui.cpp
@@ -375,7 +375,7 @@ void LolImGui::RenderDrawListsMethod(ImDrawData* draw_data)
         m_vdecl->SetStream(vbo, m_attribs[0], m_attribs[1], m_attribs[2]);
 
         const ImDrawIdx* idx_buffer_offset = 0;
-        for (size_t cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
         {
             const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[(int)cmd_i];
 #ifdef SHOW_IMGUI_DEBUG
diff --git a/src/lolua/baselua.cpp b/src/lolua/baselua.cpp
index 8a1c035d..faffef0f 100644
--- a/src/lolua/baselua.cpp
+++ b/src/lolua/baselua.cpp
@@ -40,8 +40,9 @@ class LuaBaseData
         int status = luaL_dostring(l, s.C());
         if (status == 1)
         {
-            LuaString error; error.Get(l, -1);
-            msg::error("Lua error %s\n", error().C());
+            auto stack = LuaStack::Begin(l, -1);
+            auto error = stack.Get<String>();
+            msg::error("Lua error %s\n", error.C());
             lua_pop(l, 1);
         }
         return status;
@@ -53,8 +54,8 @@ class LuaBaseData
         if (lua_isnoneornil(l, 1))
             return LUA_ERRFILE;
 
-        LuaCharPtr var; var.Get(l, 1);
-        char const *filename = var;// lua_tostring(l, 1);
+        auto stack = LuaStack::Begin(l);
+        char const *filename = stack.Get<char const*>();
         int status = LUA_ERRFILE;
 
         File f;
@@ -76,8 +77,9 @@ class LuaBaseData
             msg::error("could not find Lua file %s\n", filename);
         else if (status == 1)
         {
-            LuaString error; error.Get(l, -1);
-            msg::error("Lua error %s\n", error().C());
+            stack.SetIndex(-1);
+            auto error = stack.Get<String>();
+            msg::error("Lua error %s\n", error.C());
             lua_pop(l, 1);
         }
 
diff --git a/src/lolua/baselua.h b/src/lolua/baselua.h
index 54cc511b..ca30fa35 100644
--- a/src/lolua/baselua.h
+++ b/src/lolua/baselua.h
@@ -33,69 +33,70 @@ typedef struct ClassVar
 } ClassVar;
 
 //-----------------------------------------------------------------------------
-struct ObjectLib
+class Object
 {
-    typedef struct ClassVarStr
+public:
+    //-----------------------------------------------------------------------------
+    struct Library
     {
-        ClassVarStr() { }
-        ClassVarStr(String var_name, lua_CFunction get, lua_CFunction set)
+        typedef struct ClassVarStr
         {
-            m_get_name = String("Get") + var_name;
-            m_set_name = String("Set") + var_name;
-            m_get = get;
-            m_set = set;
-        }
-        String m_get_name = "";
-        String m_set_name = "";
-        lua_CFunction m_get = nullptr;
-        lua_CFunction m_set = nullptr;
-    } ClassVarStr;
-
-    ObjectLib(String class_name,
-        array<ClassMethod> const& statics,
-        array<ClassMethod> const& methods,
-        array<ClassVar> const& variables)
-    {
-        m_class_name = class_name;
-        m_static_name = class_name + "_lib";
-        m_method_name = class_name + "_inst";
-
-        m_statics = statics;
-        if (m_statics.count() == 0
-            || m_statics.last().name != nullptr
-            || m_statics.last().func != nullptr)
-            m_statics.push({ nullptr, nullptr });
-
-        m_methods = methods;
-        if (m_methods.count() == 0
-            || m_methods.last().name != nullptr
-            || m_methods.last().func != nullptr)
-            m_methods.push({ nullptr, nullptr });
-
-        for (ClassVar const& cv : variables)
+            ClassVarStr() { }
+            ClassVarStr(String var_name, lua_CFunction get, lua_CFunction set)
+            {
+                m_get_name = String("Get") + var_name;
+                m_set_name = String("Set") + var_name;
+                m_get = get;
+                m_set = set;
+            }
+            String m_get_name = "";
+            String m_set_name = "";
+            lua_CFunction m_get = nullptr;
+            lua_CFunction m_set = nullptr;
+        } ClassVarStr;
+
+        Library(String class_name,
+            array<ClassMethod> const& statics,
+            array<ClassMethod> const& methods,
+            array<ClassVar> const& variables)
         {
-            if (cv.name && cv.get && cv.set)
+            m_class_name = class_name;
+            m_static_name = class_name + "_lib";
+            m_method_name = class_name + "_inst";
+
+            m_statics = statics;
+            if (m_statics.count() == 0
+                || m_statics.last().name != nullptr
+                || m_statics.last().func != nullptr)
+                m_statics.push({ nullptr, nullptr });
+
+            m_methods = methods;
+            if (m_methods.count() == 0
+                || m_methods.last().name != nullptr
+                || m_methods.last().func != nullptr)
+                m_methods.push({ nullptr, nullptr });
+
+            for (ClassVar const& cv : variables)
             {
-                m_variables.push({ cv.name, cv.get, cv.set });
+                if (cv.name && cv.get && cv.set)
+                {
+                    m_variables.push({ cv.name, cv.get, cv.set });
+                }
             }
+            if (m_variables.count() == 0
+                || variables.last().name != nullptr
+                || variables.last().get != nullptr
+                || variables.last().set != nullptr)
+                m_variables.push(ClassVarStr());
         }
-        if (m_variables.count() == 0
-            || variables.last().name != nullptr
-            || variables.last().get != nullptr
-            || variables.last().set != nullptr)
-            m_variables.push(ClassVarStr());
-    }
-    String m_class_name = "";
-    String m_static_name = "";
-    String m_method_name = "";
-    array<ClassMethod> m_statics;
-    array<ClassMethod> m_methods;
-    array<ClassVarStr> m_variables;
-};
+        String m_class_name = "";
+        String m_static_name = "";
+        String m_method_name = "";
+        array<ClassMethod> m_statics;
+        array<ClassMethod> m_methods;
+        array<ClassVarStr> m_variables;
+    };
 
-//-----------------------------------------------------------------------------
-class Object
-{
 public:
     Object() { }
     virtual ~Object() { }
@@ -106,19 +107,20 @@ public:
         ASSERT(false);
         return nullptr;
     }
-    static const ObjectLib* GetLib() { ASSERT(false); return nullptr; }
+    static const Library* GetLib() { ASSERT(false); return nullptr; }
 };
 
 //-----------------------------------------------------------------------------
 // Class available to link C++ class to Lua methods
 //--
-class ObjectDef
+class ObjectHelper
 {
-public:
+private:
     //-------------------------------------------------------------------------
-    ObjectDef() { }
-    virtual ~ObjectDef() { }
+    ObjectHelper() { }
+    virtual ~ObjectHelper() { }
 
+public:
     //-------------------------------------------------------------------------
     template <typename TLuaClass>
     static void Register(lua_State *l)
@@ -129,20 +131,19 @@ public:
             { "New", New<TLuaClass> },
             { "Store", Store<TLuaClass> },
             { "__gc", Del<TLuaClass> },
+            { "__tostring", ToString<TLuaClass> },
+            { "__add", OpAdd<TLuaClass> },
+            { "__sub", OpSubstract<TLuaClass> },
+            { "__mul", OpMultiply<TLuaClass> },
+            { "__div", OpDivide<TLuaClass> },
+            { "__mod", OpModulo<TLuaClass> },
+            { "__unm", OpUnaryNeg<TLuaClass> },
+            { "__concat", OpConcat<TLuaClass> },
+            { "__eq", CmpEqual<TLuaClass> },
+            { "__lt", CmpLessThan<TLuaClass> },
+            { "__le", CmpLessEqual<TLuaClass> },
             { NULL, NULL }
         };
-        //TODO: Touky: Implement that
-        //__tostring : ToString
-        //__add : Addition(+)
-        //__sub : Subtraction(-)
-        //__mul : Multiplication(*)
-        //__div : Division(/ )
-        //__mod : Modulos(%)
-        //__unm : Unary - , used for negation on numbers
-        //__concat : Concatenation(..)
-        //__eq : Equality(== )
-        //__lt : Less than(<)
-        //__le : Less than or equal to(<= )
 
         //Create Static metatable
         luaL_newmetatable(l, GetStaticName<TLuaClass>());
@@ -163,8 +164,8 @@ public:
         lua_setfield(l, -1, "__index");
 
         //Create variables Get/Set
-        const array<ObjectLib::ClassVarStr>& variables = GetVariables<TLuaClass>();
-        for (const ObjectLib::ClassVarStr& var : variables)
+        const array<Object::Library::ClassVarStr>& variables = GetVariables<TLuaClass>();
+        for (const Object::Library::ClassVarStr& var : variables)
         {
             if (!var.m_get || !var.m_set)
                 continue;
@@ -183,27 +184,29 @@ public:
     }
 
 private:
+    //-------------------------------------------------------------------------
     template <typename TLuaClass>
-    static const ObjectLib* GetLib()
+    static const Object::Library* GetLibrary()
     {
-        const ObjectLib* lib = TLuaClass::GetLib();
+        const Object::Library* lib = TLuaClass::GetLib();
         ASSERT(lib);
         return lib;
     }
 
 public:
+    //-------------------------------------------------------------------------
     template <typename TLuaClass>
-    static const char* GetObjectName() { return GetLib<TLuaClass>()->m_class_name.C(); }
+    static const char* GetObjectName() { return GetLibrary<TLuaClass>()->m_class_name.C(); }
     template <typename TLuaClass>
-    static const char* GetStaticName() { return GetLib<TLuaClass>()->m_static_name.C(); }
+    static const char* GetStaticName() { return GetLibrary<TLuaClass>()->m_static_name.C(); }
     template <typename TLuaClass>
-    static const char* GetMethodName() { return GetLib<TLuaClass>()->m_method_name.C(); }
+    static const char* GetMethodName() { return GetLibrary<TLuaClass>()->m_method_name.C(); }
     template <typename TLuaClass>
-    static const ClassMethod* GetStaticMethods() { return GetLib<TLuaClass>()->m_statics.data(); }
+    static const ClassMethod* GetStaticMethods() { return GetLibrary<TLuaClass>()->m_statics.data(); }
     template <typename TLuaClass>
-    static const ClassMethod* GetInstanceMethods() { return GetLib<TLuaClass>()->m_methods.data(); }
+    static const ClassMethod* GetInstanceMethods() { return GetLibrary<TLuaClass>()->m_methods.data(); }
     template <typename TLuaClass>
-    static const array<ObjectLib::ClassVarStr>& GetVariables() { return GetLib<TLuaClass>()->m_variables; }
+    static const array<Object::Library::ClassVarStr>& GetVariables() { return GetLibrary<TLuaClass>()->m_variables; }
 
 protected:
     //-------------------------------------------------------------------------
@@ -228,6 +231,18 @@ protected:
     //-------------------------------------------------------------------------
     template <typename TLuaClass> static int Store(lua_State * l);
     template <typename TLuaClass> static int Del(lua_State * l);
+    //-------------------------------------------------------------------------
+    template <typename TLuaClass> static int ToString(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpAdd(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpSubstract(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpMultiply(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpDivide(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpModulo(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpUnaryNeg(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int OpConcat(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int CmpEqual(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int CmpLessThan(lua_State* l) { ASSERT(false); return 0; }
+    template <typename TLuaClass> static int CmpLessEqual(lua_State* l) { ASSERT(false); return 0; }
 };
 
 //-----------------------------------------------------------------------------
@@ -242,730 +257,321 @@ public:
 };
 
 //-----------------------------------------------------------------------------
-template<typename T>
-class VarPtr
+// Stack: Main class that encapsulates everything -----------------------------
+//-----------------------------------------------------------------------------
+class Stack
 {
-protected:
-    T* m_value = nullptr;
-    bool m_optional = false;
-
+    //-------------------------------------------------------------------------
 public:
-    VarPtr(bool optional = false)
+    static Stack Begin(lua_State* state, int32_t start_index = 1)
     {
-        m_optional = optional;
+        return Stack(state, start_index);
     }
-    VarPtr(T* value, bool optional = false)
-        : VarPtr(optional)
+
+    //-------------------------------------------------------------------------
+    void SetIndex(int32_t index)
     {
-        m_value = value;
+        m_index = index;
     }
-    VarPtr(lua_State* l, int& index, bool optional = false)
-        : VarPtr(optional)
+
+    //-------------------------------------------------------------------------
+    int32_t End()
     {
-        GetInc(l, index);
+        return m_result;
     }
-    VarPtr(T* value, lua_State* l, int& index, bool optional = false)
-        : VarPtr(value, optional)
+
+    //-------------------------------------------------------------------------
+protected:
+    Stack(lua_State* l, int32_t start_index = 1)
     {
-        GetInc(l, index);
+        m_state = l;
+        m_index = start_index;
     }
 
-    inline T* operator ()()       { return m_value; }
-    inline T* operator ->()       { return m_value; }
-    inline T* operator=(T* value) { m_value = value; }
-    inline T* GetValue()          { return m_value; }
-    inline bool IsValid(lua_State* l, int index)
+public:
+    virtual ~Stack() { }
+
+protected:
+    int32_t GetArgs()
     {
-        return InnerIsValid(l, index);
+        return lua_gettop(m_state);
     }
-    inline bool IsOptional()
+
+public:
+    //-------------------------------------------------------------------------
+    //The encapsulating struct for pointers
+    template<typename T>
+    struct Ptr
     {
-        return m_optional;
-    }
+    public:
+        T* m_value = nullptr;
+        bool m_throw_error = false;
+
+        //---------------------------------------------------------------------
+        //m_value: Your stored value
+        //throw_error: If true, lua will throw an error if the value get fails
+        Ptr(T* value, bool throw_error = false)
+        {
+            m_value = value;
+            m_throw_error = throw_error;
+        }
+        Ptr(const T*& value) { m_value = value; }
+        inline operator T*() { return m_value; }
+        inline T* operator ->() { return m_value; }
+        inline Ptr<T>& operator=(T const*& value) { m_value = value; return *this; }
+    };
+
 private:
-    inline void GetInc(lua_State* l, int& index)
+    bool AllowGet(bool is_optional, bool value_validity)
     {
-        bool is_nil = lua_isnil(l, index);
-        if (!m_optional || (!is_nil && InnerIsValid(l, index)))
+        bool is_nil = lua_isnil(m_state, m_index);
+        if (!is_optional || (!is_nil && value_validity))
         {
-            ASSERT(!is_nil);
-            InnerGet(l, index);
+            ASSERT(!is_nil); /* touky: should it assert, though ? */
+            return true;
         }
+        return false;
     }
+
 public:
-    inline void Get(lua_State* l, int index)
-    {
-        int idx = index;
-        GetInc(l, idx);
-    }
-    inline int Return(lua_State* l)
-    {
-        InnerPush(l);
-        return 1;
-    }
+	//-------------------------------------------------------------------------
+    template<typename T> T Get() { return Get(InnerDefault<T>(), false); }
+    template<typename T> T Get(T default_value) { return Get(default_value, true); }
+    template<typename E> SafeEnum<E> GetEnum() { return GetEnum(InnerDefaultSafeEnum<E>(), false); }
+    template<typename E> SafeEnum<E> GetEnum(SafeEnum<E> default_value) { return GetEnum(default_value, true); }
+    template<typename P> Ptr<P> GetPtr() { return GetPtr(InnerDefaultPtr<P>(), false); }
+    template<typename P> Ptr<P> GetPtr(Ptr<P> default_value) { return GetPtr(default_value, true); }
 
-protected:
-    virtual bool InnerIsValid(lua_State* l, int index)
+private:
+    //-------------------------------------------------------------------------
+    template<typename T> T Get(T default_value, bool is_optional)
     {
-        return !!lua_isuserdata(l, index);
+        if (AllowGet(is_optional, InnerIsValid<T>()))
+            return InnerGet(default_value);
+        return default_value;
     }
-    virtual void InnerGet(lua_State* l, int& index)
+    template<typename E> SafeEnum<E> GetEnum(SafeEnum<E> default_value, bool is_optional)
     {
-        T** obj = static_cast<T**>(luaL_checkudata(l, index++, ObjectDef::GetMethodName<T>()));
-        m_value = obj ? *obj : nullptr;
+        if (AllowGet(is_optional, InnerIsValidSafeEnum<E>()))
+            return InnerGetSafeEnum(default_value);
+        return default_value;
     }
-    void InnerPush(lua_State* l)
+    template<typename P> Ptr<P> GetPtr(Ptr<P> default_value, bool is_optional)
     {
-        T** data = (T**)lua_newuserdata(l, sizeof(T*));
-        *data = m_value;
+        if (AllowGet(is_optional, InnerIsValidPtr<P>()))
+            return InnerGetPtr(default_value);
+        return default_value;
     }
-};
 
-//-----------------------------------------------------------------------------
-/* TODO: FIX THAT TOUKY !!
-template<typename T>
-class VarPtrLight
-{
 public:
-    VarPtrLight(bool optional = false) : VarPtr(optional) { }
-    VarPtrLight(T* value, bool optional = false) : VarPtr(value, optional) { }
-    VarPtrLight(lua_State* l, int& index, bool optional = false) : VarPtr(l, index, optional) { }
-    VarPtrLight(T* value, lua_State* l, int& index, bool optional = false) : VarPtr(value, l, index, optional) { }
-protected:
-    virtual void InnerGet(lua_State* l, int& index)
-    {
-        T** obj = static_cast<T**>(luaL_testudata(l, index++, ObjectDef::GetMethodName<T>()));
-        m_value = obj ? *obj : nullptr;
-    }
-};
-*/
-//-----------------------------------------------------------------------------
-template<typename T>
-class Var
-{
+    //-------------------------------------------------------------------------
+    template<typename T> Stack& operator<<(T value) { m_result += InnerPush<T>(value); return *this; }
+    template<typename E> Stack& operator<<(SafeEnum<E> value) { m_result += InnerPushSafeEnum<E>(value); return *this; }
+    template<typename P> Stack& operator<<(Ptr<P> value) { m_result += InnerPushPtr<P>(value); return *this; }
+
 protected:
-    bool m_optional = false;
-    T m_value;
+    //-------------------------------------------------------------------------
+    #define INNER_ERROR "Your type is not implemented. For pointers, use LuaPtr<MyType>()"
+    template<typename T> T InnerDefault() { return T(0); }
+	template<typename T> bool InnerIsValid() { ASSERT(false, INNER_ERROR); return false; }
+    template<typename T> T InnerGet(T value) { UNUSED(value); ASSERT(false, INNER_ERROR); return InnerDefault<T>(); }
+    template<typename T> int InnerPush(T value) { UNUSED(value); ASSERT(false, INNER_ERROR); return 0; }
 
-public:
-    Var(bool optional = false)
-    {
-        m_optional = optional;
-        InnerInit();
-    }
-    Var(T value, bool optional = false)
-    {
-        m_optional = optional;
-        m_value = value;
-    }
-    Var(lua_State* l, int& index, bool optional = false)
-    {
-        m_optional = optional;
-        GetInc(l, index);
-    }
-    Var(T value, lua_State* l, int& index, bool optional = false)
-    {
-        m_optional = optional;
-        m_value = value;
-        GetInc(l, index);
-    }
-    inline operator T()     { return m_value; }
-    inline T& operator ()() { return m_value; }
-    inline T& GetValue()    { return m_value; }
-    inline bool IsValid(lua_State* l, int index)
-    {
-        return InnerIsValid(l, index);
-    }
-    inline bool IsOptional()
-    {
-        return m_optional;
-    }
-private:
-    void GetInc(lua_State* l, int& index)
-    {
-        bool is_nil = lua_isnil(l, index);
-        if (!m_optional || (!is_nil && InnerIsValid(l, index)))
-        {
-            ASSERT(!is_nil);
-            InnerGet(l, index);
-        }
-    }
-public:
-    inline void Get(lua_State* l, int index)
+#ifndef INNER_SAFE_ENUM
+    template<typename E> SafeEnum<E> InnerDefaultSafeEnum() { return SafeEnum<E>(); }
+    template<typename E> bool InnerIsValidSafeEnum() { return InnerIsValid<String>(); }
+    template<typename E> SafeEnum<E> InnerGetSafeEnum(SafeEnum<E> value) { return FindValue<SafeEnum<E> >(InnerGet<String>(value.ToString())); }
+    template<typename E> int InnerPushSafeEnum(SafeEnum<E> value) { return InnerPush<String>(value.ToString()); }
+#endif //STACK_STRING
+
+#ifndef INNER_PTR
+    template<typename P> inline Ptr<P> InnerDefaultPtr() { return Ptr<P>(nullptr); }
+    template<typename P> inline bool InnerIsValidPtr() { return !!lua_isuserdata(m_state, m_index); }
+    template<typename P> inline Ptr<P> InnerGetPtr(Ptr<P> value)
     {
-        int idx = index;
-        GetInc(l, idx);
+        P** obj = static_cast<P**>(value.m_throw_error
+                                        ? luaL_checkudata(m_state, m_index++, ObjectHelper::GetMethodName<P>())
+                                        : luaL_testudata(m_state, m_index++, ObjectHelper::GetMethodName<P>()) );
+        return Ptr<P>(obj ? *obj : value.m_value);
     }
-    inline int Return(lua_State* l)
+    template<typename P> inline int InnerPushPtr(Ptr<P> value)
     {
-        return InnerPush(l);
+        P** data = (P**)lua_newuserdata(m_state, sizeof(P*));
+        *data = value.m_value;
     }
-    inline Var<T>&  operator-(const T& value)  { m_value - value; return *this; }
-    inline Var<T>&  operator+(const T& value)  { m_value + value; return *this; }
-    inline Var<T>&  operator*(const T& value)  { m_value  * value; return *this; }
-    inline Var<T>&  operator/(const T& value)  { m_value / value; return *this; }
-    inline Var<T>&  operator=(const T& value)  { m_value = value; return *this; }
-    inline Var<T>& operator-=(const T& value)  { m_value -= value; return *this; }
-    inline Var<T>& operator+=(const T& value)  { m_value += value; return *this; }
-    inline Var<T>& operator*=(const T& value)  { m_value *= value; return *this; }
-    inline Var<T>& operator/=(const T& value)  { m_value /= value; return *this; }
-    inline Var<T>&  operator-(const Var<T>& o) { m_value - o.m_value; return *this; }
-    inline Var<T>&  operator+(const Var<T>& o) { m_value + o.m_value; return *this; }
-    inline Var<T>&  operator*(const Var<T>& o) { m_value  * o.m_value; return *this; }
-    inline Var<T>&  operator/(const Var<T>& o) { m_value / o.m_value; return *this; }
-    inline Var<T>&  operator=(const Var<T>& o) { m_value = o.m_value; return *this; }
-    inline Var<T>& operator-=(const Var<T>& o) { m_value -= o.m_value; return *this; }
-    inline Var<T>& operator+=(const Var<T>& o) { m_value += o.m_value; return *this; }
-    inline Var<T>& operator*=(const Var<T>& o) { m_value *= o.m_value; return *this; }
-    inline Var<T>& operator/=(const Var<T>& o) { m_value /= o.m_value; return *this; }
-    inline bool operator==(const T& value)     { return m_value == value; }
-    inline bool operator!=(const T& value)     { return m_value != value; }
-    inline bool operator==(const Var<T>& o)    { return m_value == o.m_value; }
-    inline bool operator!=(const Var<T>& o)    { return m_value != o.m_value; }
+#endif //STACK_STRING
 
-protected:
-    void InnerInit()                          { m_value = T(0); }
-    bool InnerIsValid(lua_State* l, int index) { UNUSED(l); UNUSED(index); ASSERT(false); return false; }
-    void InnerGet(lua_State* l, int& index)    { UNUSED(l); UNUSED(index); ASSERT(false); }
-    int InnerPush(lua_State* l)                { UNUSED(l); ASSERT(false); return 0; }
+    //-------------------------------------------------------------------------
+private:
+    lua_State*  m_state = nullptr;
+    int32_t m_index = 1;
+    int32_t m_result = 0;
 };
 
 //-----------------------------------------------------------------------------
-template<> inline bool Var<bool>::InnerIsValid(lua_State* l, int index)
-{
-    return lua_isboolean(l, index);
-}
-template<> inline void Var<bool>::InnerGet(lua_State* l, int& index)
-{
-    m_value = !!lua_toboolean(l, index++);
-}
-template<> inline int Var<bool>::InnerPush(lua_State* l)
-{
-    lua_pushboolean(l, m_value);
-    return 1;
-}
-//-----------------------------------------------------------------------------
-template<> inline bool Var<char const*>::InnerIsValid(lua_State* l, int index)
-{
-    return !!lua_isstring(l, index);
-}
-template<> inline void Var<char const*>::InnerGet(lua_State* l, int& index)
-{
-    m_value = lua_tostring(l, index++);
-}
-template<> inline int Var<char const*>::InnerPush(lua_State* l)
-{
-    lua_pushstring(l, m_value);
-    return 1;
-}
-//-----------------------------------------------------------------------------
-template<> inline void Var<String>::InnerInit()
-{
-    m_value = String();
-}
-template<> inline bool Var<String>::InnerIsValid(lua_State* l, int index)
-{
-    Var<char const*> v;
-    return v.IsValid(l, index);
-}
-template<> inline void Var<String>::InnerGet(lua_State* l, int& index)
-{
-    Var<char const*> v(l, index);
-    m_value = v();
-}
-template<> inline int Var<String>::InnerPush(lua_State* l)
-{
-    Var<char const*> v;
-    v = m_value.C();
-    return v.Return(l);
-}
+#define /***/ LOLUA_VAR_1(a00) auto v00 = s.a00;
+#define /***/ LOLUA_VAR_2(a00, a01) LOLUA_VAR_1(a00) auto v01 = s.a01;
+#define /***/ LOLUA_VAR_3(a00, a01, a02) LOLUA_VAR_2(a00, a01) auto v02 = s.a02;
+#define /***/ LOLUA_VAR_4(a00, a01, a02, a03) LOLUA_VAR_3(a00, a01, a02) auto v03 = s.a03;
+#define /***/ LOLUA_VAR_5(a00, a01, a02, a03, a04) LOLUA_VAR_4(a00, a01, a02, a03) auto v04 = s.a04;
+#define /***/ LOLUA_VAR_6(a00, a01, a02, a03, a04, a05) LOLUA_VAR_5(a00, a01, a02, a03, a04) auto v05 = s.a05;
+#define /***/ LOLUA_VAR_7(a00, a01, a02, a03, a04, a05, a06) LOLUA_VAR_6(a00, a01, a02, a03, a04, a05) auto v06 = s.a06;
+#define /***/ LOLUA_VAR_8(a00, a01, a02, a03, a04, a05, a06, a07) LOLUA_VAR_7(a00, a01, a02, a03, a04, a05, a06) auto v07 = s.a07;
+#define /***/ LOLUA_VAR_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) LOLUA_VAR_8(a00, a01, a02, a03, a04, a05, a06, a07) auto v08 = s.a08;
+#define /**/ LOLUA_VAR_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) LOLUA_VAR_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) auto v09 = s.a09;
+#define /**/ LOLUA_VAR_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10) LOLUA_VAR_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) auto v10 = s.a10;
+#define /**/ LOLUA_VAR_12(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11) LOLUA_VAR_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) auto v11 = s.a11;
 //-----------------------------------------------------------------------------
-template<> inline bool Var<double>::InnerIsValid(lua_State* l, int index)
-{
-    return !!lua_isnumber(l, index);
-}
-template<> inline void Var<double>::InnerGet(lua_State* l, int& index)
-{
-    m_value = lua_tonumber(l, index++);
-}
-template<> inline int Var<double>::InnerPush(lua_State* l)
-{
-    lua_pushnumber(l, m_value);
-    return 1;
-}
+#define /***/ LOLUA_ARG_1(a00) v00
+#define /***/ LOLUA_ARG_2(a00, a01) LOLUA_ARG_1(a00), v01
+#define /***/ LOLUA_ARG_3(a00, a01, a02) LOLUA_ARG_2(a00, a01), v02
+#define /***/ LOLUA_ARG_4(a00, a01, a02, a03) LOLUA_ARG_3(a00, a01, a02), v03
+#define /***/ LOLUA_ARG_5(a00, a01, a02, a03, a04) LOLUA_ARG_4(a00, a01, a02, a03), v04
+#define /***/ LOLUA_ARG_6(a00, a01, a02, a03, a04, a05) LOLUA_ARG_5(a00, a01, a02, a03, a04), v05
+#define /***/ LOLUA_ARG_7(a00, a01, a02, a03, a04, a05, a06) LOLUA_ARG_6(a00, a01, a02, a03, a04, a05), v06
+#define /***/ LOLUA_ARG_8(a00, a01, a02, a03, a04, a05, a06, a07) LOLUA_ARG_7(a00, a01, a02, a03, a04, a05, a06), v07
+#define /***/ LOLUA_ARG_9(a00, a01, a02, a03, a04, a05, a06, a07, a08) LOLUA_ARG_8(a00, a01, a02, a03, a04, a05, a06, a07), v08
+#define /**/ LOLUA_ARG_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09) LOLUA_ARG_9(a00, a01, a02, a03, a04, a05, a06, a07, a08), v09
+#define /**/ LOLUA_ARG_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10) LOLUA_ARG_10(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09), v10
+#define /**/ LOLUA_ARG_12(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, a11) LOLUA_ARG_11(a00, a01, a02, a03, a04, a05, a06, a07, a08, a09), v11
 //-----------------------------------------------------------------------------
-template<> inline bool Var<float>::InnerIsValid(lua_State* l, int index)
-{
-    Var<double> v;
-    return v.IsValid(l, index);
-}
-template<> inline void Var<float>::InnerGet(lua_State* l, int& index)
-{
-    Var<double> v(l, index);
-    m_value = (float)v();
-}
-template<> inline int Var<float>::InnerPush(lua_State* l)
-{
-    Var<double> v = (double)m_value;
-    return v.Return(l);
-}
 
-#if 0
 //-----------------------------------------------------------------------------
-template<> inline bool Var<int64_t>::InnerIsValid(lua_State* l, int index)
-{
-    return !!lua_isnumber(l, index);
-}
-template<> inline void Var<int64_t>::InnerGet(lua_State* l, int& index)
-{
-    m_value = lua_tointeger(l, index++);
-}
-template<> inline int Var<int64_t>::InnerPush(lua_State* l)
-{
-    lua_pushinteger(l, m_value);
-    return 1;
-}
-#endif
+#define LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET) \
+    static int LUA_FUNC_NAME(lua_State* l) \
+    { \
+        auto s = LuaStack::Begin(l); \
+        auto o = s.INSTANCE_GET;
 
-//-----------------------------------------------------------------------------
-template<> inline bool Var<int32_t>::InnerIsValid(lua_State* l, int index)
-{
-    Var<int64_t> v;
-    return v.IsValid(l, index);
-}
-template<> inline void Var<int32_t>::InnerGet(lua_State* l, int& index)
-{
-    Var<int64_t> v(l, index);
-    m_value = (int32_t)v();
-}
-template<> inline int Var<int32_t>::InnerPush(lua_State* l)
-{
-    Var<int64_t> v = (int64_t)m_value;
-    return v.Return(l);
-}
+#define LOLUA_DECLARE_VARS(...) \
+    LOL_CALL(LOL_CAT(LOLUA_VAR_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__));
 
-//-----------------------------------------------------------------------------
-template<> inline bool Var<uint32_t>::InnerIsValid(lua_State* l, int index)
-{
-    return !!lua_isnumber(l, index);
-}
-template<> inline void Var<uint32_t>::InnerGet(lua_State* l, int& index)
-{
-    m_value = (uint32_t)(lua_Unsigned)lua_tointeger(l, index++);
-}
-template<> inline int Var<uint32_t>::InnerPush(lua_State* l)
-{
-    lua_pushinteger(l, (lua_Integer)m_value);
-    return 1;
-}
+#define LOLUA_DECLARE_CALL(INSTANCE_CALL, ...) \
+    o->INSTANCE_CALL(LOL_CALL(LOL_CAT(LOLUA_ARG_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)));
 
-#if 0
-//-----------------------------------------------------------------------------
-template<> inline bool Var<uint64_t>::InnerIsValid(lua_State* l, int index)
-{
-    Var<uint32_t> v;
-    return v.IsValid(l, index);
-}
-template<> inline void Var<uint64_t>::InnerGet(lua_State* l, int& index)
-{
-    Var<uint32_t> v(l, index);
-    m_value = (uint64_t)v();
-}
-template<> inline int Var<uint64_t>::InnerPush(lua_State* l)
-{
-    Var<uint32_t> v = (uint32_t)m_value;
-    return v.Return(l);
-}
-#endif
+#define LOLUA_DECLARE_CALL_VOID(INSTANCE_CALL) \
+    o->INSTANCE_CALL();
+
+#define LOLUA_DECLARE_END \
+        return s.End(); \
+    }
 
 //-----------------------------------------------------------------------------
-template<> inline bool Var<vec2>::InnerIsValid(lua_State* l, int index)
-{
-    Var<float> x;
-    return x.IsValid(l, index);
-}
-template<> inline void Var<vec2>::InnerGet(lua_State* l, int& index)
-{
-    Var<float> x(l, index);
-    Var<float> y(x(), l, index, true);
-    m_value = vec2(x, y);
-}
-template<> inline int Var<vec2>::InnerPush(lua_State* l)
-{
-    Var<float> x = m_value.x;
-    Var<float> y = m_value.y;
-    return (x.Return(l) + y.Return(l));
-}
-//-----------------------------------------------------------------------------
-template<> inline bool Var<vec3>::InnerIsValid(lua_State* l, int index)
-{
-    Var<float> x;
-    return x.IsValid(l, index);
-}
-template<> inline void Var<vec3>::InnerGet(lua_State* l, int& index)
-{
-    Var<float> x(l, index);
-    Var<float> y(x(), l, index, true);
-    Var<float> z(x(), l, index, true);
-    m_value = vec3(x, y, z);
-}
-template<> inline int Var<vec3>::InnerPush(lua_State* l)
-{
-    Var<float> x = m_value.x;
-    Var<float> y = m_value.y;
-    Var<float> z = m_value.z;
-    return (x.Return(l) + y.Return(l) + z.Return(l));
-}
+#define LOLUA_DECLARE_VOID_METHOD_VOID(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
+    LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET); \
+    LOLUA_DECLARE_CALL_VOID(INSTANCE_CALL) \
+    LOLUA_DECLARE_END
+
+#define LOLUA_DECLARE_VOID_METHOD_ARGS(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
+    LOLUA_DECLARE_BEGIN(LUA_FUNC_NAME, INSTANCE_GET); \
+    LOLUA_DECLARE_VARS(__VA_ARGS__) \
+    LOLUA_DECLARE_CALL(INSTANCE_CALL, __VA_ARGS__) \
+    LOLUA_DECLARE_END
+
 //-----------------------------------------------------------------------------
-template<> inline bool Var<vec4>::InnerIsValid(lua_State* l, int index)
-{
-    Var<float> x;
-    return x.IsValid(l, index);
-}
-template<> inline void Var<vec4>::InnerGet(lua_State* l, int& index)
-{
-    Var<float> x(l, index);
-    Var<float> y(x(), l, index, true);
-    Var<float> z(x(), l, index, true);
-    Var<float> w(x(), l, index, true);
-    m_value = vec4(x, y, z, w);
-}
-template<> inline int Var<vec4>::InnerPush(lua_State* l)
-{
-    Var<float> x = m_value.x;
-    Var<float> y = m_value.y;
-    Var<float> z = m_value.z;
-    Var<float> w = m_value.w;
-    return (x.Return(l) + y.Return(l) + z.Return(l) + w.Return(l));
-}
+#define LOLUA_DECLARE_RETURN_METHOD_ARGS(LUA_FUNC_NAME, INSTANCE_GET, INSTANCE_CALL, ...) \
+    static int LUA_FUNC_NAME(lua_State* l) \
+    { \
+        auto s = LuaStack::Begin(l); \
+        auto o = s.INSTANCE_GET; \
+        LOL_CALL(LOL_CAT(LOLUA_VAR_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)) \
+        s << o->INSTANCE_CALL(LOL_CALL(LOL_CAT(LOLUA_ARG_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__))); \
+        return s.End(); \
+    }
 
 //-----------------------------------------------------------------------------
-class VarColor
-{
-protected:
-    Var<vec4> m_value;
+#ifndef REGION_STACK_VAR
 
-public:
-    VarColor(bool optional = false)
-    {
-        m_value = Var<vec4>(optional);
-        InnerInit();
-    }
-    VarColor(vec4 value, bool optional = false)
-    {
-        m_value = Var<vec4>(value, optional);
-    }
-    VarColor(lua_State* l, int& index, bool optional = false)
-        : VarColor(optional)
-    {
-        GetInc(l, index);
-    }
-    VarColor(vec4 value, lua_State* l, int& index, bool optional = false)
-        : VarColor(value, optional)
-    {
-        GetInc(l, index);
-    }
+#ifndef STACK_BOOL
+template<> inline bool Stack::InnerIsValid<bool>()       { return lua_isboolean(m_state, m_index); }
+template<> inline bool Stack::InnerGet<bool>(bool value) { UNUSED(value); return !!lua_toboolean(m_state, m_index++); }
+template<> inline int Stack::InnerPush<bool>(bool value) { lua_pushboolean(m_state, value); return 1; }
+#endif // STACK_BOOL
 
-    inline operator vec4()     { return m_value; }
-    inline vec4& operator ()() { return m_value(); }
-    inline vec4& GetValue()    { return m_value.GetValue(); }
-    inline bool IsValid(lua_State* l, int index)
-    {
-        return InnerIsValid(l, index);
-    }
-    inline bool IsOptional()
-    {
-        return m_value.IsOptional();
-    }
-private:
-    void GetInc(lua_State* l, int& index)
-    {
-        bool is_nil = lua_isnil(l, index);
-        if (!m_value.IsOptional() || (!is_nil && InnerIsValid(l, index)))
-        {
-            ASSERT(!is_nil);
-            InnerGet(l, index);
-        }
-    }
-public:
-    inline void Get(lua_State* l, int index)
-    {
-        int idx = index;
-        GetInc(l, idx);
-    }
-    inline int Return(lua_State* l)
-    {
-        return InnerPush(l);
-    }
-    inline VarColor&  operator-(const vec4& value)  { m_value - value; return *this; }
-    inline VarColor&  operator+(const vec4& value)  { m_value + value; return *this; }
-    inline VarColor&  operator*(const vec4& value)  { m_value  * value; return *this; }
-    inline VarColor&  operator/(const vec4& value)  { m_value / value; return *this; }
-    inline VarColor&  operator=(const vec4& value)  { m_value = value; return *this; }
-    inline VarColor& operator-=(const vec4& value)  { m_value -= value; return *this; }
-    inline VarColor& operator+=(const vec4& value)  { m_value += value; return *this; }
-    inline VarColor& operator*=(const vec4& value)  { m_value *= value; return *this; }
-    inline VarColor& operator/=(const vec4& value)  { m_value /= value; return *this; }
-    inline VarColor&  operator-(const Var<vec4>& o) { m_value - o; return *this; }
-    inline VarColor&  operator+(const Var<vec4>& o) { m_value + o; return *this; }
-    inline VarColor&  operator*(const Var<vec4>& o) { m_value  * o; return *this; }
-    inline VarColor&  operator/(const Var<vec4>& o) { m_value / o; return *this; }
-    inline VarColor&  operator=(const Var<vec4>& o) { m_value = o; return *this; }
-    inline VarColor& operator-=(const Var<vec4>& o) { m_value -= o; return *this; }
-    inline VarColor& operator+=(const Var<vec4>& o) { m_value += o; return *this; }
-    inline VarColor& operator*=(const Var<vec4>& o) { m_value *= o; return *this; }
-    inline VarColor& operator/=(const Var<vec4>& o) { m_value /= o; return *this; }
-    inline bool operator==(const vec4& value)     { return m_value == value; }
-    inline bool operator!=(const vec4& value)     { return m_value != value; }
-    inline bool operator==(const Var<vec4>& o)    { return m_value == o; }
-    inline bool operator!=(const Var<vec4>& o)    { return m_value != o; }
-    inline VarColor&  operator-(const VarColor& v)  { m_value -  v.m_value; return *this; }
-    inline VarColor&  operator+(const VarColor& v)  { m_value +  v.m_value; return *this; }
-    inline VarColor&  operator*(const VarColor& v)  { m_value  * v.m_value; return *this; }
-    inline VarColor&  operator/(const VarColor& v)  { m_value /  v.m_value; return *this; }
-    inline VarColor&  operator=(const VarColor& v)  { m_value =  v.m_value; return *this; }
-    inline VarColor& operator-=(const VarColor& v)  { m_value -= v.m_value; return *this; }
-    inline VarColor& operator+=(const VarColor& v)  { m_value += v.m_value; return *this; }
-    inline VarColor& operator*=(const VarColor& v)  { m_value *= v.m_value; return *this; }
-    inline VarColor& operator/=(const VarColor& v)  { m_value /= v.m_value; return *this; }
-    inline bool operator==(const VarColor& v)     { return m_value == v.m_value; }
-    inline bool operator!=(const VarColor& v)     { return m_value != v.m_value; }
+//-----------------------------------------------------------------------------
+#ifndef STACK_CHAR_CONST
+template<> inline bool Stack::InnerIsValid<char const*>()                     { return !!lua_isstring(m_state, m_index); }
+template<> inline char const* Stack::InnerGet<char const*>(char const* value) { UNUSED(value); return lua_tostring(m_state, m_index++); }
+template<> inline int Stack::InnerPush<char const*>(char const* value)        { lua_pushstring(m_state, value); return 1; }
+#endif // STACK_CHAR_CONST
 
-protected:
-    void InnerInit()
-    {
-        m_value = vec4::zero;
-    }
-    bool InnerIsValid(lua_State* l, int index)
-    {
-        Var<String> s;
-        return m_value.IsValid(l, index) || s.IsValid(l, index);
-    }
-    void InnerGet(lua_State* l, int& index)
-    {
-        //Try vec4 first
-        if (m_value.IsValid(l, index))
-        {
-            m_value.Get(l, index);
-        }
-        else
-        {
-            Var<String> c(l, index);
-            *this = Color::C8BppHexString(c);
-        }
-    }
-    int InnerPush(lua_State* l)
-    {
-        Var<String> c = Color::HexString8Bpp(m_value);
-        return c.Return(l);
-    }
-};
+//-----------------------------------------------------------------------------
+#ifndef STACK_STRING
+template<> inline String Stack::InnerDefault<String>()         { return String(); }
+template<> inline bool Stack::InnerIsValid<String>()           { return InnerIsValid<char const*>(); }
+template<> inline String Stack::InnerGet<String>(String value) { return String(InnerGet<char const*>(value.C())); }
+template<> inline int Stack::InnerPush<String>(String value)   { return InnerPush<char const*>(value.C()); }
+#endif //STACK_STRING
 
 //-----------------------------------------------------------------------------
-template<typename E>
-class VarEnum
-{
-protected:
-    SafeEnum<E> m_value;
-    bool m_optional = false;
+#ifndef STACK_STRING
+template<> inline bool Stack::InnerIsValid<double>()           { return !!lua_isnumber(m_state, m_index); }
+template<> inline double Stack::InnerGet<double>(double value) { UNUSED(value); return lua_tonumber(m_state, m_index++); }
+template<> inline int Stack::InnerPush<double>(double value)   { lua_pushnumber(m_state, value); return 1; }
+#endif //STACK_STRING
 
-public:
-    VarEnum(bool optional = false)
-    {
-        m_optional = optional;
-        InnerInit();
-    }
-    VarEnum(SafeEnum<E> value, bool optional = false)
-        : VarEnum(optional)
-    {
-        m_value = value;
-    }
-    VarEnum(lua_State* l, int& index, bool optional = false)
-        : VarEnum(optional)
-    {
-        GetInc(l, index);
-    }
-    VarEnum(SafeEnum<E> value, lua_State* l, int& index, bool optional = false)
-        : VarEnum(value, optional)
-    {
-        GetInc(l, index);
-    }
+//-----------------------------------------------------------------------------
+#ifndef STACK_FLOAT
+template<> inline bool Stack::InnerIsValid<float>()         { return InnerIsValid<double>(); }
+template<> inline float Stack::InnerGet<float>(float value) { return (float)InnerGet<double>((double)value); }
+template<> inline int Stack::InnerPush<float>(float value)  { return InnerPush<double>((double)value); }
+#endif //STACK_FLOAT
 
-    inline operator SafeEnum<E>()     { return m_value; }
-    inline SafeEnum<E>& operator ()() { return m_value; }
-    inline SafeEnum<E>& GetValue()    { return m_value; }
-    inline bool IsValid(lua_State* l, int index)
-    {
-        return InnerIsValid(l, index);
-    }
-    inline bool IsOptional()
-    {
-        return m_optional;
-    }
-private:
-    void GetInc(lua_State* l, int& index)
-    {
-        bool is_nil = lua_isnil(l, index);
-        if (!m_optional || (!is_nil && InnerIsValid(l, index)))
-        {
-            ASSERT(!is_nil);
-            InnerGet(l, index);
-        }
-    }
-public:
-    inline void Get(lua_State* l, int index)
-    {
-        int idx = index;
-        GetInc(l, idx);
-    }
-    inline int Return(lua_State* l)
-    {
-        return InnerPush(l);
-    }
-    inline VarEnum<E>&  operator-(const SafeEnum<E>& value)  { m_value - value; return *this; }
-    inline VarEnum<E>&  operator+(const SafeEnum<E>& value)  { m_value + value; return *this; }
-    inline VarEnum<E>&  operator*(const SafeEnum<E>& value)  { m_value  * value; return *this; }
-    inline VarEnum<E>&  operator/(const SafeEnum<E>& value)  { m_value / value; return *this; }
-    inline VarEnum<E>&  operator=(const SafeEnum<E>& value)  { m_value = value; return *this; }
-    inline VarEnum<E>& operator-=(const SafeEnum<E>& value)  { m_value -= value; return *this; }
-    inline VarEnum<E>& operator+=(const SafeEnum<E>& value)  { m_value += value; return *this; }
-    inline VarEnum<E>& operator*=(const SafeEnum<E>& value)  { m_value *= value; return *this; }
-    inline VarEnum<E>& operator/=(const SafeEnum<E>& value)  { m_value /= value; return *this; }
-    inline bool operator==(const SafeEnum<E>& value)     { return m_value == value; }
-    inline bool operator!=(const SafeEnum<E>& value)     { return m_value != value; }
-    inline VarEnum<E>&  operator-(const VarEnum<E>& v)  { m_value - v.m_value; return *this; }
-    inline VarEnum<E>&  operator+(const VarEnum<E>& v)  { m_value + v.m_value; return *this; }
-    inline VarEnum<E>&  operator*(const VarEnum<E>& v)  { m_value  * v.m_value; return *this; }
-    inline VarEnum<E>&  operator/(const VarEnum<E>& v)  { m_value / v.m_value; return *this; }
-    inline VarEnum<E>&  operator=(const VarEnum<E>& v)  { m_value = v.m_value; return *this; }
-    inline VarEnum<E>& operator-=(const VarEnum<E>& v)  { m_value -= v.m_value; return *this; }
-    inline VarEnum<E>& operator+=(const VarEnum<E>& v)  { m_value += v.m_value; return *this; }
-    inline VarEnum<E>& operator*=(const VarEnum<E>& v)  { m_value *= v.m_value; return *this; }
-    inline VarEnum<E>& operator/=(const VarEnum<E>& v)  { m_value /= v.m_value; return *this; }
-    inline bool operator==(const VarEnum<E>& v)     { return m_value == v.m_value; }
-    inline bool operator!=(const VarEnum<E>& v)     { return m_value != v.m_value; }
+//-----------------------------------------------------------------------------
+#ifndef STACK_INT64
+template<> inline bool Stack::InnerIsValid<int64_t>()             { return !!lua_isnumber(m_state, m_index); }
+template<> inline int64_t Stack::InnerGet<int64_t>(int64_t value) { UNUSED(value); return lua_tointeger(m_state, m_index++); }
+template<> inline int Stack::InnerPush<int64_t>(int64_t value)    { lua_pushinteger(m_state, value); return 1; }
+#endif //STACK_INT64
 
-protected:
-    void InnerInit()
-    {
-        m_value = SafeEnum<E>(0);
-    }
-    bool InnerIsValid(lua_State* l, int index)
-    {
-        Var<String> s;
-        return s.IsValid(l, index);
-    }
-    void InnerGet(lua_State* l, int& index)
-    {
-        Var<String> c(l, index);
-        *this = FindValue<SafeEnum<E> >(c);
-    }
-    int InnerPush(lua_State* l)
-    {
-        Var<String> s = this->GetValue().ToString();
-        return s.Return(l);
-    }
-};
+//-----------------------------------------------------------------------------
+#ifndef STACK_UINT64
+template<> inline bool Stack::InnerIsValid<uint64_t>()               { return !!lua_isnumber(m_state, m_index); }
+template<> inline uint64_t Stack::InnerGet<uint64_t>(uint64_t value) { UNUSED(value); return (uint64_t)lua_tointeger(m_state, m_index++); }
+template<> inline int Stack::InnerPush<uint64_t>(uint64_t value)     { lua_pushinteger(m_state, (lua_Unsigned)value); return 1; }
+#endif //STACK_UINT64
 
 //-----------------------------------------------------------------------------
-class Stack
-{
-public:
-    Stack(lua_State* l, int32_t start_index = 1)
-    {
-        m_state = l;
-        m_index = start_index;
-    }
-    virtual ~Stack() { }
-    inline operator int32_t() { return m_result; }
-    int32_t GetArgs()
-    {
-        return lua_gettop(m_state);
-    }
+#ifndef STACK_INT32
+template<> inline bool Stack::InnerIsValid<int32_t>()             { return !!lua_isnumber(m_state, m_index); }
+template<> inline int32_t Stack::InnerGet<int32_t>(int32_t value) { UNUSED(value); return (int32_t)lua_tointeger(m_state, m_index++); }
+template<> inline int Stack::InnerPush<int32_t>(int32_t value)    { lua_pushinteger(m_state, (lua_Integer)value); return 1; }
+#endif STACK_INT32
 
-    //-------------------------------------------------------------------------
-    template<typename T>
-    Stack& operator>>(T& var)
-    {
-        var = T(var.GetValue(), m_state, m_index, var.IsOptional());
-        return *this;
-    }
+//-----------------------------------------------------------------------------
+#ifndef STACK_UINT32
+template<> inline bool Stack::InnerIsValid<uint32_t>()               { return !!lua_isnumber(m_state, m_index); }
+template<> inline uint32_t Stack::InnerGet<uint32_t>(uint32_t value) { UNUSED(value); return (uint32_t)(lua_Unsigned)lua_tointeger(m_state, m_index++); }
+template<> inline int Stack::InnerPush<uint32_t>(uint32_t value)     { lua_pushinteger(m_state, (lua_Unsigned)value); return 1; }
+#endif //STACK_UINT32
 
-    /*
-    template<typename T>
-    Stack& operator>>(Var<T>& var)
-    {
-        var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
-        return *this;
-    }
-    template<typename T>
-    Stack& operator>>(Var<T>& var)
-    {
-        var = Var<T>(var.GetValue(), m_state, m_index, var.IsOptional());
-        return *this;
-    }
-    template<typename T>
-    Stack& operator>>(VarPtr<T>& var)
-    {
-        var = VarPtr<T>(m_state, m_index);
-        return *this;
-    }
-    */
-    /*
-    template<typename T>
-    Stack& operator>>(T& var)
-    {
-        Var<T> ret(m_state, m_index);
-        var = ret.GetValue();
-        return *this;
-    }
-    template<typename T>
-    Stack& operator>>(VarPtrLight<T>& var)
-    {
-        var = VarPtrLight<T>(m_state, m_index);
-        return *this;
-    }
-    */
+//-----------------------------------------------------------------------------
+#ifndef STACK_VEC2
+template<> inline bool Stack::InnerIsValid<vec2>()       { return InnerIsValid<float>(); }
+template<> inline vec2 Stack::InnerGet<vec2>(vec2 value) { return vec2(InnerGet<float>(value.x), Get<float>(value.y, true)); }
+template<> inline int Stack::InnerPush<vec2>(vec2 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y)); }
+#endif //STACK_VEC2
 
-    //-------------------------------------------------------------------------
-    template<typename T>
-    Stack& operator<<(T& var)
-    {
-        m_result += var.Return(m_state);
-        return *this;
-    }
-    /*
-    template<typename T>
-    Stack& operator<<(T& var)
-    {
-        Var<T> ret(var, false);
-        m_result += ret.Return(m_state);
-        return *this;
-    }
-    template<typename T>
-    Stack& operator<<(VarPtr<T>& var)
-    {
-        m_result += var.Return(m_state);
-        return *this;
-    }
-    template<typename T>
-    Stack& operator<<(VarPtrLight<T>& var)
-    {
-        m_result += var.Return(m_state);
-        return *this;
-    }
-    */
+//-----------------------------------------------------------------------------
+#ifndef STACK_VEC3
+template<> inline bool Stack::InnerIsValid<vec3>()       { return InnerIsValid<float>(); }
+template<> inline vec3 Stack::InnerGet<vec3>(vec3 value) { return vec3(InnerGet<float>(value.x), Get<float>(value.y, true), Get<float>(value.z, true)); }
+template<> inline int Stack::InnerPush<vec3>(vec3 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y) + InnerPush<float>(value.z)); }
+#endif //STACK_VEC3
 
-private:
-    lua_State*  m_state = nullptr;
-    int32_t m_index = 1;
-    int32_t m_result = 0;
-};
+//-----------------------------------------------------------------------------
+#ifndef STACK_VEC4
+template<> inline bool Stack::InnerIsValid<vec4>()       { return InnerIsValid<float>(); }
+template<> inline vec4 Stack::InnerGet<vec4>(vec4 value) { return vec4(InnerGet<float>(value.x), Get<float>(value.y, true), Get<float>(value.z, true), Get<float>(value.w, true)); }
+template<> inline int Stack::InnerPush<vec4>(vec4 value) { return (InnerPush<float>(value.x) + InnerPush<float>(value.y) + InnerPush<float>(value.z) + InnerPush<float>(value.w)); }
+#endif STACK_VEC4
+
+#endif //REGION_STACK_VAR
 
 //-----------------------------------------------------------------------------
 class Loader
 {
-    friend class ObjectDef;
+    friend class ObjectHelper;
 public:
     Loader();
     virtual ~Loader();
@@ -973,23 +579,24 @@ public:
     bool ExecLuaFile(String const &lua);
     bool ExecLuaCode(String const &lua);
 
-    template<typename T>
-    T GetVar(String const &name)
-    {
-        lua_getglobal(m_lua_state, name.C());
-        Var<T> var; var.Get(m_lua_state, -1);
-        lua_pop(m_lua_state, 1);
-        return var;
-    }
-    template<typename T>
-    T* GetPtr(String const &name)
-    {
-        lua_getglobal(m_lua_state, name.C());
-        VarPtr<T> var; var.Get(m_lua_state, -1);
-        lua_pop(m_lua_state, 1);
-        return var();
+    //-------------------------------------------------------------------------
+#define DECLARE_LOADER_GET(T0, T1, GET_NAME) \
+    template<typename T0> \
+    T1 GET_NAME(String const &name) \
+    { \
+        lua_getglobal(m_lua_state, name.C()); \
+        auto stack = LuaStack::Begin(m_lua_state, -1); \
+        auto result = stack.GET_NAME<T0>(); \
+        lua_pop(m_lua_state, 1); \
+        return result; \
     }
 
+    DECLARE_LOADER_GET(T, T, Get);
+    DECLARE_LOADER_GET(E, SafeEnum<E>, GetEnum);
+    DECLARE_LOADER_GET(P, P*, GetPtr);
+
+#undef DECLARE_LOADER_GET
+
 protected:
     lua_State* GetLuaState();
     static void Store(lua_State* l, Loader* loader);
@@ -1003,48 +610,37 @@ private:
 };
 
 //-----------------------------------------------------------------------------
-// ObjectDef member implementations that require VarPtr
+// ObjectHelper member implementations that require VarPtr
 
 template <typename TLuaClass>
-int ObjectDef::Store(lua_State * l)
+int ObjectHelper::Store(lua_State * l)
 {
-    VarPtr<TLuaClass> obj;
-    obj.Get(l, 1);
-    ASSERT(obj());
-    Loader::StoreObject(l, obj());
+    auto stack = LuaStack::Begin(l);
+    TLuaClass* obj = stack.GetPtr<TLuaClass>();
+    ASSERT(obj);
+    Loader::StoreObject(l, obj);
     return 0;
 }
 
 template <typename TLuaClass>
-int ObjectDef::Del(lua_State * l)
+int ObjectHelper::Del(lua_State * l)
 {
-    VarPtr<TLuaClass> obj;
-    obj.Get(l, 1);
-    ASSERT(obj());
-    delete obj();
+    auto stack = LuaStack::Begin(l);
+    TLuaClass* obj = stack.GetPtr<TLuaClass>();
+    ASSERT(obj);
+    delete obj;
     return 0;
 }
 
 } /* namespace Lolua */
 
+//TYPEDEFS
 typedef Lolua::Function         LuaFunction;
-typedef Lolua::ObjectDef        LuaObjectDef;
+typedef Lolua::ObjectHelper     LuaObjectHelper;
 typedef Lolua::Object           LuaObject;
-typedef Lolua::ObjectLib        LuaObjectLib;
+typedef Lolua::Object::Library  LuaObjectLibrary;
 typedef Lolua::Loader           LuaLoader;
-typedef Lolua::Var<bool>        LuaBool;
-typedef Lolua::Var<char const*> LuaCharPtr;
-typedef Lolua::Var<String>      LuaString;
-typedef Lolua::Var<double>      LuaDouble;
-typedef Lolua::Var<float>       LuaFloat;
-typedef Lolua::Var<int64_t>     LuaInt64;
-typedef Lolua::Var<int32_t>     LuaInt32;
-typedef Lolua::Var<uint32_t>    LuaUInt32;
-typedef Lolua::Var<uint64_t>    LuaUInt64;
-typedef Lolua::Var<vec2>        LuaVec2;
-typedef Lolua::Var<vec3>        LuaVec3;
-typedef Lolua::Var<vec4>        LuaVec4;
-typedef Lolua::VarColor         LuaColor;
 typedef Lolua::Stack            LuaStack;
+template <typename P> using LuaPtr = Lolua::Stack::Ptr<P>;
 
 } /* namespace lol */
diff --git a/src/utils.h b/src/utils.h
index 3faf9d84..5929394e 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -61,6 +61,12 @@ template< class T > inline int GetRandom(array<T> src)
 
 // Gets the value for the given enum type.
 template<class T> inline T FindValue(const char* name)
+{
+    auto str = String(name);
+    return FindValue<T>(str);
+}
+
+template<class T> inline T FindValue(String const& name)
 {
     String n = name;
     n.to_lower();
@@ -72,10 +78,6 @@ template<class T> inline T FindValue(const char* name)
     }
     return T::Max;
 }
-template<class T> inline T FindValue(String const& name)
-{
-    return FindValue<T>(name.C());
-}
 
 } /* namespace lol */