Mod manager for the game CrossCode!
Open the menu from the options menu and look for the Mods
button.
Read the in-game manual in the help menu for usage instructions.
{
type: 'CHECKBOX',
init: true,
/* optional */ changeEvent() {
// code
},
name: 'My checkbox',
description: 'My least favorite button.',
}
{
type: 'BUTTON_GROUP',
init: 0 /* option1 */,
enum: { option1: 0, option2: 1 },
buttonNames: ['Option 1', 'Option 2'],
name: 'My buttons',
description: 'My (not really) favorite button group.',
}
// Or with an enum variable
const myenum = {
option1: 0,
option2: 1,
}
/// ...
{
type: 'BUTTON_GROUP',
init: myenum.option1 /* option1 */,
enum: myenum,
buttonNames: ['Option 1', 'Option 2'],
name: 'My buttons',
description: 'My beloved button group.',
}
{
// Creates a slider that displays values from 1 to 8
type: 'OBJECT_SLIDER',
init: 1,
min: 0.8,
max: 1.5,
step: 0.1,
fill: true,
name: 'Slider',
description: 'My somewhat favorite slider.',
}
{
// Creates a slider that displays values from 0% to 100%
type: 'OBJECT_SLIDER',
init: 0.5,
min: 0,
max: 1,
step: 0.1,
fill: true,
showPercentage: true,
thumbWidth: 50, // Force the thumb width to 50px
name: 'Percentage slider',
description: 'My (maybe) somewhat favorite slider.',
}
{
// Creates a slider that displays values from 4 to 13
type: 'OBJECT_SLIDER',
init: 7,
min: 4,
max: 13,
step: 1,
fill: true,
customNumberDisplay(index) {
const num = this.min
return num + index
},
name: 'Number slider',
description: 'My (definitely) somewhat favorite slider.',
}
{
type: 'BUTTON',
onPress() {
// code
},
name: 'Button',
description: 'My favorite button.',
}
{
type: 'INFO',
name: 'Hello to all!\n<-- New line.'
}
{
type: 'CONTROLS',
init: { key1: ig.KEY.I },
// If false, the keybinding only works in-game
// If true, the keybinding works everywhere
global: false,
pressEvent() {
// keybinding pressed! I will trigger only once
// code
},
holdEvent() {
// keybinding is pressed now! I will trigger every frame the key is pressed
// code
},
name: 'My keybinding',
description: 'Does something I guess.',
}
{
type: 'JSON_DATA',
init: 123,
/* optional */ changeEvent() {
// code
}
}
// for typescript:
// import type * as _ from 'ccmodmanager/types/plugin'
const Opts = modmanager.registerAndGetModOptions(
{
modId: 'my-mod', // the same as the `id` field in `ccmod.json`
title: 'My mod', // the same as the `title` field in `ccmod.json`
},
{
general: {
settings: {
title: 'General', // tab title
tabIcon: 'general', // icon id
},
headers: {
'My header title': {
myCheckbox: {
type: 'CHECKBOX',
init: true,
name: 'My checkbox',
description: "It's initialized as true by default.",
},
myEnum: {
type: 'BUTTON_GROUP',
init: 0 /* option1 */,
enum: { option1: 0, option2: 1 },
buttonNames: ['Option 1', 'Option 2'],
name: 'My buttons',
description: 'Hello.',
},
mySlider: {
// Creates a slider with the following text:
// 1 2 3 4 5 6 7 8
// that resolve to the following values:
// 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5
type: 'OBJECT_SLIDER',
init: 1,
min: 0.8,
max: 1.5,
step: 0.1,
fill: true,
showPercentage: false /* Show the values as % (example: 0.9 => 90%) */,
name: 'Slider',
description: 'My somewhat favorite slider.',
},
myButton: {
type: 'BUTTON',
onPress() {
console.log('Button presssed!')
},
name: 'Button',
description: 'My favorite button.',
},
myInfo: {
type: 'INFO',
name: 'Hello!',
},
myKeybinding: {
type: 'CONTROLS',
init: { key1: ig.KEY.I },
// If false, the keybinding only works in-game
// If true, the keybinding works everywhere
global: false,
pressEvent() {
console.log('keybinding pressed!')
},
name: 'Keybinding',
description: 'Does something I guess.',
},
// JSON_DATA is not visible in the menu
myNumberStorage: {
type: 'JSON_DATA',
init: 123,
},
myJsonStorage: {
type: 'JSON_DATA',
init: { a: 1, b: 2, c: 3 },
},
},
},
},
}
)
// Usage
Opts.myCheckbox // boolean
Opts.myEnum // 0 | 1
Opts.mySlider // 0.8 | 0.9 | 1.0 | 1.1 | 1.2 | 1.3 | 1.4 | 1.5
// Opts.myInfo is not accessible, since it does not store data
// Opts.myKeybinding is not accessible, since it does not store data
Opts.myNumberStorage // number
Opts.myJsonStorage.a // number
Opts.myJsonStorage.b // number
Opts.myJsonStorage.c // number
/* Invalid code: */
// Opts.myJsonStorage.a = 2 // The stored data is read-only, you need to override the whole object
/* This is how you do it: */
Opts.myJsonStorage = { ...Opts.myJsonStorage, a: 2 }
- (javascript) cc-staircase-effect-fix as an example of
INFO
,CHECKBOX
andOBJECT_SLIDER
- (typescript) cc-fancy-crash as an example of
BUTTON_GROUP
andCHECKBOX
- (typescript) cc-record as an example of
OBJECT_SLIDER
andCONTROLS
- (typescript) CCModManager as an example of
JSON_DATA
andBUTTON
- (typescript) CrossedEyes as an example of a big multi-tab menu with a custom language getter
git clone https://github.com/CCDirectLink/CCModManager
cd CCModManager
pnpm install
pnpm run start
# this should return no errors (hopefully)
npx tsc