npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sugarch/bc-asset-manager

v1.0.13

Published

An asset manager for Bondage Club mods, easily add custom assets to the game.

Readme

@sugarch/bc-asset-manager

A package for managing assets in BC. It includes functions for loading, modifying, and validating assets, as well as handling custom dialogs and image mappings.

Installation

This package requires the @sugarch/bc-mod-hook-manager package to be installed. Make sure to install it before installing this package.

To install the package, use:

# Using pnpm
pnpm add @sugarch/bc-asset-manager

# Using yarn
yarn add @sugarch/bc-asset-manager

# Using npm
npm install @sugarch/bc-asset-manager

[!IMPORTANT] This package has a peer dependency setting. If you encounter peer dependency errors, install the required package versions manually by adding a version suffix (for example @sugarch/[email protected]).


Simple Example

Here's a quick example of how to use the AssetManager:

import { AssetManager } from '@sugarch/bc-asset-manager';

// Define a simple asset
const assetDef = {
    Name: "SimpleExample",
    Left: 150,
    Top: 200,
    Priority: 40,
    DefaultColor: ["#FFFFFF"],
    Layer: [
        {
            Name: "Base",
            AllowColorize: true,
        },
    ],
};

AssetManager.init(() => {
    // Add the asset to the game
    AssetManager.addAsset("ItemHandheld", assetDef);

    // Add image mappings for the asset
    AssetManager.addImageMapping({
        "Assets/Female3DCG/ItemHandheld/SimpleExample_Base.png": "https://example.com/SimpleExample_Base.png",
        "Assets/Female3DCG/ItemHandheld/Preview/SimpleExample.png": "https://example.com/SimpleExample_Preview.png",
    });
});

API Reference

The AssetManager class provides a set of methods to manage assets in Bondage Club. Below is a detailed description of each method:

addAsset(group: CustomGroupName, asset: CustomAssetDefinition, extended?, translation?, noMirror = false): void

Adds an asset to a specific group. If the asset belongs to ItemTorso or ItemTorso2, a mirror will be automatically added.

  • Parameters:
    • group: The asset group name.
    • asset: The asset definition.
    • extended (optional): Extended asset properties.
    • translation (optional): Translated name of the asset.
    • noMirror (default false): Whether to disable automatic mirroring.

addAssetWithConfig(group: CustomGroupName, asset: CustomAssetDefinition, config: AddAssetConfig): void

Adds an asset with detailed configuration.

  • Parameters:
    • group: The asset group name.
    • asset: The asset definition.
    • config: The asset configuration. Note: translation and layerNames are required by the type AddAssetConfig.
      • translation (Translation.Entry) — Translated name of the asset. (required)
      • layerNames (Translation.String) — Layer and color-group name translations. (required)
      • noMirror (optional): Whether to disable automatic mirroring.
      • extended (optional): Extended asset properties (AssetArchetypeConfig).
      • assetStrings (optional): Custom asset strings (Translation.String).

addGroupedAssets(groupedAssets: CustomGroupedAssetDefinitions, translations?, extended?): void

Adds multiple assets to multiple groups.

  • Parameters:
    • groupedAssets: A mapping of groups to their respective assets.
    • translations (optional): Translations for asset names.
    • extended (optional): Extended asset properties.

addGroupedAssetsWithConfig(groupedAssets: CustomGroupedAssetDefinitions, translations, groupedLayerNames): void

Adds multiple assets to multiple groups with detailed configuration.

  • Parameters:
    • groupedAssets: A mapping of groups to their respective assets.
    • translations: Translations for asset names.
    • groupedLayerNames: Layer names grouped by language.

addGroupedConfig(extendedConfig: ExtendedItemMainConfig): void

Adds grouped configuration for assets.

  • Parameters:
    • extendedConfig: The grouped configuration.

modifyAsset(group: CustomGroupName | CustomGroupName[], asset: string, work: FuncWork): void

Modifies an asset's properties. The group parameter can be a single group name or an array of group names.

  • Parameters:
    • group: The asset group name, or an array of group names to apply the modification to.
    • asset: The asset name.
    • work: A function to modify the asset.

modifyAssetLayers(filter: (asset: Asset) => boolean, work: FuncWork): void

Modifies the layers of assets that match a filter.

  • Parameters:
    • filter: A function to filter assets.
    • work: A function to modify the asset layers.

modifyGroup(group: CustomGroupName, work: FuncWork): void

Modifies a body group's properties.

  • Parameters:
    • group: The body group name.
    • work: A function to modify the group.

addCustomAssetString(assetStrings: Translation.String): void

Adds custom asset strings.

  • Parameters:
    • assetStrings: The custom asset strings.

addImageMapping(mappings: ImageMappingRecord): void

Adds custom image mappings.

  • Parameters:
    • mappings: A record of image mappings.

imageMapping (getter)

Provides access to the internal image mapping helper. The object exposes a storage object with basic, customSrc, custom records and helper methods such as addImgMapping, rebuildCustomMapping, setBasicImgMapping, mapImgSrc and mapImg. It also exposes convenience methods directly on the getter like addImgMapping and setBasicImgMapping.

