Just a simple library for Black_Moss. :)
- Overview
- Installation
- Quick Start
- Localization System
- Command System
- Language Generator
- Tools Reference
- Constants Reference
- UI Toolkit (WIP)
Moss Lib is a BepInEx plugin library for Casualties Unknown (and its demo), providing a set of reusable base classes and utility tools to simplify mod development. It includes:
| Module | Description |
|---|---|
ModLocaleBase |
Multi-language localization system with JSON-based language files |
ModCommandBase |
Base class for registering custom in-game console commands |
ModLangGenBase |
Language file generator that produces JSON locale files from code |
Log |
Advanced in-game console logging utilities |
GameConsole |
Wrapper to execute game console commands programmatically |
World |
World manipulation: place blocks, items, and background tiles |
Player |
Player manipulation: teleport, alerts, inventory management |
Key |
Input handling: key binding checks, mouse click waiting, world-space coordinates |
Multiplayer |
Multiplayer support with reflection-based KrokoshaCasualtiesMP integration |
Config |
BepInEx configuration entry toggling helpers |
RichText |
Unity rich text formatting: color, alpha, bold, italic, size |
Tools |
Argument validation, float/int parsing utilities |
Blocks |
Strongly-typed block definitions with properties |
Items |
Strongly-typed item definitions with properties |
Backgrounds |
Background ID string constants |
Keys |
Strongly-typed key action constants |
- Install BepInEx 5.x for Casualties Unknown.
- Download the latest
MossLib.dllfrom the Releases page (or Nexus Mods). - Place
MossLib.dllinto yourBepInEx/plugins/folder. - (Optional) For multiplayer features, install KrokoshaCasualtiesMP as a soft dependency.
For mod developers: Add a reference to
MossLib.dllin your project, and addBepInDependency("blackmoss.mosslib")to your plugin class.
[BepInPlugin(Guid, Name, Version)]
[BepInDependency("blackmoss.mosslib")] // Add this line
public class MyPlugin : BaseUnityPlugin
{
// ...
}// Create a locale class (singleton wrapper)
public class MyLocale : ModLocaleBase
{
private static MyLocale _instance;
public static void Initialize(ManualLogSource logger)
{
_instance = new MyLocale();
_instance.Initialize(logger, Assembly.GetExecutingAssembly());
}
public static string Get(string key) => _instance?.GetString(key) ?? $"[{key}]";
public static string GetFormat(string key, params object[] args) => _instance?.GetStringFormatted(key, args) ?? $"[{key}]";
}[HarmonyPatch(typeof(ConsoleScript))]
public class MyCommand : ModCommandBase
{
[HarmonyPatch("RegisterAllCommands")]
[HarmonyPostfix]
public static void RegisterCustomCommands(ConsoleScript __instance)
{
ConsoleScript.Commands.Add(new Command(
"mycommand",
"Description of my command",
_ => Log.Info("Command executed!", Plugin.Logger),
null
));
}
}The localization system loads JSON language files from the Lang/ folder inside your plugin directory.
BepInEx/plugins/YourPlugin/
├── Lang/
│ ├── EN.json # English (fallback)
│ ├── zh-CN.json # Simplified Chinese
│ └── zh-TW.json # Traditional Chinese
└── YourPlugin.dll
Language files use nested JSON keys with dot notation for organization:
{
"welcome": "Welcome!",
"command": {
"mycommand": {
"description": "My custom command",
"text": "Hello {0}!"
}
},
"tool": {
"player": {
"bodynull": "Player body is null"
}
}
}| Method | Description |
|---|---|
GetString(key) |
Get localized string by key; falls back to English, then returns [key] |
GetStringFormatted(key, args...) |
Get localized string and apply string.Format() with arguments |
GetStringArray(key) |
Get a localized string array (JSON array) |
GetStringDictionary(key) |
Get a localized dictionary (JSON object) |
HasKey(key) |
Check if a translation key exists |
See Example/ModLocale.cs for a complete singleton implementation.
// Initialize in plugin Awake()
MyLocale.Initialize(Logger);
// Usage
string welcome = MyLocale.Get("welcome"); // "Welcome!"
string message = MyLocale.GetFormat("command.mycommand.text", "World"); // "Hello World!"The command system allows you to register custom console commands via Harmony patching.
Base Class: ModCommandBase
| Member | Description |
|---|---|
Initialize(logger, assembly, harmony?) |
Initialize with logger and plugin assembly; optionally provide Harmony instance |
LogToConsole(text) |
Log text to the in-game console |
ApplicationLogCallback(condition, stackTrace, type) |
Callback for Unity log messages with color-coded console output |
Logger |
Protected ManualLogSource property for subclasses |
[HarmonyPatch(typeof(ConsoleScript))]
public class MyCommand : ModCommandBase
{
[HarmonyPatch("RegisterAllCommands")]
[HarmonyPostfix]
public static void RegisterCustomCommands(ConsoleScript __instance)
{
ConsoleScript.Commands.Add(new Command(
"hello",
"Says hello",
args => {
string name = args.Length > 1 ? args[1] : "World";
LogToConsole($"Hello, {name}!");
},
null
));
}
}See Example/ModCommand.cs for a complete example.
The language generator auto-creates JSON language files from C# code, eliminating the need to manually write and maintain locale JSON files.
Base Class: ModLangGenBase
| Member | Description |
|---|---|
LanguageCode |
Abstract property; return the language code (e.g., "EN", "zh-CN") |
BuildLocaleData() |
Abstract method; call Add() to register translations |
Add(key, value) |
Add a translation entry |
Generate(outputDirectory?) |
Generate the JSON file; merges with existing files (doesn't overwrite existing entries) |
Count |
Number of registered translation entries |
public class EnLangGenerator : ModLangGenBase
{
protected override string LanguageCode => "EN";
protected override void BuildLocaleData()
{
Add("welcome", "Welcome!");
Add("command.hello.description", "Says hello");
Add("command.hello.text", "Hello, {0}!");
}
}Use LocaleGenerator to register and generate all language files:
| Method | Description |
|---|---|
SetLogger(logger) |
Set the logger |
Register(generator, logger) |
Register a language generator |
GenerateAll(outputDirectory?) |
Generate all registered language files |
GenerateSingle(languageCode, outputDirectory?) |
Generate a single language file |
PrintInfo() |
Print info about all registered generators |
// In plugin Awake()
LocaleGenerator.SetLogger(Logger);
LocaleGenerator.Register(new EnLangGenerator(), Logger);
LocaleGenerator.Register(new ZhCnLangGenerator(), Logger);
LocaleGenerator.GenerateAll(); // Creates EN.json, zh-CN.json in Lang/ folderNote: The generator merges with existing JSON files — it only adds new entries, preserving any user modifications to existing translations.
Log — Enhanced in-game console logging with BepInEx integration.
| Method | Description |
|---|---|
LogToConsole(text) |
Write a message to the in-game console with timestamp |
Info(text, logger) |
Log to both in-game console and BepInEx log |
Debug(text, logger) |
Log debug message with [DEBUG] prefix |
Error(text, logger) |
Log error message with [ERROR] prefix |
Warning(text, logger) |
Log warning message with [WARNING] prefix |
Alert(text, logger, important, delay?) |
Log and show a player alert (screen notification) |
NewLine() |
Insert a blank line in the console |
Divider(char?, length?) |
Insert a divider line |
GameConsole — Execute game console commands programmatically.
// Execute any in-game console command
GameConsole.RunCommand("some_command arg1 arg2");World — World manipulation tools.
| Method | Description |
|---|---|
PlaceBlock(x, y, block) |
Place a block at tile coordinates |
PlaceBlock(vector2, block) |
Place a block at a Vector2 position |
PlaceItem(x, y, item) |
Spawn an item at tile coordinates |
PlaceItem(vector2, item) |
Spawn an item at a Vector2 position |
PlaceBackground(pos, backgroundId) |
Place a background tile (accepts Vector2) |
PlaceBackground(pos, backgroundId) |
Place a background tile (accepts Vector2Int) |
CreateTileMesh(pos) |
Create a tiled mesh for background rendering |
CheckForWorld() |
Throw if no world is loaded |
ClearCache() |
Clear sprite/mesh/material caches |
Player — Player manipulation tools.
| Method | Description |
|---|---|
Alert(text, important) |
Show a screen alert to the player |
Alert(text, important, delay) |
Show a delayed screen alert |
Tp(vector2) |
Teleport the player (works in singleplayer and multiplayer) |
Tp(x, y) |
Teleport to float coordinates |
PickItem(item, slot, force?) |
Give an item to a specific inventory slot |
// Examples
Player.Alert("Watch out!", true); // Important alert
Player.Tp(100.5f, 200.3f); // Teleport
Player.PickItem("rifle", 0, true); // Give rifle to slot 0Key — Input handling utilities.
| Method | Description |
|---|---|
HasKey(action) |
Check if a key binding action name exists |
IsKey(action) |
Check if a key is currently held down |
IsKeyDown(action) |
Check if a key was pressed this frame |
IsKeyUp(action) |
Check if a key was released this frame |
MouseWorldPosition() |
Get the mouse position in world coordinates |
LeftClickPosition() |
Get left click world position (only valid on click frame) |
RightClickPosition() |
Get right click world position (only valid on click frame) |
Coroutine-based waiting methods — These wait until the player clicks, then return the world position:
| Method | Description |
|---|---|
WaitForLeftClick(Action<Vector2>) |
Coroutine: wait for left click, invoke callback with position |
WaitForRightClick(Action<Vector2>) |
Coroutine: wait for right click, invoke callback with position |
WaitForLeftClick() |
Coroutine: wait for left click, returns WaitForClickResult |
WaitForRightClick() |
Coroutine: wait for right click, returns WaitForClickResult |
WaitForClickResult — Inherits from
CustomYieldInstruction,
supports yield return waiting; use .Result to get the click position in world coordinates after waiting completes.
Key action constants are defined in Key.InputAction:
| Constant | Value | Description |
|---|---|---|
InputAction.LeftClick |
"attack" |
Left mouse click action |
InputAction.RightClick |
"iteminteract" |
Right mouse click action |
// Check if left click is pressed this frame
if (Key.IsKeyDown(Key.InputAction.LeftClick))
{
Vector2 pos = Key.MouseWorldPosition();
// Do something...
}
// ── Coroutine: wait for player to click ──
IEnumerator MyCoroutine()
{
// Pattern 1: Callback-based
yield return Key.WaitForLeftClick(pos => {
Player.Tp(pos);
});
// Pattern 2: Result-based (cleaner)
var waiter = Key.WaitForRightClick();
yield return waiter;
Player.Tp(waiter.Result);
}For a full list of key action names, see Constant/Keys.
Multiplayer — Multiplayer integration via KrokoshaCasualtiesMP.
| Member | Description |
|---|---|
IsNetworkRunning |
Check if the multiplayer network is active |
IsClient |
Check if this instance is a client |
Tp(vector2) |
Teleport local player in multiplayer |
Tp(x, y) |
Teleport to float coordinates |
Tp(playerName, vector2) |
Teleport a specific player (use "@a" for all players) |
Tp(playerName, x, y) |
Teleport a player to float coordinates |
GetPlayerName(player) |
Get the name of a player object |
// Teleport all players to a location
if (Multiplayer.IsNetworkRunning)
{
Multiplayer.Tp("@a", new Vector2(50f, 100f));
}Config — BepInEx configuration helpers.
| Method | Description |
|---|---|
ChangeConfig(entry, value) |
Set a config entry value and save |
SwitchType(configEntry, configName) |
Toggle a boolean config entry |
SwitchType(configEntry, configName, logger, important) |
Toggle with optional player alert |
// Toggle a config value
ConfigEntry<bool> mySetting = Config.Bind("General", "MySetting", true, "Description");
Config.SwitchType(mySetting, "My Setting");RichText — Unity rich text formatting utilities for in-game console messages.
| Method | Description |
|---|---|
Color(text, color) |
Wrap text in <color> tag by name |
Color(text, color) |
Wrap text in <color> tag by Unity Color |
Hex(text, hex) |
Wrap text in <color> tag by hex value |
Alpha(text, alphaHex) |
Set text alpha by hex value |
Alpha(text, alpha) |
Set text alpha by float (0–1) |
Alpha(text, alpha) |
Set text alpha by byte (0–255) |
Alpha(text, alpha) |
Set text alpha by int (0–255) |
Bold(text) |
Wrap text in <b> tag |
Italic(text) |
Wrap text in <i> tag |
Size(text, size) |
Wrap text in <size> tag |
Shorthand color methods:
| Method | Color |
|---|---|
Blue(text) |
blue |
Red(text) |
red |
Green(text) |
green |
Yellow(text) |
yellow |
White(text) |
white |
Black(text) |
black |
Cyan(text) |
cyan |
Magenta(text) |
magenta |
Gray(text) |
gray |
Orange(text) |
orange |
Purple(text) |
purple |
Pink(text) |
pink |
Brown(text) |
brown |
// Format colorful console messages
string msg = RichText.Color("Warning: ", "red") + RichText.Bold("Low health!");
Log.Info(msg, Plugin.Logger);
// With hex color
string fancy = RichText.Hex("Hello", "#FF8800") + " " + RichText.Italic("World");Tools — Utility methods for argument parsing and validation.
| Method | Description |
|---|---|
CheckArgumentCount(args, desired) |
Ensure args array has at least desired + 1 elements |
ParseFloat(s) |
Parse a float with invariant culture; throws on failure |
ParseInt(s) |
Parse an int with invariant culture; throws on failure |
TryParseFloat(s, out result) |
Try-parse a float without exception |
// In a command handler
Tools.CheckArgumentCount(args, 2); // Requires at least 2 args
float x = Tools.ParseFloat(args[1]); // Parse float argument
int count = Tools.ParseInt(args[2]); // Parse int argumentThe Constant/ namespace provides strongly-typed constants for game objects, making it easier and safer to
reference blocks, items, backgrounds, and key bindings without memorizing string IDs.
Blocks — Strongly-typed block definitions. Implicitly convertible to ushort.
| Property | Type | Description |
|---|---|---|
Id |
ushort |
Block ID |
LocaleKey |
string |
Localization key |
Health |
float |
Block hit points |
HitSound |
string |
Sound played when hit |
StepSound |
string |
Sound played when walking on it |
SleepQuality |
string |
Sleep quality rating |
IsMetallic |
bool |
Whether the block is metallic |
NoVariation |
bool |
Whether the block has no visual variation |
Toxicity |
float |
Toxicity level |
IsSlippery |
bool |
Whether the block is slippery |
Use Blocks.FromId(ushort) to resolve a block ID to its constant.
// Place blocks using strongly-typed constants
World.PlaceBlock(10, 20, Blocks.Granite);
World.PlaceBlock(new Vector2(15, 25), Blocks.SteelTile);
// Implicit conversion to ushort
ushort blockId = Blocks.Copper; // 34Items — Strongly-typed item definitions. Implicitly convertible to string.
| Property | Type | Description |
|---|---|---|
Id |
string |
Item ID |
Category |
string |
Item category (food, medical, tool, etc.) |
Weight |
float |
Item weight |
Value |
int |
Item value |
Rec |
int |
Item rarity/recipe tier |
Use Items.FromId(string) to resolve an item ID to its constant.
// Give items using strongly-typed constants
Player.PickItem(Items.Rifle, 0, true);
Player.PickItem(Items.Bandage, 1);
// Implicit conversion to string
string itemId = Items.Rifle; // "rifle"Backgrounds — String constants for background tile IDs.
| Constant | Value |
|---|---|
Backgrounds.Fungal |
"fungalBackground" |
Backgrounds.Grass |
"grassBackground" |
Backgrounds.Ice |
"iceBackground" |
Backgrounds.Rock |
"rockBackground" |
Backgrounds.Sand |
"sandBackground" |
Backgrounds.Soil |
"soilBackground" |
Backgrounds.Steel |
"steelBackground" |
Backgrounds.Vents |
"ventsBackground" |
Backgrounds.Wasteland |
"wastelandBackground" |
// Place backgrounds using constants
World.PlaceBackground(new Vector2Int(10, 20), Backgrounds.Grass);
World.PlaceBackground(new Vector2(15f, 25f), Backgrounds.Sand);Keys — Strongly-typed key action constants. Implicitly convertible to string.
| Constant | Action Name |
|---|---|
Keys.Jump |
"jump" |
Keys.Up |
"up" |
Keys.Left |
"left" |
Keys.Right |
"right" |
Keys.Down |
"down" |
Keys.Attack |
"attack" |
Keys.ItemInteract |
"iteminteract" |
Keys.Throw |
"throw" |
Keys.ToggleInventory |
"toggleinventory" |
Keys.Pause |
"pause" |
Keys.Console |
"console" |
Keys.Craft |
"craft" |
Use Keys.FromAction(string) to resolve an action name to its constant.
// Check key bindings using constants
if (Key.IsKeyDown(Keys.Attack))
{
// Player attacked
}
// Implicit conversion to string
string action = Keys.Jump; // "jump"The Tool/UI/ directory contains in-development UI creation utilities for building in-game mod interfaces.
Currently commented out and under active development.
| File | Description |
|---|---|
UILayout |
Canvas management, panel creation, RectTransform helpers |
UIWidgets |
Button and text creation with game-style styling and localization support |
These will be enabled in a future release.
MossLib/
├── Plugin.cs # Main plugin entry point
├── Base/
│ ├── ModCommandBase.cs # Command registration base class
│ ├── ModLangGenBase.cs # Language generator base class
│ └── ModLocaleBase.cs # Localization base class
├── Constant/
│ ├── Backgrounds.cs # Background ID constants
│ ├── Blocks.cs # Strongly-typed block definitions
│ ├── Items.cs # Strongly-typed item definitions
│ └── Keys.cs # Key action name constants
├── Example/
│ ├── ModCommand.cs # Example command implementation
│ ├── ModLocale.cs # Example locale implementation
│ └── Lang/
│ ├── EnLangGenerator.cs # English language generator
│ ├── ZhCnLangGenerator.cs # Simplified Chinese generator
│ └── ZhTwLangGenerator.cs # Traditional Chinese generator
└── Tool/
├── Config.cs # Config toggling utilities
├── Console.cs # Game console wrapper
├── Key.cs # Input handling (key binds, mouse click waiting)
├── LocaleGenerator.cs # Language file generator manager
├── Log.cs # Console logging utilities
├── Multiplayer.cs # Multiplayer integration
├── Player.cs # Player manipulation tools
├── RichText.cs # Rich text formatting utilities
├── Tools.cs # Argument/parsing utilities
├── World.cs # World manipulation tools
└── UI/ # UI Toolkit (WIP, commented out)
├── UILayout.cs # Canvas and panel creation
└── UIWidgets.cs # Button and text creation
