# Brass & Sigil KubeJS scripts

All custom server behaviour lives here. Files in this tree ship via the
modpack manifest (see `scripts/Build-Pack.ps1` — `kubejs/` is in
`managedRoots`), get synced to both server and client installs, and are
loaded by KubeJS on startup.

## File layout

```
kubejs/
├── README.md              this file
│
├── server_scripts/        Loaded by the SERVER's KubeJS on world load.
│   ├── recipes_<x>.js     Crafting-recipe overhauls per mod.
│   ├── waystones_policy.js Waystones placement gating (1/player + bans).
│   ├── welcome.js         First-join grant: waystone + manual book.
│   ├── cc_recipes.js      Full ComputerCraft recipe overhaul.
│   └── bns_admin.js       /bns admin <subcommand> for OP diagnostics.
│
└── client_scripts/        Loaded by the CLIENT's KubeJS on game load.
    └── jei_hides.js       Hide specific items from the JEI ingredient list.
```

## Conventions

- **Logging prefix**: every console line uses `[bns/<module>]` so server
  logs can be filtered with `journalctl -u brass-sigil-server.service |
  grep '\[bns/'`. Keeps our output separate from mod output.
- **One concern per file**. Recipe overhauls live in `recipes_<modname>`.
  Block/item policy goes in a `<thing>_policy.js`. Don't mix recipe
  removal with event listeners in the same file.
- **Persistent player data** keys are prefixed `bns` to avoid clashing
  with other mods' use of `player.persistentData`. Currently used keys:
  - `bnsWaystoneCount` (int) — see `waystones_policy.js`
  - `bnsWelcomeGranted` (bool) — see `welcome.js`
- **Performance**: hot-path event handlers (BlockEvents.placed/broken,
  PlayerEvents.loggedIn) must stay O(1). Use `Set` for ID lookups, never
  Array.includes inside an event handler. Avoid Modrinth/network calls
  in event handlers — never. No periodic-tick polling unless absolutely
  necessary.
- **Server commands** are registered under the `/bns` namespace
  (`/bns admin ...`, future: `/bns plot ...`). See `bns_admin.js` for
  the registration pattern.

## Diagnostics

When something looks wrong in-game, first port of call:

1. `/bns admin info` — prints active flags + counts for the running player
2. `/bns admin waystone-count <player>` — read stored count
3. `/bns admin reset-welcome <player>` — re-trigger the first-join grant
4. Server log: `journalctl -u brass-sigil-server.service -f | grep '\[bns/'`

## See also

- `pack/overrides/defaultconfigs/` — first-run mod configs (auto-copied
  to `config/` by NeoForge on first launch only)
- `scripts/Check-Deps.ps1` — pre-flight dep check, runs before any
  Deploy-Brass `-Stage Pack` deploy
- The memory file `project-mc-player-economy.md` for the broader plan
