diff --git a/README.md b/README.md index 796baf8..f4c3423 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,12 @@ packs: a full client pack and a server-only pack. ``` . -├── server_pack/ # Server-only packwiz pack (137 mod files) -├── client_pack/ # Full client packwiz pack (146 mod files) +├── server_pack/ # Server-only packwiz pack (135 mod files) +├── client_pack/ # Full client packwiz pack (144 mod files) │ └── shaderpacks/ # Complementary Reimagined setup guide (4GB VRAM preset) -├── kubejs/ # (generated inside each pack) story scripts + datapack -├── tools/gen_textures.py # regenerates placeholder item/block textures -├── SERVER_MASTER_GUIDE.md # install, server.properties, JVM flags, operations -├── STORY_CANON.md # the lore bible — where story lives & how to extend it +├── STORY/ # the story — canon, items, phases, dialogue (edit here) +├── docs/ # operations — setup, server, performance, mods +├── tools/ # gen_story.py, sync_kubejs.sh, gen_textures.py └── README.md ``` @@ -63,7 +62,8 @@ Both packs are identical except the client pack adds render/shader/visual mods. Keep them in sync after any change: ```bash -rm -rf client_pack/kubejs && cp -r server_pack/kubejs client_pack/kubejs +bash tools/sync_kubejs.sh # kubejs/ → client_pack +python tools/gen_story.py # STORY/*.md → en_us.json (both packs) ``` --- @@ -87,7 +87,7 @@ java -Xms4G -Xmx8G -XX:+UseG1GC \ ``` Recommended `server.properties`: `view-distance=8`, `simulation-distance=6`. -Full details in **SERVER_MASTER_GUIDE.md**. +Full details in **docs/server.md**. ## Install — client @@ -104,7 +104,7 @@ install via the Modrinth/packwiz installers. Drop a shaderpack into > **Multiplayer:** players join with the **client pack**; the server runs > the **server pack**. Never put client-only mods on the server (see the -> client-only list in SERVER_MASTER_GUIDE.md §2). +> client-only list in docs/mods.md). --- @@ -122,8 +122,9 @@ install via the Modrinth/packwiz installers. Drop a shaderpack into 6. **The Doctor connection is atmospheric only** — Renegade Glass, *Per Spatium*, portal styling. Never plot-driving. -Full canon, file map, and a 5-minute "add a story beat" workflow: -**STORY_CANON.md**. +Full canon, the phase tree, and the 5-minute "add a story beat" workflow: +**STORY/00-index.md**. Story text is generated from STORY/ into `en_us.json` +via `tools/gen_story.py` — edit prose, not scripts. --- diff --git a/SERVER_MASTER_GUIDE.md b/SERVER_MASTER_GUIDE.md deleted file mode 100644 index 114233b..0000000 --- a/SERVER_MASTER_GUIDE.md +++ /dev/null @@ -1,247 +0,0 @@ -# SERVER MASTER GUIDE — SCICRAFT: The Dark Photon Protocol - -**NeoForge 1.21.1 (21.1.248) · packwiz v1.1.0 · version 1.0.0** - ---- - -## 1. The Dark Photon Protocol (Lore) - -> In the year 4.2.2.0.5, the universe is burning. The Time Lords sealed a -> collapsing star-empire inside a **Dimensional Door** — but the seal is -> decaying. The **Void Dimension** leaks entropy into the Overworld, and the -> **Deeper and Darker** have begun to answer. -> -> A single broadcast survives the fall: the **Dark Photon Protocol**, a plan -> to stabilize the galaxy by re-binding reality itself. You are the last -> engineer of the Second Renegade Flight. Construct the means, master the -> sciences of **Mekanism, Applied Energistics and Create**, and re-forge the -> photon lattice before the void consumes every world. - -### Objective trees (what the pack asks you to build) -1. **Reignite the Ark** — build a base with power (Mekanism turbines / - Flux Networks), storage (AE2 / Sophisticated / Functional Storage), - and logistics (LaserIO / Modular Routers / Entangled / FastPipes). -2. **Walk the Stars** — unlock **Stellaris** rocket tiers; visit Mars, - Venus, and beyond through the rocket menu. -3. **Breach the Doors** — survive **Dimensional Doors**, recover the - **Void Dimension** stabilizer, and descend into the **Deeper and Darker**. -4. **The Protocol** — complete the FTB Quests line and KubeJS advancements. - ---- - -## 2. Packs & Directories - -| Path | Contents | -|------|----------| -| `./server_pack/` | Server-only modpack (137 mod files). No shaders, no client render mods. | -| `./client_pack/` | Full client pack (146 mod files). Adds Iris + Sodium (native NeoForge), Cull Leaves, LambDynamicLights, Dynamic FPS, 3D Skin Layers, Visuality, flywheel compat. | - -### Key client-only mods (server must NOT have these) -`iris`, `sodium`, `iris-flw-compat`, `cull-leaves`, `lambdynamiclights`, -`dynamic-fps`, `3dskinlayers`, `visuality-forge`, `midnightlib`. - -### Bridge layer (both packs) -Sinytra Connector + Forgified Fabric API run a small set of Fabric mods -(Immersive Portals, LambDynamicLights, Waystones-compat). Do not remove -either; the pack will not boot without them. - ---- - -## 3. Install & Update - -### Prereqs -- Java 21 (Adoptium Temurin 21 LTS recommended) -- ~12 GB RAM free for client, 8 GB minimum for server -- Disk: keep under **100 GB** total for world + packs - -### First-time server setup -```bash -# from this repo root -packwiz install --dir server_pack # downloads all mods into server_pack/ -java -Xms2G -Xmx6G -jar server_pack/neoforge-21.1.248-installer.jar --installServer -# accept EULA, then launch: -java -Xms2G -Xmx6G -XX:+UseG1GC -jar server_pack/neoforge-21.1.248-server.jar nogui -``` - -### Adding a mod (both packs) -```bash -packwiz --dir server_pack curseforge add --addon-id -y -packwiz --dir client_pack curseforge add --addon-id -y -packwiz --dir server_pack modrinth add -y -packwiz --dir client_pack modrinth add -y -packwiz --dir server_pack refresh -packwiz --dir client_pack refresh -``` -- Always add to **both** packs unless the mod is client- or server-only. -- For Fabric mods that must run through Sinytra, use - `packwiz url add "" "" --force` and verify the Sinytra - connector tolerates the version. - ---- - -## 4. Server Properties (view-distance=8, simulation-distance=6) - -`server_pack/server.properties` — set these values: - -```properties -view-distance=8 -simulation-distance=6 -max-players=8 -motd=SCICRAFT - The Dark Photon Protocol -difficulty=hard -spawn-protection=0 -network-compression-threshold=256 -enable-command-block=true -online-mode=true -``` - -`server_pack/eula.txt` → `eula=true` (after review). - ---- - -## 5. Recommended JVM Flags (server) - -```bash -java -Xms4G -Xmx8G \ - -XX:+UseG1GC \ - -XX:+ParallelRefProcEnabled \ - -XX:MaxGCPauseMillis=200 \ - -XX:+UnlockExperimentalVMOptions \ - -XX:+DisableExplicitGC \ - -XX:+AlwaysPreTouch \ - -XX:G1NewSizePercent=30 \ - -XX:G1MaxNewSizePercent=40 \ - -XX:G1HeapRegionSize=8M \ - -XX:G1ReservePercent=20 \ - -XX:G1HeapWastePercent=5 \ - -XX:G1MixedGCCountTarget=4 \ - -XX:InitiatingHeapOccupancyPercent=15 \ - -XX:G1MixedGCLiveThresholdPercent=90 \ - -XX:G1RSetUpdatingPauseTimePercent=5 \ - -Dlog4j2.formatMsgNoLookups=true \ - -jar neoforge-21.1.248-server.jar nogui -``` - -Notes: -- G1 tuning keeps large-tech-server TPS stable under chunk gen (Krypton - Reno + BadOptimizations help server-side). -- `-Xms4G` avoids early GC churn. Cap at 8G; this pack is RAM-hungry - from AE2/Mekanism tick load but does not need 16G. - ---- - -## 6. Shader Tuning for 4GB VRAM (client) - -Shader loader is **Iris** (native NeoForge). Recommended shaderpack: -**Complementary Reimagined r5.4** (`client_pack/shaderpacks/`, see README). - -Preset for 4GB VRAM: -- Preset: **Fast / Performance** -- Render Distance: **8** (server view-distance) -- Antialiasing: **OFF** -- SSAO: **Fast**, Shadow Quality **1.0x** (0.5x if <30 FPS) -- Shadow Distance: **64** -- Bloom: **OFF/Low**, Clouds: **2D Fast** -- Water Reflections: **Screenspace Fast** -- Colored Light / Block Light: **OFF** - -If still under 60 FPS: reduce Shadow Quality to 0.5x, then disable Bloom, -before touching render distance. - ---- - -## 7. Mod Feature Hotspots (Quick Orientation) - -| Domain | Mods | Notes | -|--------|------|-------| -| Power | Mekanism (turbine/boiler), Flux Networks | Flux wireless transfer; Mekanism cables for bulk | -| Storage | AE2, Sophisticated Storage, Functional Storage, Sophisticated Backpacks | AE2 for autocraft; Sophisticated for bulk; Functional for drawers | -| Logistics | LaserIO, Modular Routers, Entangled, FastPipes, Create belts | FastPipes adds vanilla pipe QoL | -| Automation | Create + Steam 'n' Rails + Rechiseled + FastPipes | Flywheel + Iris compat bundled | -| Tech Building | Building Gadgets, Hologenica, FramedBlocks, Chipped, Supplementaries | | -| Dimensions | Per Spatium/Stellaris, Dimensional Doors, Void Dimension, Deeper and Darker | Stellaris portal → rockets; Doors are the endgame hook | -| Mobs/Combat | Born in Chaos, Mutant Monsters, Nyf's Spiders, Better Combat, Simply Swords | Hard difficulty | -| UI/QoL | JEI, Jade (+Addons), JourneyMap, Waystones, AppleSkin, IPN, Clumps, Mouse Tweaks | JEI is the recipe source (no EMI) | -| Scripting | KubeJS (+Create, +Mekanism), LootJS, Blocks You Need | Advancements & loot live here | -| Server utils | FTB Chunks/Quests/Teams/Library | Chunk claims + questbook | - ---- - -## 8. Story System (KubeJS + datapack) - -Lore is code. All story text lives in the **story bible** and is referenced -from scripts — never hardcoded. See `STORY_CANON.md` for the full -canon, file map, and "add a beat in 5 minutes" workflow. - -### File layout (mirrored in BOTH packs under `kubejs/`) -``` -kubejs/ -├── startup_scripts/registry_blocks.js # photon_core, photon_fragment, -│ # void_stabilizer, quantum_lattice, renegade_glass -├── server_scripts/ -│ ├── 00_lore.js # THE STORY BIBLE (edit here first) -│ ├── 01_corruption_tide.js # global Corruption Tide + Lattice re-seal -│ ├── 02_events.js # photon buffs, void/darker hazards -│ ├── 03_recipes_tags.js # crafting chain + ore/ingot tag unification -│ └── 04_loot.js # LootJS: Darker bosses drop Photon Fragments -├── client_scripts/ -│ ├── 01_tooltips.js # hover lore on Protocol items -│ └── 02_jei_info.js # JEI "how to obtain" pages -├── data/scicraft/advancements/protocol/*.json # 9-node phase tree (non-terminal) -└── assets/scicraft/ # lang, textures -``` - -### The phase tree (not a finale — the Protocol is maintained) -1. `root` — The Dark Photon Protocol (on login) -2. `first_signal` — recover a Photon Fragment -3. `the_core` — press 3 fragments → Photon Core -4. `the_seal` — craft the Void Stabilizer -5. `the_lattice` — assemble the Quantum Lattice -6. `the_legacy` — craft Renegade Glass -7. `through_the_doors` — enter Dimensional Doors Limbo -8. `the_wound` / `the_answer` / `per_spatium` — Void, Deeper&Darker, Stellaris - -### Global Corruption Tide -- Rises +1 every 60s while Doors stay unsealed (global, all players share). -- Right-click a **Quantum Lattice** with a **Void Stabilizer** to re-seal - a Door: −15 tide. -- ≥30 tide: players get `darkness`. ≥60: `darker_threshold` for future - spawn ramps. 100 = maximum dark. No fail state — soft escalation only. - -### Reload rules -- Server scripts / recipes / advancements: `/reload` -- Client tooltips / JEI / textures / lang: `F3+T` -- New items/blocks (`registry_blocks.js`): **full restart** - -### Keep both packs in sync -```bash -rm -rf client_pack/kubejs && cp -r server_pack/kubejs client_pack/kubejs -``` - ---- - -## 9. Operations & Troubleshooting - -### Server start order -1. `packwiz install --dir server_pack` (first time / after changes) -2. Accept EULA. -3. Launch with the JVM flags above. - -### Common failures -| Symptom | Fix | -|---------|-----| -| "Mismatched mods" on client join | Run `packwiz refresh` both packs, redeploy. | -| Sinytra connector errors | Update Sinytra Connector + Forgified Fabric API together. | -| Iris black screen | Disable flywheel compat first, then test without shaders. | -| Crash on world gen (Deeper and Darker) | Ensure CF 659011 + its lithostitched data load; update both. | -| TPS lag from many AE2 cells | Check FTB chunk claims; lower `simulation-distance`. | -| Immersive Portals won't load | Must be the Fabric jar added via `url add --force` (Modrinth blocks loader mismatch). | - -### Backups -- World: copy `server_pack/world/` (or use FTB Chunks backups). -- Configs: `server_pack/config/` mirrors client defaults; keep both in sync - when changing KubeJS scripts or FTB settings. - ---- - -*Generated for SciCraft Server · packwiz refresh passing on both packs · 146 client / 137 server files.* diff --git a/STORY/00-index.md b/STORY/00-index.md new file mode 100644 index 0000000..976d29e --- /dev/null +++ b/STORY/00-index.md @@ -0,0 +1,73 @@ +# STORY — SCICRAFT: The Dark Photon Protocol + +**This folder is the single source of truth for the pack's story.** +Every piece of player-facing text in the game comes from here. + +## How editing works + +1. Edit prose and text in `STORY/*.md`. +2. Run the generator: + ```bash + python tools/gen_story.py + ``` +3. It merges every ````lang` JSON block into `en_us.json` in **both** packs + and fails if any referenced lang key is missing. +4. Reload in-game: `/reload` for server text, `F3+T` for client text. + +> **Golden rule:** never hand-edit `en_us.json` and never hardcode a story +> string inside a `.js` script. Text lives here (or in the `STORY/*.md` +> prose); scripts only reference lang keys. + +## File map + +| File | What lives here | Game artifact | +|------|-----------------|---------------| +| `00-index.md` | This index + the editing workflow + verified IDs | — | +| `01-canon.md` | The canon, in one page (the actual story) | — | +| `02-items.md` | Item/block names, hover tooltips, JEI pages | `item.*`, `block.*`, `tooltip.*`, `jei.*` | +| `03-dimensions.md` | Dimension lore + verified dimension IDs | — | +| `04-phases.md` | The advancement phase tree (titles + descriptions) | `advancements.scicraft.protocol.*` | +| `05-dialogue.md` | Player messages: tide warnings, signals, lattice hum | `scicraft.phrases.*` | +| `06-loot.md` | Who drops what, and why | `04_loot.js` (LootJS) | +| `07-todo.md` | Future story beats (drop in whenever) | — | + +## The phase tree (non-terminal — the Protocol is maintained) + +1. `root` — The Dark Photon Protocol (on login) +2. `first_signal` — recover a Photon Fragment +3. `the_core` — press 3 fragments → Photon Core +4. `the_seal` — craft the Void Stabilizer +5. `the_lattice` — assemble the Quantum Lattice +6. `the_legacy` — craft Renegade Glass +7. `through_the_doors` — enter Dimensional Doors Limbo +8. `the_wound` / `the_answer` / `per_spatium` — Void, Deeper&Darker, Stellaris + +## Adding a new story beat (5-minute workflow) + +1. **Write the prose** in the right `STORY/*.md` file (canon → `01-canon.md`, + item → `02-items.md`, message → `05-dialogue.md`, goal → `04-phases.md`). +2. **Add the lang keys** to that file's ````lang` block. +3. **If it's a new item/block**: add to `kubejs/startup_scripts/registry_blocks.js` + + run `tools/gen_textures.py` for a placeholder texture. **Restart** to apply. +4. **Wire the beat** into a script (tide → `01_corruption_tide.js`, + powers → `02_events.js`, craft → `03_recipes_tags.js`, drop → `04_loot.js`). + Use `Text.translate('key')` — never a raw string. +5. Run `python tools/gen_story.py`, then sync: + ```bash + bash tools/sync_kubejs.sh + ``` +6. Reload: `/reload` (server) or `F3+T` (client). Startup items need a restart. + +## Verified IDs (do not guess these — they were checked against the jars) + +| Thing | Correct ID | +|---|---| +| Limbo (Dimensional Doors) | `dimensionaldoors:limbo` | +| The Wound (Void Dimension) | `thevoiddimension:overworld` | +| The Othersides (Deeper & Darker) | `deeperdarker:otherside` | +| Stellaris moon | `stellaris:moon` (mars/venus/mercury likewise) | +| Warden | `minecraft:warden` | +| Mutant Zombie / Skeleton / Enderman | `mutantmonsters:mutant_zombie` / `mutant_skeleton` / `mutant_enderman` | +| Born in Chaos Dark Vortex / Dread Hound / Nightmare Stalker | `born_in_chaos_v1:dark_vortex` / `dread_hound` / `nightmare_stalker` | + +When in doubt, verify against the installed jar before writing an ID into a script. \ No newline at end of file diff --git a/STORY/01-canon.md b/STORY/01-canon.md new file mode 100644 index 0000000..a1d974b --- /dev/null +++ b/STORY/01-canon.md @@ -0,0 +1,58 @@ +# The Canon — in one page + +## The canon + +1. **Dark photons are real.** A fifth force the Second Renegade Flight + harnessed. They are the *binding force of the Door* — the pressure that + keeps a collapsed star-empire from unravelling back into reality. +2. **You are a proto-Time-Lord.** Born with the resonance, never finished + training. The signal chose you because only a renegade could read the + Protocol the mortals can't. +3. **The wound.** The Flight sealed the empire inside a Dimensional Door. + The seal is failing. The Void Dimension is the raw wound; the Doors are + scar-tissue; the Deeper and Darker is what's *answering from inside*. +4. **The job.** Rebuild the **Quantum Lattice** — the Protocol's emitter — + and keep it online. The Protocol is never finished; it is maintained. +5. **The tide.** Corruption rises while Doors go unsealed (global, shared by + all players). Re-seal Doors at the Lattice to push it back. No fail state — + just a world that gets darker while you procrastinate. +6. **The Doctor connection is atmospheric only.** TARDIS-blue glass + ("Renegade Glass"), the phrase *Per Spatium*, portal styling. Present but + never plot-driving; players who don't care can ignore it entirely. + +## The short version (for the README) + +1. Dark photons are real — a fifth force the Flight harnessed, the binding + force of the Door. +2. You are a proto-Time-Lord — the only one who can read the Protocol. +3. The wound — the Flight's seal on a collapsed star-empire is failing. The + Void Dimension is the leak; the Deeper and Darker is what answers. +4. The Protocol — rebuild the Quantum Lattice and keep it online. +5. The Corruption Tide — rises while Doors go unsealed (global, shared). + Re-seal Doors at the Lattice with a Void Stabilizer. No fail state. +6. The Doctor connection is atmospheric only — Renegade Glass, *Per Spatium*, + portal styling. Never plot-driving. + +## The opening blurb (in-game) + +> In the year 4.2.2.0.5, the universe is burning. The Time Lords sealed a +> collapsing star-empire inside a **Dimensional Door** — but the seal is +> decaying. The **Void Dimension** leaks entropy into the Overworld, and the +> **Deeper and Darker** have begun to answer. +> +> A single broadcast survives the fall: the **Dark Photon Protocol**, a plan +> to stabilize the galaxy by re-binding reality itself. You are the last +> engineer of the Second Renegade Flight. Construct the means, master the +> sciences of **Mekanism, Applied Energistics and Create**, and re-forge the +> photon lattice before the void consumes every world. + +## Objective trees (what the pack asks you to build) + +1. **Reignite the Ark** — build a base with power (Mekanism turbines / + Flux Networks), storage (AE2 / Sophisticated / Functional Storage), and + logistics (LaserIO / Modular Routers / Entangled / FastPipes). +2. **Walk the Stars** — unlock **Stellaris** rocket tiers; visit Mars, + Venus, and beyond through the rocket menu. +3. **Breach the Doors** — survive **Dimensional Doors**, recover the + **Void Dimension** stabilizer, and descend into the **Deeper and Darker**. +4. **The Protocol** — complete the FTB Quests line and KubeJS advancements. \ No newline at end of file diff --git a/STORY/02-items.md b/STORY/02-items.md new file mode 100644 index 0000000..e7bcdbf --- /dev/null +++ b/STORY/02-items.md @@ -0,0 +1,65 @@ +# Items & Blocks + +Every name, tooltip line, and JEI page for the Protocol's items. Keep the +tooltips in the same order they should render (top of list = first line). + +## Photon Core + +The raw fifth-force crystal. Lattice fuel. Held items let you feel the seals. + +## Photon Fragment + +Shattered cores recovered from the Darker's remains. Three can be pressed +into a Core. + +## Void Stabilizer + +The renegades' tool for closing wounds — the "door's key". Right-click a +powered Quantum Lattice with it to re-seal a Door and push back the tide. + +## Quantum Lattice + +The Protocol's emitter. Must stay powered. It holds the world together. + +## Renegade Glass + +The TARDIS-blue glass of the Second Renegade Flight. Purely decorative; +some say it hums near Doors. + +```lang +{ + "item.scicraft.photon_core": "Photon Core", + "item.scicraft.photon_fragment": "Photon Fragment", + "item.scicraft.void_stabilizer": "Void Stabilizer", + "block.scicraft.quantum_lattice": "Quantum Lattice", + "block.scicraft.renegade_glass": "Renegade Glass", + + "tooltip.scicraft.photon_core.1": "Dark photons — the binding force of the Door.", + "tooltip.scicraft.photon_core.2": "A sliver of the fifth force the Flight harnessed.", + "tooltip.scicraft.photon_core.3": "Hold it and feel the seals.", + "tooltip.scicraft.photon_fragment.1": "A splinter of light stolen from the collapse.", + "tooltip.scicraft.photon_fragment.2": "Recovered from the Darker's remains.", + "tooltip.scicraft.photon_fragment.3": "Three of these may be pressed into a Core.", + "tooltip.scicraft.void_stabilizer.1": "Per Spatium — the renegades' seal for the wound in the world.", + "tooltip.scicraft.void_stabilizer.2": "Right-click a powered Quantum Lattice to re-seal a Door.", + "tooltip.scicraft.void_stabilizer.3": "It will never break. The work will.", + "tooltip.scicraft.quantum_lattice.1": "The Protocol's emitter. It must stay powered.", + "tooltip.scicraft.quantum_lattice.2": "Feed it steel, circuits, and Photon Cores.", + "tooltip.scicraft.quantum_lattice.3": "Right-click with a Void Stabilizer to push back the tide.", + "tooltip.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "tooltip.scicraft.renegade_glass.2": "Decorative. Some say it hums near Doors.", + + "jei.scicraft.photon_fragment.1": "The Darker carry these.", + "jei.scicraft.photon_fragment.2": "Slay Wardens, Mutant Monsters, or Born in Chaos mobs to recover them.", + "jei.scicraft.photon_fragment.3": "You can also extract one from an Echo Shard and Glowstone Dust.", + "jei.scicraft.photon_core.1": "Compress three Photon Fragments in a Create Press,", + "jei.scicraft.photon_core.2": "or smelt an Ender Pearl in the heart of the wound.", + "jei.scicraft.void_stabilizer.1": "The seal of the Flight. Crafted from Photon Cores and an Ender Eye.", + "jei.scicraft.void_stabilizer.2": "Use it on a powered Quantum Lattice to re-seal a Door and lower the Corruption Tide.", + "jei.scicraft.quantum_lattice.1": "The emitter of the Dark Photon Protocol.", + "jei.scicraft.quantum_lattice.2": "Powered by steel, circuits, and Photon Cores, it holds the world together.", + "jei.scicraft.quantum_lattice.3": "Right-click it with a Void Stabilizer to push back the global Corruption Tide.", + "jei.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "jei.scicraft.renegade_glass.2": "Decorative. Crafted around a Photon Fragment." +} +``` \ No newline at end of file diff --git a/STORY/03-dimensions.md b/STORY/03-dimensions.md new file mode 100644 index 0000000..bcd6dc5 --- /dev/null +++ b/STORY/03-dimensions.md @@ -0,0 +1,33 @@ +# Dimensions + +The geography of the story. Prose lives here; the actual dimension IDs are +verified in `00-index.md` — do not invent new ones. + +## The Overworld — the Ark + +Where the Protocol must be rebuilt. The Lattice belongs here; doors leak +here. Corruption rises here faster than anywhere. + +## Limbo (Dimensional Doors) + +The scar-tissue of the Flight's prison — the space *between* the doors. +Entering a Door is entering the memory of the collapse. The first test of +the renegade's nerve. + +## The Wound (Void Dimension) + +The raw leak of the collapsing star-empire. Physically hostile: entropy +drains the life of anyone inside. The Void Stabilizer is the only tool that +can begin closing it. + +## The Othersides (Deeper & Darker) + +What is *answering from inside* the prison. The Darker press against the +world here. Carries the worst ambient dread in the pack — and the richest +harvest of Photon Fragments. + +## The Stars (Stellaris) + +The Flight scattered its data across the worlds of this system. The moon, +Mars, Venus, Mercury — each holds a piece of the Protocol's history and its +own quiet dread. *Per Spatium.* \ No newline at end of file diff --git a/STORY/04-phases.md b/STORY/04-phases.md new file mode 100644 index 0000000..cd49cb7 --- /dev/null +++ b/STORY/04-phases.md @@ -0,0 +1,37 @@ +# The Phase Tree + +The advancement tree is the player's story spine. Titles and descriptions +are player-facing — write them like lore, not like tech specs. The tree is +non-terminal: the Protocol is maintained, not completed. + +Phases in order: `root` → `first_signal` → `the_core` → `the_seal` → +`the_lattice` → `the_legacy` → `through_the_doors` → (`the_wound`, +`the_answer`, `per_spatium`). + +> To add a node: copy `kubejs/data/scicraft/advancements/protocol/the_core.json`, +> change `parent`, rename the file, and add its title/description keys below. + +```lang +{ + "advancements.scicraft.protocol.root.title": "The Dark Photon Protocol", + "advancements.scicraft.protocol.root.description": "The last signal of the Second Renegade Flight has found you. Rebuild the Lattice.", + "advancements.scicraft.protocol.first_signal.title": "The Signal", + "advancements.scicraft.protocol.first_signal.description": "Recover your first Photon Fragment from a creature of the Dark.", + "advancements.scicraft.protocol.the_core.title": "The Core", + "advancements.scicraft.protocol.the_core.description": "Press three Fragments into a Photon Core.", + "advancements.scicraft.protocol.the_seal.title": "The Seal", + "advancements.scicraft.protocol.the_seal.description": "Craft the Void Stabilizer — the renegades' tool for closing wounds.", + "advancements.scicraft.protocol.the_lattice.title": "The Lattice", + "advancements.scicraft.protocol.the_lattice.description": "Assemble the Quantum Lattice — the Protocol's emitter — and keep it powered.", + "advancements.scicraft.protocol.the_legacy.title": "The Legacy", + "advancements.scicraft.protocol.the_legacy.description": "Craft Renegade Glass — rebuild what the Flight left behind.", + "advancements.scicraft.protocol.through_the_doors.title": "Through the Doors", + "advancements.scicraft.protocol.through_the_doors.description": "Enter a Dimensional Door. The scar-tissue of the Flight's prison.", + "advancements.scicraft.protocol.the_wound.title": "The Wound", + "advancements.scicraft.protocol.the_wound.description": "Descend into the Void Dimension — the raw leak of the collapsing empire.", + "advancements.scicraft.protocol.the_answer.title": "The Answer", + "advancements.scicraft.protocol.the_answer.description": "Reach the Othersides of the Deeper and Darker — what answers from inside the prison.", + "advancements.scicraft.protocol.per_spatium.title": "Per Spatium", + "advancements.scicraft.protocol.per_spatium.description": "Launch a rocket. The Flight's data was scattered across the stars." +} +``` \ No newline at end of file diff --git a/STORY/05-dialogue.md b/STORY/05-dialogue.md new file mode 100644 index 0000000..0644fad --- /dev/null +++ b/STORY/05-dialogue.md @@ -0,0 +1,22 @@ +# Dialogue & Player Messages + +Every message the player can see. These keys are referenced from scripts via +`Text.translate('scicraft.phrases.')`. + +- **signal** — broadcast once on login; the first vision. +- **lattice_hum** — spoken when a Door is re-sealed at the Lattice. +- **tide_low** — the calm phase of the Corruption Tide. +- **tide_mid** — the world is waking; darkness begins. +- **tide_high** — the Darker press against the world. +- **seal_fail** — reserved for when the Lattice can't close a door. + +```lang +{ + "scicraft.phrases.signal": "The last signal of the Second Renegade Flight hums in your blood.", + "scicraft.phrases.lattice_hum": "The Lattice hums. Reality holds — for now.", + "scicraft.phrases.tide_low": "The seal holds. The tide is calm.", + "scicraft.phrases.tide_mid": "A Door stirs somewhere. The dark is waking.", + "scicraft.phrases.tide_high": "The Darker press against the world. The Protocol calls.", + "scicraft.phrases.seal_fail": "The Lattice sputters. It needs more power — and a Stabilizer." +} +``` \ No newline at end of file diff --git a/STORY/06-loot.md b/STORY/06-loot.md new file mode 100644 index 0000000..e2b821c --- /dev/null +++ b/STORY/06-loot.md @@ -0,0 +1,25 @@ +# Loot & Drops + +Who carries Photon Fragments, and why. Implemented in +`kubejs/server_scripts/04_loot.js` (LootJS) — the prose here explains the +*motivation*, the script holds the counts. + +## The Warden + +A creature of the Deep Dark, now answering the signal. It carries the most +fragments of the overworld's horrors — the Protocol's first real harvest. + +## Mutant Monsters + +The corrupted remnants of the Flight's containment. Mutant Zombie and +Mutant Skeleton carry fragments; Mutant Enderman, the most corrupted, drops +the richest haul. + +## Born in Chaos + +The Darker's forward scouts. Dark Vortex and Dread Hound carry a single +fragment each — the first taste of the Dark. Nightmare Stalker, which hunts +silently, carries more. + +> The very first fragment should always drop — the player is never locked +> out of the story by bad luck. \ No newline at end of file diff --git a/STORY/07-todo.md b/STORY/07-todo.md new file mode 100644 index 0000000..52e42af --- /dev/null +++ b/STORY/07-todo.md @@ -0,0 +1,18 @@ +# Future Story Beats + +Drop these in whenever. Beats get promoted to a numbered file once they're +implemented; until then they live here as design. + +- [ ] **Door network** — a set of Doors that opens/closes on a schedule, each + carrying its own phrase in `05-dialogue.md` (add `scicraft.phrases.` + keys as they land). +- [ ] **Star fragments** — Stellaris planets each recover a named fragment + ("Mars shard", "Venus shard") → new advancement nodes in `04-phases.md`. +- [ ] **Lattice upkeep** — it slowly *consumes* Photon Cores while powered; + running dry raises the tide (ties the tide to real infrastructure). +- [ ] **The Legacy tier** — Renegade Glass builds that hum: block interactions + that whisper one `scicraft.phrases.*` line. +- [ ] **FTB Quests questbook** mirroring the advancement phases in `04-phases.md`. +- [ ] **Tide warning gating** — currently `tide_*` messages broadcast every + 200 ticks to all players; gate them to *phase changes* only to avoid + spam. See `kubejs/server_scripts/01_corruption_tide.js`. \ No newline at end of file diff --git a/STORY_CANON.md b/STORY_CANON.md deleted file mode 100644 index ebb3309..0000000 --- a/STORY_CANON.md +++ /dev/null @@ -1,114 +0,0 @@ -# STORY CANON — SCICRAFT: The Dark Photon Protocol - -**This is the single source of truth for the pack's story.** -All lore text lives here or is referenced from here. Editing the story means -editing this file (or the files it points to) — nothing else. - ---- - -## The canon, in one page - -1. **Dark photons are real.** A fifth force the Second Renegade Flight - harnessed. They are the *binding force of the Door* — the pressure that - keeps a collapsed star-empire from unravelling back into reality. -2. **You are a proto-Time-Lord.** Born with the resonance, never finished - training. The signal chose you because only a renegade could read the - Protocol the mortals can't. -3. **The wound.** The Flight sealed the empire inside a Dimensional Door. - The seal is failing. The Void Dimension is the raw wound; the Doors are - scar-tissue; the Deeper and Darker is what's *answering from inside*. -4. **The job.** Rebuild the **Quantum Lattice** — the Protocol's emitter — - and keep it online. The Protocol is never finished; it is maintained. -5. **The tide.** Corruption rises while Doors go unsealed (global, shared by - all players). Re-seal Doors at the Lattice to push it back. No fail state — - just a world that gets darker while you procrastinate. -6. **The Doctor connection is atmospheric only.** TARDIS-blue glass - ("Renegade Glass"), the phrase *Per Spatium*, portal styling. Present but - never plot-driving; players who don't care can ignore it entirely. - ---- - -## Where the story lives (file map) - -| What you want to change | Where | Reload | -|---|---|---| -| Global story strings, tide tuning, dimension IDs | `kubejs/server_scripts/00_lore.js` | `/reload` | -| Item/block names + advancement titles/descriptions | `kubejs/assets/scicraft/lang/en_us.json` | resource reload | -| Player messages (tide warnings, signals) | `00_lore.js` → `scicraft.phrases.*` + `en_us.json` | `/reload` | -| Item tooltips (hover lore) | `kubejs/client_scripts/01_tooltips.js` | `F3+T` | -| JEI info pages | `kubejs/client_scripts/02_jei_info.js` | `F3+T` | -| Crafting chain / gating recipes | `kubejs/server_scripts/03_recipes_tags.js` | `/reload` | -| Corruption tide logic | `kubejs/server_scripts/01_corruption_tide.js` | `/reload` | -| Player powers / void hazards | `kubejs/server_scripts/02_events.js` | `/reload` | -| Boss → Photon Fragment drops | `kubejs/server_scripts/04_loot.js` (LootJS) | `/reload` | -| Advancement phase tree | `kubejs/data/scicraft/advancements/protocol/*.json` | `/reload` | -| Advancement reward loot | `kubejs/data/scicraft/loot_tables/protocol/*.json` | `/reload` | -| Item & block definitions (ID, texture, stats) | `kubejs/startup_scripts/registry_blocks.js` | **restart** | -| Textures | `kubejs/assets/scicraft/textures/{item,block}/*.png` | `F3+T` | - -> **Golden rule:** `00_lore.js` is the bible. If you add a new story beat, -> put its strings there first, then reference `SC.` from the other -> scripts. Never hardcode lore text in a script body. - ---- - -## Adding a new story beat (5-minute workflow) - -1. **Edit `00_lore.js`** — add your phrase to `phrases`, or your item to - `items`. -2. **Add the lang key** to `en_us.json` (same key you used in `Text.translate`). -3. **If it's a new item/block**: add to `registry_blocks.js` + run - `tools/gen_textures.py` for a placeholder texture. This step needs a - **full restart**. -4. **Add a tooltip / JEI page** if it's a carried item. -5. **Wire the beat into the tide** (if it's an event) or into a recipe - (if it's a gated item) or into an advancement JSON (if it's a goal). -6. **Sync to both packs:** - ```bash - rm -rf client_pack/kubejs && cp -r server_pack/kubejs client_pack/kubejs - ``` -7. Reload: `/reload` (server scripts/advancements/recipes) or `F3+T` - (client assets/tooltips). Startup item changes require a game restart. - ---- - -## Adding a new advancement node - -Copy `data/scicraft/advancements/protocol/the_core.json` and change: -- `"parent"` — the node before it -- `"title"`/`"description"` — lore text (also add the matching - `advancements.scicraft.protocol..title/.description` keys to `en_us.json`) -- `"criteria"` — the trigger (inventory_changed / changed_dimension / tick) - -Rename the file `.json`. The tree is non-terminal: the Protocol -is maintained, not completed. - ---- - -## Verified IDs (do not guess these — they were checked against the jars) - -| Thing | Correct ID | -|---|---| -| Limbo (Dimensional Doors) | `dimensionaldoors:limbo` | -| The Wound (Void Dimension) | `thevoiddimension:overworld` | -| The Othersides (Deeper & Darker) | `deeperdarker:otherside` | -| Stellaris moon | `stellaris:moon` (mars/venus/mercury likewise) | -| Warden | `minecraft:warden` | -| Mutant Zombie / Skeleton / Enderman | `mutantmonsters:mutant_zombie` / `mutant_skeleton` / `mutant_enderman` | -| Born in Chaos Dark Vortex / Dread Hound / Nightmare Stalker | `born_in_chaos_v1:dark_vortex` / `dread_hound` / `nightmare_stalker` | - -When in doubt, verify against the installed jar before writing an ID into a script. - ---- - -## TODO — future story beats (drop in whenever) - -- [ ] New Doors: a "Door network" that opens/closes on a schedule, each - carrying its own phrase in `00_lore.js`. -- [ ] Star fragments: Stellaris planets each recover a named fragment - ("Mars shard", "Venus shard") → new advancement nodes. -- [ ] Lattice upkeep: it slowly *consumes* Photon Cores while powered; - running dry raises the tide (ties tide to real infrastructure). -- [ ] Final "The Legacy" tier of Renegade Glass builds that hum — block - interactions that whisper one `scicraft.phrases.*` line. -- [ ] FTB Quests questbook mirroring the advancement phases. \ No newline at end of file diff --git a/client_pack/kubejs/assets/scicraft/lang/en_us.json b/client_pack/kubejs/assets/scicraft/lang/en_us.json index 2c7d131..635983c 100644 --- a/client_pack/kubejs/assets/scicraft/lang/en_us.json +++ b/client_pack/kubejs/assets/scicraft/lang/en_us.json @@ -4,6 +4,32 @@ "item.scicraft.void_stabilizer": "Void Stabilizer", "block.scicraft.quantum_lattice": "Quantum Lattice", "block.scicraft.renegade_glass": "Renegade Glass", + "tooltip.scicraft.photon_core.1": "Dark photons — the binding force of the Door.", + "tooltip.scicraft.photon_core.2": "A sliver of the fifth force the Flight harnessed.", + "tooltip.scicraft.photon_core.3": "Hold it and feel the seals.", + "tooltip.scicraft.photon_fragment.1": "A splinter of light stolen from the collapse.", + "tooltip.scicraft.photon_fragment.2": "Recovered from the Darker's remains.", + "tooltip.scicraft.photon_fragment.3": "Three of these may be pressed into a Core.", + "tooltip.scicraft.void_stabilizer.1": "Per Spatium — the renegades' seal for the wound in the world.", + "tooltip.scicraft.void_stabilizer.2": "Right-click a powered Quantum Lattice to re-seal a Door.", + "tooltip.scicraft.void_stabilizer.3": "It will never break. The work will.", + "tooltip.scicraft.quantum_lattice.1": "The Protocol's emitter. It must stay powered.", + "tooltip.scicraft.quantum_lattice.2": "Feed it steel, circuits, and Photon Cores.", + "tooltip.scicraft.quantum_lattice.3": "Right-click with a Void Stabilizer to push back the tide.", + "tooltip.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "tooltip.scicraft.renegade_glass.2": "Decorative. Some say it hums near Doors.", + "jei.scicraft.photon_fragment.1": "The Darker carry these.", + "jei.scicraft.photon_fragment.2": "Slay Wardens, Mutant Monsters, or Born in Chaos mobs to recover them.", + "jei.scicraft.photon_fragment.3": "You can also extract one from an Echo Shard and Glowstone Dust.", + "jei.scicraft.photon_core.1": "Compress three Photon Fragments in a Create Press,", + "jei.scicraft.photon_core.2": "or smelt an Ender Pearl in the heart of the wound.", + "jei.scicraft.void_stabilizer.1": "The seal of the Flight. Crafted from Photon Cores and an Ender Eye.", + "jei.scicraft.void_stabilizer.2": "Use it on a powered Quantum Lattice to re-seal a Door and lower the Corruption Tide.", + "jei.scicraft.quantum_lattice.1": "The emitter of the Dark Photon Protocol.", + "jei.scicraft.quantum_lattice.2": "Powered by steel, circuits, and Photon Cores, it holds the world together.", + "jei.scicraft.quantum_lattice.3": "Right-click it with a Void Stabilizer to push back the global Corruption Tide.", + "jei.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "jei.scicraft.renegade_glass.2": "Decorative. Crafted around a Photon Fragment.", "advancements.scicraft.protocol.root.title": "The Dark Photon Protocol", "advancements.scicraft.protocol.root.description": "The last signal of the Second Renegade Flight has found you. Rebuild the Lattice.", "advancements.scicraft.protocol.first_signal.title": "The Signal", @@ -28,5 +54,6 @@ "scicraft.phrases.lattice_hum": "The Lattice hums. Reality holds — for now.", "scicraft.phrases.tide_low": "The seal holds. The tide is calm.", "scicraft.phrases.tide_mid": "A Door stirs somewhere. The dark is waking.", - "scicraft.phrases.tide_high": "The Darker press against the world. The Protocol calls." -} \ No newline at end of file + "scicraft.phrases.tide_high": "The Darker press against the world. The Protocol calls.", + "scicraft.phrases.seal_fail": "The Lattice sputters. It needs more power — and a Stabilizer." +} diff --git a/client_pack/kubejs/client_scripts/01_tooltips.js b/client_pack/kubejs/client_scripts/01_tooltips.js index 750fb7d..0e0d58b 100644 --- a/client_pack/kubejs/client_scripts/01_tooltips.js +++ b/client_pack/kubejs/client_scripts/01_tooltips.js @@ -1,34 +1,35 @@ // SCICRAFT — The Dark Photon Protocol // Client tooltips: the story rides on the items you carry. +// Text lives in STORY/02-items.md (tooltip.scicraft.* keys) — never hardcode. ItemEvents.tooltip(event => { event.add('scicraft:photon_core', [ '', - '§3Dark photons — the binding force of the Door.', - '§7A sliver of the fifth force the Flight harnessed.', - '§8Hold it and feel the seals.' + Text.translate('tooltip.scicraft.photon_core.1'), + Text.translate('tooltip.scicraft.photon_core.2'), + Text.translate('tooltip.scicraft.photon_core.3') ]) event.add('scicraft:photon_fragment', [ '', - '§3A splinter of light stolen from the collapse.', - '§7Recovered from the Darker\'s remains.', - '§8Three of these may be pressed into a Core.' + Text.translate('tooltip.scicraft.photon_fragment.1'), + Text.translate('tooltip.scicraft.photon_fragment.2'), + Text.translate('tooltip.scicraft.photon_fragment.3') ]) event.add('scicraft:void_stabilizer', [ '', - '§3Per Spatium — the renegades\' seal for the wound in the world.', - '§7Right-click a powered Quantum Lattice to re-seal a Door.', - '§8It will never break. The work will.' + Text.translate('tooltip.scicraft.void_stabilizer.1'), + Text.translate('tooltip.scicraft.void_stabilizer.2'), + Text.translate('tooltip.scicraft.void_stabilizer.3') ]) event.add('scicraft:quantum_lattice', [ '', - '§3The Protocol\'s emitter. It must stay powered.', - '§7Feed it steel, circuits, and Photon Cores.', - '§8Right-click with a Void Stabilizer to push back the tide.' + Text.translate('tooltip.scicraft.quantum_lattice.1'), + Text.translate('tooltip.scicraft.quantum_lattice.2'), + Text.translate('tooltip.scicraft.quantum_lattice.3') ]) event.add('scicraft:renegade_glass', [ '', - '§3The TARDIS-blue glass of the Second Renegade Flight.', - '§7Decorative. Some say it hums near Doors.' + Text.translate('tooltip.scicraft.renegade_glass.1'), + Text.translate('tooltip.scicraft.renegade_glass.2') ]) }) \ No newline at end of file diff --git a/client_pack/kubejs/client_scripts/02_jei_info.js b/client_pack/kubejs/client_scripts/02_jei_info.js index 92df7ab..a623c45 100644 --- a/client_pack/kubejs/client_scripts/02_jei_info.js +++ b/client_pack/kubejs/client_scripts/02_jei_info.js @@ -1,27 +1,28 @@ // SCICRAFT — The Dark Photon Protocol // JEI info pages: where the story is and where to get the pieces. +// Text lives in STORY/02-items.md (jei.scicraft.* keys) — never hardcode. JEIEvents.information(event => { event.addItem('scicraft:photon_fragment', [ - 'The Darker carry these.', - 'Slay Wardens, Mutant Monsters, or Born in Chaos mobs to recover them.', - 'You can also extract one from an Echo Shard and Glowstone Dust.' + Text.translate('jei.scicraft.photon_fragment.1'), + Text.translate('jei.scicraft.photon_fragment.2'), + Text.translate('jei.scicraft.photon_fragment.3') ]) event.addItem('scicraft:photon_core', [ - 'Compress three Photon Fragments in a Create Press,', - 'or smelt an Ender Pearl in the heart of the wound.' + Text.translate('jei.scicraft.photon_core.1'), + Text.translate('jei.scicraft.photon_core.2') ]) event.addItem('scicraft:void_stabilizer', [ - 'The seal of the Flight. Crafted from Photon Cores and an Ender Eye.', - 'Use it on a powered Quantum Lattice to re-seal a Door and lower the Corruption Tide.' + Text.translate('jei.scicraft.void_stabilizer.1'), + Text.translate('jei.scicraft.void_stabilizer.2') ]) event.addItem('scicraft:quantum_lattice', [ - 'The emitter of the Dark Photon Protocol.', - 'Powered by steel, circuits, and Photon Cores, it holds the world together.', - 'Right-click it with a Void Stabilizer to push back the global Corruption Tide.' + Text.translate('jei.scicraft.quantum_lattice.1'), + Text.translate('jei.scicraft.quantum_lattice.2'), + Text.translate('jei.scicraft.quantum_lattice.3') ]) event.addItem('scicraft:renegade_glass', [ - 'The TARDIS-blue glass of the Second Renegade Flight.', - 'Decorative. Crafted around a Photon Fragment.' + Text.translate('jei.scicraft.renegade_glass.1'), + Text.translate('jei.scicraft.renegade_glass.2') ]) }) \ No newline at end of file diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json b/client_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json index 33e63e0..72bda3a 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/root", "display": { - "icon": { "item": "scicraft:photon_fragment" }, - "title": { "text": "The Signal" }, - "description": { "text": "Recover your first Photon Fragment from a creature of the Dark." }, + "icon": { + "item": "scicraft:photon_fragment" + }, + "title": { + "translate": "advancements.scicraft.protocol.first_signal.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.first_signal.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_fragment": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:photon_fragment"] }] + "items": [ + { + "items": [ + "scicraft:photon_fragment" + ] + } + ] } } }, - "requirements": [["has_fragment"]], - "rewards": { "experience": 100 } -} \ No newline at end of file + "requirements": [ + [ + "has_fragment" + ] + ], + "rewards": { + "experience": 100 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json b/client_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json index fe78127..6d03d04 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "stellaris:rocket" }, - "title": { "text": "Per Spatium" }, - "description": { "text": "Launch a rocket. The Flight's data was scattered across the stars." }, + "icon": { + "item": "stellaris:rocket" + }, + "title": { + "translate": "advancements.scicraft.protocol.per_spatium.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.per_spatium.description" + }, "frame": "goal", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "launch_rocket": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "stellaris:moon" } + "conditions": { + "to": "stellaris:moon" + } } }, - "requirements": [["launch_rocket"]], - "rewards": { "experience": 600 } -} \ No newline at end of file + "requirements": [ + [ + "launch_rocket" + ] + ], + "rewards": { + "experience": 600 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/root.json b/client_pack/kubejs/data/scicraft/advancements/protocol/root.json index d32e38e..49bb2c3 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/root.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/root.json @@ -1,8 +1,14 @@ { "display": { - "icon": { "item": "scicraft:photon_core" }, - "title": { "text": "The Dark Photon Protocol" }, - "description": { "text": "The last signal of the Second Renegade Flight has found you. Rebuild the Lattice." }, + "icon": { + "item": "scicraft:photon_core" + }, + "title": { + "translate": "advancements.scicraft.protocol.root.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.root.description" + }, "background": "minecraft:textures/block/blackstone.png", "frame": "task", "show_toast": true, @@ -15,6 +21,14 @@ "conditions": {} } }, - "requirements": [["first_signal"]], - "rewards": { "loot": ["scicraft:protocol/root_reward"] } -} \ No newline at end of file + "requirements": [ + [ + "first_signal" + ] + ], + "rewards": { + "loot": [ + "scicraft:protocol/root_reward" + ] + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json index 9e3b2f0..e34f257 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "minecraft:sculk_sensor" }, - "title": { "text": "The Answer" }, - "description": { "text": "Reach the Othersides of the Deeper and Darker — what answers from inside the prison." }, + "icon": { + "item": "minecraft:sculk_sensor" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_answer.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_answer.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_darker": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "deeperdarker:otherside" } + "conditions": { + "to": "deeperdarker:otherside" + } } }, - "requirements": [["enter_darker"]], - "rewards": { "experience": 750 } -} \ No newline at end of file + "requirements": [ + [ + "enter_darker" + ] + ], + "rewards": { + "experience": 750 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_core.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_core.json index 06bb26a..906711d 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_core.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_core.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/first_signal", "display": { - "icon": { "item": "scicraft:photon_core" }, - "title": { "text": "The Core" }, - "description": { "text": "Press three Fragments into a Photon Core." }, + "icon": { + "item": "scicraft:photon_core" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_core.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_core.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_core": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:photon_core"] }] + "items": [ + { + "items": [ + "scicraft:photon_core" + ] + } + ] } } }, - "requirements": [["has_core"]], - "rewards": { "experience": 250 } -} \ No newline at end of file + "requirements": [ + [ + "has_core" + ] + ], + "rewards": { + "experience": 250 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json index 9ceab8d..0ece078 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_seal", "display": { - "icon": { "item": "scicraft:quantum_lattice" }, - "title": { "text": "The Lattice" }, - "description": { "text": "Assemble the Quantum Lattice — the Protocol's emitter — and keep it powered." }, + "icon": { + "item": "scicraft:quantum_lattice" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_lattice.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_lattice.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_lattice": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:quantum_lattice"] }] + "items": [ + { + "items": [ + "scicraft:quantum_lattice" + ] + } + ] } } }, - "requirements": [["has_lattice"]], - "rewards": { "experience": 1000 } -} \ No newline at end of file + "requirements": [ + [ + "has_lattice" + ] + ], + "rewards": { + "experience": 1000 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json index 35fa14a..f6fb54e 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "scicraft:renegade_glass" }, - "title": { "text": "The Legacy" }, - "description": { "text": "Craft Renegade Glass — rebuild what the Flight left behind." }, + "icon": { + "item": "scicraft:renegade_glass" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_legacy.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_legacy.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_glass": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:renegade_glass"] }] + "items": [ + { + "items": [ + "scicraft:renegade_glass" + ] + } + ] } } }, - "requirements": [["has_glass"]], - "rewards": { "experience": 300 } -} \ No newline at end of file + "requirements": [ + [ + "has_glass" + ] + ], + "rewards": { + "experience": 300 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json index 7f0ff02..5fd892e 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_core", "display": { - "icon": { "item": "scicraft:void_stabilizer" }, - "title": { "text": "The Seal" }, - "description": { "text": "Craft the Void Stabilizer — the renegades' tool for closing wounds." }, + "icon": { + "item": "scicraft:void_stabilizer" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_seal.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_seal.description" + }, "frame": "goal", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_stabilizer": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:void_stabilizer"] }] + "items": [ + { + "items": [ + "scicraft:void_stabilizer" + ] + } + ] } } }, - "requirements": [["has_stabilizer"]], - "rewards": { "experience": 500 } -} \ No newline at end of file + "requirements": [ + [ + "has_stabilizer" + ] + ], + "rewards": { + "experience": 500 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json b/client_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json index 114afaf..5bc94be 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "minecraft:respawn_anchor" }, - "title": { "text": "The Wound" }, - "description": { "text": "Descend into the Void Dimension — the raw leak of the collapsing empire." }, + "icon": { + "item": "minecraft:respawn_anchor" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_wound.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_wound.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_void": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "thevoiddimension:overworld" } + "conditions": { + "to": "thevoiddimension:overworld" + } } }, - "requirements": [["enter_void"]], - "rewards": { "experience": 750 } -} \ No newline at end of file + "requirements": [ + [ + "enter_void" + ] + ], + "rewards": { + "experience": 750 + } +} diff --git a/client_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json b/client_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json index bb6fa00..9e494ea 100644 --- a/client_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json +++ b/client_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_seal", "display": { - "icon": { "item": "minecraft:ender_eye" }, - "title": { "text": "Through the Doors" }, - "description": { "text": "Enter a Dimensional Door. The scar-tissue of the Flight's prison." }, + "icon": { + "item": "minecraft:ender_eye" + }, + "title": { + "translate": "advancements.scicraft.protocol.through_the_doors.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.through_the_doors.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_doors": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "dimensionaldoors:limbo" } + "conditions": { + "to": "dimensionaldoors:limbo" + } } }, - "requirements": [["enter_doors"]], - "rewards": { "experience": 400 } -} \ No newline at end of file + "requirements": [ + [ + "enter_doors" + ] + ], + "rewards": { + "experience": 400 + } +} diff --git a/client_pack/kubejs/server_scripts/00_lore.js b/client_pack/kubejs/server_scripts/00_lore.js index d256265..f98d53b 100644 --- a/client_pack/kubejs/server_scripts/00_lore.js +++ b/client_pack/kubejs/server_scripts/00_lore.js @@ -1,6 +1,6 @@ // SCICRAFT — The Dark Photon Protocol -// THE STORY BIBLE. Edit lore here; every script reads from this object. -// Reload with /reload after editing (startup items require a restart). +// CONFIG OBJECT. Text lives in STORY/*.md (generated into en_us.json) — +// never hardcode story strings here. /reload after editing. global.SCICRAFT = { items: { @@ -29,14 +29,5 @@ global.SCICRAFT = { void_dim: 'thevoiddimension:overworld', darker_dim: 'deeperdarker:otherside', dimensional_doors: 'dimensionaldoors:limbo' - }, - - phrases: { - signal: 'The last signal of the Second Renegade Flight hums in your blood.', - lattice_hum: 'The Lattice hums. Reality holds — for now.', - tide_low: 'The seal holds. The tide is calm.', - tide_mid: 'A Door stirs somewhere. The dark is waking.', - tide_high: 'The Darker press against the world. The Protocol calls.', - seal_fail: 'The Lattice sputters. It needs more power — and a Stabilizer.' } } \ No newline at end of file diff --git a/client_pack/kubejs/server_scripts/02_events.js b/client_pack/kubejs/server_scripts/02_events.js index c684bf9..b6d7fca 100644 --- a/client_pack/kubejs/server_scripts/02_events.js +++ b/client_pack/kubejs/server_scripts/02_events.js @@ -35,11 +35,5 @@ PlayerEvents.tick(event => { PlayerEvents.loggedIn(event => { event.player.tell(Text.translate('scicraft.phrases.signal')) }) - -// The very first fragment always drops when a Darker falls — never lost. -EntityEvents.death(event => { - const ent = event.entity - if (ent.type === 'minecraft:warden') { - ent.level.spawnItem('scicraft:photon_fragment', ent.blockPosition(), { count: 2 }) - } -}) \ No newline at end of file +// Note: Warden fragment drops are handled in 04_loot.js (LootJS) — do not +// duplicate them here or players get double drops. \ No newline at end of file diff --git a/client_pack/kubejs/startup_scripts/registry_blocks.js b/client_pack/kubejs/startup_scripts/registry_blocks.js index a6fb844..546e3d2 100644 --- a/client_pack/kubejs/startup_scripts/registry_blocks.js +++ b/client_pack/kubejs/startup_scripts/registry_blocks.js @@ -1,5 +1,6 @@ // SCICRAFT — The Dark Photon Protocol // Custom items & blocks for the Protocol. +// Names + tooltips come from the lang file (STORY/*.md → en_us.json). // Startup scripts: requires a full restart to apply. const SC = global.SCICRAFT @@ -7,38 +8,31 @@ const SC = global.SCICRAFT StartupEvents.registry('item', event => { // Photon Core — the raw fifth-force crystal. Lattice fuel. event.create('scicraft:photon_core') - .displayName('Photon Core') .texture('scicraft:item/photon_core') .maxStackSize(64) .tag('scicraft:photon') .tag('c:gems') .glow(true) - .tooltip('Dark photons — the binding force of the Door.') // Photon Fragment — shattered cores recovered from the Darker. event.create('scicraft:photon_fragment') - .displayName('Photon Fragment') .texture('scicraft:item/photon_fragment') .maxStackSize(64) .tag('scicraft:photon') .tag('c:gems') .glow(true) - .tooltip('A splinter of light stolen from the collapse.') // Void Stabilizer — the tool that re-seals Doors at the Lattice. event.create('scicraft:void_stabilizer') - .displayName('Void Stabilizer') .texture('scicraft:item/void_stabilizer') .maxStackSize(1) .unbreakable() .tag('scicraft:stabilizer') - .tooltip('Per Spatium — the renegades\' seal for the wound in the world.') }) StartupEvents.registry('block', event => { // Quantum Lattice — the Protocol's emitter. Must stay powered. event.create('scicraft:quantum_lattice', 'basic') - .displayName('Quantum Lattice') .textureAll('scicraft:block/quantum_lattice') .hardness(5.0) .resistance(1200.0) @@ -49,7 +43,6 @@ StartupEvents.registry('block', event => { // Renegade Glass — the TARDIS-blue glass of the Flight. Purely decorative. event.create('scicraft:renegade_glass', 'glass') - .displayName('Renegade Glass') .textureAll('scicraft:block/renegade_glass') .hardness(0.3) .resistance(0.3) diff --git a/docs/00-index.md b/docs/00-index.md new file mode 100644 index 0000000..a684268 --- /dev/null +++ b/docs/00-index.md @@ -0,0 +1,35 @@ +# Docs Index — SCICRAFT: The Dark Photon Protocol + +**NeoForge 1.21.1 (21.1.248) · packwiz v1.1.0 · version 1.0.0** + +This folder holds every operational guide. Story/canon content lives in +`STORY/` (see `STORY/00-index.md`); repo overview lives in `README.md`. + +## Guides + +| File | What it covers | +|------|----------------| +| `setup.md` | Install & update (server + client), adding/removing mods | +| `server.md` | Server properties, JVM flags, operations, troubleshooting | +| `performance.md` | Shader tuning (4GB VRAM preset) and client perf notes | +| `mods.md` | Mod feature hotspots, pack layout, client-only list | + +## Quick links + +- **Story** → `STORY/00-index.md` +- **Repo overview** → `README.md` +- **Tools** → `tools/` (`gen_story.py`, `sync_kubejs.sh`, `gen_textures.py`) + +## The two packs + +| Path | Contents | +|------|----------| +| `./server_pack/` | Server-only modpack (135 mod files). No shaders, no client render mods. | +| `./client_pack/` | Full client pack (144 mod files). Adds Iris + Sodium (native NeoForge), Cull Leaves, LambDynamicLights, Dynamic FPS, 3D Skin Layers, Visuality, flywheel compat. | + +Keep them in sync after any change: + +```bash +bash tools/sync_kubejs.sh # kubejs/ → client_pack +packwiz refresh --dir server_pack && packwiz refresh --dir client_pack +``` \ No newline at end of file diff --git a/docs/mods.md b/docs/mods.md new file mode 100644 index 0000000..c318641 --- /dev/null +++ b/docs/mods.md @@ -0,0 +1,27 @@ +# Mods — Hotspots & Pack Layout + +## Mod Feature Hotspots (Quick Orientation) + +| Domain | Mods | Notes | +|--------|------|-------| +| Power | Mekanism (turbine/boiler), Flux Networks | Flux wireless transfer; Mekanism cables for bulk | +| Storage | AE2, Sophisticated Storage, Functional Storage, Sophisticated Backpacks | AE2 for autocraft; Sophisticated for bulk; Functional for drawers | +| Logistics | LaserIO, Modular Routers, Entangled, FastPipes, Create belts | FastPipes adds vanilla pipe QoL | +| Automation | Create + Steam 'n' Rails + Rechiseled + FastPipes | Flywheel + Iris compat bundled | +| Tech Building | Building Gadgets, Hologenica, FramedBlocks, Chipped, Supplementaries | | +| Dimensions | Per Spatium/Stellaris, Dimensional Doors, Void Dimension, Deeper and Darker | Stellaris portal → rockets; Doors are the endgame hook | +| Mobs/Combat | Born in Chaos, Mutant Monsters, Nyf's Spiders, Better Combat, Simply Swords | Hard difficulty | +| UI/QoL | JEI, Jade (+Addons), JourneyMap, Waystones, AppleSkin, IPN, Clumps, Mouse Tweaks | JEI is the recipe source (no EMI) | +| Scripting | KubeJS (+Create, +Mekanism), LootJS, Blocks You Need | Advancements & loot live here | +| Server utils | FTB Chunks/Quests/Teams/Library | Chunk claims + questbook | + +## Key client-only mods (server must NOT have these) + +`iris`, `sodium`, `iris-flw-compat`, `cull-leaves`, `lambdynamiclights`, +`dynamic-fps`, `3dskinlayers`, `visuality-forge`, `midnightlib`. + +## Bridge layer (both packs) + +Sinytra Connector + Forgified Fabric API run a small set of Fabric mods +(Immersive Portals, LambDynamicLights, Waystones-compat). Do not remove +either; the pack will not boot without them. \ No newline at end of file diff --git a/docs/performance.md b/docs/performance.md new file mode 100644 index 0000000..0add0f6 --- /dev/null +++ b/docs/performance.md @@ -0,0 +1,25 @@ +# Performance — Client + +## Shader Tuning for 4GB VRAM + +Shader loader is **Iris** (native NeoForge). Recommended shaderpack: +**Complementary Reimagined r5.4** (`client_pack/shaderpacks/`, see README). + +Preset for 4GB VRAM: +- Preset: **Fast / Performance** +- Render Distance: **8** (server view-distance) +- Antialiasing: **OFF** +- SSAO: **Fast**, Shadow Quality **1.0x** (0.5x if <30 FPS) +- Shadow Distance: **64** +- Bloom: **OFF/Low**, Clouds: **2D Fast** +- Water Reflections: **Screenspace Fast** +- Colored Light / Block Light: **OFF** + +If still under 60 FPS: reduce Shadow Quality to 0.5x, then disable Bloom, +before touching render distance. + +## Reload rules + +- Server scripts / recipes / advancements: `/reload` +- Client tooltips / JEI / textures / lang: `F3+T` +- New items/blocks (`registry_blocks.js`): **full restart** \ No newline at end of file diff --git a/docs/server.md b/docs/server.md new file mode 100644 index 0000000..765e620 --- /dev/null +++ b/docs/server.md @@ -0,0 +1,71 @@ +# Server — Properties, JVM, Operations + +## Server properties (view-distance=8, simulation-distance=6) + +`server_pack/server.properties` — set these values: + +```properties +view-distance=8 +simulation-distance=6 +max-players=8 +motd=SCICRAFT - The Dark Photon Protocol +difficulty=hard +spawn-protection=0 +network-compression-threshold=256 +enable-command-block=true +online-mode=true +``` + +`server_pack/eula.txt` → `eula=true` (after review). + +## Recommended JVM Flags (server) + +```bash +java -Xms4G -Xmx8G \ + -XX:+UseG1GC \ + -XX:+ParallelRefProcEnabled \ + -XX:MaxGCPauseMillis=200 \ + -XX:+UnlockExperimentalVMOptions \ + -XX:+DisableExplicitGC \ + -XX:+AlwaysPreTouch \ + -XX:G1NewSizePercent=30 \ + -XX:G1MaxNewSizePercent=40 \ + -XX:G1HeapRegionSize=8M \ + -XX:G1ReservePercent=20 \ + -XX:G1HeapWastePercent=5 \ + -XX:G1MixedGCCountTarget=4 \ + -XX:InitiatingHeapOccupancyPercent=15 \ + -XX:G1MixedGCLiveThresholdPercent=90 \ + -XX:G1RSetUpdatingPauseTimePercent=5 \ + -Dlog4j2.formatMsgNoLookups=true \ + -jar neoforge-21.1.248-server.jar nogui +``` + +Notes: +- G1 tuning keeps large-tech-server TPS stable under chunk gen (Krypton + Reno + BadOptimizations help server-side). +- `-Xms4G` avoids early GC churn. Cap at 8G; this pack is RAM-hungry + from AE2/Mekanism tick load but does not need 16G. + +## Server start order + +1. `packwiz install --dir server_pack` (first time / after changes) +2. Accept EULA. +3. Launch with the JVM flags above. + +## Common failures + +| Symptom | Fix | +|---------|-----| +| "Mismatched mods" on client join | Run `packwiz refresh` both packs, redeploy. | +| Sinytra connector errors | Update Sinytra Connector + Forgified Fabric API together. | +| Iris black screen | Disable flywheel compat first, then test without shaders. | +| Crash on world gen (Deeper and Darker) | Ensure CF 659011 + its lithostitched data load; update both. | +| TPS lag from many AE2 cells | Check FTB chunk claims; lower `simulation-distance`. | +| Immersive Portals won't load | Must be the Fabric jar added via `url add --force` (Modrinth blocks loader mismatch). | + +## Backups + +- World: copy `server_pack/world/` (or use FTB Chunks backups). +- Configs: `server_pack/config/` mirrors client defaults; keep both in sync + when changing KubeJS scripts or FTB settings. \ No newline at end of file diff --git a/docs/setup.md b/docs/setup.md new file mode 100644 index 0000000..f78154b --- /dev/null +++ b/docs/setup.md @@ -0,0 +1,61 @@ +# Setup — Install & Update + +## Prereqs + +- Java 21 (Adoptium Temurin 21 LTS recommended) +- ~12 GB RAM free for client, 8 GB minimum for server +- Disk: keep under **100 GB** total for world + packs + +## First-time server setup + +```bash +# from this repo root +packwiz install --dir server_pack # downloads all mods into server_pack/ +java -Xms2G -Xmx6G -jar server_pack/neoforge-21.1.248-installer.jar --installServer +# accept EULA, then launch: +java -Xms2G -Xmx6G -XX:+UseG1GC -jar server_pack/neoforge-21.1.248-server.jar nogui +``` + +## First-time client setup + +```bash +git clone git@git.mithraic.cloud:ad3laid3/SciCraft.git +cd SciCraft +packwiz install --dir client_pack +``` + +Add `client_pack` as a **packwiz** modpack in your launcher +(Prism/ATLauncher/PolyMC) or use `packwiz serve` from `client_pack` and +install via the Modrinth/packwiz installers. Drop a shaderpack into +`client_pack/shaderpacks/` — see the README there for the 4 GB VRAM preset. + +> **Multiplayer:** players join with the **client pack**; the server runs +> the **server pack**. Never put client-only mods on the server (see +> `mods.md`). + +## Adding a mod (both packs) + +```bash +packwiz --dir server_pack curseforge add --addon-id -y +packwiz --dir client_pack curseforge add --addon-id -y +packwiz --dir server_pack modrinth add -y +packwiz --dir client_pack modrinth add -y +packwiz --dir server_pack refresh +packwiz --dir client_pack refresh +``` + +- Always add to **both** packs unless the mod is client- or server-only. +- For Fabric mods that must run through Sinytra, use + `packwiz url add "" "" --force` and verify the Sinytra + connector tolerates the version. + +## Editing story text + +```bash +# edit STORY/*.md first, then: +python tools/gen_story.py # regenerates en_us.json in BOTH packs +bash tools/sync_kubejs.sh # mirrors server_pack/kubejs → client_pack/kubejs +``` + +Never hand-edit `en_us.json` — it is generated. Full workflow: +`STORY/00-index.md`. \ No newline at end of file diff --git a/server_pack/kubejs/assets/scicraft/lang/en_us.json b/server_pack/kubejs/assets/scicraft/lang/en_us.json index 2c7d131..635983c 100644 --- a/server_pack/kubejs/assets/scicraft/lang/en_us.json +++ b/server_pack/kubejs/assets/scicraft/lang/en_us.json @@ -4,6 +4,32 @@ "item.scicraft.void_stabilizer": "Void Stabilizer", "block.scicraft.quantum_lattice": "Quantum Lattice", "block.scicraft.renegade_glass": "Renegade Glass", + "tooltip.scicraft.photon_core.1": "Dark photons — the binding force of the Door.", + "tooltip.scicraft.photon_core.2": "A sliver of the fifth force the Flight harnessed.", + "tooltip.scicraft.photon_core.3": "Hold it and feel the seals.", + "tooltip.scicraft.photon_fragment.1": "A splinter of light stolen from the collapse.", + "tooltip.scicraft.photon_fragment.2": "Recovered from the Darker's remains.", + "tooltip.scicraft.photon_fragment.3": "Three of these may be pressed into a Core.", + "tooltip.scicraft.void_stabilizer.1": "Per Spatium — the renegades' seal for the wound in the world.", + "tooltip.scicraft.void_stabilizer.2": "Right-click a powered Quantum Lattice to re-seal a Door.", + "tooltip.scicraft.void_stabilizer.3": "It will never break. The work will.", + "tooltip.scicraft.quantum_lattice.1": "The Protocol's emitter. It must stay powered.", + "tooltip.scicraft.quantum_lattice.2": "Feed it steel, circuits, and Photon Cores.", + "tooltip.scicraft.quantum_lattice.3": "Right-click with a Void Stabilizer to push back the tide.", + "tooltip.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "tooltip.scicraft.renegade_glass.2": "Decorative. Some say it hums near Doors.", + "jei.scicraft.photon_fragment.1": "The Darker carry these.", + "jei.scicraft.photon_fragment.2": "Slay Wardens, Mutant Monsters, or Born in Chaos mobs to recover them.", + "jei.scicraft.photon_fragment.3": "You can also extract one from an Echo Shard and Glowstone Dust.", + "jei.scicraft.photon_core.1": "Compress three Photon Fragments in a Create Press,", + "jei.scicraft.photon_core.2": "or smelt an Ender Pearl in the heart of the wound.", + "jei.scicraft.void_stabilizer.1": "The seal of the Flight. Crafted from Photon Cores and an Ender Eye.", + "jei.scicraft.void_stabilizer.2": "Use it on a powered Quantum Lattice to re-seal a Door and lower the Corruption Tide.", + "jei.scicraft.quantum_lattice.1": "The emitter of the Dark Photon Protocol.", + "jei.scicraft.quantum_lattice.2": "Powered by steel, circuits, and Photon Cores, it holds the world together.", + "jei.scicraft.quantum_lattice.3": "Right-click it with a Void Stabilizer to push back the global Corruption Tide.", + "jei.scicraft.renegade_glass.1": "The TARDIS-blue glass of the Second Renegade Flight.", + "jei.scicraft.renegade_glass.2": "Decorative. Crafted around a Photon Fragment.", "advancements.scicraft.protocol.root.title": "The Dark Photon Protocol", "advancements.scicraft.protocol.root.description": "The last signal of the Second Renegade Flight has found you. Rebuild the Lattice.", "advancements.scicraft.protocol.first_signal.title": "The Signal", @@ -28,5 +54,6 @@ "scicraft.phrases.lattice_hum": "The Lattice hums. Reality holds — for now.", "scicraft.phrases.tide_low": "The seal holds. The tide is calm.", "scicraft.phrases.tide_mid": "A Door stirs somewhere. The dark is waking.", - "scicraft.phrases.tide_high": "The Darker press against the world. The Protocol calls." -} \ No newline at end of file + "scicraft.phrases.tide_high": "The Darker press against the world. The Protocol calls.", + "scicraft.phrases.seal_fail": "The Lattice sputters. It needs more power — and a Stabilizer." +} diff --git a/server_pack/kubejs/client_scripts/01_tooltips.js b/server_pack/kubejs/client_scripts/01_tooltips.js index 750fb7d..0e0d58b 100644 --- a/server_pack/kubejs/client_scripts/01_tooltips.js +++ b/server_pack/kubejs/client_scripts/01_tooltips.js @@ -1,34 +1,35 @@ // SCICRAFT — The Dark Photon Protocol // Client tooltips: the story rides on the items you carry. +// Text lives in STORY/02-items.md (tooltip.scicraft.* keys) — never hardcode. ItemEvents.tooltip(event => { event.add('scicraft:photon_core', [ '', - '§3Dark photons — the binding force of the Door.', - '§7A sliver of the fifth force the Flight harnessed.', - '§8Hold it and feel the seals.' + Text.translate('tooltip.scicraft.photon_core.1'), + Text.translate('tooltip.scicraft.photon_core.2'), + Text.translate('tooltip.scicraft.photon_core.3') ]) event.add('scicraft:photon_fragment', [ '', - '§3A splinter of light stolen from the collapse.', - '§7Recovered from the Darker\'s remains.', - '§8Three of these may be pressed into a Core.' + Text.translate('tooltip.scicraft.photon_fragment.1'), + Text.translate('tooltip.scicraft.photon_fragment.2'), + Text.translate('tooltip.scicraft.photon_fragment.3') ]) event.add('scicraft:void_stabilizer', [ '', - '§3Per Spatium — the renegades\' seal for the wound in the world.', - '§7Right-click a powered Quantum Lattice to re-seal a Door.', - '§8It will never break. The work will.' + Text.translate('tooltip.scicraft.void_stabilizer.1'), + Text.translate('tooltip.scicraft.void_stabilizer.2'), + Text.translate('tooltip.scicraft.void_stabilizer.3') ]) event.add('scicraft:quantum_lattice', [ '', - '§3The Protocol\'s emitter. It must stay powered.', - '§7Feed it steel, circuits, and Photon Cores.', - '§8Right-click with a Void Stabilizer to push back the tide.' + Text.translate('tooltip.scicraft.quantum_lattice.1'), + Text.translate('tooltip.scicraft.quantum_lattice.2'), + Text.translate('tooltip.scicraft.quantum_lattice.3') ]) event.add('scicraft:renegade_glass', [ '', - '§3The TARDIS-blue glass of the Second Renegade Flight.', - '§7Decorative. Some say it hums near Doors.' + Text.translate('tooltip.scicraft.renegade_glass.1'), + Text.translate('tooltip.scicraft.renegade_glass.2') ]) }) \ No newline at end of file diff --git a/server_pack/kubejs/client_scripts/02_jei_info.js b/server_pack/kubejs/client_scripts/02_jei_info.js index 92df7ab..a623c45 100644 --- a/server_pack/kubejs/client_scripts/02_jei_info.js +++ b/server_pack/kubejs/client_scripts/02_jei_info.js @@ -1,27 +1,28 @@ // SCICRAFT — The Dark Photon Protocol // JEI info pages: where the story is and where to get the pieces. +// Text lives in STORY/02-items.md (jei.scicraft.* keys) — never hardcode. JEIEvents.information(event => { event.addItem('scicraft:photon_fragment', [ - 'The Darker carry these.', - 'Slay Wardens, Mutant Monsters, or Born in Chaos mobs to recover them.', - 'You can also extract one from an Echo Shard and Glowstone Dust.' + Text.translate('jei.scicraft.photon_fragment.1'), + Text.translate('jei.scicraft.photon_fragment.2'), + Text.translate('jei.scicraft.photon_fragment.3') ]) event.addItem('scicraft:photon_core', [ - 'Compress three Photon Fragments in a Create Press,', - 'or smelt an Ender Pearl in the heart of the wound.' + Text.translate('jei.scicraft.photon_core.1'), + Text.translate('jei.scicraft.photon_core.2') ]) event.addItem('scicraft:void_stabilizer', [ - 'The seal of the Flight. Crafted from Photon Cores and an Ender Eye.', - 'Use it on a powered Quantum Lattice to re-seal a Door and lower the Corruption Tide.' + Text.translate('jei.scicraft.void_stabilizer.1'), + Text.translate('jei.scicraft.void_stabilizer.2') ]) event.addItem('scicraft:quantum_lattice', [ - 'The emitter of the Dark Photon Protocol.', - 'Powered by steel, circuits, and Photon Cores, it holds the world together.', - 'Right-click it with a Void Stabilizer to push back the global Corruption Tide.' + Text.translate('jei.scicraft.quantum_lattice.1'), + Text.translate('jei.scicraft.quantum_lattice.2'), + Text.translate('jei.scicraft.quantum_lattice.3') ]) event.addItem('scicraft:renegade_glass', [ - 'The TARDIS-blue glass of the Second Renegade Flight.', - 'Decorative. Crafted around a Photon Fragment.' + Text.translate('jei.scicraft.renegade_glass.1'), + Text.translate('jei.scicraft.renegade_glass.2') ]) }) \ No newline at end of file diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json b/server_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json index 33e63e0..72bda3a 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/first_signal.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/root", "display": { - "icon": { "item": "scicraft:photon_fragment" }, - "title": { "text": "The Signal" }, - "description": { "text": "Recover your first Photon Fragment from a creature of the Dark." }, + "icon": { + "item": "scicraft:photon_fragment" + }, + "title": { + "translate": "advancements.scicraft.protocol.first_signal.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.first_signal.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_fragment": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:photon_fragment"] }] + "items": [ + { + "items": [ + "scicraft:photon_fragment" + ] + } + ] } } }, - "requirements": [["has_fragment"]], - "rewards": { "experience": 100 } -} \ No newline at end of file + "requirements": [ + [ + "has_fragment" + ] + ], + "rewards": { + "experience": 100 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json b/server_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json index fe78127..6d03d04 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/per_spatium.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "stellaris:rocket" }, - "title": { "text": "Per Spatium" }, - "description": { "text": "Launch a rocket. The Flight's data was scattered across the stars." }, + "icon": { + "item": "stellaris:rocket" + }, + "title": { + "translate": "advancements.scicraft.protocol.per_spatium.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.per_spatium.description" + }, "frame": "goal", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "launch_rocket": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "stellaris:moon" } + "conditions": { + "to": "stellaris:moon" + } } }, - "requirements": [["launch_rocket"]], - "rewards": { "experience": 600 } -} \ No newline at end of file + "requirements": [ + [ + "launch_rocket" + ] + ], + "rewards": { + "experience": 600 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/root.json b/server_pack/kubejs/data/scicraft/advancements/protocol/root.json index d32e38e..49bb2c3 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/root.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/root.json @@ -1,8 +1,14 @@ { "display": { - "icon": { "item": "scicraft:photon_core" }, - "title": { "text": "The Dark Photon Protocol" }, - "description": { "text": "The last signal of the Second Renegade Flight has found you. Rebuild the Lattice." }, + "icon": { + "item": "scicraft:photon_core" + }, + "title": { + "translate": "advancements.scicraft.protocol.root.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.root.description" + }, "background": "minecraft:textures/block/blackstone.png", "frame": "task", "show_toast": true, @@ -15,6 +21,14 @@ "conditions": {} } }, - "requirements": [["first_signal"]], - "rewards": { "loot": ["scicraft:protocol/root_reward"] } -} \ No newline at end of file + "requirements": [ + [ + "first_signal" + ] + ], + "rewards": { + "loot": [ + "scicraft:protocol/root_reward" + ] + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json index 9e3b2f0..e34f257 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_answer.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "minecraft:sculk_sensor" }, - "title": { "text": "The Answer" }, - "description": { "text": "Reach the Othersides of the Deeper and Darker — what answers from inside the prison." }, + "icon": { + "item": "minecraft:sculk_sensor" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_answer.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_answer.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_darker": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "deeperdarker:otherside" } + "conditions": { + "to": "deeperdarker:otherside" + } } }, - "requirements": [["enter_darker"]], - "rewards": { "experience": 750 } -} \ No newline at end of file + "requirements": [ + [ + "enter_darker" + ] + ], + "rewards": { + "experience": 750 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_core.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_core.json index 06bb26a..906711d 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_core.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_core.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/first_signal", "display": { - "icon": { "item": "scicraft:photon_core" }, - "title": { "text": "The Core" }, - "description": { "text": "Press three Fragments into a Photon Core." }, + "icon": { + "item": "scicraft:photon_core" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_core.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_core.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_core": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:photon_core"] }] + "items": [ + { + "items": [ + "scicraft:photon_core" + ] + } + ] } } }, - "requirements": [["has_core"]], - "rewards": { "experience": 250 } -} \ No newline at end of file + "requirements": [ + [ + "has_core" + ] + ], + "rewards": { + "experience": 250 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json index 9ceab8d..0ece078 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_lattice.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_seal", "display": { - "icon": { "item": "scicraft:quantum_lattice" }, - "title": { "text": "The Lattice" }, - "description": { "text": "Assemble the Quantum Lattice — the Protocol's emitter — and keep it powered." }, + "icon": { + "item": "scicraft:quantum_lattice" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_lattice.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_lattice.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_lattice": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:quantum_lattice"] }] + "items": [ + { + "items": [ + "scicraft:quantum_lattice" + ] + } + ] } } }, - "requirements": [["has_lattice"]], - "rewards": { "experience": 1000 } -} \ No newline at end of file + "requirements": [ + [ + "has_lattice" + ] + ], + "rewards": { + "experience": 1000 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json index 35fa14a..f6fb54e 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_legacy.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "scicraft:renegade_glass" }, - "title": { "text": "The Legacy" }, - "description": { "text": "Craft Renegade Glass — rebuild what the Flight left behind." }, + "icon": { + "item": "scicraft:renegade_glass" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_legacy.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_legacy.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_glass": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:renegade_glass"] }] + "items": [ + { + "items": [ + "scicraft:renegade_glass" + ] + } + ] } } }, - "requirements": [["has_glass"]], - "rewards": { "experience": 300 } -} \ No newline at end of file + "requirements": [ + [ + "has_glass" + ] + ], + "rewards": { + "experience": 300 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json index 7f0ff02..5fd892e 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_seal.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_core", "display": { - "icon": { "item": "scicraft:void_stabilizer" }, - "title": { "text": "The Seal" }, - "description": { "text": "Craft the Void Stabilizer — the renegades' tool for closing wounds." }, + "icon": { + "item": "scicraft:void_stabilizer" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_seal.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_seal.description" + }, "frame": "goal", "show_toast": true, "announce_to_chat": true, @@ -13,10 +19,22 @@ "has_stabilizer": { "trigger": "minecraft:inventory_changed", "conditions": { - "items": [{ "items": ["scicraft:void_stabilizer"] }] + "items": [ + { + "items": [ + "scicraft:void_stabilizer" + ] + } + ] } } }, - "requirements": [["has_stabilizer"]], - "rewards": { "experience": 500 } -} \ No newline at end of file + "requirements": [ + [ + "has_stabilizer" + ] + ], + "rewards": { + "experience": 500 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json b/server_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json index 114afaf..5bc94be 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/the_wound.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_lattice", "display": { - "icon": { "item": "minecraft:respawn_anchor" }, - "title": { "text": "The Wound" }, - "description": { "text": "Descend into the Void Dimension — the raw leak of the collapsing empire." }, + "icon": { + "item": "minecraft:respawn_anchor" + }, + "title": { + "translate": "advancements.scicraft.protocol.the_wound.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.the_wound.description" + }, "frame": "challenge", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_void": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "thevoiddimension:overworld" } + "conditions": { + "to": "thevoiddimension:overworld" + } } }, - "requirements": [["enter_void"]], - "rewards": { "experience": 750 } -} \ No newline at end of file + "requirements": [ + [ + "enter_void" + ] + ], + "rewards": { + "experience": 750 + } +} diff --git a/server_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json b/server_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json index bb6fa00..9e494ea 100644 --- a/server_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json +++ b/server_pack/kubejs/data/scicraft/advancements/protocol/through_the_doors.json @@ -1,9 +1,15 @@ { "parent": "scicraft:protocol/the_seal", "display": { - "icon": { "item": "minecraft:ender_eye" }, - "title": { "text": "Through the Doors" }, - "description": { "text": "Enter a Dimensional Door. The scar-tissue of the Flight's prison." }, + "icon": { + "item": "minecraft:ender_eye" + }, + "title": { + "translate": "advancements.scicraft.protocol.through_the_doors.title" + }, + "description": { + "translate": "advancements.scicraft.protocol.through_the_doors.description" + }, "frame": "task", "show_toast": true, "announce_to_chat": true, @@ -12,9 +18,17 @@ "criteria": { "enter_doors": { "trigger": "minecraft:changed_dimension", - "conditions": { "to": "dimensionaldoors:limbo" } + "conditions": { + "to": "dimensionaldoors:limbo" + } } }, - "requirements": [["enter_doors"]], - "rewards": { "experience": 400 } -} \ No newline at end of file + "requirements": [ + [ + "enter_doors" + ] + ], + "rewards": { + "experience": 400 + } +} diff --git a/server_pack/kubejs/server_scripts/00_lore.js b/server_pack/kubejs/server_scripts/00_lore.js index d256265..f98d53b 100644 --- a/server_pack/kubejs/server_scripts/00_lore.js +++ b/server_pack/kubejs/server_scripts/00_lore.js @@ -1,6 +1,6 @@ // SCICRAFT — The Dark Photon Protocol -// THE STORY BIBLE. Edit lore here; every script reads from this object. -// Reload with /reload after editing (startup items require a restart). +// CONFIG OBJECT. Text lives in STORY/*.md (generated into en_us.json) — +// never hardcode story strings here. /reload after editing. global.SCICRAFT = { items: { @@ -29,14 +29,5 @@ global.SCICRAFT = { void_dim: 'thevoiddimension:overworld', darker_dim: 'deeperdarker:otherside', dimensional_doors: 'dimensionaldoors:limbo' - }, - - phrases: { - signal: 'The last signal of the Second Renegade Flight hums in your blood.', - lattice_hum: 'The Lattice hums. Reality holds — for now.', - tide_low: 'The seal holds. The tide is calm.', - tide_mid: 'A Door stirs somewhere. The dark is waking.', - tide_high: 'The Darker press against the world. The Protocol calls.', - seal_fail: 'The Lattice sputters. It needs more power — and a Stabilizer.' } } \ No newline at end of file diff --git a/server_pack/kubejs/server_scripts/02_events.js b/server_pack/kubejs/server_scripts/02_events.js index c684bf9..b6d7fca 100644 --- a/server_pack/kubejs/server_scripts/02_events.js +++ b/server_pack/kubejs/server_scripts/02_events.js @@ -35,11 +35,5 @@ PlayerEvents.tick(event => { PlayerEvents.loggedIn(event => { event.player.tell(Text.translate('scicraft.phrases.signal')) }) - -// The very first fragment always drops when a Darker falls — never lost. -EntityEvents.death(event => { - const ent = event.entity - if (ent.type === 'minecraft:warden') { - ent.level.spawnItem('scicraft:photon_fragment', ent.blockPosition(), { count: 2 }) - } -}) \ No newline at end of file +// Note: Warden fragment drops are handled in 04_loot.js (LootJS) — do not +// duplicate them here or players get double drops. \ No newline at end of file diff --git a/server_pack/kubejs/startup_scripts/registry_blocks.js b/server_pack/kubejs/startup_scripts/registry_blocks.js index a6fb844..546e3d2 100644 --- a/server_pack/kubejs/startup_scripts/registry_blocks.js +++ b/server_pack/kubejs/startup_scripts/registry_blocks.js @@ -1,5 +1,6 @@ // SCICRAFT — The Dark Photon Protocol // Custom items & blocks for the Protocol. +// Names + tooltips come from the lang file (STORY/*.md → en_us.json). // Startup scripts: requires a full restart to apply. const SC = global.SCICRAFT @@ -7,38 +8,31 @@ const SC = global.SCICRAFT StartupEvents.registry('item', event => { // Photon Core — the raw fifth-force crystal. Lattice fuel. event.create('scicraft:photon_core') - .displayName('Photon Core') .texture('scicraft:item/photon_core') .maxStackSize(64) .tag('scicraft:photon') .tag('c:gems') .glow(true) - .tooltip('Dark photons — the binding force of the Door.') // Photon Fragment — shattered cores recovered from the Darker. event.create('scicraft:photon_fragment') - .displayName('Photon Fragment') .texture('scicraft:item/photon_fragment') .maxStackSize(64) .tag('scicraft:photon') .tag('c:gems') .glow(true) - .tooltip('A splinter of light stolen from the collapse.') // Void Stabilizer — the tool that re-seals Doors at the Lattice. event.create('scicraft:void_stabilizer') - .displayName('Void Stabilizer') .texture('scicraft:item/void_stabilizer') .maxStackSize(1) .unbreakable() .tag('scicraft:stabilizer') - .tooltip('Per Spatium — the renegades\' seal for the wound in the world.') }) StartupEvents.registry('block', event => { // Quantum Lattice — the Protocol's emitter. Must stay powered. event.create('scicraft:quantum_lattice', 'basic') - .displayName('Quantum Lattice') .textureAll('scicraft:block/quantum_lattice') .hardness(5.0) .resistance(1200.0) @@ -49,7 +43,6 @@ StartupEvents.registry('block', event => { // Renegade Glass — the TARDIS-blue glass of the Flight. Purely decorative. event.create('scicraft:renegade_glass', 'glass') - .displayName('Renegade Glass') .textureAll('scicraft:block/renegade_glass') .hardness(0.3) .resistance(0.3) diff --git a/tools/gen_story.py b/tools/gen_story.py new file mode 100755 index 0000000..66caa6c --- /dev/null +++ b/tools/gen_story.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +"""SCICRAFT — story generator. + +Reads STORY/*.md, merges every ```lang JSON block (in filename order) into +en_us.json, writes it to BOTH packs, and validates that every lang key +referenced from the KubeJS scripts and advancement JSONs resolves. + +Usage: + python tools/gen_story.py + +Edit the story by editing STORY/*.md, then run this script. Never hand-edit +en_us.json — it is a generated artifact. +""" + +import json +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +STORY_DIR = ROOT / "STORY" +LANGS = [ + ROOT / "server_pack" / "kubejs" / "assets" / "scicraft" / "lang" / "en_us.json", + ROOT / "client_pack" / "kubejs" / "assets" / "scicraft" / "lang" / "en_us.json", +] +KUBEJS_DIRS = [ROOT / "server_pack" / "kubejs"] +ADVANCEMENT_DIR = ROOT / "server_pack" / "kubejs" / "data" / "scicraft" / "advancements" + +LANG_BLOCK = re.compile(r"```lang\s*\n(.*?)```", re.S) + + +def load_lang_files(): + merged = {} + order = [] + for path in sorted(STORY_DIR.glob("*.md")): + text = path.read_text(encoding="utf-8") + for i, match in enumerate(LANG_BLOCK.finditer(text)): + try: + data = json.loads(match.group(1)) + except json.JSONDecodeError as e: + sys.exit(f"BAD JSON in {path.name} block #{i + 1}: {e}") + for key, value in data.items(): + if key in merged: + print(f"WARN: duplicate key {key!r} ({path.name} overrides)") + merged[key] = value + order.append(key) + return merged, order + + +def write_lang(merged, order): + payload = {k: merged[k] for k in order} + for target in LANGS: + target.parent.mkdir(parents=True, exist_ok=True) + target.write_text( + json.dumps(payload, ensure_ascii=False, indent="\t") + "\n", + encoding="utf-8", + ) + print(f"wrote {target.relative_to(ROOT)} ({len(payload)} keys)") + + +def validate(merged): + missing = set() + + def check_key(key, source): + if key not in merged: + missing.add((key, source)) + + for root_dir in KUBEJS_DIRS: + for script in root_dir.rglob("*.js"): + for key in re.findall(r"Text\.translate\(\s*['\"]([^'\"]+)['\"]\s*(?:\+|\))", script.read_text(encoding="utf-8")): + # Keys followed by ` + msg` are dynamic templates — skip. + if key.endswith("."): + continue + check_key(key, str(script.relative_to(ROOT))) + + if ADVANCEMENT_DIR.exists(): + for jf in ADVANCEMENT_DIR.rglob("*.json"): + for key in re.findall(r'"translate"\s*:\s*"([^"]+)"', jf.read_text(encoding="utf-8")): + check_key(key, str(jf.relative_to(ROOT))) + + if missing: + print("\nMISSING LANG KEYS:") + for key, source in sorted(missing): + print(f" {key} (used in {source})") + sys.exit(1) + print("all referenced lang keys resolve") + + +if __name__ == "__main__": + merged, order = load_lang_files() + write_lang(merged, order) + validate(merged) \ No newline at end of file diff --git a/tools/sync_kubejs.sh b/tools/sync_kubejs.sh new file mode 100755 index 0000000..a279f51 --- /dev/null +++ b/tools/sync_kubejs.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# SCICRAFT — sync KubeJS story system from server_pack to client_pack. +# Run after editing anything under server_pack/kubejs (or STORY/*.md → gen_story.py). +set -euo pipefail +cd "$(dirname "$0")/.." + +rm -rf client_pack/kubejs +cp -r server_pack/kubejs client_pack/kubejs + +echo "kubejs synced to client_pack" +echo "verify: diff -r server_pack/kubejs client_pack/kubejs && echo IDENTICAL" \ No newline at end of file