MoneyRace

Developer API

Hook your own plugin into MoneyRace money, teams, events and placeholders

This page is for plugin developers. Server owners do not need it.

Start with Vault

If you only need to read or change balances, use the Vault API. In MONEYRACE mode MoneyRace is the Vault economy, so your plugin works without touching MoneyRace classes. The rest of this page is for deeper integration.

Getting the plugin

Add MoneyRace as a depend or softdepend in your plugin.yml, compile against the jar you bought, and get the main class:

MoneyRace plugin = (MoneyRace) Bukkit.getPluginManager().getPlugin("MoneyRace");

The package is cc.arrowtan.moneyrace. The API is reached through the main class and has not been published to a Maven repository, so use the jar from your download as a provided dependency. Classes outside the api package are internal and can change.

Money

plugin.money() is a MoneyService.

CallWhat it does
balance(uuid), has(uuid, amount)Read a balance
add, takeChange a balance. take is all or nothing
takeUpToTake what is there and return how much
setSet a balance
transfer(from, to, amount, Reason, text)Move money between players
payTeam(team, amount, PayoutMode, Reason, text)Pay a team
chargeTeam(...)Charge a team, in proportion to member balances in split modes, and return what was taken
vaultBalance(team), addVault, takeVault, setVaultTeam vault balance
format(amount)The configured currency format

Every call writes one row to the ledger, so pass the right Reason. There are reasons for capture points, altars, world events, vaults, rituals, insurance, seasons and events. plugin.ledger().listen(entry -> ...) sees every change, which is handy for daily caps and stats.

Payout helpers do not apply multipliers. Multiply first:

double amount = base * plugin.multipliers().payout(team);

Offline players are loaded from the database on demand, blocking for up to 10 seconds. Prefer online players on the main thread.

Teams

plugin.teams() is a TeamService.

CallWhat it does
team(uuid), byId(id), byName(name), teams()Find teams
members(team), onlineMembers(team)Players in a team
color(team), displayName(team)Colour object and a coloured name in MiniMessage
score(team), rank(team), sorted(), leading(), medianScore()Standings. Ranks refresh every leaderboard.refresh-seconds, so call resort() after a big change
sameTeam(a, b)Same team
isFriendly(actor, target)Same team, or the actor trusts the target. Use this for "no damage from MoneyRace mechanics"
tagBeside(team, playerName)The coloured team name to print next to a player, or an empty string for a solo team

A Team also keeps a free string map, data(key) and data(key, value), for your own values. Call plugin.teams().save(team) after changing it.

Multipliers

plugin.multipliers().set(Multipliers.Scope.PAYOUT, "my_plugin", 1.5);
plugin.multipliers().clear("my_plugin");

World events use the same call for Double Money. kill(team) and payout(team) are what every payout asks, and payout includes the underdog bonus.

addKillHook(Consumer<KillContext>) lets you change reward, victimLoss and bonus, or call cancel() on a kill transfer.

Registering a module

A module is a small unit with a lifecycle. MoneyRace enables them after every core service exists and disables them in reverse order before storage closes.

public final class MyModule implements RaceModule {
    public String id() { return "my-module"; }
    public void enable() { }
    public void disable() { }
    public void reload() { }
}

Register it with plugin.registerModule(new MyModule()). Use plugin.scheduler().group() for your own timers, so cancelAll() in disable() only touches yours.

Commands

plugin.routes() adds subcommands:

plugin.routes().admin("point", route);   // /moneyrace admin point ...
plugin.routes().player("vault", route);  // /moneyrace vault ...

A CommandRoute gives permission(), execute(sender, label, args) and complete(sender, args). The args start after the route name.

Placeholders

plugin.placeholders().register("world_event", (player, params) -> "...");

This answers any %moneyrace_<name>% that starts with the prefix you registered.

Give items

plugin.giveItems().register("my_item", (target, extra) -> itemStack);

This makes /moneyrace admin give my_item [player] [extra...] work, with tab completion. Tag your items with Keys.tag(meta, kind) and recognise them only through Keys.kind(item).

  • plugin.menus().registerMenu("id", player -> ...) lets action: MENU buttons in menus.yml open a coded menu. Plain menus can be added straight to menus.yml and opened with menus().open(player, id).
  • plugin.bossbars() keeps one bar per key. Use bar, update, show, hide, viewers, showAll and remove. Quitting removes a player from every bar.
  • plugin.selections().get(player) returns the player's wand selection.

Season clock

Core code reads the season through plugin.seasonClock(), with active(), day(), finalWeek(), pvpMoney(), phase() and timeLeftMillis(). The default is SeasonClock.NONE.

Main events

Extend MainEvent and register it with plugin.events().register(...).

public final class MyEvent extends MainEvent {
    public MyEvent(MoneyRace plugin) { super(plugin, "my-event"); }
    protected void onStart() { }
    protected void onTick(int secondsRunning) { }
    protected void onPlayerEliminated(Player player, Player killer) { }
    protected void onEnd(EndReason reason) { }
}

Core handles joining, countdown, saving and restoring inventories, bossbars and prizes. Read your own settings with config(), which is events.<id> in events.yml. Placements are paid through the ledger with a payout reason and the team multiplier.

Compatibility rules

One jar runs on every supported server version, so keep these in mind when you build on it:

  • Do not call methods on Sound, Attribute or other enums that became interfaces. Use string keys.
  • Look potion effects and attributes up from the registry by key.
  • Put anything that needs a newer server than the oldest supported one in a separate class behind a version check.
  • Never listen to PlayerLoginEvent. Load data in AsyncPlayerPreLoginEvent.

On this page