diff --git a/GamecraftModdingAPI/Commands/CommandManager.cs b/GamecraftModdingAPI/Commands/CommandManager.cs index 6ff3046..32af704 100644 --- a/GamecraftModdingAPI/Commands/CommandManager.cs +++ b/GamecraftModdingAPI/Commands/CommandManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; namespace GamecraftModdingAPI.Commands @@ -35,9 +36,9 @@ namespace GamecraftModdingAPI.Commands return _customCommands[name]; } - public static Dictionary GetCommands() + public static string[] GetCommandNames() { - return _customCommands; + return _customCommands.Keys.ToArray(); } public static void RemoveCommand(string name) diff --git a/GamecraftModdingAPI/Commands/CommandPatch.cs b/GamecraftModdingAPI/Commands/CommandPatch.cs index bc75df5..5a11de3 100644 --- a/GamecraftModdingAPI/Commands/CommandPatch.cs +++ b/GamecraftModdingAPI/Commands/CommandPatch.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection; + using Harmony; using Svelto.Context; using Svelto.ECS; diff --git a/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs b/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs index 7e48dfc..417dd51 100644 --- a/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs +++ b/GamecraftModdingAPI/Commands/CommandRegistrationHelper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using uREPL; using RobocraftX.CommandLine.Custom; diff --git a/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs b/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs index ce0ba4d..0b1d305 100644 --- a/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs +++ b/GamecraftModdingAPI/Commands/ICustomCommandEngine.cs @@ -3,20 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; +using GamecraftModdingAPI.Utility; + namespace GamecraftModdingAPI.Commands { /// /// Engine interface to handle command operations /// - public interface ICustomCommandEngine : IEngine, IQueryingEntitiesEngine, IDisposable + public interface ICustomCommandEngine :IApiEngine { - /// - /// The name of the command - /// - string Name { get; } - /// /// The command's description, shown in command help messages /// diff --git a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs index 7427f82..e1c7817 100644 --- a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine.cs @@ -1,10 +1,11 @@ -using Svelto.ECS; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Svelto.ECS; + namespace GamecraftModdingAPI.Commands { /// diff --git a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs index 268a808..dd8e43c 100644 --- a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine1.cs @@ -1,10 +1,11 @@ -using Svelto.ECS; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Svelto.ECS; + namespace GamecraftModdingAPI.Commands { /// diff --git a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs index ee872de..e21df26 100644 --- a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine2.cs @@ -1,10 +1,11 @@ -using Svelto.ECS; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Svelto.ECS; + namespace GamecraftModdingAPI.Commands { /// diff --git a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs index b5c24b1..c3bf6a8 100644 --- a/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs +++ b/GamecraftModdingAPI/Commands/SimpleCustomCommandEngine3.cs @@ -1,10 +1,11 @@ -using Svelto.ECS; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Svelto.ECS; + namespace GamecraftModdingAPI.Commands { /// diff --git a/GamecraftModdingAPI/Events/EventEngineFactory.cs b/GamecraftModdingAPI/Events/EventEngineFactory.cs index 4a9edf7..817e64e 100644 --- a/GamecraftModdingAPI/Events/EventEngineFactory.cs +++ b/GamecraftModdingAPI/Events/EventEngineFactory.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; namespace GamecraftModdingAPI.Events diff --git a/GamecraftModdingAPI/Events/EventManager.cs b/GamecraftModdingAPI/Events/EventManager.cs index bcb4e3c..11d012b 100644 --- a/GamecraftModdingAPI/Events/EventManager.cs +++ b/GamecraftModdingAPI/Events/EventManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; namespace GamecraftModdingAPI.Events @@ -39,9 +40,9 @@ namespace GamecraftModdingAPI.Events return _eventHandlers[name]; } - public static Dictionary GetEventHandlers() + public static string[] GetEventHandlerNames() { - return _eventHandlers; + return _eventHandlers.Keys.ToArray(); } public static void RemoveEventHandler(string name) @@ -71,9 +72,9 @@ namespace GamecraftModdingAPI.Events return _eventEmitters[name]; } - public static Dictionary GetEventEmitters() + public static string[] GetEventEmitterNames() { - return _eventEmitters; + return _eventEmitters.Keys.ToArray(); } public static void RemoveEventEmitter(string name) diff --git a/GamecraftModdingAPI/Events/GameActivatedPatch.cs b/GamecraftModdingAPI/Events/GameActivatedPatch.cs index 784e666..b85a6e6 100644 --- a/GamecraftModdingAPI/Events/GameActivatedPatch.cs +++ b/GamecraftModdingAPI/Events/GameActivatedPatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX; using Svelto.ECS; @@ -19,6 +20,8 @@ namespace GamecraftModdingAPI.Events { public static void Postfix(ref EnginesRoot ____mainGameEnginesRoot) { + // register custom game engines + GameEngineManager.RegisterEngines(____mainGameEnginesRoot); // A new EnginesRoot is always created when ActivateGame is called // so all event emitters and handlers must be re-registered. EventManager.RegisterEngines(____mainGameEnginesRoot); diff --git a/GamecraftModdingAPI/Events/GameReloadedPatch.cs b/GamecraftModdingAPI/Events/GameReloadedPatch.cs index d1367bd..7c8cfe3 100644 --- a/GamecraftModdingAPI/Events/GameReloadedPatch.cs +++ b/GamecraftModdingAPI/Events/GameReloadedPatch.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX; -using Svelto.ECS; using GamecraftModdingAPI.Utility; diff --git a/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs b/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs index 6b192e8..04cf065 100644 --- a/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs +++ b/GamecraftModdingAPI/Events/GameSwitchedToPatch.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX; -using Svelto.ECS; using GamecraftModdingAPI.Utility; diff --git a/GamecraftModdingAPI/Events/IEventEmitterEngine.cs b/GamecraftModdingAPI/Events/IEventEmitterEngine.cs index 124a771..ad6ffad 100644 --- a/GamecraftModdingAPI/Events/IEventEmitterEngine.cs +++ b/GamecraftModdingAPI/Events/IEventEmitterEngine.cs @@ -3,20 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; +using GamecraftModdingAPI.Utility; + namespace GamecraftModdingAPI.Events { /// /// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called. /// - public interface IEventEmitterEngine : IEngine, IQueryingEntitiesEngine, IDisposable + public interface IEventEmitterEngine : IApiEngine { - /// - /// The name of the IEventEmitterEngine - /// - string Name { get; } - /// /// The type of event emitted /// diff --git a/GamecraftModdingAPI/Events/IEventHandlerEngine.cs b/GamecraftModdingAPI/Events/IEventHandlerEngine.cs index cfe54d1..7f0aa3f 100644 --- a/GamecraftModdingAPI/Events/IEventHandlerEngine.cs +++ b/GamecraftModdingAPI/Events/IEventHandlerEngine.cs @@ -3,19 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; using Svelto.ECS.Internal; +using GamecraftModdingAPI.Utility; + namespace GamecraftModdingAPI.Events { /// /// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines. /// - public interface IEventHandlerEngine : IEngine, IQueryingEntitiesEngine, IReactOnAddAndRemove, IReactOnAddAndRemove, IDisposable + public interface IEventHandlerEngine : IApiEngine, IReactOnAddAndRemove, IReactOnAddAndRemove { - /// - /// The name of the IEventHandlerEngine - /// - string Name { get; } } } diff --git a/GamecraftModdingAPI/Events/MenuActivatedPatch.cs b/GamecraftModdingAPI/Events/MenuActivatedPatch.cs index a8aeb3d..accc1b1 100644 --- a/GamecraftModdingAPI/Events/MenuActivatedPatch.cs +++ b/GamecraftModdingAPI/Events/MenuActivatedPatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX; using Svelto.ECS; @@ -21,6 +22,8 @@ namespace GamecraftModdingAPI.Events private static bool firstLoad = true; public static void Postfix(ref EnginesRoot ____frontEndEnginesRoot) { + // register custom menu engines + MenuEngineManager.RegisterEngines(____frontEndEnginesRoot); // A new EnginesRoot is always created when ActivateMenu is called // so all event emitters and handlers must be re-registered. EventManager.RegisterEngines(____frontEndEnginesRoot); diff --git a/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs b/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs index 7f19b32..ae26268 100644 --- a/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs +++ b/GamecraftModdingAPI/Events/MenuSwitchedToPatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX; using Svelto.ECS; diff --git a/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs b/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs index e333229..5172d9c 100644 --- a/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs +++ b/GamecraftModdingAPI/Events/ModEventEntityDescriptor.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; namespace GamecraftModdingAPI.Events diff --git a/GamecraftModdingAPI/Events/ModEventEntityStruct.cs b/GamecraftModdingAPI/Events/ModEventEntityStruct.cs index a1dadef..3619e69 100644 --- a/GamecraftModdingAPI/Events/ModEventEntityStruct.cs +++ b/GamecraftModdingAPI/Events/ModEventEntityStruct.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; -using Svelto.ECS.Hybrid; namespace GamecraftModdingAPI.Events { diff --git a/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs b/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs index 152a555..be4f61d 100644 --- a/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs +++ b/GamecraftModdingAPI/Events/SimpleEventEmitterEngine.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; using GamecraftModdingAPI.Utility; diff --git a/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs b/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs index bc9b45a..267a603 100644 --- a/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs +++ b/GamecraftModdingAPI/Events/SimpleEventHandlerEngine.cs @@ -1,10 +1,11 @@ -using Svelto.ECS; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Svelto.ECS; + namespace GamecraftModdingAPI.Events { /// diff --git a/GamecraftModdingAPI/Main.cs b/GamecraftModdingAPI/Main.cs index dded179..dd8bf54 100644 --- a/GamecraftModdingAPI/Main.cs +++ b/GamecraftModdingAPI/Main.cs @@ -3,16 +3,28 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using Harmony; using System.Reflection; + +using Harmony; + using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Events; namespace GamecraftModdingAPI { + /// + /// The main class of the GamecraftModdingAPI. + /// Use this to initialize the API before calling it. + /// static class Main { private static HarmonyInstance harmony; + + /// + /// Initializes the GamecraftModdingAPI. + /// This should be called ASAP after Gamecraft starts up. + /// Ideally, this should be called from your main Plugin class's OnApplicationStart() method. + /// public static void Init() { var currentAssembly = Assembly.GetExecutingAssembly(); @@ -31,6 +43,11 @@ namespace GamecraftModdingAPI Logging.Log($"{currentAssembly.GetName().Name} {currentAssembly.GetName().Version} init & patch complete"); } + /// + /// Shuts down & cleans up the GamecraftModdingAPI. + /// This should be called ASAP before Gamecraft quits. + /// Ideally, this should be called from your main Plugin class's OnApplicationQuit() method. + /// public static void Shutdown() { var currentAssembly = Assembly.GetExecutingAssembly(); diff --git a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs index 84520f4..bea2d9a 100644 --- a/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs +++ b/GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; + using Harmony; using GamecraftModdingAPI.Commands; diff --git a/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs index b8ca08a..984fd2a 100644 --- a/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs +++ b/GamecraftModdingAPI/Utility/ApiExclusiveGroups.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Svelto.ECS; namespace GamecraftModdingAPI.Utility diff --git a/GamecraftModdingAPI/Utility/GameEngineManager.cs b/GamecraftModdingAPI/Utility/GameEngineManager.cs new file mode 100644 index 0000000..f3ba5d3 --- /dev/null +++ b/GamecraftModdingAPI/Utility/GameEngineManager.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Utility +{ + public static class GameEngineManager + { + private static Dictionary _gameEngines = new Dictionary(); + + public static void AddGameEngine(IApiEngine engine) + { + _gameEngines[engine.Name] = engine; + } + + public static bool ExistsGameEngine(string name) + { + return _gameEngines.ContainsKey(name); + } + + public static bool ExistsGameEngine(IApiEngine engine) + { + return ExistsGameEngine(engine.Name); + } + + public static IApiEngine GetGameEngine(string name) + { + return _gameEngines[name]; + } + + public static string[] GetGameEngineNames() + { + return _gameEngines.Keys.ToArray(); + } + + public static void RemoveGameEngine(string name) + { + _gameEngines.Remove(name); + } + + public static void RegisterEngines(EnginesRoot enginesRoot) + { + foreach (var key in _gameEngines.Keys) + { + enginesRoot.AddEngine(_gameEngines[key]); + } + } + } +} diff --git a/GamecraftModdingAPI/Utility/IApiEngine.cs b/GamecraftModdingAPI/Utility/IApiEngine.cs new file mode 100644 index 0000000..0dd3e78 --- /dev/null +++ b/GamecraftModdingAPI/Utility/IApiEngine.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Base engine interface used by all GamecraftModdingAPI engines + /// + public interface IApiEngine : IEngine, IQueryingEntitiesEngine, IDisposable + { + /// + /// The name of the engine + /// + string Name { get; } + } +} diff --git a/GamecraftModdingAPI/Utility/Logging.cs b/GamecraftModdingAPI/Utility/Logging.cs index 7dae150..751136c 100644 --- a/GamecraftModdingAPI/Utility/Logging.cs +++ b/GamecraftModdingAPI/Utility/Logging.cs @@ -145,6 +145,8 @@ namespace GamecraftModdingAPI.Utility Svelto.Console.SystemLog(obj.ToString()); } + // descriptive logging + /// /// Write a descriptive message to Gamecraft's log only when the API is a Debug build /// @@ -167,5 +169,56 @@ namespace GamecraftModdingAPI.Utility var method = (new StackTrace()).GetFrame(1).GetMethod(); Log($"[{DateTime.Now.ToString()}][{method.DeclaringType.Name}.{method.Name}]{obj.ToString()}"); } + + // CLI logging + + /// + /// Write a message to Gamecraft's command line + /// + /// The object to log + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLog(object obj) + { + CommandLog(obj.ToString()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLog(string msg) + { + uREPL.Log.Output(msg); + } + + /// + /// Write an error message to Gamecraft's command line + /// + /// The object to log + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLogError(object obj) + { + CommandLogError(obj.ToString()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLogError(string msg) + { + uREPL.Log.Error(msg); + } + + /// + /// Write a warning message to Gamecraft's command line + /// + /// The object to log + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLogWarning(object obj) + { + CommandLogWarning(obj.ToString()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CommandLogWarning(string msg) + { + uREPL.Log.Warn(msg); + } + } } diff --git a/GamecraftModdingAPI/Utility/MenuEngineManager.cs b/GamecraftModdingAPI/Utility/MenuEngineManager.cs new file mode 100644 index 0000000..d5c7458 --- /dev/null +++ b/GamecraftModdingAPI/Utility/MenuEngineManager.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Svelto.ECS; + +namespace GamecraftModdingAPI.Utility +{ + /// + /// Keeps track of custom menu-modifying engines + /// + public static class MenuEngineManager + { + private static Dictionary _menuEngines = new Dictionary(); + + // menu engine management + public static void AddMenuEngine(IApiEngine engine) + { + _menuEngines[engine.Name] = engine; + } + + public static bool ExistsMenuEngine(string name) + { + return _menuEngines.ContainsKey(name); + } + + public static bool ExistsMenuEngine(IApiEngine engine) + { + return ExistsMenuEngine(engine.Name); + } + + public static IApiEngine GetMenuEngine(string name) + { + return _menuEngines[name]; + } + + public static string[] GetMenuEngineNames() + { + return _menuEngines.Keys.ToArray(); + } + + public static void RemoveMenuEngine(string name) + { + _menuEngines.Remove(name); + } + + public static void RegisterEngines(EnginesRoot enginesRoot) + { + foreach (var key in _menuEngines.Keys) + { + enginesRoot.AddEngine(_menuEngines[key]); + } + } + } +} diff --git a/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs b/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs index 1136342..739c232 100644 --- a/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs +++ b/GamecraftModdingAPI/Utility/MinimumSpecsCheckPatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX.FrontEnd; diff --git a/GamecraftModdingAPI/Utility/SteamInitPatch.cs b/GamecraftModdingAPI/Utility/SteamInitPatch.cs index 7215ad2..c57b4e8 100644 --- a/GamecraftModdingAPI/Utility/SteamInitPatch.cs +++ b/GamecraftModdingAPI/Utility/SteamInitPatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; + using Harmony; using RobocraftX.Common; diff --git a/README.md b/README.md index 3fee7c6..4a5b483 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,16 @@ # GamecraftModdingAPI -Gamecraft modding API for a stable interface between Gamecraft and mods +Unofficial Gamecraft modding API for interfacing Gamecraft from mods. + +The GamecraftModdingAPI aims to simplify the mods in two ways: +- *Ease-of-Use* The API provides many easy methods to call to do common tasks such as moving blocks and adding commands. +All of the Harmony patchings are done for you, so you can focus on writing your mod instead of reading swathes of undocumented code. +- *Stability* The API aims to be reliable and consistent between versions. +This means your code won't break when the GamecraftModdingAPI or Gamecraft updates. + +For more info & support, please join the ExMods Discord: https://discord.gg/xjnFxQV + +# Disclaimer +This API is an unofficial modification of Gamecraft software, and is not endorsed or supported by FreeJam or Gamecraft. +The GamecraftModdingAPI developer(s) claim no rights on the Gamecraft code referenced within this project. -For more information, join the ExMods Discord: https://discord.gg/xjnFxQV \ No newline at end of file