This framework mod provides custom command support for the game console, enhancing functionality and allowing for easy integration of custom commands.
✨ Features:
✅ Unlock: Unlocks the console once at game start — no more manual enabling.
🔑Change key: Set your own key to toggle the in-game console, replacing the default binding.
🎮Bind commands: Set binds for commands and have them stay saved between game sessions — no need to rebind every launch.
🚫 Duplicate Command List: Stops the command list from being recreated every time you reload a save — unlike the default behavior.
🔑 How to change console key in-game:
Console Key: Type consolekey [f2] and press “Enter”.
(Replace [f2] with the value you want to use. For example, you would type: consolekey f2)
🎮 How to bind commands:
Command Binding: Type bind [L] [command] and press “Enter”.
(Replace [L] with the key you want to use. Replace [command] with the value you want to use. For example, you would type: bind L changecash 500)
❌ How to remove bind commands:
Command Unbinding: Type unbind [L] and press “Enter”.
(Replace [L] with the key you want to use. For example, you would type: unbind L)
Example mods using this framework:
Character Customizer
Phone Wallpaper
Night Shift
Enhanced Suppliers
Custom Commands Pack
Help:❓
If for any reason bindings are messed up delete the following files from:
C:\Program Files (x86)\Steam\steamapps\common\Schedule I\UserData
CustomCommandFrameworkBinds.json
CustomCommandsFramework.cfg
Download:
MelonLoader
Custom Commands Framework
Extract to:
C:\Program Files (x86)\Steam\steamapps\common\Schedule I\Mods
For Developers:
Important: You must add reference to CustomCommandsFramework.dll in your mod. Do not bundle this DLL in your mod. Instead, list it as a required mod.
For ease of use, new users should opt for the [CustomCommand] attribute. Manual registration still works but is mostly for legacy purposes.
Methods ():
// Adds a custom command hint to the game console UI window.
Command.Registry.AddCustomCommandHint(string commandName, string CommandExample = null, string CommandDescription = null, bool log = false)
// Adds a custom command to the game console.
CommandRegistry.AddCustomCommand(string commandName, Action action, bool log = false)
// Displays a custom notification on right of the screen only if in game. Duration = 0f means infinite or on enter press
CustomNotification.ShowNotification(string message, float delay = 0f, duration = 5f);
// Displays a custom text notification on left of the screen only if in game. Duration = 0f means instant close
CustomNotification.ShowTextNotification(string header, string message, Sprite sprite = null, float delay = 0f, float duration = 5f, bool sound = true)
Below is an example main class:
using System;
using System.IO;
using CustomCommandsFramework; // REQUIRED IF NOT USING ATTRIBUTE
using MelonLoader;
using MelonLoader.Utils;
[assembly: MelonInfo(typeof(QuitGameCommand.QuitGameCommand), “Quit Game Command”, “1.0.0”, “Cubandsweety”)]
[assembly: MelonGame(“TVGS”, “Schedule I”)]
namespace QuitGameCommand
{
internal class QuitGameCommand : MelonMod
{
// Called when the mod is initialized
public override void OnInitializeMelon()
{
// Optional don’t use if using [CustomCommand] — only use one method to prevent warnings.
CheckAndRegisterCommands();
}
// Method to check for the DLL and register the custom commands
private static void CheckAndRegisterCommands()
{
try
{
// Add custom command hint (optional, for help)
CommandRegistry.AddCustomCommandHint(“quit”, “quit false”, “Quits and saves (Default is true) the game.”);
// Register the command with its handler
CommandRegistry.AddCustomCommand(“quit”, Command.SaveCommand);
}
catch (Exception ex)
{
MelonLogger.Error($”Failed to register console commands: {ex}”);
}
}
}
}
Below is an example command class:
using System;
using System.Collections;
using CustomCommandsFramework; // REQUIRED FOR ATTRIBUTE
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Persistence;
using MelonLoader;
using UnityEngine;
namespace QuitGameCommand
{
internal static class Command
{
// The main command logic for the ‘quit’ command
// Uncomment below line and disable CheckAndRegisterCommands(); as it is no longer required if using attribute
//[CustomCommand(“quit”, “quit false”, “Quits and saves (Default is true) the game.”)]
internal static void SaveCommand(string args)
{
bool shouldSave = false;
var parts = args.Split(‘ ‘);
// Easy
//if (args == “quit”)
//{
//Application.Quit();
//}
// Advanced If no argument or the argument is ‘true’, the game will save
if (parts.Length == 1 || (parts.Length == 2 && parts[1].Equals(“true”, StringComparison.OrdinalIgnoreCase)))
{
shouldSave = true;
}
// Retrieve the SaveManager instance
var instance = Singleton.Instance;
if (!instance)
{
Logs.LogWarning(“Failed to find SaveManager instance.”);
return;
}
// Call the success method to save and quit
SuccessMethod(instance, shouldSave);
}
// Logic to handle saving and quitting
private static void SuccessMethod(SaveManager instance, bool shouldSave)
{
// Save if ‘shouldSave’ is true
if (shouldSave)
{
instance.Save();
}
// Quit the game
Application.Quit();
}
}
}
Cubandsweety