@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(defaultfalse): 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:translationandlayerNamesare required by the typeAddAssetConfig.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:
trueif the asset is custom, otherwisefalse.
assetNameIsStrictCustomed(assetName: string): boolean
Checks if an asset name is strictly custom.
- Parameters:
assetName: The name of the asset.
- Returns:
trueif the asset name is strictly custom, otherwisefalse.
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
AssetManagerinstance.
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();
});