LogoRobo.js

Configuration

Complete reference for all XP plugin configuration options.

The XP plugin supports configuration at three levels with clear precedence: guild config overrides global config, which overrides system defaults.

Config precedence

  1. Guild config (highest) -- set via /xp config or config.set(guildId, ...)
  2. Global config -- set via plugin options defaults or config.setGlobal(...)
  3. System defaults (lowest) -- built-in fallback values

Plugin options file

The plugin config file at config/plugins/robojs/xp.ts controls global defaults and advanced features like custom level curves.

config/plugins/robojs/xp.ts
import type { PluginOptions } from '@robojs/xp'

export default {
	defaults: {
		cooldownSeconds: 90,
		xpRate: 1.5,
		rewardsMode: 'stack',
		leaderboard: { public: true },
		labels: { xpDisplayName: 'Reputation' }
	}
} satisfies PluginOptions
config/plugins/robojs/xp.js
export default {
	defaults: {
		cooldownSeconds: 90,
		xpRate: 1.5,
		rewardsMode: 'stack',
		leaderboard: { public: true },
		labels: { xpDisplayName: 'Reputation' }
	}
}

The defaults field accepts any GuildConfig fields. These are applied as global defaults on startup via Flashcore and persist across restarts.

PluginOptions fields

Prop

Type

Guild configuration

All configuration fields with their types, defaults, and validation rules.

Basic settings

Prop

Type

Exclusions

Prop

Type

Role rewards

Prop

Type

Multipliers

Prop

Type

Multipliers combine multiplicatively: effective = server * max(role) * user. The result is rounded to 3 decimal places.

Setting any multiplier to 0 disables automatic XP earning at that scope. Admin commands (/xp give, /xp set) still work regardless.

import { config } from '@robojs/xp'

// Disable automatic XP for entire guild (manual control only)
await config.set(guildId, {
	multipliers: { server: 0 }
})

// 2x boost for booster role
await config.set(guildId, {
	multipliers: {
		role: { '123456789012345678': 2.0 }
	}
})
import { config } from '@robojs/xp'

// Disable automatic XP for entire guild (manual control only)
await config.set(guildId, {
	multipliers: { server: 0 }
})

// 2x boost for booster role
await config.set(guildId, {
	multipliers: {
		role: { '123456789012345678': 2.0 }
	}
})

Leaderboard

Prop

Type

Theme

Prop

Type

Custom branding

Prop

Type

Rename "XP" to match your server's theme. All user-facing displays update automatically while command names stay the same.

import { config } from '@robojs/xp'

await config.set(guildId, {
	labels: { xpDisplayName: 'Reputation' }
})
import { config } from '@robojs/xp'

await config.set(guildId, {
	labels: { xpDisplayName: 'Reputation' }
})
LabelUse caseDisplay
'Reputation'Community reputation"1,500 Reputation"
'Points'Point-based rewards"1,500 Points"
'Karma'Reddit-style systems"1,500 Karma"
'Credits'Economy/currency"1,500 Credits"
'Exp'Gaming experience"1,500 Exp"

Level curves

Prop

Type

Environment variables

Prop

Type

.env
XP_ADMIN_PERMISSION=Administrator

Setting config via API

import { config } from '@robojs/xp'

// Get merged config for a guild (never returns null)
const guildConfig = await config.get(guildId)

// Partial updates -- only specified fields change
await config.set(guildId, {
	cooldownSeconds: 45,
	noXpChannelIds: ['123456789012345678'],
	roleRewards: [
		{ level: 5, roleId: '111111111111111111' },
		{ level: 10, roleId: '222222222222222222' }
	]
})

// Validate config before applying
const { valid, errors } = config.validate(partialConfig)
if (!valid) {
	console.log('Validation errors:', errors)
}
import { config } from '@robojs/xp'

// Get merged config for a guild (never returns null)
const guildConfig = await config.get(guildId)

// Partial updates -- only specified fields change
await config.set(guildId, {
	cooldownSeconds: 45,
	noXpChannelIds: ['123456789012345678'],
	roleRewards: [
		{ level: 5, roleId: '111111111111111111' },
		{ level: 10, roleId: '222222222222222222' }
	]
})

// Validate config before applying
const { valid, errors } = config.validate(partialConfig)
if (!valid) {
	console.log('Validation errors:', errors)
}

Global configuration

Global defaults apply to all guilds that haven't overridden specific fields.

import { config } from '@robojs/xp'

// Set global defaults
await config.setGlobal({
	cooldownSeconds: 45,
	xpRate: 1.5,
	leaderboard: { public: true }
})

// Read global defaults
const globalConfig = await config.getGlobal()

// Get system defaults (before any overrides)
const systemDefaults = config.getDefault()
import { config } from '@robojs/xp'

// Set global defaults
await config.setGlobal({
	cooldownSeconds: 45,
	xpRate: 1.5,
	leaderboard: { public: true }
})

// Read global defaults
const globalConfig = await config.getGlobal()

// Get system defaults (before any overrides)
const systemDefaults = config.getDefault()

Setting global config clears all guild config caches. This forces a re-merge on the next access.

Per-store configuration

When using multi-store, each store has independent configuration. Pass { storeId } as the options argument.

import { config } from '@robojs/xp'

// Default store config
await config.set(guildId, { cooldownSeconds: 60 })

// Reputation store gets a longer cooldown
await config.set(guildId, { cooldownSeconds: 120 }, { storeId: 'reputation' })
import { config } from '@robojs/xp'

// Default store config
await config.set(guildId, { cooldownSeconds: 60 })

// Reputation store gets a longer cooldown
await config.set(guildId, { cooldownSeconds: 120 }, { storeId: 'reputation' })

Next steps

On this page