diff --git a/src/vscript/CMakeLists.txt b/src/vscript/CMakeLists.txt
index f7c28ec1..ff13f9a6 100644
--- a/src/vscript/CMakeLists.txt
+++ b/src/vscript/CMakeLists.txt
@@ -23,6 +23,7 @@ add_sources( SOURCE_GROUP "Squirrel_RE/squirrel"
     "languages/squirrel_re/squirrel/sqstring.cpp"
     "languages/squirrel_re/squirrel/sqtable.cpp"
     "languages/squirrel_re/squirrel/sqmem.cpp"
+    "languages/squirrel_re/squirrel/sqstate.cpp"
     "languages/squirrel_re/squirrel/sqvm.cpp"
 )
 
diff --git a/src/vscript/languages/squirrel_re/include/sqstate.h b/src/vscript/languages/squirrel_re/include/sqstate.h
index 1adbf85a..01aefb85 100644
--- a/src/vscript/languages/squirrel_re/include/sqstate.h
+++ b/src/vscript/languages/squirrel_re/include/sqstate.h
@@ -13,6 +13,10 @@ struct RefTable {
 		SQUnsignedInteger refs;
 		struct RefNode* next;
 	};
+	void AddRef(SQObject& obj);
+	SQBool Release(SQObject& obj);
+
+	RefTable::RefNode* Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add);
 private:
 	SQUnsignedInteger _numofslots;
 	SQUnsignedInteger _slotused;
diff --git a/src/vscript/languages/squirrel_re/include/squirrel.h b/src/vscript/languages/squirrel_re/include/squirrel.h
index 6b5c5b64..1244ed98 100644
--- a/src/vscript/languages/squirrel_re/include/squirrel.h
+++ b/src/vscript/languages/squirrel_re/include/squirrel.h
@@ -47,6 +47,9 @@ to the following restrictions:
 
 #define _SC(a) a
 
+#define SQTrue  (1)
+#define SQFalse (0)
+
 typedef long SQInteger;
 typedef unsigned long SQUnsignedInteger;
 typedef short SQShort;
@@ -64,6 +67,8 @@ typedef SQInteger SQRESULT;
 typedef int ScriptDataType_t;
 
 typedef struct SQVM* HSQUIRRELVM;
+//typedef SQObject HSQOBJECT;
+
 struct SQBufState;
 
 typedef char SQChar;
@@ -170,6 +175,8 @@ SQRESULT sq_getthread(HSQUIRRELVM v, SQInteger idx, HSQUIRRELVM* thread);
 SQRESULT sq_getstring(HSQUIRRELVM v, SQInteger idx, const SQChar** c);
 SQRESULT sq_get(HSQUIRRELVM v, SQInteger idx);
 SQInteger sq_gettop(HSQUIRRELVM v);
+SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po);
+void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop);
 SQRESULT sq_pushroottable(HSQUIRRELVM v);
 void sq_pushbool(HSQUIRRELVM v, SQBool b);
 void sq_pushstring(HSQUIRRELVM v, const SQChar* string, SQInteger len);
@@ -186,6 +193,9 @@ SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerr
 SQRESULT sq_startconsttable(HSQUIRRELVM v);
 SQRESULT sq_endconsttable(HSQUIRRELVM v);
 
+void sq_addref(HSQUIRRELVM v, SQObject* po);
+SQBool sq_release(HSQUIRRELVM v, SQObject* po);
+
 /*UTILITY MACRO*/
 #define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
 #define sq_istable(o) ((o)._type==OT_TABLE)
@@ -227,6 +237,9 @@ inline SQRESULT (*v_sq_endconsttable)(HSQUIRRELVM v);
 
 inline SQString* (*v_StringTable__Add)(void* a1, const SQChar* str, SQInteger len);
 
+inline void* /*RefTable::RefNode*/ (*v_RefTable__Get)(void* /*RefTable*/ thisp, SQObject* obj, SQHash* mainpos, void*/*RefTable::RefNode**/ prev, bool add);
+inline SQBool(*v_RefTable__Release)(void* /*RefTable*/ thisp, SQObject* obj);
+
 ///////////////////////////////////////////////////////////////////////////////
 class VSquirrelAPI : public IDetour
 {
@@ -250,6 +263,9 @@ class VSquirrelAPI : public IDetour
 		LogFunAdr("sq_endconsttable", v_sq_endconsttable);
 
 		LogFunAdr("StringTable::Add", v_StringTable__Add);
+
+		LogFunAdr("RefTable::Get", v_RefTable__Get);
+		LogFunAdr("RefTable::Release", v_RefTable__Release);
 	}
 	virtual void GetFun(void) const
 	{
@@ -271,6 +287,9 @@ class VSquirrelAPI : public IDetour
 		g_GameDll.FindPatternSIMD("8B 41 78 45 33 C0 FF C8 8B D0 89 41 78 48 C1 E2 04 48 03 91 ?? ?? ?? ?? 8B 02 48 C7 02 ?? ?? ?? ?? 25 ?? ?? ?? ?? 74 15").GetPtr(v_sq_endconsttable);
 
 		g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 41 8D 4D FF").FollowNearCallSelf().GetPtr(v_StringTable__Add);
+
+		g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? FF 40 10 FF C6").FollowNearCallSelf().GetPtr(v_RefTable__Get);
+		g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 84 7D BC").FollowNearCallSelf().GetPtr(v_RefTable__Release);
 	}
 	virtual void GetVar(void) const { }
 	virtual void GetCon(void) const { }
