You are viewing a potentially older version of this package. View all versions.
CeruleanCutlass-ForgeKit-0.4.2 icon

ForgeKit

Dependency-free dev-tooling for Outward BepInEx mods: file-driven dev command loop, self-test harness, on-screen toasts, player-ready lifecycle wait, embedded/override table loaders, and a shared dev-verb pack (movement/combat/skill/status probes).

Date uploaded 2 days ago
Version 0.4.2
Download link CeruleanCutlass-ForgeKit-0.4.2.zip
Downloads 51
Dependency string CeruleanCutlass-ForgeKit-0.4.2

This mod requires the following mods to function

BepInEx-BepInExPack_Outward-5.4.19 icon
BepInEx-BepInExPack_Outward

BepInEx pack for Outward.

Preferred version: 5.4.19

README

ForgeKit

📖 Full documentation: ForgeKit wiki page

Dependency-free dev-tooling library for people writing BepInEx 5 mods for Outward: Definitive Edition. It doesn't add anything a player sees on its own — it's the plumbing several other mods (CompanionKit, SpawnKit, and more) build on, and other modders are welcome to build on it too.

Requires: BepInEx 5 (Outward's Mono branch — see Compatibility below). No SideLoader, no Harmony, no other mod dependency.

What's in it

Piece What it gives you
CommandChannel + CommandRegistry A file-driven dev command loop: write a verb into BepInEx/config/<yourmod>_cmd.txt, it runs on the next poll (unscaled time, so it still fires while the game is paused). Unknown verb or help lists everything registered. It runs on unscaled time, so it still fires while the game is paused.
SelfTestHarness The [SELFTEST] BEGIN / PASS: / FAIL: / SKIP: / DONE pass= fail= skip= report shape — wire up Check(name, condition) / CheckIf(canRun, …) calls and get one consistent, greppable self-test report (skips are unrunnable-here, not failures).
Notify An on-screen info toast for the player, mirrored to the log.
Lifecycle WhenPlayerReady — a coroutine that waits past the game's void/staging coordinates before your mod starts touching the player, plus IsSanePosition for the same check inline.
TableLoader<T> / EmbeddedRes Embedded-default-plus-config-override text/texture tables: ship a sane default inside your DLL, let players override it by dropping a file in BepInEx/config/.
CommonVerbs The shared dev-verb pack — one CommonVerbs.RegisterAll(registry, Log, opts) call and ~36 verbs answer on your channel. See the table below.
ScriptRunner script / scriptcancel / scriptstatus — run a file of verbs as a sequence. Auto-registered into every channel.
Keybinds The cross-mod keybind registry. A mod cannot see another mod's config, so this is the only place a key collision is knowable — Claim your keys at boot and a clash gets reported instead of firing both mods.
IdPool The generated id constants for this workspace's allocated range (see docs/id-pool.md). Never type a numeric id.
Suggest / StatusApplyGate Nearest-match hints for a mistyped verb / a guard around status-effect application.

The shared verb pack (CommonVerbs)

CommonVerbs.RegisterAll(registry, Log, opts) in your RegisterVerbs gives your mod's own <Mod>_cmd.txt this set — no new channel, no relay change, and registries are per-mod so there's no collision (CommandRegistry warns on a twice-registered verb). opts excludes any your mod supersedes.

Domain Verbs
Give give · drop · useitem · givewater · equip · unequip · givemoney
Stage teleport · goto · moveto · face · pos · settime
Player sethp · combatclear · killnearest · swing · lockon · lockoff
Skills learnskill · unlearnskill · resetcooldowns · castspell
Status grantstatus · removestatus · statusdump
Diag scenedump · skydump · groundprobe · combatmgrdump · keybinds · ragdolldump · psdump · containerdump · containerroll · reloadcfg

Log tags are a byte-stable grep contract — don't rename them.

Installing (for players)

Drop the ForgeKit folder into BepInEx/plugins/. It has no effect by itself — install it because another mod you're using declares it as a dependency.

Using it (for modders)

<!-- your .csproj -->
<ProjectReference Include="path\to\ForgeKit\ForgeKit.csproj" Private="false" />
[BepInPlugin(GUID, NAME, VERSION)]
[BepInDependency(ForgeKit.Plugin.GUID)]
public class Plugin : BaseUnityPlugin
{
    private CommandRegistry _commands;
    private CommandChannel _channel;

    void Awake()
    {
        _commands = new CommandRegistry(Logger);
        _commands.Register("hello", "hello — logs a greeting.", args => Logger.LogMessage("Hi!"));
        _channel = new CommandChannel("YourMod_cmd.txt", Logger, _commands);
    }

    void Update() => _channel.Tick();
}

Private="false" matters — it stops MSBuild from copying a second ForgeKit.dll into your mod's own output folder. The kit ships from its own BepInEx/plugins/ForgeKit/ folder; your mod just references it and declares the dependency so BepInEx loads it first.

Configuration

ForgeKit has no configuration file of its own — it provides the command channel and config-table helpers that consuming mods use. The dev command loop reads a per-consumer file at BepInEx/config/<Mod>_cmd.txt (e.g. BepInEx/config/YourMod_cmd.txt), and TableLoader<T> lets a consumer ship an embedded default table overridable by a file the player drops in BepInEx/config/. Any settings live in the consuming mod's own cobalt.<name>.cfg, not here.

Compatibility

Outward must be on its Mono Steam beta branch, not the default IL2CPP build — like every BepInEx 5 mod for this game. If your game runs but no BepInEx mods load and there's no crash log, this is almost always why (Properties → Betas → select mono in Steam).

License

Apache License 2.0 — see LICENSE in the repository root. You may use, modify, and redistribute this kit (including in commercial mods) provided you keep the copyright/license notice; see the license text for the full terms.

CHANGELOG

ForgeKit changelog

0.4.2 — 2026-08-11

  • ForgeKit agent test-automation verbs: screenshot pipeline + removeitem
  • Merge branch 'main' into fix/sa-0808-kits
  • Static-analysis 2026-08-08 wave D-kits: P2-13/P2-15 + the kit P3 group
  • Static-analysis 2026-08-08 wave E: close the test-debt list (§4)
  • Static-analysis 2026-08-08 wave 0: nine P1/P2 fixes
  • Fix BUG-RAGDOLLJOINTLOSS: the rig re-init pass ate healthy ragdoll joints
  • Review fixes for lane B: drop the dead destroy companions, close the destroy-wanted ghost window, honest wording
  • Fix BUG-CHOWNOTCONSUMED family: authoritative guest consumption via ForgeKit.Inventories.ConsumeOne
  • invdump: read the player's inventory, and answer "how many X" with a number
  • loadsave: a session can now start its own world (live-verified)
  • W4: fixes for everything D1 found, plus the join-race P1
  • Log levels: a per-mod [Diag] LogLevel, gating at the source
  • Stuck-in-combat hardening: wedge-proof the vanilla hostility checker
  • ForgeKit: fake-null sweep in GiveVerbs equip/unequip (UNT0008)

Unreleased

  • New (built, NOT live-verified): screenshot [supersize 1-4] [label] CommonVerbs verb (EngineDiag domain, [SHOT] tag, works at the main menu) — captures the frame to BepInEx/screenshots/ and prints [SHOT] saved <path> <bytes> bytes once the file is size-stable, so a driving agent can retrieve and Read the PNG for visual analysis (scripts/game-shot.sh is the dispatch+retrieval wrapper). Pure grammar in DevShot (unit-tested).

  • New (built, NOT live-verified): removeitem [qty 1-999|all] <name-or-ItemID> CommonVerbs verb (Items domain, [REMOVE] tag) — the reverse of give, built on Inventories.ConsumeOne so guest-side destruction rides vanilla's compensation. Refuses ambiguous name matches, reports observed TOTAL QTY before -> after, never touches equipped gear. Pure grammar + stack allocation in DevRemove (unit-tested).

  • New (built, NOT live-verified): Inventories.ConsumeOne — authoritative item consumption on any Photon role. A bare Item.RemoveQuantity is a no-op for the last unit on a co-op guest (item destruction is master-gated in vanilla), which let guests feed/tame/bandage for free in consumer mods. The helper mirrors vanilla's own compensation (CharacterInventory.RemoveItem: destroy RPC to the master + local hide) and returns read-back facts (before/after/shortfall/ destroy-requested) so callers log from observation, not intent. With it, Inventories.All/AllByContainer now skip destroy-wanted items (the vanilla ItemContainer.ItemStackCount precedent), so a guest's just-spent item is no longer enumerable — or counted by invdump — during the destroy round-trip window.

0.4.1 — 2026-08-02

  • Cleanup: collapse three repeated verb preambles into helpers that already had a home
  • ForgeKit/SkillKit/StoryKit: fix five guards that could never fire, and stop the recovery verb lying
  • ForgeKit: one numeric-token parser for every dev verb, and it refuses NaN
  • Docs sweep: archive, condense, and validate the whole documentation tree

0.4.0 — 2026-07-30

  • Cap all-status build-up resistance below the engine's refusal sentinel
  • Review fixes: the shared kits must not enforce OUR id allocation
  • Draw every custom id from the community-allocated pool (87000-87999)
  • Wire the test-automation tooling wave: Containers+Resilience CommonVerbs domains, caravanreroll rows, ForgeKit 0.4.0, ledger/STATUS, limits survey
  • Merge lane 3: container/caravan queue-unblocker verbs + review fixes (scavengesim reachability honesty, quest-event disclosure, reopen gate typing, pristine-state skip)
  • Lane 3 review fixes: honesty gates on the container + scavenge-sim verbs
  • Merge lane 2: session resilience (unstick/LoadGate/goto hardening) + review fixes (Done precedence, sawLoading acceptance, latch decoupling)
  • Merge lane 1: ForgeKit command-script runner (script/scriptcancel/scriptstatus) + review fixes (waitloaded stale-flag acceptance rule, NaN rejection, pump-gap wording)
  • Review fixes F2/F3/F4-F5/F6: watchdog pre-load window, granular refusal, comment truth, latch ownership
  • Review fixes: waitloaded stale-TRUE trap, NaN waits, pump-gap misblame
  • Concurrent-session work committed as-is: grantstatus [force] + StatusApplyGate (DoT thread) + 2026-07-29/30 live-session testplan results
  • Session resilience: unstick verb, [LOADGATE] watchdog, hardened goto
  • Lane 3: container + caravan queue-unblocker verbs
  • Add script runner: one command line, several verbs, real time between steps
  • Hyena/Pearlbird tuning wave: HAO taunt, gifts, bone relic, feed rule