Zeni and everything that spends it, and the player facing side: chat, ranks, guilds, teleports, tasks and holograms.
Source tree: shuruisutilities/. All module code is under shuruisutilities/src/main/java/net/shurui/shuruisutilities/.
dmz_ragnarok_key), except the Patreon perks
themselves (supporter crowns and Patreon wardrobe cosmetics), which work on any server running the mods. The section names (Economy.*, Social.*) are the names these modules had in the old operator switchboard, config/dmz_ragnarok/modules.cfg, which is no longer read.
@SUModule names (see ModuleCatalog.su(...)): Economy->Economy,
Economy.Trade->Trade, Economy.Auction->Auction, Economy.Bounty->Bounty, Economy.Crates->Crate, Economy.Airdrops->Airdrop; Social.Chat->Chat, Social.TabList->TabList, Social.Ranks->Ranks, Social.Guilds->Guilds, Social.Teleport->Teleport, Social.Tasks->Tasks, Social.Patreon->Patreon, Social.Holograms->Hologram. Social itself and Economy's children hierarchy are declared in ModuleCatalog. All default ON.
ConfigLoaderBase/ConfigSaver write a Forge
TOML at <gamedir>/ShuruisUtilities/<Name>.toml (routed there by SUModConfig, NOT config/). Everything else persists operator-editable JSON directly under <gamedir>/ShuruisUtilities/ via DataManager. The shared COMMON config is <gamedir>/ShuruisUtilities/main.toml (SUConfig).
DefaultPermissionLevel.{ALL, OP, NONE} (api/permissions/DefaultPermissionLevel.java).
A command's getPermissionLevel() is its base gate; individual subcommands add .requires(hasPermission(s, <node>)). An unset SU node behaves per its registered default.
without the Ragnarok Key. There is one key and no tiers: the economy, trade, auctions, bounties, crates, airdrops, chat, tab list, ranks (badges included), guilds, teleports, tasks, holograms and /patreon all need it.
The Zeni currency (ModuleEconomy, EconomyManager, ZeniEconomy). Every player has a persistent Zeni balance. Economy registers a ZeniEconomy as the shared economy API that the other four paying systems (Trade, Auction, Bounty, Crates) and CustomNPCs shops transact through. On a shard network balances are shared through SQL (ShardEconomyBridge); on a single server they live in a local JSON file. A short server-side poll pushes each player their own balance for the HUD.
/money (aliases /balance, /bal, /zeni); base ALL, console allowed.
/money : show your own balance (console gets an error, has no balance).
/money top : the 10 richest players.
/money <player> : look up a player's balance. Requires su.economy.admin.
/money give <player> <amount> : add Zeni (amount >= 1). Requires su.economy.admin.
/money take <player> <amount> : subtract, floored at 0 (amount >= 1). Requires su.economy.admin.
/money set <player> <amount> : set exact balance (amount >= 0). Requires su.economy.admin.
Player-facing for self/top; the rest are staff/owner.
/pay <player> <amount> : transfer Zeni to another ONLINE player (amount >= 1). Base ALL,
player-only. Atomic debit-then-credit; cannot pay yourself; rate-limited by CommandSpamGuard.
su.economy : parent description node (grants nothing on its own).
su.economy.balance : ALL. su.economy.pay : ALL. su.economy.top : ALL.
su.economy.admin : OP (give/take/set/lookup).
<gamedir>/ShuruisUtilities/economy/economy.json (EconomyManager.EconomyConfig), auto-created:
currencyName : default "Zeni". The word shown in every money message.
startingBalance : default 0. Balance an unseen player is treated as having (not written until first credit/spend). Clamped to >= 0.
<gamedir>/ShuruisUtilities/economy/balances.json : the balance store, { "<uuid>": <long> }. On a shard network the shared SQL table is authoritative and this local file is only used for the one-time carry-over.
modules.cfg key Economy.
Economy off takes Trade, Auction, Bounty, Crates and Airdrops with it. Economy is
both the currency module AND the dotted-hierarchy parent of Economy.Trade, Economy.Auction, Economy.Bounty, Economy.Crates, Economy.Airdrops in ModuleCatalog. SuiteModules.on(...) walks the chain, so Economy = false disables all four dependents. This is deliberate: leaving trading/auctions/bounties/crates running with no currency to move would break them.
/money and /pay only register when the key is present. A server
without the key (singleplayer included) has no economy commands.
are already network-shared and are not touched by that sync.
Player-to-player trading (ModuleTrade, TradeManager). /trade <player> requests; accepting opens a custom confirm/cancel GUI where both sides stake items AND Zeni. Staged items live in a persisted escrow (TradeEscrow); staked Zeni is escrowed on confirm (TradeZeniEscrow). Leaving mid-trade or a crash returns staged items.
/trade <player> : request a trade. Base ALL, player-only.
/trade accept / /trade deny : respond to a pending request.
All player-facing.
None registered specifically (command base level ALL; ModuleTrade registers no permission nodes).
None. No TOML and no JSON config file; escrow state is persisted internally, not operator-edited. Module master on/off: modules.cfg key Economy.Trade (and Economy above it).
Economy is off (dotted hierarchy).
A server-authoritative auction house (AuctionModule, AuctionServer, AuctionStore). Players list the item in their main hand for a starting bid and an optional buy-now, bid or buy through the GUI, and collect unsold items and refunds from a claim queue. The server reads the held stack itself (never a client-sent item) and escrows it. Optional CustomNPCs "auctioneer" NPC opens the house on right-click. Expired listings are swept ~every 30s.
/auctionhouse (alias /ah) : open the auction house GUI. Base ALL, player-only.
/ah sell <start> : list held item for starting bid <start> (>= 1).
/ah sell <start> <buynow> : also set a buy-now price (buynow >= 0).
All player-facing.
su.auction : ALL ("Open the auction house").
<gamedir>/ShuruisUtilities/Auction.toml, category [Auction]:
enabled : true. Master switch; when false the command and hub button do nothing and nothing expires.
listingDurationHours : 48 (range 1..720). Hours a listing stays open before it expires.
listingFee : 100 (0..Long.MAX). Flat Zeni fee charged and removed from the economy on listing. 0 disables.
saleTaxPercent : 5.0 (0.0..100.0). Percent of sale price taken as a Zeni sink before the seller is paid. 0 disables.
maxActiveListings : 5 (1..1000). Max simultaneous listings per player.
minBidIncrement : 10 (1..Long.MAX). Minimum Zeni a new bid must beat the current top bid by.
npcAuctioneerEnabled : true. When true and CustomNPCs is installed, an NPC tagged as the auctioneer opens the house on right-click.
npcAuctioneerTag : "su_auctioneer". The scoreboard/CustomNPCs tag that marks an auctioneer NPC.
Economy is off.
refund owed while offline is settled on next login/server start.
Stacking Zeni bounties on players (ModuleBounty, BountyManager). Anyone can add to a target's bounty pool; hunters accept and auto-claim the pool on the kill. An ally rule (three-day party memory, BountyAllies) prevents collecting on allies. Persists to bounties.json.
/bounty set <player> <amount> : place/add a bounty (amount >= 1). <player> is a
GameProfileArgument (offline players resolve via profile cache). Player-only (needs a wallet).
/bounty accept <player> : accept the hunt on a target. Player-only.
/bounty list : list open bounties.
/bounty clear <player> : clear a bounty and refund all contributors. Requires su.bounty.admin.
Base ALL, player-only. set/accept/list player-facing; clear staff/owner.
su.bounty : ALL (set/accept/list).
su.bounty.admin : OP (clear + refund).
None (no TOML). Data persists to <gamedir>/ShuruisUtilities/bounties.json and an allies file. Module master on/off: modules.cfg key Economy.Bounty (and Economy).
Economy is off.
A crate-plugin-style reward system (ModuleCrate, CrateManager, Crate). Admins define named crates (each with a key item and a weighted reward list), then bind physical world blocks to a crate. Right-clicking a bound block while holding its key consumes one key and rolls a reward, revealed as a real spinning item entity floating above the block (no GUI). Rewards can be items, /-style commands (supports %player), and/or a chat message. Keys are NBT-stamped so survival players cannot forge them. Shift-right-clicking a bound crate opens its loot editor (needs su.crate.admin).
/crate : base OP, player-only. Subcommands (all admin):
create <name> : make a new crate.
delete <name> : delete a crate (unbinds its blocks).
list : list crates with key item and reward count.
setkey <name> : set the crate's key to the item in your main hand.
additem <name> [weight] : add the held item as a weighted reward (weight >= 1, default 1).
addcommand <name> <weight> <command> : add a weighted command reward.
items <name> : list a crate's rewards with indices and weights.
removeitem <name> <index> : remove reward at index.
bind <name> : bind the block you are looking at to the crate.
unbind : unbind the crate block you are looking at.
givekey <name> [player] [count] : give crate keys (count >= 1, default 1; defaults to self).
Owner/staff facing throughout.
su.crate : parent description node.
su.crate.admin : OP (manage crates via /crate, and open the shift-click loot editor).
No TOML. All data persists to <gamedir>/ShuruisUtilities/crates.json (CrateManager.CrateData):
crates : map of crate name -> Crate { name, keyItem (registry id, default "minecraft:tripwire_hook"), displayName, rewards[] }. Each CrateReward carries an item stack, weight, optional command, optional message.
bindings : map of "<dim>;x;y;z" -> crate name.
Module master on/off: modules.cfg key Economy.Crates (and Economy).
shuruis_dmz_dungeons.
keyItem field is only the BASE item a key is stamped onto; holding that plain item does nothing. Players need an actual /crate givekey output.
Economy is off.
Randomized airdrops (ModuleAirdrop, AirdropManager). On a random timer a loot chest lands at a random surface spot inside a configured NPC region, announced to everyone, marked on the HUD compass (with SDU), first-come-first-served, and despawns once emptied. Airdrops are configured per NPC region (each region's own Airdrop screen), not globally.
/airdrop : base OP, player-only. Every action re-checks su.airdrop.admin.
spawn : force a drop now (fails if one is active or no region has airdrops enabled). Fans out network-wide.
clear : remove the active chest. Fans out network-wide.
info : report the timer / active-drop status.
Owner/staff facing.
su.airdrop : parent description node.
su.airdrop.admin : OP (configure/force/clear; also gates region Airdrop editor saves).
<gamedir>/ShuruisUtilities/airdrop.json (AirdropConfig + live state). Only two keys are LIVE (the rest are legacy, kept only for one-time migration and not read):
playXpDing : default true. Play the vanilla level-up "ding" to every online player when a drop is announced.
playLegacyRegionSound : default false. Master switch for the old per-region landing sound; off by default so no region's legacy sound plays until set true.
enabled, minIntervalMinutes (30), maxIntervalMinutes (60), regions, loot, announcement.
Module master on/off: modules.cfg key Economy.Airdrops (and Economy).
/airdrop spawn needs at least one NPC region with airdrops enabled, or it errors.
Economy is off.
Social is a group parent in ModuleCatalog (modules.cfg key Social, default ON). Turning it off takes every child below (Social.Chat, Social.TabList, Social.Ranks, Social.Guilds, Social.Teleport, Social.Tasks, Social.Patreon, Social.Holograms) with it via the dotted hierarchy. It has no commands, permission nodes or config of its own.
Chat formatting, channels and mail (ModuleChat, ChatConfig, ChatChannels, Censor, TimedMessages, Mailer). Formats public chat with a rank badge, supporter crown, prestige name colour, title tag and shard label; supports & colour codes (with permission), clickable URLs, %replacement tokens and emoji shortcuts. Adds staff/admin channels, social spy, private messaging with a sticky target, mute/tempmute, nicknames, group messages, a censor, automated timed messages, per-recipient delivery hooks (for the translator), a welcome message and a login MOTD.
ModuleChat unless noted)/mute <player> : OP, permanent mute.
/tempmute <player> <duration> [reason] : OP, timed mute (auto-expires).
/unmute <player> : OP.
/nickname (alias /nick) : base ALL. setSelf <name>, clearSelf, setPlayer <player> <name>, clearPlayer <player>. Editing others needs su.chat.nickname.others (OP).
/pm : base ALL. /pm <message-or-target> sets a sticky PM target or sends; /pm clear clears the target; /pm shows current target. After setting a target, plain chat is routed to them (cross-shard aware).
/reply (alias /r) : base ALL. /reply <message> to the last person you messaged.
/staffchat (alias /sc) : OP. /sc <message>, or toggle the channel. Needs su.chat.channel.staff.
/adminchat (alias /achat) : OP. /achat <message>. Needs su.chat.channel.admin.
/socialspy <on|off> : OP. Mirror private messages and guild chat. Needs su.chat.channel.spy.
/gmsg <group> <message> : base ALL. Message a permission group.
/timedmessage (alias /tm) : OP. help, add <message>, list, delete <number>, send <number>, interval <number>, shuffle <bool>.
/mail : base ALL, registered by Mailer (not ModuleChat.registerCommands, and NOT behind the module-entitled guard the others use). read, readall, send <player> <message>.
su.chat (parent), su.chat.chat : ALL (write public chat), su.chat.usecolor : ALL,
su.chat.urls : ALL, su.chat.range (property), su.chat.textformat (property), su.chat.playerformat (property).
su.chat.nickname.others : OP.
su.chat.channel.staff : OP, su.chat.channel.admin : OP, su.chat.channel.spy : OP.
<gamedir>/ShuruisUtilities/Chat.toml (all categories written by ModuleChat.load):
[Chat] : ChatFormat (default "<{name}> "; must contain the {name} token or it resets to default), LogChat (true; writes ChatLog/*.log), WelcomeMessage ("New player @player joined the server!"), LoginMessage (list; default welcome + "This server is running DMZ Ragnarok" + Discord link).
[Gamemodes] : Survival ("survival"), Creative ("creative"), Adventure ("adventure").
[Mute] : mutedCommands (list; default me, say) - commands blocked while muted.
[Scoreboard] : Enabled (false).
[Censor] : enable (true), slapDamage (1), censorSymbol ("#"), words (list).
[TimedMessage] : inverval [sic] (60, 0 disables), enabled (false), shuffle (false), messages (list).
RankManager.withBadge), plus the supporter crown and title tag inside the name.
/mail is registered separately by Mailer and does not pass through the same module-entitled key gate as the other chat commands.
A configurable header/footer on the vanilla tab player-list, plus an optional banner image across the top (ModuleTabList). Sent via ClientboundTabListPacket so it works on any client. Supports & colours, \n, and {online}/{max}/{player}/{server} placeholders. Refreshed on join and every 2 seconds. On a shard network {online} is the whole-network count and {max} is the network cap.
None.
None.
<gamedir>/ShuruisUtilities/TabList.toml, category [General]:
enabled : true.
header : default "&6&l{server}\n&7Welcome, {player}!".
footer : default "&7{online}/{max} online".
serverName : default "" (empty uses the shard id from shard.json; set to override, e.g. on a single non-sharded server that reports the default id smp).
Plus <gamedir>/ShuruisUtilities/tablist/banner.png : drop a (wide) PNG here to show a banner across the top of the tab list; a README is auto-created. Max ~900 KB.
{online} refresh on /su reload / config bake; a changed banner.png is re-read then and pushed to everyone.
{max} shows the network cap (ShardConfig.networkPlayerCap, fallback 150) only on a server holding the Ragnarok Key; any other server shows its own max-players.
Image ranks (ModuleRanks, RankManager, RankAssetServer): a badge rendered before a player's name in chat, in the tab list, and above their head. A player's badge comes from their permission GROUP's su.rank property (there is no per-player rank menu). Badges can be animated. The rank NAME/codepoint table is baked into the jar (/rank_index.json); the badge ART (PNGs) is NOT in the jar - it is streamed to clients from a server folder.
/rank : base ALL, console allowed.
/rank list (also the bare /rank) : list available badge names. Player-facing.
/rank setgroup <group> <rank> : assign a rank to a permission group. Requires su.ranks.admin.
/rank cleargroup <group> : clear a group's rank. Requires su.ranks.admin.
/rank reloadassets : re-read the badge PNG folder and push to everyone online. Requires su.ranks.admin.
su.ranks (parent), su.ranks.use (declared), su.ranks.admin : OP.
su.rank : the group's chosen rank name (set via the perms GUI prefix menu or /rank setgroup).
<gamedir>/ShuruisUtilities/ranks/ : the operator's badge PNG folder (with a README). Put the
badge PNGs here in the same layout the mod used to ship in assets/shuruisutilities/textures/font/rank/, including anim/<rank>/<frame>.png for animated ranks. This is the ONLY place badge art lives; nothing is bundled in the jar.
display, animStart, frames, frameTime, set) are in
the jar resource /rank_index.json and are NOT operator-editable on disk. No TOML.
<gamedir>/ShuruisUtilities/ranks/, not shipped in the jar, and are key
gated.** The badge streamer lives in the Ragnarok Key, so a server without the key streams NO badges at all. If badges are missing, check for the key before anything else.
/rank reloadassets. The zip is built once and cached, so a
changed badge set otherwise only reaches players on a full server restart. reloadassets re-reads the folder and pushes it; clients reload only when the content version differs from their cache.
whose absence crashes rendering). Chat badges are server-rendered (always show); above-head badges are drawn client-side from a synced cache, so a missed sync can show a chat badge but no head badge until the next ~10s re-broadcast.
Player-run factions with land claims, roles, diplomacy, a shared Zeni bank, homes/warps, guild and ally chat, and planet raids (ModuleGuilds, GuildManager, GuildProtectionHandler, GuildRaidManager). A guild's claim limit scales with the MIN of a member-count ceiling and a battle-power gate, so a guild needs both members and aggregate DragonMineZ battle power to hold more territory. Territory is protected by chunk claims; a destroyed raid target's blocks are salvaged into a vault.
/guild (aliases /g, /guilds) : base ALL, player-only. Player-facing subcommands:
create <name>, disband, info [name], list, map, power/claims, invite <player>, uninvite <player>, join <name>, leave, kick <player>, promote <player>, demote <player>, leader <player>, claim, claimat <cx> <cz>, claimarea <cx1> <cz1> <cx2> <cz2>, unclaim, unclaimall, autoclaim, sethome, home, open, rename <name>, desc <text>, motd <text>, setwarp <warp>, warp <warp>, delwarp <warp>, warps, ally <name>, enemy <name>, truce <name>, neutral <name>, relations, raid <name>, raidabort, raiddefend, raidstatus, flag <flag> on|off, permuser <member> <permission> on|off|clear, perm <role> <permission> on|off, bank / bank deposit <amount> / bank withdraw <amount>, salvage take <index> / salvage takeall, gui. Owner/staff subcommands under /guild admin ... (requires su.guilds.admin): gui, disband <name>, raidwin <name>, inspect <name>, salvage container <rate> / salvage block <rate> / salvage scanheight <blocks> / salvage override <block> <rate> / salvage removeoverride <block> / salvage clearoverrides / salvage tickets <amount>, ticket give <targets> <amount>.
/gc <message> : base ALL. Guild chat (or toggle the channel).
/ac <message> : base ALL. Ally chat (or toggle the channel).
su.guilds (parent), su.guilds.use : ALL (create and use guilds),
su.guilds.admin : OP (administer any guild), su.guilds.admin.bypass : OP (bypass territory protection).
No TOML. Tunables persist as JSON at <gamedir>/ShuruisUtilities/guilds/config.json (GuildConfig), editable from the admin guilds GUI:
creationCost : 0 (Zeni to found; 0 = free).
claimCost : 0 (Zeni per chunk; 0 = free).
maxMembers : 20.
baseClaimsPerGuild : 25 (starting allowance and absolute floor).
baseClaimsPerMember : 5.0 (size ceiling per member).
battlePowerPerClaim : 500000.0 (aggregate BP to unlock one chunk of the ceiling).
maxClaimsHardCap : 0 (0/negative disables the absolute cap).
allowOverclaim : true.
protectClaims : true (master switch for territory protection).
pvpProtectionInClaims : true.
homeWarmupSeconds : 0.
raidFailureLockoutMillis : 259200000 (3 days).
raidSuccessLockoutMillis : 259200000 (3 days; 0/negative disables).
raidCountdownSeconds : 15.
raidTimeLimitSeconds : 600 (0/negative = no limit).
raidDefenderOptInSeconds : 60 (0/negative disables the opt-in window).
salvageContainerRate : 1.0 (fraction of destroyed-planet container contents recovered).
salvageBlockRate : 0.5 (fraction of other blocks recovered).
salvageBlockRateOverrides : {} (per-block-id rate 0..1; set an id to 0 to exclude it).
salvageScanHeightAbove : 64.
raidWinTicketReward : 3 (raid tickets per participating winner; 0 disables; item shuruisutilities:ss_ticket).
Guild data itself persists per-guild via GuildManager.
MIN(member ceiling, power gate), floored at baseClaimsPerGuild (25), NOT a sum.
The scaling only bites above 25 on both halves at once.
guilds/config.json already lists
raidSuccessLockoutMillis keeps the on-disk value; the loader never overwrites an existing key with a changed default. A config generated while that default was 0 stays 0 until the line is edited or deleted.
ShardHomes.restrictedTo).
Homes, warps, spawn, TPA, RTP and the teleport commands (TeleportModule), plus admin portals and a safe-landing pass over the vanilla /tp. Cooldowns/warmups are permission-property driven.
TeleportModule)/home : base ALL. set, setPlayer <player> (needs su.teleport.home.other), plus go-home.
/spawn [player] : base ALL. Teleport to spawn; [player] needs su.teleport.spawn.others.
/setspawn ... : base OP. bed enable|disable, here, clear, <pos>, help.
/back : base ALL. Return to last death (...back.ondeath) or pre-teleport (...back.ontp) location.
/bed [player] : base ALL. To your bed; [player] needs su.teleport.bed.others.
/tp ... : base OP. Vanilla-style (to entity, to coords, targets). Cross-server via su.teleport.tp.crossserver (OP).
/tppos <pos> : base ALL.
/tpa <player> : base ALL. here, position <pos> (needs ...tpa.loc, OP), help.
/top [player] : base ALL. To highest block; [player] needs su.teleport.top.others.
/warp ... : base OP. warp <warp>, set <warp> (...warp.set), delete <warp> (...warp.delete). Per-warp access via su.teleport.warp.<name> or the su.teleport.warp.allowed property.
/pwarp (aliases /pw, /personalwarp) : base OP. list, <name> set|delete, help. Limit from su.teleport.personalwarp.max property (default 10).
/rtp [player] : base ALL. Random teleport; [player] needs su.teleport.rtp.others (OP).
/jump : base OP. Teleport where you are looking; tool use needs su.teleport.jump.tool (OP).
/portal ... : base OP. Admin portal create/recreate/target (frame gen, target coords/dim, spawn, floor, nextfloor).
su.teleport.back.ondeath : ALL, su.teleport.back.ontp : ALL.
su.teleport.bed.others : OP.
su.teleport.home : ALL, su.teleport.home.set : ALL, su.teleport.home.other : OP.
su.teleport.spawn.others : OP, su.teleport.top.others : OP.
su.teleport.tpa.sendrequest : ALL, su.teleport.tpa.here : ALL, su.teleport.tpa.loc : OP.
su.teleport.tpahere.sendrequest : ALL.
su.teleport.warp.admin : OP, su.teleport.warp.set : OP, su.teleport.warp.delete : OP, su.teleport.warp.* : OP.
su.teleport.personalwarp.set : OP, su.teleport.personalwarp.delete : OP.
su.teleport.jump.tool : OP.
su.teleport.rtp.others : OP.
su.teleport.vanillatp.bypass : NONE (skip SU safe-landing on vanilla /tp; defaults to nobody, ops included, on purpose).
su.teleport.tp.crossserver : OP.
su.teleport.tpa.timeout (default "20" sec), su.teleport.warp.allowed, su.teleport.personalwarp.max (default "10"). Cooldown/warmup properties are registered by TeleportHelper.
<gamedir>/ShuruisUtilities/Teleport.toml, category [General]:
portalBlock : default "minecraft:glass_pane". Material for new admin portals (does not override vanilla nether/end; minecraft:portal unsupported).
safeLandVanillaTp : default true. Route the vanilla /tp through SU safe landing so a teleport into terrain relocates to the nearest clear spot (catches Xaero World Map teleports). Command blocks/functions/console are always exempt, as is anyone with su.teleport.vanillatp.bypass. Turn off for exact-coordinate /tp.
Homes are per-player; warps/personal warps and portals persist via their managers under the SU dir.
/tp; disabling the flag or granting the bypass node returns exact-coordinate behaviour.
Daily/weekly/monthly task boards (ModuleTasks, TaskManager, TaskPool). Each board offers a player three tasks drawn from an admin-written pool; a player may work one at a time. Finishing pays Zeni, training points and any commands the task carries; an unworked row can be rerolled for a price. Boards turn over on the real clock; a finished-but-unclaimed reward is held past turnover.
None. The player board is opened by a keybind (PacketOpenEditor("taskboard")) and from the hub menu; the admin task-pool editor opens from the hub (EditorServer.open(p, "tasks")), gated on su.gui.tasks.
su.tasks (parent), su.tasks.use : ALL (open the board), su.tasks.admin : OP (edit the pool and reroll prices).
No TOML. Pool and per-board reroll prices persist to <gamedir>/ShuruisUtilities/tasks.json (TaskPool.PoolData):
tasks : map of task id -> TaskDef (goal, target, amount, rewards: Zeni/TP/commands).
rerollCost : map of board period key -> Zeni cost (0 = free reroll, not disabled). Built-in starting prices apply when unset.
A player's own three rows live in their Forge PERSISTED NBT (survive death and logout).
su.tasks.use, not a missing command.
ReleaseToggles.TASK_BOARD_GUI (currently true) for the hub entry.
Patreon account linking and supporter perks/crowns (ModulePatreon, PatreonManager, PatreonAPI, PatreonCrowns). Fetches each player's supporter tier from a backend on join and on a refresh timer, caches it with a grace window, and drives other SU features (crowns above the head/tab, form cosmetics, perks). Works against the built-in backend with no setup; entirely server-side.
/patreon : base ALL, console allowed for unlink only.
link : start the account-link flow (a keyed server hands a one-click link; elsewhere sends browser instructions). Player-only.
claim <code> : redeem a link code. Player-only.
status : show your current supporter tier (and grace-hold note). Player-only.
unlink <player> : clear a player's cached tier on this server. Requires su.patreon.admin.
su.patreon (parent), su.patreon.use : ALL (link and check your tier), su.patreon.admin : OP (clear a cached tier).
COMMON config <gamedir>/ShuruisUtilities/main.toml, category [Patreon] (COMMON so the API key never rides a synced SERVER config to clients):
BackendUrl : default "https://api.shuruidev.win". Leave empty to use the built-in backend (perks work on any server with no setup). Put off (or none/disabled/-) to switch supporter linking off.
ServerApiKey : default "". Optional; only useful to whoever runs the backend (lets the server mint a one-time link code for a one-click link). A SECRET, never logged or sent to clients.
RefreshMinutes : default 30 (1..1440). How often a logged-in player's tier is re-fetched.
GraceHours : default 72 (0..8760). How long a last-known-good tier keeps applying while the backend is unreachable.
HttpTimeoutSeconds : default 10 (1..120). Per-request HTTP timeout (off-thread).
Permanent grants (permanent supporter tiers) load from a permanent_grants.json (PatreonGrants), reloadable on /rgreload without a restart.
cosmetics follow the supporter's active Patreon tier (grace window included) on any server running the mods, with or without the key. The /patreon command itself registers only on a server holding the Ragnarok Key.
BackendUrl is off (or the feature is unconfigured): every command path reports "not available".
Floating-text holograms with animated GIF/image billboards and item displays (ModuleHologram, HologramManager, HologramGifs). Admins create named holograms with styled multi-line text, placeholders/leaderboards, colour/gradient/rainbow effects, per-line animation (|| frames), and optional <gif:name> image lines. Rendered client-side; persists to JSON and respawns on start.
/hologram (alias /holo) : base OP, player-only. Subcommands: create <name> <text>,
addline <name> <text>, setline <name> <index> <text>, removeline <name> <index>, insertline <name> <index> <text>, move <name> (to you), movevertical <name> <offset>, teleport <name>, near, style <name> <option> <value>, placeholders, gifs, gifs reload, delete <name>, info <name>, list, refresh. style options: scale, gifsize, billboard, background, opacity, shadow, seethrough, glow, glowcolor, align, linewidth, yaw, pitch, viewrange, item, backlight, textoffset, gifoffset. All owner/staff facing.
su.hologram (parent), su.hologram.admin : OP (manage holograms via /hologram).
No TOML. Holograms persist to <gamedir>/ShuruisUtilities/holograms.json (name, dim, x/y/z, lines, and style fields). Image files (.gif, .png, .jpg) go in the HologramGifs.folder() under the SU directory; /hologram gifs reload re-reads them and pushes to everyone online.
/hologram gifs reload (it re-sends the folder and respawns billboards); a plain restart also picks them up.
<gif:name> on its own line draws an image; set its width with /hologram style <name> gifsize <blocks>.