diff --git a/src/vscript/languages/squirrel_re/include/sqvm.h b/src/vscript/languages/squirrel_re/include/sqvm.h
index 7f82b708..0bcbd025 100644
--- a/src/vscript/languages/squirrel_re/include/sqvm.h
+++ b/src/vscript/languages/squirrel_re/include/sqvm.h
@@ -20,6 +20,9 @@ struct SQVM : public CHAINABLE_OBJ
 {
 	void PrintObjVal(const SQObject* oin, SQObject* oout);
 
+	void Pop();
+	void Pop(SQInteger n);
+
 	// push sqobjectptr on to the stack
 	void Push(const SQObjectPtr& o);
 
@@ -59,6 +62,7 @@ static_assert(offsetof(SQVM, _top) == 0x78);
 static_assert(offsetof(SQVM, _nnativecalls) == 0x130);
 
 inline SQObjectPtr& stack_get(HSQUIRRELVM v, SQInteger idx) { return ((idx >= 0) ? (v->_stackbase[idx-1]) : (v->GetUp(idx))); }
+#define _ss(_vm_) (_vm_)->_sharedstate
 
 /* ==== SQUIRREL ======================================================================================================================================================== */
 inline SQRESULT(*v_SQVM_PrintFunc)(HSQUIRRELVM v, SQChar* fmt, ...);
diff --git a/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp b/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp
index 707df29f..b5e213af 100644
--- a/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp
+++ b/src/vscript/languages/squirrel_re/squirrel/sqapi.cpp
@@ -94,6 +94,20 @@ SQInteger sq_gettop(HSQUIRRELVM v)
 	return (v->_top - v->_bottom);
 }
 
+//---------------------------------------------------------------------------------
+SQRESULT sq_getstackobj(HSQUIRRELVM v, SQInteger idx, SQObject* po)
+{
+	*po = stack_get(v, idx);
+	return SQ_OK;
+}
+
+//---------------------------------------------------------------------------------
+void sq_pop(HSQUIRRELVM v, SQInteger nelemstopop)
+{
+	Assert(v->_top >= nelemstopop);
+	v->Pop(nelemstopop);
+}
+
 //---------------------------------------------------------------------------------
 SQRESULT sq_pushroottable(HSQUIRRELVM v)
 {
@@ -174,16 +188,32 @@ SQRESULT sq_call(HSQUIRRELVM v, SQInteger params, SQBool retval, SQBool raiseerr
 	return v_sq_call(v, params, retval, raiseerror);
 }
 
+//---------------------------------------------------------------------------------
 SQRESULT sq_startconsttable(HSQUIRRELVM v)
 {
 	return v_sq_startconsttable(v);
 }
 
+//---------------------------------------------------------------------------------
 SQRESULT sq_endconsttable(HSQUIRRELVM v)
 {
 	return v_sq_endconsttable(v);
 }
 
+//---------------------------------------------------------------------------------
+void sq_addref(HSQUIRRELVM v, SQObject* po)
+{
+	if (!ISREFCOUNTED(sq_type(*po))) return;
+	_ss(v)->_refs_table.AddRef(*po);
+}
+
+//---------------------------------------------------------------------------------
+SQBool sq_release(HSQUIRRELVM v, SQObject* po)
+{
+	if (!ISREFCOUNTED(sq_type(*po))) return SQTrue;
+	return _ss(v)->_refs_table.Release(*po);
+}
+
 void VSquirrelAPI::Detour(const bool bAttach) const
 {
 	DetourSetup(&v_sq_pushroottable, &sq_pushroottable, bAttach);
diff --git a/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp b/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp
new file mode 100644
index 00000000..bd7d6077
--- /dev/null
+++ b/src/vscript/languages/squirrel_re/squirrel/sqstate.cpp
@@ -0,0 +1,22 @@
+/*
+	see copyright notice in squirrel.h
+*/
+#include "sqstate.h"
+
+void RefTable::AddRef(SQObject& obj)
+{
+	SQHash mainpos;
+	RefNode* prev;
+	RefNode* ref = Get(obj, mainpos, &prev, true);
+	ref->refs++;
+}
+
+SQBool RefTable::Release(SQObject& obj)
+{
+	return v_RefTable__Release(this, &obj);
+}
+
+RefTable::RefNode* RefTable::Get(SQObject& obj, SQHash& mainpos, RefNode** prev, bool add)
+{
+	return (RefTable::RefNode*)v_RefTable__Get(this, &obj, &mainpos, prev, add);
+}
diff --git a/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp b/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp
index ae478ea1..c24d234b 100644
--- a/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp
+++ b/src/vscript/languages/squirrel_re/squirrel/sqvm.cpp
@@ -174,6 +174,16 @@ void SQVM_LogicError(SQBool bPrompt)
 	v_SQVM_LogicError(bPrompt);
 }
 
+void SQVM::Pop() {
+	_stack[--_top] = _null_;
+}
+
+void SQVM::Pop(SQInteger n) {
+	for (SQInteger i = 0; i < n; i++) {
+		_stack[--_top] = _null_;
+	}
+}
+
 void SQVM::Push(const SQObjectPtr& o) { _stack[_top++] = o; }
 SQObjectPtr& SQVM::Top() { return _stack[_top - 1]; }
 SQObjectPtr& SQVM::PopGet() { return _stack[--_top]; }