Files
firefrost-services/services/bitch-bot/CLAUDE.md
Claude Code e6552864f0 Bitch Bot: full source scaffold for NeoForge 1.21.1 (REQ-2026-04-15-bitch-bot)
First-boot server provisioner. Named by Holly. Architecture per Gemini 4-round
consultation. Drops a provision.json in server root, mod runs once on
ServerStartedEvent: pastes spawn schematic, places TP command blocks pointing
at the original level.dat spawn, sets worldspawn, gamerules, YAWP region file,
self-destructs by renaming jar to .jar.disabled.

Files (services/bitch-bot/1.21.1/):
- build.gradle / settings.gradle / gradle.properties / gradle wrapper (mirrors rules-mod 1.21.1)
- META-INF/neoforge.mods.toml
- BitchBot.java        — @Mod entry, ServerStartedEvent listener, Throwable net
- Provisioner.java     — sequenced step runner, per-step try/catch, success tracking gates self-destruct
- ProvisionConfig.java — Gson POJO matching provision.json schema verbatim
- SchematicLoader.java — HTTP download + SHA-256 verify + Sponge v2 .schem parser (NbtIo + varint + BlockStateParser palette)
- CommandBlockPlacer.java — impulse command blocks with /tp @p baked into CommandBlockEntity
- SignPlacer.java      — oak signs, 4-line front text via SignBlockEntity#setText
- YawpConfigWriter.java — drops region JSON to world/serverconfig/yawp/regions/{name}.json
- SelfDestruct.java    — ProtectionDomain → CodeSource → jar rename, Windows fallback to deleteOnExit

Plus services/bitch-bot/CLAUDE.md (project doc) and sample-provision.json.

NOT COMPILED — no Java/Gradle on Nitro per repo CLAUDE.md. Compile on Dev Panel:
  cd /opt/mod-builds/firefrost-services/services/bitch-bot/1.21.1
  source use-java 21
  /opt/gradle-8.8/bin/gradle build --no-daemon

Risk areas flagged in CLAUDE.md for first compile: schematic parser (untested
against real WorldEdit output), YAWP file format (best-guess schema).
2026-04-15 12:47:08 -05:00

4.6 KiB

Bitch Bot — First-Boot Server Provisioner

Named by: Holly (The Catalyst) Architecture: Locked via 4-round Gemini consultation — see firefrost-operations-manual/docs/consultations/gemini-modpack-installer-followup-2026-04-15.md REQ: docs/code-bridge/archive/REQ-2026-04-15-bitch-bot.md Status: Source scaffold complete on Nitro. Compile on Dev Panel.

Project Structure

  • 1.21.1/ — NeoForge (Java 21, Gradle 8.8, moddev 2.0.141) — primary target
  • (1.20.1/Forge port can be added later if needed)

What Bitch Bot Does

On ServerStartedEvent, if provision.json exists in the server root:

  1. Reads original spawn coords from level.dat via level.getSharedSpawnPos()
  2. Downloads the schematic from schematic_url, verifies SHA-256 against schematic_hash
  3. Pastes Sponge Schematic v2 (.schem) at spawn_coords (centered if paste_origin == "center")
  4. Places impulse command blocks at every position in command_blocks[] with /tp @p [orig_x] [orig_y] [orig_z] baked into NBT
  5. Places oak signs at every entry in rules_signs[] with up to 4 lines each
  6. Sets worldspawn to spawn_coords + worldspawn_offset
  7. Sets gamerule doFireTick false
  8. Writes a YAWP region config to world/serverconfig/yawp/regions/{name}.json
  9. If self_destruct_on_success: true AND every step succeeded: renames BitchBot-1.0.0-neoforge-1.21.1.jar.jar.disabled
  10. Renames provision.jsonprovision.json.applied so it doesn't re-trigger

Failure Behavior

  • Every step is independently try/catch'd. A failure logs and moves on.
  • If ANY step fails, self-destruct does NOT fire — admin can fix the issue and reboot for retry.
  • The server is NEVER crashed by Bitch Bot. The outermost handler in BitchBot.onServerStarted is a Throwable net.

Source Files

src/main/java/com/firefrostgaming/bitchbot/
├── BitchBot.java              # @Mod entry, ServerStartedEvent listener
├── Provisioner.java           # Sequenced step runner + success tracking
├── ProvisionConfig.java       # Gson POJO for provision.json
├── SchematicLoader.java       # HTTP download + SHA-256 + Sponge v2 NBT parser + paste
├── CommandBlockPlacer.java    # Impulse command blocks with TP NBT
├── SignPlacer.java            # Oak signs with 4 lines of front text
├── YawpConfigWriter.java      # Drops YAWP region JSON to world/serverconfig/yawp/regions/
└── SelfDestruct.java          # Locates own jar via ProtectionDomain, renames to .jar.disabled

Building (Dev Panel only — no Java/Gradle on Nitro)

cd /opt/mod-builds/firefrost-services/services/bitch-bot/1.21.1
source use-java 21
/opt/gradle-8.8/bin/gradle build --no-daemon
# Output: build/libs/BitchBot-1.0.0-neoforge-1.21.1.jar

Provisioning a New Server

  1. Drop the jar into the server's mods/ folder
  2. Drop a populated provision.json (see sample-provision.json) into the server root (next to server.properties)
  3. Boot the server
  4. Watch the log — Bitch Bot prints every step to [BitchBot] lines
  5. Once provisioning is reported successful, the jar renames itself to .jar.disabled and provision.json renames to .applied

Architectural Notes from Gemini

  • Do NOT write to .mca region files from Node.js — corruption-prone on 1.20+. The whole reason Bitch Bot exists as a real mod and not Node-side region manipulation.
  • Do NOT rely on RCON or WorldEdit console — everything is in-process via the Forge API.
  • YAWP config is written as a dropped file in world/serverconfig/yawp/regions/{name}.json. If the on-disk format diverges from what YAWP expects, fix YawpConfigWriter.java — it's the only file that touches the format.
  • BlockEntities and Entities tags in the .schem are ignored. Spawn buildings should be vanilla blocks only. (If we later need item frames or armor stands, extend SchematicLoader.pasteAt.)

Risk Areas to Test on First Real Run

  1. Schematic parsing — only tested against the Sponge v2 spec, not against real WorldEdit .schem output. If parsing fails, palette key strings or varint stream encoding may need tweaks.
  2. Command block NBTcbe.getCommandBlock().setCommand(...) should persist, but verify the command actually fires when a player presses the button on top.
  3. Self-destruct on Linux — every Firefrost server is Linux, so Files.move should work in-place. Windows fallback uses deleteOnExit.
  4. YAWP file formatYawpConfigWriter writes a reasonable JSON shape but the actual YAWP mod schema may need adjustment. Watch for "region not loaded" warnings on second boot.