c699dcc77b
Tidying pass on the KubeJS suite before plot system V1 lands. Sets up
the file structure + conventions + diagnostics so the larger plot
system has a clean foundation.
Changes:
1. NEW kubejs/README.md
File layout doc + conventions: logging prefix [bns/<module>],
persistent-data key naming (bns* prefix), one concern per file,
performance discipline (O(1) lookups, no polling).
2. Split economy_policy.js -> recipes_waystones.js + recipes_numismatics.js
Single-concern files. recipes_waystones removes ALL waystones
crafting (welcome.js distributes the only allowed waystone instead).
recipes_numismatics removes the 5 coin-denomination crafts.
3. NEW kubejs/server_scripts/bns_admin.js
/bns admin subcommands for OP diagnostics:
- info calling player's flags+counts
- waystone-count <player> read stored count
- waystone-set <player> <n> override stored count
- reset-welcome <player> clear bnsWelcomeGranted -- replays
the welcome grant on next login
Registered via ServerEvents.commandRegistry with Brigadier tree,
permission level 2 (OP). No performance cost (operator-triggered only).
4. Logging added to waystones_policy.js + welcome.js
Every action prints `[bns/<module>] ...` so server logs can be
filtered with `journalctl ... | grep '\[bns/'`.
Performance discipline applied:
- All event-handler lookups use Set.has (O(1)), not Array.includes
- No periodic tick polling anywhere
- No network calls in event handlers
- console.info is cheap (no string format unless logged)
Bumps to 0.20.0. Plot system V1 follows in v0.21.x as a separate
multi-file submodule under server_scripts/plots/.
55 lines
2.5 KiB
JavaScript
55 lines
2.5 KiB
JavaScript
// Brass & Sigil — first-join welcome grant
|
|
//
|
|
// Gives each new player exactly 1 Waystone + 1 server manual book on
|
|
// first login. Gated by a per-player persistent flag so it fires once
|
|
// even if the player relogs.
|
|
//
|
|
// Future: replace the vanilla written book with a Patchouli book in a
|
|
// custom tweak jar once we have enough content to warrant the rich
|
|
// formatting. Patchouli is already in the pack so swapping later is
|
|
// purely a content+recipe change, no mod-add needed.
|
|
|
|
const WELCOME_FLAG = 'bnsWelcomeGranted';
|
|
|
|
const MANUAL_PAGES = [
|
|
'Welcome to Brass & Sigil.\n\nThis manual covers the basics. Read it once, then keep it or toss it.',
|
|
'WAYSTONES\n\nYou have one Waystone item. Place it at your base -- it is the only one you get.\n\nNeed to travel further? Build trains, roads, or Create Aeronautics planes.',
|
|
'MONEY\n\nCoins cannot be crafted.\n\nTake valuables (diamonds etc.) to the bank at spawn. The exchange will trade them for coins.\n\nDynamic rates are planned.',
|
|
'SPAWN PLOTS\n\nComing soon: buy a small commercial plot at spawn to set up your shop. One plot per player.\n\nYour home base goes OUT in the world -- claim it with FTB Chunks (free, anywhere).',
|
|
'RULES\n\n- Be excellent to each other.\n- No griefing.\n- Lost your Waystone? Ask an OP or buy one from the bank (soon).\n- Report bugs to staff.\n\nHave fun.',
|
|
];
|
|
|
|
function giveManual(player) {
|
|
// 1.21 components-based written book: pages are filterable text
|
|
// components, title supports the same. Plain strings are accepted.
|
|
const book = Item.of('minecraft:written_book');
|
|
book.set('minecraft:written_book_content', {
|
|
title: { raw: 'Brass & Sigil Manual' },
|
|
author: 'Server Staff',
|
|
pages: MANUAL_PAGES.map(text => ({ raw: text })),
|
|
resolved: true,
|
|
});
|
|
player.give(book);
|
|
}
|
|
|
|
function giveStarterWaystone(player) {
|
|
player.give(Item.of('waystones:waystone'));
|
|
}
|
|
|
|
PlayerEvents.loggedIn(event => {
|
|
const player = event.player;
|
|
const data = player.persistentData;
|
|
if (data.getBoolean(WELCOME_FLAG)) return;
|
|
|
|
try {
|
|
giveStarterWaystone(player);
|
|
giveManual(player);
|
|
data.putBoolean(WELCOME_FLAG, true);
|
|
player.tell(Text.gold('Welcome to Brass & Sigil. Check your inventory for a Waystone and the server manual.'));
|
|
console.info(`[bns/welcome] granted starter packet to ${player.username}`);
|
|
} catch (e) {
|
|
// If something goes wrong, don't set the flag -- player gets another chance.
|
|
console.error(`[bns/welcome] failed for ${player.username}: ${e}`);
|
|
}
|
|
});
|