diff --git a/src/BizHawk.Tests/BizHawk.Tests.csproj b/src/BizHawk.Tests/BizHawk.Tests.csproj
index 780a2da2c3..e2f653b882 100644
--- a/src/BizHawk.Tests/BizHawk.Tests.csproj
+++ b/src/BizHawk.Tests/BizHawk.Tests.csproj
@@ -16,6 +16,8 @@
+
+
diff --git a/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs b/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs
new file mode 100644
index 0000000000..cd31e2bfe3
--- /dev/null
+++ b/src/BizHawk.Tests/Client.Common/lua/LuaTests.cs
@@ -0,0 +1,874 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using BizHawk.Client.Common;
+using BizHawk.Common.StringExtensions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace BizHawk.Tests.Client.Common.Lua
+{
+ [TestClass]
+ public class LuaTests
+ {
+ private static readonly NLua.Lua LuaInstance = new();
+ private static readonly NLuaTableHelper _th = new(LuaInstance, Console.WriteLine);
+
+ // NOTE: NET6 changed Default encoding behavior.
+ // It no longer represents the default ANSI encoding
+ // Rather it now represents the "default encoding for this NET implementation"
+ // on Win10 this seems to just be an alias to UTF8, so it doesn't work here
+
+ private static string? FixString(string? s)
+ => s is null
+ ? null
+ : Encoding.UTF8.GetString(s.ToCharCodepointArray());
+
+ private static string? UnFixString(string? s)
+ => s is null
+ ? null
+ : StringExtensions.CharCodepointsToString(Encoding.UTF8.GetBytes(s));
+
+ private static object? ExpectedValue { get; set; }
+
+ [LuaMethod("pass_object", "")]
+ public static void PassObject(object? o)
+ => Assert.IsTrue(o == ExpectedValue);
+
+ // seems nil passed over here gets turned into false
+ [LuaMethod("pass_bool", "")]
+ public static void PassBool(bool? o)
+ => Assert.IsTrue(o == ((bool?)ExpectedValue ?? false));
+
+ [LuaMethod("pass_s8", "")]
+ public static void PassS8(sbyte? o)
+ => Assert.IsTrue(o == (sbyte?)ExpectedValue);
+
+ [LuaMethod("pass_u8", "")]
+ public static void PassU8(byte? o)
+ => Assert.IsTrue(o == (byte?)ExpectedValue);
+
+ [LuaMethod("pass_s16", "")]
+ public static void PassS16(short? o)
+ => Assert.IsTrue(o == (short?)ExpectedValue);
+
+ [LuaMethod("pass_u16", "")]
+ public static void PassU16(ushort? o)
+ => Assert.IsTrue(o == (ushort?)ExpectedValue);
+
+ [LuaMethod("pass_s32", "")]
+ public static void PassS32(int? o)
+ => Assert.IsTrue(o == (int?)ExpectedValue);
+
+ [LuaMethod("pass_u32", "")]
+ public static void PassU32(uint? o)
+ => Assert.IsTrue(o == (uint?)ExpectedValue);
+
+ [LuaMethod("pass_s64", "")]
+ public static void PassS64(long? o)
+ => Assert.IsTrue(o == (long?)ExpectedValue);
+
+ [LuaMethod("pass_u64", "")]
+ public static void PassU64(ulong? o)
+ => Assert.IsTrue(o == (ulong?)ExpectedValue);
+
+ [LuaMethod("pass_f32", "")]
+ public static void PassF32(float? o)
+ => Assert.IsTrue(o == (float?)ExpectedValue);
+
+ [LuaMethod("pass_f64", "")]
+ public static void PassF64(double? o)
+ => Assert.IsTrue(o == (double?)ExpectedValue);
+
+ [LuaMethod("pass_f128", "")]
+ public static void PassF128(decimal? o)
+ => Assert.IsTrue(o == (decimal?)ExpectedValue);
+
+ [LuaMethod("pass_intptr", "")]
+ public static void PassIntPtr(IntPtr? o)
+ => Assert.IsTrue(o == (IntPtr?)ExpectedValue);
+
+ [LuaMethod("pass_uintptr", "")]
+ public static void PassUIntPtr(UIntPtr? o)
+ => Assert.IsTrue(o == (UIntPtr?)ExpectedValue);
+
+ [LuaMethod("pass_char", "")]
+ public static void PassChar(char? o)
+ => Assert.IsTrue(o == (char?)ExpectedValue);
+
+ [LuaMethod("pass_string", "")]
+ public static void PassString(string? o)
+ {
+ Assert.IsTrue(FixString(o) == (string?)ExpectedValue);
+ Assert.IsTrue(o == UnFixString((string?)ExpectedValue));
+ }
+
+ [LuaMethod("pass_color", "")]
+ public static void PassColor(object? o)
+ => Assert.IsTrue(_th.SafeParseColor(o)?.ToArgb() == ((Color?)ExpectedValue)?.ToArgb());
+
+ [LuaMethod("pass_table", "")]
+ public static void PassTable(NLua.LuaTable? o)
+ {
+ if (ExpectedValue is null)
+ {
+ Assert.IsNull(o);
+ }
+ else
+ {
+ var t = _th.EnumerateEntries