mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-03 06:49:22 +00:00
Compare commits
4 commits
8b34359d1b
...
bf877124c1
Author | SHA1 | Date | |
---|---|---|---|
|
bf877124c1 | ||
|
cc7762293d | ||
|
b75dce1d02 | ||
|
0a01534aa4 |
13 changed files with 123 additions and 52 deletions
|
@ -2,9 +2,9 @@
|
|||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public class LuaNetVarsMod : MelonMod
|
||||
public class LuaNetworkVariablesMod : MelonMod
|
||||
{
|
||||
internal static MelonLogger.Instance Logger;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ using ABI.Scripting.CVRSTL.Common;
|
|||
using JetBrains.Annotations;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace NAK.LuaNetVars.Modules;
|
||||
namespace NAK.LuaNetworkVariables.Modules;
|
||||
|
||||
[PublicAPI]
|
||||
public class LuaNetModule : BaseScriptedStaticWrapper
|
||||
|
@ -37,7 +37,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ public class LuaNetModule : BaseScriptedStaticWrapper
|
|||
|
||||
if (_controller == null)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error("LuaNetVarController is null.");
|
||||
LuaNetworkVariablesMod.Logger.Error("LuaNetVarController is null.");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using MoonSharp.Interpreter;
|
||||
using ABI_RC.Core.Player;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public struct LuaEventContext
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
internal class LuaEventTracker
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ using MoonSharp.Interpreter;
|
|||
using UnityEngine;
|
||||
using Coroutine = UnityEngine.Coroutine;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public partial class LuaNetVarController : MonoBehaviour
|
||||
{
|
||||
|
@ -58,13 +58,13 @@ public partial class LuaNetVarController : MonoBehaviour
|
|||
|
||||
if (ModNetworkID.Length > ModNetworkManager.MaxMessageIdLength)
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error($"ModNetworkID ({ModNetworkID}) exceeds max length of {ModNetworkManager.MaxMessageIdLength} characters!");
|
||||
LuaNetworkVariablesMod.Logger.Error($"ModNetworkID ({ModNetworkID}) exceeds max length of {ModNetworkManager.MaxMessageIdLength} characters!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_hashes.Add(_uniquePathHash);
|
||||
ModNetworkManager.Subscribe(ModNetworkID, OnMessageReceived);
|
||||
LuaNetVarsMod.Logger.Msg($"Registered LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Registered LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
|
||||
switch (_luaClientBehaviour.Context.objContext)
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ public partial class LuaNetVarController : MonoBehaviour
|
|||
return;
|
||||
|
||||
ModNetworkManager.Unsubscribe(ModNetworkID);
|
||||
LuaNetVarsMod.Logger.Msg($"Unsubscribed LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Unsubscribed LuaNetVarController with ModNetworkID: {ModNetworkID}");
|
||||
_hashes.Remove(_uniquePathHash);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
using ABI_RC.Systems.ModNetwork;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace NAK.LuaNetVars
|
||||
namespace NAK.LuaNetworkVariables
|
||||
{
|
||||
public partial class LuaNetVarController
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace NAK.LuaNetVars
|
|||
msg.Read(out string varName);
|
||||
DynValue newValue = DeserializeDynValue(msg);
|
||||
|
||||
LuaNetVarsMod.Logger.Msg($"Received LuaVariable update: {varName} = {newValue}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Received LuaVariable update: {varName} = {newValue}");
|
||||
|
||||
if (_registeredNetworkVars.TryGetValue(varName, out DynValue var))
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ namespace NAK.LuaNetVars
|
|||
}
|
||||
else
|
||||
{
|
||||
LuaNetVarsMod.Logger.Warning($"Received update for unregistered variable {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Received update for unregistered variable {varName}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace NAK.LuaNetVars
|
|||
args[i + 1] = DeserializeDynValue(msg);
|
||||
}
|
||||
|
||||
LuaNetVarsMod.Logger.Msg($"Received LuaEvent: {eventName} from {context.SenderName} with {argsCount} args");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Received LuaEvent: {eventName} from {context.SenderName} with {argsCount} args");
|
||||
|
||||
InvokeLuaEvent(eventName, args);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ namespace NAK.LuaNetVars
|
|||
}
|
||||
else
|
||||
{
|
||||
LuaNetVarsMod.Logger.Warning($"Received sync for unregistered variable {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Received sync for unregistered variable {varName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace NAK.LuaNetVars
|
|||
}
|
||||
else
|
||||
{
|
||||
LuaNetVarsMod.Logger.Warning($"No registered callback for event {eventName}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"No registered callback for event {eventName}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ namespace NAK.LuaNetVars
|
|||
}
|
||||
modMsg.Send();
|
||||
|
||||
LuaNetVarsMod.Logger.Msg($"Sent variable sync to {userId}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Sent variable sync to {userId}");
|
||||
}
|
||||
|
||||
private void RequestVariableSync()
|
||||
|
@ -167,7 +167,7 @@ namespace NAK.LuaNetVars
|
|||
using ModNetworkMessage modMsg = new(ModNetworkID);
|
||||
modMsg.Write((byte)MessageType.RequestSync);
|
||||
modMsg.Send();
|
||||
LuaNetVarsMod.Logger.Msg("Requested variable sync");
|
||||
LuaNetworkVariablesMod.Logger.Msg("Requested variable sync");
|
||||
}
|
||||
|
||||
// private DynValue SendLuaEventCallback(ScriptExecutionContext context, CallbackArguments args)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public partial class LuaNetVarController
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ public partial class LuaNetVarController
|
|||
{
|
||||
if (_registeredNetworkVars.ContainsKey(varName))
|
||||
{
|
||||
LuaNetVarsMod.Logger.Warning($"Network variable {varName} already registered!");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Network variable {varName} already registered!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ public partial class LuaNetVarController
|
|||
RegisterGetterFunction(varName);
|
||||
RegisterSetterFunction(varName);
|
||||
|
||||
LuaNetVarsMod.Logger.Msg($"Registered network variable {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Registered network variable {varName}");
|
||||
}
|
||||
|
||||
private void RegisterGetterFunction(string varName)
|
||||
|
@ -38,7 +38,7 @@ public partial class LuaNetVarController
|
|||
var newValue = args[0];
|
||||
if (!IsSupportedDynValue(newValue))
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error($"Unsupported DynValue type: {newValue.Type} for variable {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Error($"Unsupported DynValue type: {newValue.Type} for variable {varName}");
|
||||
return DynValue.Nil;
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,10 @@ public partial class LuaNetVarController
|
|||
if (!ValidateCallback(callback) || !ValidateNetworkVar(varName)) return;
|
||||
|
||||
if (_registeredNotifyCallbacks.ContainsKey(varName))
|
||||
LuaNetVarsMod.Logger.Warning($"Overwriting notify callback for {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Overwriting notify callback for {varName}");
|
||||
|
||||
_registeredNotifyCallbacks[varName] = callback;
|
||||
LuaNetVarsMod.Logger.Msg($"Registered notify callback for {varName}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Registered notify callback for {varName}");
|
||||
}
|
||||
|
||||
internal void RegisterEventCallback(string eventName, DynValue callback)
|
||||
|
@ -79,23 +79,23 @@ public partial class LuaNetVarController
|
|||
if (!ValidateCallback(callback)) return;
|
||||
|
||||
if (_registeredEventCallbacks.ContainsKey(eventName))
|
||||
LuaNetVarsMod.Logger.Warning($"Overwriting event callback for {eventName}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Overwriting event callback for {eventName}");
|
||||
|
||||
_registeredEventCallbacks[eventName] = callback;
|
||||
LuaNetVarsMod.Logger.Msg($"Registered event callback for {eventName}");
|
||||
LuaNetworkVariablesMod.Logger.Msg($"Registered event callback for {eventName}");
|
||||
}
|
||||
|
||||
private bool ValidateCallback(DynValue callback)
|
||||
{
|
||||
if (callback?.Function != null) return true;
|
||||
LuaNetVarsMod.Logger.Error("Passed DynValue must be a function");
|
||||
LuaNetworkVariablesMod.Logger.Error("Passed DynValue must be a function");
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ValidateNetworkVar(string varName)
|
||||
{
|
||||
if (_registeredNetworkVars.ContainsKey(varName)) return true;
|
||||
LuaNetVarsMod.Logger.Error($"Attempted to register notify callback for non-registered variable {varName}.");
|
||||
LuaNetworkVariablesMod.Logger.Error($"Attempted to register notify callback for non-registered variable {varName}.");
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using ABI_RC.Systems.ModNetwork;
|
||||
using MoonSharp.Interpreter;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public partial class LuaNetVarController
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ public partial class LuaNetVarController
|
|||
case DataType.Nil:
|
||||
return DynValue.Nil;
|
||||
default:
|
||||
LuaNetVarsMod.Logger.Error($"Unsupported data type received: {dataType}");
|
||||
LuaNetworkVariablesMod.Logger.Error($"Unsupported data type received: {dataType}");
|
||||
return DynValue.Nil;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public partial class LuaNetVarController
|
|||
msg.Write((byte)DataType.Nil);
|
||||
break;
|
||||
default:
|
||||
LuaNetVarsMod.Logger.Error($"Unsupported DynValue type: {value.Type}");
|
||||
LuaNetworkVariablesMod.Logger.Error($"Unsupported DynValue type: {value.Type}");
|
||||
msg.Write((byte)DataType.Nil);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.LuaNetVars;
|
||||
namespace NAK.LuaNetworkVariables;
|
||||
|
||||
public partial class LuaNetVarController
|
||||
{
|
||||
|
@ -13,10 +13,10 @@ public partial class LuaNetVarController
|
|||
// Check if it already exists (this **should** only matter in worlds)
|
||||
if (_hashes.Contains(hash))
|
||||
{
|
||||
LuaNetVarsMod.Logger.Warning($"Duplicate RelativeSyncMarker found at path {path}");
|
||||
LuaNetworkVariablesMod.Logger.Warning($"Duplicate RelativeSyncMarker found at path {path}");
|
||||
if (!FindAvailableHash(ref hash)) // Super lazy fix idfc
|
||||
{
|
||||
LuaNetVarsMod.Logger.Error($"Failed to find available hash for RelativeSyncMarker after 16 tries! {path}");
|
||||
LuaNetworkVariablesMod.Logger.Error($"Failed to find available hash for RelativeSyncMarker after 16 tries! {path}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
using ABI.Scripting.CVRSTL.Common;
|
||||
using HarmonyLib;
|
||||
using MoonSharp.Interpreter;
|
||||
using NAK.LuaNetVars.Modules;
|
||||
using NAK.LuaNetworkVariables.Modules;
|
||||
|
||||
namespace NAK.LuaNetVars.Patches;
|
||||
namespace NAK.LuaNetworkVariables.Patches;
|
||||
|
||||
internal static class LuaScriptFactory_Patches
|
||||
{
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
using NAK.LuaNetVars.Properties;
|
||||
using NAK.LuaNetworkVariables.Properties;
|
||||
using MelonLoader;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.LuaNetVars))]
|
||||
[assembly: AssemblyTitle(nameof(NAK.LuaNetworkVariables))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.LuaNetVars))]
|
||||
[assembly: AssemblyProduct(nameof(NAK.LuaNetworkVariables))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.LuaNetVars.LuaNetVarsMod),
|
||||
nameof(NAK.LuaNetVars),
|
||||
typeof(NAK.LuaNetworkVariables.LuaNetworkVariablesMod),
|
||||
nameof(NAK.LuaNetworkVariables),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidoS/NAK_CVR_Mods/tree/main/LuaNetworkVariables"
|
||||
|
@ -24,9 +24,9 @@ using System.Reflection;
|
|||
[assembly: MelonAuthorColor(255, 158, 21, 32)] // red
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.LuaNetVars.Properties;
|
||||
namespace NAK.LuaNetworkVariables.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.1";
|
||||
public const string Version = "1.0.2";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
|
@ -1,6 +1,77 @@
|
|||
# WhereAmIPointing
|
||||
# LuaNetworkVariables
|
||||
|
||||
Simple mod that makes your controller rays always visible when the menus are open. Useful for when you're trying to aim at something in the distance. Also visualizes which ray is being used for menu interaction.
|
||||
Adds a simple module for creating network variables & events *kinda* similar to Garry's Mod.
|
||||
|
||||
Example Usage:
|
||||
```lua
|
||||
-- Requires UnityEngine and NetworkModule
|
||||
UnityEngine = require("UnityEngine")
|
||||
NetworkModule = require("NetworkModule")
|
||||
|
||||
-- Unity Events --
|
||||
|
||||
function Start()
|
||||
|
||||
if NetworkModule == nil then
|
||||
print("NetworkModule did not load.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Registers "AvatarHeight" as a network variable
|
||||
-- This creates Get and Set functions (GetAvatarHeight() and SetAvatarHeight())
|
||||
NetworkModule:RegisterNetworkVar("AvatarHeight")
|
||||
|
||||
-- Registers a callback for when "AvatarHeight" is changed.
|
||||
NetworkModule:RegisterNotifyCallback("AvatarHeight", function(varName, oldValue, newValue)
|
||||
print(varName .. " changed from " .. tostring(oldValue) .. " to " .. tostring(newValue))
|
||||
end)
|
||||
|
||||
-- Registers "ButtonClickedEvent" as a networked event. This provides context alongside the arguments passed.
|
||||
NetworkModule:RegisterEventCallback("ButtonClickedEvent", function(context, message)
|
||||
print("ButtonClickedEvent triggered by " .. tostring(context.SenderName) .. " with message: " .. tostring(message))
|
||||
print("Context details:")
|
||||
print(" SenderId: " .. tostring(context.SenderId))
|
||||
print(" SenderName: " .. tostring(context.SenderName))
|
||||
print(" LastInvokeTime: " .. tostring(context.LastInvokeTime))
|
||||
print(" TimeSinceLastInvoke: " .. tostring(context.TimeSinceLastInvoke))
|
||||
print(" IsLocal: " .. tostring(context.IsLocal))
|
||||
end)
|
||||
|
||||
-- Secondry example
|
||||
NetworkModule:RegisterEventCallback("CoolEvent", OnCoolEventOccured)
|
||||
end
|
||||
|
||||
function Update()
|
||||
if not NetworkModule:IsSyncOwner() then
|
||||
return
|
||||
end
|
||||
|
||||
SetAvatarHeight(PlayerAPI.LocalPlayer:GetViewPointPosition().y)
|
||||
end
|
||||
|
||||
-- Global Functions --
|
||||
|
||||
function SendClickEvent()
|
||||
NetworkModule:SendLuaEvent("ButtonClickedEvent", "The button was clicked!")
|
||||
print("Sent ButtonClickedEvent")
|
||||
end
|
||||
|
||||
function SendCoolEvent()
|
||||
NetworkModule:SendLuaEvent("CoolEvent", 1, 2)
|
||||
end
|
||||
|
||||
-- Listener Functions --
|
||||
|
||||
function OnCoolEventOccured(context, value, value2)
|
||||
print("CoolEvent triggered by " .. tostring(context.SenderName))
|
||||
print("Received values: " .. tostring(value) .. ", " .. tostring(value2))
|
||||
print("Context details:")
|
||||
print(" SenderId: " .. tostring(context.SenderId))
|
||||
print(" LastInvokeTime: " .. tostring(context.LastInvokeTime))
|
||||
print(" TimeSinceLastInvoke: " .. tostring(context.TimeSinceLastInvoke))
|
||||
print(" IsLocal: " .. tostring(context.IsLocal))
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|------|-------------|----------|
|
||||
| [CVRLuaToolsExtension](.Experimental/CVRLuaToolsExtension/README.md) | Extension mod for [CVRLuaTools](https://github.com/NotAKidoS/CVRLuaTools) Hot Reload functionality. | No Download |
|
||||
| [CustomRichPresence](.Experimental/CustomRichPresence/README.md) | Lets you customize the Steam & Discord rich presence messages & values. | No Download |
|
||||
| [LuaNetworkVariables](.Experimental/LuaNetworkVariables/README.md) | Simple mod that makes your controller rays always visible when the menus are open. Useful for when you're trying to aim at something in the distance. Also visualizes which ray is being used for menu interaction. | No Download |
|
||||
| [LuaNetworkVariables](.Experimental/LuaNetworkVariables/README.md) | Adds a simple module for creating network variables & events *kinda* similar to Garry's Mod. | [Download](https://github.com/NotAKidoS/NAK_CVR_Mods/releases/download/r46/LuaNetworkVariables.dll) |
|
||||
| [LuaTTS](.Experimental/LuaTTS/README.md) | Provides access to the built-in text-to-speech (TTS) functionality to lua scripts. Allows you to make the local player speak. | No Download |
|
||||
| [OriginShift](.Experimental/OriginShift/README.md) | Experimental mod that allows world origin to be shifted to prevent floating point precision issues. | No Download |
|
||||
| [ScriptingSpoofer](.Experimental/ScriptingSpoofer/README.md) | Prevents **local** scripts from accessing your Username or UserID by spoofing them with random values each session. | No Download |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue