You are viewing a potentially older version of this package. View all versions.
Cray-SBGItemFramework-0.1.0 icon

SBGItemFramework

Shared backbone for custom item mods. Register an ItemType and a use-handler; it owns the Harmony plumbing for inventory injection, localized names, hotkey labels, tooltips, and pool-spawn injection. Required by dependent mods.

Date uploaded 15 hours ago
Version 0.1.0
Download link Cray-SBGItemFramework-0.1.0.zip
Downloads 8
Dependency string Cray-SBGItemFramework-0.1.0

This mod requires the following mods to function

BepInEx-BepInExPack-5.4.2305 icon
BepInEx-BepInExPack

BepInEx pack for Mono Unity games. Preconfigured and ready to use.

Preferred version: 5.4.2305

README

SBGItemFramework

Shared backbone for Super Battle Golf custom-item mods. Each consumer mod hands the framework a RegisteredItem description and an IItemHandler that owns the gameplay; the framework deals with everything that would otherwise force every item mod to write the same ~300 lines of ItemCollection / PlayerInventory / LocalizedString / HotkeyUi plumbing and to coordinate that plumbing pairwise with every other custom-item mod the user has installed.

Not a gameplay mod. It does nothing on its own — install it because something else lists it as a dependency.

Consumer flow

public sealed class MyItemPlugin : BaseUnityPlugin
{
    private void Awake()
    {
        ItemKit.Register(RegisteredItem.Define((ItemType)1234, "My Item")
            .WithHandler(new MyItemHandler())
            .WithIconFromVanillaItem(ItemType.OrbitalLaser)
            .WithIconTint(new Color(0.65f, 0.85f, 1.0f))
            .WithMaxUses(2)
            .WithTooltip("One-line description shown in the pause-menu probability grid.")
            .WithConfigBindings(Config, bindMaxUses: true, bindSpawnWeights: true)
            .Done());
    }
}

public sealed class MyItemHandler : ItemHandlerBase
{
    public override void OnUse(PlayerInventory inventory)
    {
        // Server-authoritative work goes through a Mirror Cmd; client-only fizz can run here.
    }
}

The framework picks a non-conflicting integer for the ItemType is the consumer's responsibility. Use anything >= 1000 to stay clear of the vanilla enum range; the framework rejects ids <= 0 and warns when two mods claim the same id (second registration loses).

What the framework owns

Concern Patch / mechanism
Count / GetItemAtIndex Idempotent ItemCollection.items[] extension
TryGetItemData Dictionary rebuilt by vanilla Initialize
TryUseItem Prefix → Handler.OnUse(inventory)
Vanilla swing eligibility GetEffectivelyEquippedItem(false) postfix → None
Item name in chat / pause / hotkey bar LocalizedString.GetLocalizedString postfix
Probability-grid tooltip PauseMenu.UpdateItemProbabilites postfix
Spawn-pool participation ItemSpawnerSettings.ResetRuntimeData postfix
Localization-table seeding First-frame retry on LocalizationSettings

What the framework deliberately does not own (yet)

  • Held-model prefab in the right hand. If a future item needs a custom mesh visible while equipped, that landed in v0.2.x of the framework.
  • Animator pose mapping for the upper body. Same v0.2 scope.
  • Custom drop visuals — vanilla pickup mesh works for sprite-based items.
  • Network helpers for cross-client gameplay events. Consumer mods register their own Mirror message handlers.

Build / deploy / release

dotnet build -c Release
pwsh tools/package.ps1
gh release create vX.Y.Z artifacts/Cray-SBGItemFramework-<ver>.zip --notes-file CHANGELOG.md

CHANGELOG

Changelog

v0.1.0

  • Initial release. Provides the Cray.SBGItemFramework library used by other custom-item mods. Surface:
    • ItemKit.Register(RegisteredItem) — entry point, takes a builder-built immutable item description.
    • RegisteredItem.Define(id, displayName) — fluent builder. Optional knobs: WithIconFromVanillaItem, WithIconOverride, WithIconTint, WithMaxUses, WithTooltip, WithSpawnWeight(poolIndex, weight), WithConfigBindings(consumerConfig, bindMaxUses, bindSpawnWeights), AllowVanillaSwingEligibility.
    • IItemHandler / ItemHandlerBase for the consumer to implement gameplay callbacks (OnUse, optional OnEquip / OnUnequip).
  • Framework-owned Harmony patches:
    • ItemCollection.Initialize / OnEnable extend the private items[] array idempotently so vanilla Count / GetItemAtIndex / TryGetItemData see custom items natively, with no per-mod prefix coordination.
    • PlayerInventory.TryUseItem dispatches to the registered handler.
    • PlayerInventory.GetEffectivelyEquippedItem(false) masks custom items to None so vanilla swing/aim eligibility doesn't get confused by an unknown ItemType.
    • LocalizedString.GetLocalizedString rewrites ITEM_<rawId> keys to the registered display name.
    • PauseMenu.UpdateItemProbabilites appends the optional tooltip text alongside the vanilla per-pool weight rows.
    • ItemSpawnerSettings.ResetRuntimeData injects custom items into the requested pools' spawnChances arrays and recalculates the totals.
  • Icon tinting goes through a CPU-pixel path on readable source textures and falls back to a Graphics.Blit through a temporary RenderTexture for unreadable ones, with results cached by (textureInstanceId, packedRgba).
  • Localization-table seeding runs once a frame from a hidden host until the Data table finishes loading, so vanilla code that bypasses the LocalizedString postfix still resolves the same display names.