Use this when you need finer control over the mapping storage or want to call helper utilities provided by the manager.


addGroup(groupDef: CustomGroupDefinition, translation?): void

Adds a new body group.

  • Parameters:
    • groupDef: The group definition.
    • translation (optional): Translated name of the group.

addCopyGroup(newGroup: CustomGroupName, copyFrom: AssetGroupName, translation?): void

Adds a new body group by copying configuration from an existing group.

  • Parameters:
    • newGroup: The new group name.
    • copyFrom: The existing group to copy from.
    • translation (optional): Translated name of the new group.

Note: The implementation supports providing optional defOverrides to change some properties of the copied group. In the code the full signature is (newGroup, copyFrom, translation?, defOverrides?) where defOverrides is a partial group definition to override fields on the new group.


addLayerNames(group: CustomGroupName, assetDef: CustomAssetDefinition, entries: Translation.String): void

Adds custom layer names based on the asset definition.

  • Parameters:
    • group: The body group name.
    • assetDef: The asset definition.
    • entries: Layer names grouped by language.

addLayerNamesRaw(group: CustomGroupName, assetName: string, entry: Translation.CustomRecord<string, string>): void

Adds custom layer names where the entry already contains full keys (raw). This does not extract names from an asset definition — it's useful when you want to provide layer names directly keyed by layer identifiers.

  • Parameters:
    • group: The body group name.
    • assetName: The asset name.
    • entry: Layer-name mapping grouped by language.

addColorGroupNamesRaw(group: CustomGroupName, assetName: string, entry: Translation.CustomRecord<string, string>): void

Adds custom color group names (raw). This only adds color-group translations and does not add layer names.

  • Parameters:
    • group: The body group name.
    • assetName: The asset name.
    • entry: Color-group-name mapping grouped by language.

assetIsCustomed(asset: Asset): boolean

Checks if an asset is custom.

  • Parameters:
    • asset: The asset to check.
  • Returns: true if the asset is custom, otherwise false.

assetNameIsStrictCustomed(assetName: string): boolean

Checks if an asset name is strictly custom.

  • Parameters:
    • assetName: The name of the asset.
  • Returns: true if the asset name is strictly custom, otherwise false.

afterLoad(wk: () => void): void

Adds an event to be executed after loading is complete.

  • Parameters:
    • wk: The function to execute.

init(componentSetup: FuncWork): void

Initializes the asset manager and adds custom components.

  • Parameters:
    • componentSetup: A function to set up custom components.

enableValidation(fromModUserTest: FromModUserTestFunc): void

Enables validation for non-mod removal.

  • Parameters:
    • fromModUserTest: A function to determine if the user is from a mod.

setLogger(logger: ILogger): void

Sets the logger for the asset manager.

  • Parameters:
    • logger: The logger instance.

typeBodyGroupNames<T extends string>(): _AssetManager<T>

Retypes the AssetManager to customize body group names and ensure type safety.

  • Returns: A retyped AssetManager instance.

Detailed Example

For a more detailed example, including how to register mods and initialize the AssetManager, see below:

import { AssetManager } from '@sugarch/bc-asset-manager';
import { HookManager } from '@sugarch/bc-mod-hook-manager';

// write a AssetDefinition for your asset, just like vanilla BC definition
const assetDef: AssetDefinition = {
    // The name of the asset, must be unique in the body group
    Name: "SimpleExample",

    // Position properties, typical player canvas size is 500x1000 (width x height)
    // With character centered in the canvas ( a little bit to the top actually )
    Left: 150,
    Top: 200,

    // if the item needs to adapt to different body type ( large/small/normal, etc )
    ParentGroup: {},

    // the drawing order of the item, higher number means drawn later, and on top of other items
    Priority: 40,

    // the default color
    DefaultColor: ["#FFFFFF"],

    // Asset layers, technically picture resource names
    Layer: [
        {
            // this means a picture resouce located at "Assets/ItemMisc/SimpleExample_Base.png"
            // it will be drawn at [Left, Top] position relative to character canvas
            Name: "Base",
            AllowColorize: true,
        },
    ],
};

// Assembling an asset registration function
// Tips: I like to pack asset in separate files, and each file will have a function like this. 
//   With custom assets piling up, it's easier to manage them this way.
function registerSimpleExample() {
    // Add the asset to the game
    AssetManager.addAsset("ItemHandheld", assetDef);
    // Mapping the images
    AssetManager.addImageMapping({
        // the image for the Base layer
        "Assets/Female3DCG/ItemHandheld/SimpleExample_Base.png": `${yourBaseURL}/SimpleExample_Base.png`,
        // the image for the dialog preview icon
        "Assets/Female3DCG/ItemHandheld/Preview/SimpleExample.png": `${yourBaseURL}/SimpleExample_Preview.png`,
    })
}

// Mod info for the mod, this is used to register the mod to bc mod sdk
const modInfo = ...;

// Initialize the hook manager, AssetManager will use it to hook essential functions
HookManager.initWithMod(bcModSdk.registerMod(modInfo));
// Or directly initialize the hook manager with modinfo
// HookManager.init(modInfo);

// Register the whole thing
AssetManager.init(() => {
    registerSimpleExample();
});