From 4a9c41197c194c5a1a92035770865f8de41f104e Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:08:16 -0700 Subject: [PATCH 01/25] docs: M0.P1 plan review: anchored ignore rules, GameTest names per loader, Fabric holder constructor, config defaults from code Co-Authored-By: Claude Opus 5.5 --- ...6-10-24-m0.p1-repository-hygiene-and-ci.md | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/docs/superpowers/plans/2026-10-24-m0.p1-repository-hygiene-and-ci.md b/docs/superpowers/plans/2026-10-24-m0.p1-repository-hygiene-and-ci.md index ff680bbc..1949591a 100644 --- a/docs/superpowers/plans/2026-10-24-m0.p1-repository-hygiene-and-ci.md +++ b/docs/superpowers/plans/2026-10-24-m0.p1-repository-hygiene-and-ci.md @@ -4,15 +4,15 @@ **Goal:** A repository a new contributor can build, run and test from the README alone, with the unit tests on `./gradlew :common:test`, the GameTests in `common` with one holder per loader, CI that builds both loaders on every push and pull request, and the two reference documents the later packages cite (`docs/config-reference.md`, `docs/performance-baseline.md`). -**Architecture:** Nine small tasks on branch `m0.p1/repo-hygiene` from `integration/1.20.1` (after PR #66 merges). The unit tests already live in `common/src/test/java`; this package gives them a real JUnit 5 runtime under Gradle and deletes the stand-in runner. The 16 GameTest bodies move to `common` as plain static methods; a Forge holder and a Fabric holder carry the loader annotations and delegate one line each, because Forge reads its `@GameTestHolder` from the declaring class and Fabric registers through an entrypoint. CI is one GitHub Actions workflow. +**Architecture:** Nine small tasks on branch `m0.p1/repo-hygiene` from `integration/1.20.1` at the PR #66 merge commit `622ef2c`. The unit tests already live in `common/src/test/java`; this package gives them a real JUnit 5 runtime under Gradle and deletes the stand-in runner. The 16 GameTest bodies move to `common` as plain static methods; a Forge holder and a Fabric holder carry the loader annotations and delegate one line each, because Forge reads its `@GameTestHolder` from the declaring class and Fabric registers through an entrypoint. CI is one GitHub Actions workflow. -**Tech Stack:** Gradle 8.14.4, Java 17, ModDevGradle legacyforge 2.0.77, fabric-loom 1.9, JUnit Jupiter 5.10.2, GitHub Actions (`actions/checkout@v4`, `actions/setup-java@v4`, `gradle/actions/setup-gradle@v3`, `actions/upload-artifact@v4`). +**Tech Stack:** Gradle 8.14.4, Java 17, ModDevGradle legacyforge 2.0.77, fabric-loom 1.9, JUnit Jupiter 5.10.2, GitHub Actions (`actions/checkout@v4`, `actions/setup-java@v4`, `gradle/actions/setup-gradle@v4`, `actions/upload-artifact@v4`). **Spec:** `docs/plan/engineering-backlog.md` section "M0.P1: Repository hygiene and CI" (lines 342 to 390), "How to use this plan" (161 to 245) and "Definition of done" (203 to 218); `docs/codebase-analysis.md` section 3.5. ## Global Constraints -- Branch `m0.p1/repo-hygiene` from `integration/1.20.1` once PR #66 (M0.P0) is merged; the PR targets `integration/1.20.1`. Never delete any branch. Do not touch `.claude/worktrees/herd-leader-sample`. +- Branch `m0.p1/repo-hygiene` from `integration/1.20.1` (PR #66, M0.P0, merged 2026-10-25 as `622ef2c`); the PR targets `integration/1.20.1` by name, because the repository default branch is still `1.20.1`. Never delete any branch. Do not touch `.claude/worktrees/herd-leader-sample`. - One commit per task with a conventional prefix. - No gameplay change. No change to game data, assets or machine code. - Do not touch `LICENSE` or `license=` (the lead handles licences). @@ -80,7 +80,7 @@ git checkout -b m0.p1/repo-hygiene origin/integration/1.20.1 git log --oneline -1 ``` -Expected: the tip is the M0.P0 merge commit (PR #66). If PR #66 is not merged yet, stop: this package depends on M0.P0. +Expected: the tip is the M0.P0 merge commit `622ef2c`. (Done 2026-10-25; the branch has no upstream until Task 8 pushes it with `-u`.) - [ ] **Step 2: Remove the remnants** @@ -100,12 +100,14 @@ Replace the M0.P0 block at the end of `.gitignore` (the comment line and the fou ``` # Not source: crash logs, data-run output, the datagen cache, agent and tool exports hs_err_*.log -*/dataRun/ -*/.cache/ +dataRun/ +.cache/ .ai/ graphify-out/ ``` +No slash before the folder names: a pattern with a slash in the middle is anchored, and `*/.cache/` does not match `common/src/generated/resources/.cache/` (checked in an empty repository). Confirm with `git check-ignore -v common/src/generated/resources/.cache/x forge/dataRun/x` (two lines, both from the new block). + - [ ] **Step 4: Remove toml4j** Delete `implementation 'com.moandjiezana.toml:toml4j:0.7.2'` from `common/build.gradle` and `include(implementation 'com.moandjiezana.toml:toml4j:0.7.2')` from `fabric/build.gradle`. Nothing imports `com.moandjiezana` (`grep -rn moandjiezana --include=*.java . | wc -l` is `0`). @@ -166,7 +168,7 @@ In `common/build.gradle`, replace `testCompileOnly 'org.junit.jupiter:junit-jupi ```groovy testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2' ``` Below the existing `sourceSets.test.compileClasspath += sourceSets.main.compileClasspath` line add: @@ -199,7 +201,7 @@ git rm -rq tools/junit-standin grep -rn "junit-standin" docs/plan docs/superpowers/handoffs README.md 2>/dev/null | cut -c1-120 ``` -The grep lists the plan pages that still name the stand-in; change each to `./gradlew :common:test` (the handoff documents are history and stay as they are). +The grep lists the pages that still name the stand-in. Change the live plan pages (`docs/plan/engineering-backlog.md`) to `./gradlew :common:test`. Handoffs, executed task plans under `docs/superpowers/plans/` (including this one) and `research_notes/` are history and stay as they are. - [ ] **Step 4: Verify the whole build still passes (the `build` task now runs the tests)** @@ -225,7 +227,9 @@ git commit -m "build: run the unit tests with JUnit 5 under Gradle and remove th - Produces: - `J/gametest/HerdGameTests`: `public final class` with a private constructor, the existing constants and helpers, and one `public static void (GameTestHelper helper)` per test, bodies unchanged; same for `MachineGameTests`. No annotation, no Forge import. Class Javadoc keeps the test list and the run commands. - `FJ/gametest/ForgeGameTests`: `@GameTestHolder(Constants.MODID) @PrefixGameTestTemplate(false) public class ForgeGameTests` with, per test, `@GameTest(template = , batch = , timeoutTicks = ) public void (GameTestHelper helper) { HerdGameTests.(helper); }` (and `MachineGameTests` for the three machine tests). Forge finds the class by its annotation, as today. - - `FaJ/gametest/FabricGameTests implements net.fabricmc.fabric.api.gametest.v1.FabricGameTest`: the same 16 methods with `template = "projectnublar:"` (Fabric reads the full id); registered in `fabric.mod.json` under `"entrypoints": { "fabric-gametest": ["net.dumbcode.projectnublar.gametest.FabricGameTests"] }`. + - `FaJ/gametest/FabricGameTests implements net.fabricmc.fabric.api.gametest.v1.FabricGameTest`: the same 16 methods with `template = "projectnublar:"` (Fabric uses an explicit template string as given, with no namespace added); registered in `fabric.mod.json` under `"entrypoints": { "fabric-gametest": ["net.dumbcode.projectnublar.gametest.FabricGameTests"] }`. No explicit constructor: Fabric builds an instance through the public no-argument constructor before each test. + - Structures: the `.nbt` files under `R/data/projectnublar/structures/` load on both loaders through vanilla's template source (Fabric only adds a second source for `gametest/structures/*.snbt`; checked in fabric-gametest-api-v1 sources). + - Test names (what `/test run` takes): on Forge, `@PrefixGameTestTemplate(false)` also drops the class prefix from the test name, so a Forge test is named by its method in lower case only (`fivegallimimusformoneherdledbythestrongest`); the old Javadoc's `herdgametests.` and `machinegametests.` prefixes do not match this. On Fabric the name is `fabricgametests.`. The common class Javadoc lists both forms, checked against the names the two GameTest server logs print. - `fabric/build.gradle` `loom.runs` gains `gametest { server(); setConfigName("Fabric GameTest"); vmArg "-Dfabric-api.gametest"; vmArg "-Dfabric-api.gametest.report-file=${project.buildDir}/junit.xml"; runDir "build/gametest" }`. - [ ] **Step 1: Move the bodies** @@ -307,7 +311,7 @@ git commit -m "chore: mod metadata, dependency declarations and pack format for - [ ] **Step 1: README** -Sections, in this order, each a few lines: **Project Nublar** (one paragraph: a Minecraft mod where the player clones dinosaurs from fossil DNA and keeps them in powered enclosures; Minecraft 1.20.1, Forge and Fabric; Beta in progress); **Beta scope** (one paragraph; link to `docs/codebase-analysis.md` section 11 and `docs/project-plan.md`); **Build** (`./gradlew build`, Java 17, the four modules, where the jars land); **Run** (`./gradlew :forge:runClient`, `./gradlew :fabric:runClient`, `./gradlew :forge:runServer`, `./gradlew :forge:runGameTestServer`, `./gradlew :fabric:runGametest`; the Fabric client has no client entry point until M0.P2); **Test** (`./gradlew :common:test`; GameTests from the client with `/test run .`); **Contribute** (branch and PR rules: link to `docs/plan/engineering-backlog.md` "How to use this plan", the Definition of done, the plan folder `docs/superpowers/plans/`); **Licence** (one line: see `LICENSE`). No badges, no screenshots. +Sections, in this order, each a few lines: **Project Nublar** (one paragraph: a Minecraft mod where the player clones dinosaurs from fossil DNA and keeps them in powered enclosures; Minecraft 1.20.1, Forge and Fabric; Beta in progress); **Beta scope** (one paragraph; link to `docs/codebase-analysis.md` section 11 and `docs/project-plan.md`); **Build** (`./gradlew build`, Java 17, the four modules, where the jars land); **Run** (`./gradlew :forge:runClient`, `./gradlew :fabric:runClient`, `./gradlew :forge:runServer`, `./gradlew :forge:runGameTestServer`, `./gradlew :fabric:runGametest`; the Fabric client has no client entry point until M0.P2); **Test** (`./gradlew :common:test`; GameTests from the Forge client in a creative world with `/test runall`, or one test with `/test run ` using the names from Task 4); **Contribute** (branch and PR rules: link to `docs/plan/engineering-backlog.md` "How to use this plan", the Definition of done, the plan folder `docs/superpowers/plans/`); **Licence** (one line: see `LICENSE`). No badges, no screenshots. - [ ] **Step 2: PR template** @@ -332,11 +336,11 @@ git commit -m "docs: README for building, running and contributing; pull request - [ ] **Step 1: config-reference.md** -Heading, one sentence on scope (every TOML key the mod reads; data pack values are not here), then the table with header `Key | Default | Type | Section 11 ref | Added by` and one row per key of `config/projectnublar-fossils.toml` (M0.P0's table): `fossils.tyrannosaurus_rex.pieces` `"biped"` string; `.special_pieces` `[tyrannosaurus_skull, tyrannosaurus_foot, tyrannosaurus_hand, tyrannosaurus_pelvis]` list of piece names; `.special_weights` `[1, 2, 2, 1]` list of int; `.weight` `1` int; `.periods` `["cretaceous"]` list of string; `.biomes` `["minecraft:desert", "minecraft:forest"]` list of string (stored, not read); `sets.biped.pieces` `[ribcage, bipedal_arm, bipedal_leg, tail, neck]`; `sets.biped.weights` `[1, 2, 2, 1, 1]`; `periods..min_y` / `.max_y` / `.rarity_mod` with defaults `2/20/0.5`, `-12/10/0.4`, `40/56/0.4` (int, int, double 0..1); `qualities..weight` / `.dna_yield` with `40/5.0`, `20/7.5`, `15/10.0`, `4/30.0` (int, double 0..100). Section 11 ref `11.1` for all; Added by `M0.P0`. Below the table, the two notes from the M0.P0 PR: only Cretaceous veins exist, so the other period bands and the species `periods` key have no effect yet; the config is COMMON and not synced to clients. +Read every key, default, type and range from `J/config/FossilsConfig.java` (the values below are what M0.P0's PR listed; where they differ, the code wins and the report names the difference). Heading, one sentence on scope (every TOML key the mod reads; data pack values are not here), then the table with header `Key | Default | Type | Section 11 ref | Added by` and one row per key of `config/projectnublar-fossils.toml` (M0.P0's table): `fossils.tyrannosaurus_rex.pieces` `"biped"` string; `.special_pieces` `[tyrannosaurus_skull, tyrannosaurus_foot, tyrannosaurus_hand, tyrannosaurus_pelvis]` list of piece names; `.special_weights` `[1, 2, 2, 1]` list of int; `.weight` `1` int; `.periods` `["cretaceous"]` list of string; `.biomes` `["minecraft:desert", "minecraft:forest"]` list of string (stored, not read); `sets.biped.pieces` `[ribcage, bipedal_arm, bipedal_leg, tail, neck]`; `sets.biped.weights` `[1, 2, 2, 1, 1]`; `periods..min_y` / `.max_y` / `.rarity_mod` with defaults `2/20/0.5`, `-12/10/0.4`, `40/56/0.4` (int, int, double 0..1); `qualities..weight` / `.dna_yield` with `40/5.0`, `20/7.5`, `15/10.0`, `4/30.0` (int, double 0..100). Section 11 ref `11.1` for all; Added by `M0.P0`. Below the table, the two notes from the M0.P0 PR: only Cretaceous veins exist, so the other period bands and the species `periods` key have no effect yet; the config is COMMON and not synced to clients. - [ ] **Step 2: performance-baseline.md** -Sections: **Reference machine** (CPU, GPU, RAM, Java version and flags; each value "not set" until the lead answers; Java flags: `-Xmx3G` from `gradle.properties` for the dev runs); **Fixed client settings** (render distance 12, fancy graphics, no shaders, no optimization mods, fullscreen off, V-sync off, max framerate unlimited); **Test world** (creative, flat, the GameTest structures `herd_arena` and `herd_track` from `common/src/main/resources/data/projectnublar/structures/`, time locked at day 1000, weather clear); **How a gate is measured** (fps from the F3 screen, three readings one minute apart, the median; server tick from `/debug start` … `/debug stop` over 60 seconds, the average); **Gates that cite this file** (the 25 ms paddock tick and the 120 fps lines, with the backlog line numbers). Ask the lead for the four machine values with the question tool (multi-select off, free text) and fill what they give. +Sections: **Reference machine** (CPU, GPU, RAM, Java version and flags; each value "not set" until the lead answers; Java flags: `-Xmx3G` from `gradle.properties` for the dev runs); **Fixed client settings** (render distance 12, fancy graphics, no shaders, no optimization mods, fullscreen off, V-sync off, max framerate unlimited); **Test world** (creative, flat, the GameTest structures `herd_arena` and `herd_track` from `common/src/main/resources/data/projectnublar/structures/`, time locked at day 1000, weather clear); **How a gate is measured** (fps from the F3 screen, three readings one minute apart, the median; server tick from `/debug start` … `/debug stop` over 60 seconds, the average); **Gates that cite this file** (the 25 ms paddock tick and the 120 fps lines, with the backlog line numbers). The controller (not the implementer, which cannot ask) asks the lead for the four machine values with the question tool (multi-select off, free text) and gives the answers to the task; values not given stay "not set". - [ ] **Step 3: Register row** @@ -370,7 +374,7 @@ jobs: with: distribution: temurin java-version: '17' - - uses: gradle/actions/setup-gradle@v3 + - uses: gradle/actions/setup-gradle@v4 - run: chmod +x gradlew && ./gradlew build :common:test --no-daemon --console=plain - uses: actions/upload-artifact@v4 with: From 20dc537c254d366dbb107c5d32dffe025db681da Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:12:59 -0700 Subject: [PATCH 02/25] chore: remove the Blockbench shape exports and toml4j; general ignore rules for logs, data runs and caches Co-Authored-By: Claude Opus 5.5 --- .gitignore | 9 ++++---- common/build.gradle | 1 - fabric/build.gradle | 1 - shapes/east.txt | 51 --------------------------------------------- shapes/north.txt | 51 --------------------------------------------- shapes/south.txt | 51 --------------------------------------------- shapes/west.txt | 51 --------------------------------------------- 7 files changed, 5 insertions(+), 210 deletions(-) delete mode 100644 shapes/east.txt delete mode 100644 shapes/north.txt delete mode 100644 shapes/south.txt delete mode 100644 shapes/west.txt diff --git a/.gitignore b/.gitignore index afdfd416..7daa0c30 100644 --- a/.gitignore +++ b/.gitignore @@ -22,8 +22,9 @@ build eclipse run -# Not source: crash logs, data-run output, the datagen cache, agent config -hs_err_pid*.log -forge/dataRun/ -common/src/generated/resources/.cache/ +# Not source: crash logs, data-run output, the datagen cache, agent and tool exports +hs_err_*.log +dataRun/ +.cache/ .ai/ +graphify-out/ diff --git a/common/build.gradle b/common/build.gradle index 0a56a0a6..47e67f0c 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -23,7 +23,6 @@ dependencies { compileOnlyApi 'net.minecraftforge:mergetool-api:1.0' implementation "fuzs.forgeconfigapiport:forgeconfigapiport-common:${project.forge_config_api_port_version}" - implementation 'com.moandjiezana.toml:toml4j:0.7.2' implementation "net.tslat.smartbrainlib:SmartBrainLib-common-${project.minecraft_version}:${project.sbl_version}" compileOnly "software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}" // implementation ("com.nyfaria.nyfsguilib:nyfsguilib-common-${minecraft_version}:${ngl_version}") {transitive = false} diff --git a/fabric/build.gradle b/fabric/build.gradle index cd0715cb..355837d0 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -15,7 +15,6 @@ dependencies { modApi "fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${project.forge_config_api_port_version}" include "fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${project.forge_config_api_port_version}" - include(implementation 'com.moandjiezana.toml:toml4j:0.7.2') modImplementation "net.tslat.smartbrainlib:SmartBrainLib-fabric-${project.minecraft_version}:${project.sbl_version}" modImplementation "software.bernie.geckolib:geckolib-fabric-${minecraft_version}:${geckolib_version}" // modImplementation "com.nyfaria.nyfsguilib:nyfsguilib-fabric-${minecraft_version}:${ngl_version}" diff --git a/shapes/east.txt b/shapes/east.txt deleted file mode 100644 index cf8df82e..00000000 --- a/shapes/east.txt +++ /dev/null @@ -1,51 +0,0 @@ -public VoxelShape makeShape(){ - VoxelShape shape = Shapes.empty(); - shape = Shapes.join(shape, Shapes.box(-0.6875, 0.4375, -0.9375, -0.125, 0.875, -0.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.296875, 1.471875, -0.6703125000000001, 0.328125, 1.528125, -0.6390625000000001), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.296875, 1.221875, -0.7953125000000001, 0.328125, 1.278125, -0.7640625000000001), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.296875, 1.471875, -0.7953125000000001, 0.328125, 1.528125, -0.7640625000000001), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.296875, 0.971875, -0.5453125000000001, 0.328125, 1.028125, -0.5140625000000001), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 0.625, 0, 0.5, 0.75, 0.8125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.7515625000000001, 0.625, 0.8125, 0.5015625, 0.75, 1.0375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 0, 0, 0.5, 0.625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0.1875, 0.875, 0.75, 0.375, 0.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.49843750000000003, 0.375, 0.875, 0.7515625, 0.4640625, 0.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.49843750000000003, 0.0984375, 0.875, 0.7515625, 0.1875, 0.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0.125, 0, 0.75, 0.4375, 0.875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0.375, 0.25, 0.8125, 0.4375, 0.8125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.25, 0.90625, -0.0625, 0.375, 1.59375, 0.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.2828125, 0.9375, 0, 0.3453125, 1.5625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6875, 0.4375, -1, 0.625, 1.625, -0.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6875, 0.4375, -0.0625, 0.625, 1.625, 0), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 1.625, -1, 0.625, 1.6875, 0), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 0, -1, 0.625, 0.4375, 0), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 0.4375, -1, -0.6875, 1.625, 0), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.4375, -0.75, 0.5, 0.625, -0.25), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.40625, 0.53125, -0.34375, 0.46875, 0.78125, -0.28125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.40625, 0.53125, -0.46875, 0.46875, 0.78125, -0.40625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.40625, 0.53125, -0.59375, 0.46875, 0.78125, -0.53125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.40625, 0.53125, -0.71875, 0.46875, 0.78125, -0.65625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.28125, 0.53125, -0.71875, 0.34375, 0.78125, -0.65625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.28125, 0.53125, -0.59375, 0.34375, 0.78125, -0.53125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.28125, 0.53125, -0.46875, 0.34375, 0.78125, -0.40625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.28125, 0.53125, -0.34375, 0.34375, 0.78125, -0.28125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.15625, 0.53125, -0.71875, 0.21875, 0.78125, -0.65625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.15625, 0.53125, -0.59375, 0.21875, 0.78125, -0.53125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.15625, 0.53125, -0.46875, 0.21875, 0.78125, -0.40625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.15625, 0.53125, -0.34375, 0.21875, 0.78125, -0.28125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.03125, 0.53125, -0.71875, 0.09375, 0.78125, -0.65625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.03125, 0.53125, -0.59375, 0.09375, 0.78125, -0.53125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.03125, 0.53125, -0.46875, 0.09375, 0.78125, -0.40625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.03125, 0.53125, -0.34375, 0.09375, 0.78125, -0.28125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6875, 1.375, -0.9375, 0.3125, 1.5625, -0.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6875, 1.125, -0.9375, 0.3125, 1.3125, -0.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.328125, 1.45625, -0.6773437499999999, 0.515625, 1.54375, -0.63359375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.328125, 1.20625, -0.8023437499999999, 0.515625, 1.29375, -0.75859375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.328125, 1.45625, -0.8023437499999999, 0.515625, 1.54375, -0.75859375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.328125, 0.95625, -0.5523437499999999, 0.515625, 1.04375, -0.50859375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6875, 0.875, -0.9375, 0.3125, 1.0625, -0.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.625, 0, -1, 0.75, 1.6875, 0), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.75, 0.625, -0.125, 0.8125, 0.9375, -0.0625), BooleanOp.OR); - - return shape; -} \ No newline at end of file diff --git a/shapes/north.txt b/shapes/north.txt deleted file mode 100644 index b1f530f3..00000000 --- a/shapes/north.txt +++ /dev/null @@ -1,51 +0,0 @@ -public VoxelShape makeShape(){ - VoxelShape shape = Shapes.empty(); - shape = Shapes.join(shape, Shapes.box(-0.9375, 0.4375, 1.125, -0.0625, 0.875, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6703125000000001, 1.471875, 0.671875, -0.6390625000000001, 1.528125, 0.703125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.7953125000000001, 1.221875, 0.671875, -0.7640625000000001, 1.278125, 0.703125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.7953125000000001, 1.471875, 0.671875, -0.7640625000000001, 1.528125, 0.703125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.5453125000000001, 0.971875, 0.671875, -0.5140625000000001, 1.028125, 0.703125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.625, 0.5, 0.8125, 0.75, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.8125, 0.625, 0.4984375, 1.0375, 0.75, 1.7515625000000001), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0, 0.5, 1, 0.625, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.875, 0.1875, 0.25, 0.9375, 0.375, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.875, 0.375, 0.24843749999999998, 0.9375, 0.4640625, 0.5015624999999999), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.875, 0.0984375, 0.24843749999999998, 0.9375, 0.1875, 0.5015624999999999), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.125, 0.25, 0.875, 0.4375, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.25, 0.375, 0.1875, 0.8125, 0.4375, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.0625, 0.90625, 0.625, 0.0625, 1.59375, 0.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.9375, 0.6546875, 1, 1.5625, 0.7171875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-1, 0.4375, 0.375, -0.9375, 1.625, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.0625, 0.4375, 0.375, 0, 1.625, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-1, 1.625, 0.375, 0, 1.6875, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-1, 0, 0.375, 0, 0.4375, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-1, 0.4375, 1.6875, 0, 1.625, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.75, 0.4375, 0.5, -0.25, 0.625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.34375, 0.53125, 0.53125, -0.28125, 0.78125, 0.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.46875, 0.53125, 0.53125, -0.40625, 0.78125, 0.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.59375, 0.53125, 0.53125, -0.53125, 0.78125, 0.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.71875, 0.53125, 0.53125, -0.65625, 0.78125, 0.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.71875, 0.53125, 0.65625, -0.65625, 0.78125, 0.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.59375, 0.53125, 0.65625, -0.53125, 0.78125, 0.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.46875, 0.53125, 0.65625, -0.40625, 0.78125, 0.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.34375, 0.53125, 0.65625, -0.28125, 0.78125, 0.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.71875, 0.53125, 0.78125, -0.65625, 0.78125, 0.84375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.59375, 0.53125, 0.78125, -0.53125, 0.78125, 0.84375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.46875, 0.53125, 0.78125, -0.40625, 0.78125, 0.84375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.34375, 0.53125, 0.78125, -0.28125, 0.78125, 0.84375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.71875, 0.53125, 0.90625, -0.65625, 0.78125, 0.96875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.59375, 0.53125, 0.90625, -0.53125, 0.78125, 0.96875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.46875, 0.53125, 0.90625, -0.40625, 0.78125, 0.96875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.34375, 0.53125, 0.90625, -0.28125, 0.78125, 0.96875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.9375, 1.375, 0.6875, -0.0625, 1.5625, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.9375, 1.125, 0.6875, -0.0625, 1.3125, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.6773437499999999, 1.45625, 0.484375, -0.63359375, 1.54375, 0.671875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.8023437499999999, 1.20625, 0.484375, -0.75859375, 1.29375, 0.671875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.8023437499999999, 1.45625, 0.484375, -0.75859375, 1.54375, 0.671875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.5523437499999999, 0.95625, 0.484375, -0.50859375, 1.04375, 0.671875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.9375, 0.875, 0.6875, -0.0625, 1.0625, 1.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-1, 0, 0.25, 0, 1.6875, 0.375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.125, 0.625, 0.1875, -0.0625, 0.9375, 0.25), BooleanOp.OR); - - return shape; -} \ No newline at end of file diff --git a/shapes/south.txt b/shapes/south.txt deleted file mode 100644 index 073be053..00000000 --- a/shapes/south.txt +++ /dev/null @@ -1,51 +0,0 @@ -public VoxelShape makeShape(){ - VoxelShape shape = Shapes.empty(); - shape = Shapes.join(shape, Shapes.box(1.0625, 0.4375, -0.6875, 1.9375, 0.875, -0.125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.6390625, 1.471875, 0.296875, 1.6703125, 1.528125, 0.328125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.7640625, 1.221875, 0.296875, 1.7953125, 1.278125, 0.328125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.7640625, 1.471875, 0.296875, 1.7953125, 1.528125, 0.328125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.5140625, 0.971875, 0.296875, 1.5453125, 1.028125, 0.328125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.1875, 0.625, -0.75, 1, 0.75, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(-0.03750000000000009, 0.625, -0.7515625000000001, 0.1875, 0.75, 0.5015625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0, -0.75, 1, 0.625, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.0625, 0.1875, 0.5, 0.125, 0.375, 0.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.0625, 0.375, 0.49843750000000003, 0.125, 0.4640625, 0.7515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.0625, 0.0984375, 0.49843750000000003, 0.125, 0.1875, 0.7515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.125, 0.125, 0.5, 1, 0.4375, 0.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.1875, 0.375, 0.5, 0.75, 0.4375, 0.8125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.9375, 0.90625, 0.25, 1.0625, 1.59375, 0.375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0, 0.9375, 0.2828125, 1, 1.5625, 0.3453125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.9375, 0.4375, -0.6875, 2, 1.625, 0.625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1, 0.4375, -0.6875, 1.0625, 1.625, 0.625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1, 1.625, -0.75, 2, 1.6875, 0.625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1, 0, -0.75, 2, 0.4375, 0.625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1, 0.4375, -0.75, 2, 1.625, -0.6875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.25, 0.4375, 0, 1.75, 0.625, 0.5), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.28125, 0.53125, 0.40625, 1.34375, 0.78125, 0.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.40625, 0.53125, 0.40625, 1.46875, 0.78125, 0.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.53125, 0.53125, 0.40625, 1.59375, 0.78125, 0.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.65625, 0.53125, 0.40625, 1.71875, 0.78125, 0.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.65625, 0.53125, 0.28125, 1.71875, 0.78125, 0.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.53125, 0.53125, 0.28125, 1.59375, 0.78125, 0.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.40625, 0.53125, 0.28125, 1.46875, 0.78125, 0.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.28125, 0.53125, 0.28125, 1.34375, 0.78125, 0.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.65625, 0.53125, 0.15625, 1.71875, 0.78125, 0.21875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.53125, 0.53125, 0.15625, 1.59375, 0.78125, 0.21875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.40625, 0.53125, 0.15625, 1.46875, 0.78125, 0.21875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.28125, 0.53125, 0.15625, 1.34375, 0.78125, 0.21875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.65625, 0.53125, 0.03125, 1.71875, 0.78125, 0.09375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.53125, 0.53125, 0.03125, 1.59375, 0.78125, 0.09375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.40625, 0.53125, 0.03125, 1.46875, 0.78125, 0.09375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.28125, 0.53125, 0.03125, 1.34375, 0.78125, 0.09375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.0625, 1.375, -0.6875, 1.9375, 1.5625, 0.3125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.0625, 1.125, -0.6875, 1.9375, 1.3125, 0.3125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.63359375, 1.45625, 0.328125, 1.67734375, 1.54375, 0.515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.75859375, 1.20625, 0.328125, 1.80234375, 1.29375, 0.515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.75859375, 1.45625, 0.328125, 1.80234375, 1.54375, 0.515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.50859375, 0.95625, 0.328125, 1.55234375, 1.04375, 0.515625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.0625, 0.875, -0.6875, 1.9375, 1.0625, 0.3125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1, 0, 0.625, 2, 1.6875, 0.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.0625, 0.625, 0.75, 1.125, 0.9375, 0.8125), BooleanOp.OR); - - return shape; -} \ No newline at end of file diff --git a/shapes/west.txt b/shapes/west.txt deleted file mode 100644 index e92583eb..00000000 --- a/shapes/west.txt +++ /dev/null @@ -1,51 +0,0 @@ -public VoxelShape makeShape(){ - VoxelShape shape = Shapes.empty(); - shape = Shapes.join(shape, Shapes.box(1.125, 0.4375, 1.0625, 1.6875, 0.875, 1.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.671875, 1.471875, 1.6390625, 0.703125, 1.528125, 1.6703125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.671875, 1.221875, 1.7640625, 0.703125, 1.278125, 1.7953125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.671875, 1.471875, 1.7640625, 0.703125, 1.528125, 1.7953125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.671875, 0.971875, 1.5140625, 0.703125, 1.028125, 1.5453125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0.625, 0.1875, 1.75, 0.75, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.4984375, 0.625, -0.03750000000000009, 1.7515625000000001, 0.75, 0.1875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0, 0, 1.75, 0.625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.25, 0.1875, 0.0625, 0.5, 0.375, 0.125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.24843749999999998, 0.375, 0.0625, 0.5015624999999999, 0.4640625, 0.125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.24843749999999998, 0.0984375, 0.0625, 0.5015624999999999, 0.1875, 0.125), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.25, 0.125, 0.125, 0.5, 0.4375, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.1875, 0.375, 0.1875, 0.5, 0.4375, 0.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.625, 0.90625, 0.9375, 0.75, 1.59375, 1.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.6546875, 0.9375, 0, 0.7171875, 1.5625, 1), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.375, 0.4375, 1.9375, 1.6875, 1.625, 2), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.375, 0.4375, 1, 1.6875, 1.625, 1.0625), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.375, 1.625, 1, 1.75, 1.6875, 2), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.375, 0, 1, 1.75, 0.4375, 2), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(1.6875, 0.4375, 1, 1.75, 1.625, 2), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.5, 0.4375, 1.25, 1, 0.625, 1.75), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.53125, 0.53125, 1.28125, 0.59375, 0.78125, 1.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.53125, 0.53125, 1.40625, 0.59375, 0.78125, 1.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.53125, 0.53125, 1.53125, 0.59375, 0.78125, 1.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.53125, 0.53125, 1.65625, 0.59375, 0.78125, 1.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.65625, 0.53125, 1.65625, 0.71875, 0.78125, 1.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.65625, 0.53125, 1.53125, 0.71875, 0.78125, 1.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.65625, 0.53125, 1.40625, 0.71875, 0.78125, 1.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.65625, 0.53125, 1.28125, 0.71875, 0.78125, 1.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.78125, 0.53125, 1.65625, 0.84375, 0.78125, 1.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.78125, 0.53125, 1.53125, 0.84375, 0.78125, 1.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.78125, 0.53125, 1.40625, 0.84375, 0.78125, 1.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.78125, 0.53125, 1.28125, 0.84375, 0.78125, 1.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.90625, 0.53125, 1.65625, 0.96875, 0.78125, 1.71875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.90625, 0.53125, 1.53125, 0.96875, 0.78125, 1.59375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.90625, 0.53125, 1.40625, 0.96875, 0.78125, 1.46875), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.90625, 0.53125, 1.28125, 0.96875, 0.78125, 1.34375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.6875, 1.375, 1.0625, 1.6875, 1.5625, 1.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.6875, 1.125, 1.0625, 1.6875, 1.3125, 1.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.484375, 1.45625, 1.63359375, 0.671875, 1.54375, 1.67734375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.484375, 1.20625, 1.75859375, 0.671875, 1.29375, 1.80234375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.484375, 1.45625, 1.75859375, 0.671875, 1.54375, 1.80234375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.484375, 0.95625, 1.50859375, 0.671875, 1.04375, 1.55234375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.6875, 0.875, 1.0625, 1.6875, 1.0625, 1.9375), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.25, 0, 1, 0.375, 1.6875, 2), BooleanOp.OR); - shape = Shapes.join(shape, Shapes.box(0.1875, 0.625, 1.0625, 0.25, 0.9375, 1.125), BooleanOp.OR); - - return shape; -} \ No newline at end of file From 85def6def20b0a482993b28bb493c42cdb1a10c7 Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:14:06 -0700 Subject: [PATCH 03/25] refactor: remove @OnlyIn from common and gui code and the mergetool-api stub it needed Co-Authored-By: Claude Opus 5.5 --- common/build.gradle | 1 - .../net/dumbcode/projectnublar/block/ElectricFenceBlock.java | 4 ---- .../projectnublar/block/entity/BlockEntityElectricFence.java | 3 --- .../block/entity/BlockEntityElectricFenceBase.java | 3 --- nublar-gui/build.gradle | 1 - .../projectnublar/gui/widget/AbstractSliderButton.java | 3 --- .../java/net/dumbcode/projectnublar/gui/widget/EditBox.java | 3 --- 7 files changed, 18 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index 47e67f0c..46d20ad4 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -20,7 +20,6 @@ dependencies { compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' compileOnly group: 'org.jetbrains',name:'annotations',version: '24.1.0' - compileOnlyApi 'net.minecraftforge:mergetool-api:1.0' implementation "fuzs.forgeconfigapiport:forgeconfigapiport-common:${project.forge_config_api_port_version}" implementation "net.tslat.smartbrainlib:SmartBrainLib-common-${project.minecraft_version}:${project.sbl_version}" diff --git a/common/src/main/java/net/dumbcode/projectnublar/block/ElectricFenceBlock.java b/common/src/main/java/net/dumbcode/projectnublar/block/ElectricFenceBlock.java index 98164b5f..52340e5b 100644 --- a/common/src/main/java/net/dumbcode/projectnublar/block/ElectricFenceBlock.java +++ b/common/src/main/java/net/dumbcode/projectnublar/block/ElectricFenceBlock.java @@ -21,8 +21,6 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import org.joml.Vector3f; public class ElectricFenceBlock extends BlockConnectableBase implements EntityBlock { @@ -95,7 +93,6 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block n public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { return new BlockEntityElectricFence(blockPos, blockState); } - @OnlyIn(Dist.CLIENT) public boolean normalize(Vector3f norm) { float f = norm.x * norm.x + norm.y * norm.y + norm.z * norm.z; if ((double)f < 1.0E-5D) { @@ -109,7 +106,6 @@ public boolean normalize(Vector3f norm) { } } - @OnlyIn(Dist.CLIENT) public float fastInvSqrt(float p_226165_0_) { float f = 0.5F * p_226165_0_; int i = Float.floatToIntBits(p_226165_0_); diff --git a/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFence.java b/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFence.java index e18430e4..e8e3abb5 100644 --- a/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFence.java +++ b/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFence.java @@ -22,8 +22,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; /** * Block entity for a wire-only fence block. Persists its {@link Connection}s under the frozen @@ -86,7 +84,6 @@ public void addConnection(Connection connection) { } @Override - @OnlyIn(Dist.CLIENT) public Set compiledRenderData() { return super.compiledRenderData(); } diff --git a/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFenceBase.java b/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFenceBase.java index 6a0affa0..2638e6fe 100644 --- a/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFenceBase.java +++ b/common/src/main/java/net/dumbcode/projectnublar/block/entity/BlockEntityElectricFenceBase.java @@ -14,8 +14,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import java.util.ArrayList; import java.util.Collections; @@ -65,7 +63,6 @@ private Connection findExistingConnection(Connection reference) { return null; } - @OnlyIn(Dist.CLIENT) public Set compiledRenderData() { Set compiled = Sets.newLinkedHashSet(); if (this.level == null) { diff --git a/nublar-gui/build.gradle b/nublar-gui/build.gradle index f5297581..15632621 100644 --- a/nublar-gui/build.gradle +++ b/nublar-gui/build.gradle @@ -14,7 +14,6 @@ legacyForge { dependencies { implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1' compileOnly group: 'org.jetbrains', name: 'annotations', version: '24.1.0' - compileOnlyApi 'net.minecraftforge:mergetool-api:1.0' } configurations { diff --git a/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/AbstractSliderButton.java b/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/AbstractSliderButton.java index 59503517..a944dccc 100644 --- a/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/AbstractSliderButton.java +++ b/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/AbstractSliderButton.java @@ -15,10 +15,7 @@ import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -@OnlyIn(Dist.CLIENT) public abstract class AbstractSliderButton extends AbstractWidget { private static final ResourceLocation SLIDER_LOCATION = new ResourceLocation("textures/gui/slider.png"); protected static final int TEXTURE_WIDTH = 200; diff --git a/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/EditBox.java b/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/EditBox.java index 6f57f916..faa7d37d 100644 --- a/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/EditBox.java +++ b/nublar-gui/src/main/java/net/dumbcode/projectnublar/gui/widget/EditBox.java @@ -19,8 +19,6 @@ import net.minecraft.network.chat.Style; import net.minecraft.util.FormattedCharSequence; import net.minecraft.util.Mth; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import javax.annotation.Nullable; import java.util.Objects; @@ -28,7 +26,6 @@ import java.util.function.Consumer; import java.util.function.Predicate; -@OnlyIn(Dist.CLIENT) public class EditBox extends AbstractWidget implements Renderable { public static final int BACKWARDS = -1; public static final int FORWARDS = 1; From bc72edf358f1b4ae9fc40d5f17614b1dd2772a6f Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:26:29 -0700 Subject: [PATCH 04/25] build: run the unit tests with JUnit 5 under Gradle and remove the stand-in runner Co-Authored-By: Claude Opus 5.5 --- common/build.gradle | 10 +++- docs/plan/engineering-backlog.md | 4 +- tools/junit-standin/RunTests.java | 33 ------------- tools/junit-standin/run.sh | 30 ------------ .../org/junit/jupiter/api/Assertions.java | 46 ------------------- .../stub/org/junit/jupiter/api/Test.java | 12 ----- 6 files changed, 11 insertions(+), 124 deletions(-) delete mode 100644 tools/junit-standin/RunTests.java delete mode 100644 tools/junit-standin/run.sh delete mode 100644 tools/junit-standin/stub/org/junit/jupiter/api/Assertions.java delete mode 100644 tools/junit-standin/stub/org/junit/jupiter/api/Test.java diff --git a/common/build.gradle b/common/build.gradle index 46d20ad4..c9f45351 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -29,11 +29,19 @@ dependencies { implementation "earth.terrarium.botarium:botarium-forge-1.20.1:2.3.4" // modImplementation "dev.architectury:architectury:$rootProject.architectury_api_version" compileOnly "dev.architectury:architectury-forge:$rootProject.architectury_api_version" - testCompileOnly 'org.junit.jupiter:junit-jupiter-api:5.10.2' + testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2' } // Unit tests may use Minecraft value classes (for example Vec3); the main compile classpath holds Minecraft. sourceSets.test.compileClasspath += sourceSets.main.compileClasspath +// The tests load Minecraft value classes and the mod libraries at run time too. +sourceSets.test.runtimeClasspath += sourceSets.main.compileClasspath + +test { + useJUnitPlatform() + testLogging { events "failed"; exceptionFormat = "full" } +} configurations { commonJava { diff --git a/docs/plan/engineering-backlog.md b/docs/plan/engineering-backlog.md index a17ddac8..efb4c3eb 100644 --- a/docs/plan/engineering-backlog.md +++ b/docs/plan/engineering-backlog.md @@ -364,7 +364,7 @@ Work packages in order: M0.P0, M0.P1, M0.P2, M0.B00. M0.P2 blocks every later wo - M0.P2 owns the full client-class cleanup. - [ ] Add a `common` unit test source set: JUnit 5 on `./gradlew :common:test`. - Add real JUnit 5 dependencies. Gradle has none today. - - Move the existing unit tests in (353 at the last green run before P12c; M0.P0 records the count after its P12c decision). Remove `tools/junit-standin/run.sh` when all of them run through Gradle. + - Move the existing unit tests in (353 at the last green run before P12c; M0.P0 records the count after its P12c decision). Run all of them with `./gradlew :common:test`. - Write `docs/performance-baseline.md`: the reference machine (CPU, GPU, RAM, Java flags), the fixed client settings (render distance 12, fancy graphics, no shaders, no optimization mods) and the test world. Every fps and tick-time gate in this plan runs on that setup. - Add first new tests: `Quality` ordering and the fossil rarity math. - The set is pure Java. Tests that need Minecraft are GameTests. @@ -384,7 +384,7 @@ Work packages in order: M0.P0, M0.P1, M0.P2, M0.B00. M0.P2 blocks every later wo - CI is green on the integration branch for both loaders. - `git status` is clean after a build. - The README answers "how do I run this" without the Gradle files. -- `./gradlew :common:test` runs every moved test and they pass. `tools/junit-standin/run.sh` is gone. `docs/performance-baseline.md` exists. +- `./gradlew :common:test` runs every moved test and they pass. It is the only unit test runner. `docs/performance-baseline.md` exists. - No build file declares `toml4j`. - The GameTests compile from `common` and run on each loader through its shim. diff --git a/tools/junit-standin/RunTests.java b/tools/junit-standin/RunTests.java deleted file mode 100644 index 587a7464..00000000 --- a/tools/junit-standin/RunTests.java +++ /dev/null @@ -1,33 +0,0 @@ -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** Runs every @Test method of the given classes on a fresh instance, prints PASS/FAIL, exits with the failure count. */ -public final class RunTests { - - public static void main(String[] classNames) throws Exception { - int runs = 0; - int failures = 0; - for (String name : classNames) { - Class type = Class.forName(name); - for (Method method : type.getDeclaredMethods()) { - if (!method.isAnnotationPresent(org.junit.jupiter.api.Test.class)) { - continue; - } - Constructor constructor = type.getDeclaredConstructor(); - constructor.setAccessible(true); - method.setAccessible(true); - runs++; - try { - method.invoke(constructor.newInstance()); - System.out.println("PASS " + type.getSimpleName() + "." + method.getName()); - } catch (InvocationTargetException e) { - failures++; - System.out.println("FAIL " + type.getSimpleName() + "." + method.getName() + ": " + e.getCause()); - } - } - } - System.out.println(runs + " run, " + failures + " failed"); - System.exit(failures); - } -} diff --git a/tools/junit-standin/run.sh b/tools/junit-standin/run.sh deleted file mode 100644 index 68f5c547..00000000 --- a/tools/junit-standin/run.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -# Runs the unit tests in common/src/test/java against the JUnit stand-ins (the project has no JUnit). -# Use from the worktree root in Git Bash on Windows, after: ./gradlew :common:compileJava -set -e -ROOT="$(pwd)" -OUT="$ROOT/build/junit-standin" -CP="$(cygpath -w "$ROOT/common/build/classes/java/main")" -CP="$CP;$(cygpath -w "$ROOT/nublar-gui/build/classes/java/main")" - -# Minecraft with the dev mappings the common module compiles against. -MC=$(ls ~/.gradle/caches/fabric-loom/minecraftMaven/net/minecraft/minecraft-merged/*/minecraft-merged-*.jar | head -1) -CP="$CP;$(cygpath -w "$MC")" -# Libraries Minecraft classes need at class-load time. -for pattern in "guava-3*.jar" "fastutil-8*.jar" "commons-lang3-*.jar" "slf4j-api-2*.jar" "datafixerupper-6*.jar" "logging-1*.jar" "annotations-2*.jar" "joml-1*.jar" "gson-2.10*.jar" "brigadier-1*.jar" "authlib-4*.jar"; do - jar=$(find ~/.gradle/caches/modules-2 -name "$pattern" | grep -v sources | head -1) - [ -n "$jar" ] && CP="$CP;$(cygpath -w "$jar")" -done -# Mod libraries, remapped by ModDevGradle. The verifier loads Dinosaur, which needs them. -for pattern in "geckolib-forge-1.20.1-*.jar" "SmartBrainLib-forge-1.20.1-*.jar"; do - jar=$(find ~/.gradle/caches -path "*transforms*" -name "$pattern" | grep -v sources | head -1) - [ -n "$jar" ] && CP="$CP;$(cygpath -w "$jar")" -done - -# Paths below are relative to the worktree root: the root path contains a space, which would split unquoted words. -rm -rf "$OUT" -TEST_SOURCES=$(cd "$ROOT" && find common/src/test/java -name "*Test.java") -TEST_CLASSES=$(cd "$ROOT/common/src/test/java" && find . -name "*Test.java" | sed 's|^\./||; s|\.java$||; s|/|.|g') -cd "$ROOT" -javac -cp "$CP" -d "$(cygpath -w "$OUT")" tools/junit-standin/stub/org/junit/jupiter/api/*.java tools/junit-standin/RunTests.java $TEST_SOURCES -java -cp "$(cygpath -w "$OUT");$CP" RunTests $TEST_CLASSES diff --git a/tools/junit-standin/stub/org/junit/jupiter/api/Assertions.java b/tools/junit-standin/stub/org/junit/jupiter/api/Assertions.java deleted file mode 100644 index c00d5376..00000000 --- a/tools/junit-standin/stub/org/junit/jupiter/api/Assertions.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.junit.jupiter.api; - -import java.util.Objects; - -/** Stand-in for the JUnit 5 assertions the unit tests use. Failures throw AssertionError. */ -public final class Assertions { - - private Assertions() { - } - - private static void fail(String message) { - throw new AssertionError(message); - } - - public static void assertTrue(boolean condition) { assertTrue(condition, "expected true"); } - public static void assertTrue(boolean condition, String message) { if (!condition) fail(message); } - public static void assertFalse(boolean condition) { assertFalse(condition, "expected false"); } - public static void assertFalse(boolean condition, String message) { if (condition) fail(message); } - public static void assertNull(Object value) { assertNull(value, "expected null"); } - public static void assertNull(Object value, String message) { if (value != null) fail(message + " (was " + value + ")"); } - public static void assertNotNull(Object value) { assertNotNull(value, "expected a value"); } - public static void assertNotNull(Object value, String message) { if (value == null) fail(message); } - public static void assertSame(Object expected, Object actual) { assertSame(expected, actual, "not the same object"); } - public static void assertSame(Object expected, Object actual, String message) { if (expected != actual) fail(message + ": expected " + expected + ", got " + actual); } - public static void assertEquals(Object expected, Object actual) { assertEquals(expected, actual, "not equal"); } - public static void assertEquals(Object expected, Object actual, String message) { if (!Objects.equals(expected, actual)) fail(message + ": expected " + expected + ", got " + actual); } - public static void assertEquals(int expected, int actual) { assertEquals(expected, actual, "not equal"); } - public static void assertEquals(int expected, int actual, String message) { if (expected != actual) fail(message + ": expected " + expected + ", got " + actual); } - public static void assertEquals(long expected, long actual) { assertEquals(expected, actual, "not equal"); } - public static void assertEquals(long expected, long actual, String message) { if (expected != actual) fail(message + ": expected " + expected + ", got " + actual); } - public static void assertNotEquals(long unexpected, long actual) { assertNotEquals(unexpected, actual, "unexpectedly equal"); } - public static void assertNotEquals(long unexpected, long actual, String message) { if (unexpected == actual) fail(message + ": both " + actual); } - public static void assertEquals(float expected, float actual, float delta) { assertEquals(expected, actual, delta, "not equal"); } - public static void assertEquals(float expected, float actual, float delta, String message) { if (Math.abs(expected - actual) > delta) fail(message + ": expected " + expected + ", got " + actual); } - public static void assertEquals(double expected, double actual, double delta) { assertEquals(expected, actual, delta, "not equal"); } - public static void assertEquals(double expected, double actual, double delta, String message) { if (Math.abs(expected - actual) > delta) fail(message + ": expected " + expected + ", got " + actual); } - - public static T assertThrows(Class expected, Runnable code) { - try { code.run(); } catch (Throwable thrown) { - if (expected.isInstance(thrown)) return expected.cast(thrown); - fail("expected " + expected.getSimpleName() + ", got " + thrown); - } - fail("expected " + expected.getSimpleName() + ", nothing was thrown"); - return null; - } -} diff --git a/tools/junit-standin/stub/org/junit/jupiter/api/Test.java b/tools/junit-standin/stub/org/junit/jupiter/api/Test.java deleted file mode 100644 index 20fe2b01..00000000 --- a/tools/junit-standin/stub/org/junit/jupiter/api/Test.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.junit.jupiter.api; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Stand-in for JUnit 5's @Test: the project has no JUnit setup. */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface Test { -} From 457b7fe9a3d8afd68b34352425e55fd24f35cfc5 Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:30:44 -0700 Subject: [PATCH 05/25] build: run the unit tests from the build folder so their log stays out of the source tree Co-Authored-By: Claude Opus 5.5 --- common/build.gradle | 3 +++ .../entity/dinosaur/ai/behavior/social/HerdSpacingTest.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/build.gradle b/common/build.gradle index c9f45351..ae73e733 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -41,6 +41,9 @@ sourceSets.test.runtimeClasspath += sourceSets.main.compileClasspath test { useJUnitPlatform() testLogging { events "failed"; exceptionFormat = "full" } + // Minecraft's log4j2.xml writes logs/ relative to the working directory, so run the tests in build output. + workingDir = layout.buildDirectory.dir("test-run") + doFirst { workingDir.mkdirs() } } configurations { diff --git a/common/src/test/java/net/dumbcode/projectnublar/entity/dinosaur/ai/behavior/social/HerdSpacingTest.java b/common/src/test/java/net/dumbcode/projectnublar/entity/dinosaur/ai/behavior/social/HerdSpacingTest.java index a1eeaf07..db12ba6b 100644 --- a/common/src/test/java/net/dumbcode/projectnublar/entity/dinosaur/ai/behavior/social/HerdSpacingTest.java +++ b/common/src/test/java/net/dumbcode/projectnublar/entity/dinosaur/ai/behavior/social/HerdSpacingTest.java @@ -9,7 +9,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -/** Unit tests for the herd spacing arithmetic. Runs on the JUnit stand-in runner (tools/junit-standin). */ +/** Unit tests for the herd spacing arithmetic. Runs with ./gradlew :common:test. */ class HerdSpacingTest { private static final double EPSILON = 1.0E-9D; From e4778d070c36f1bf1befdeede2652d3c08b9b74a Mon Sep 17 00:00:00 2001 From: Kashyap Gummaraju Date: Sat, 24 Oct 2026 21:59:34 -0700 Subject: [PATCH 06/25] test: GameTest bodies in common with a Forge and a Fabric holder; structures move to common resources Co-Authored-By: Claude Opus 5.5 --- .../projectnublar/gametest/HerdGameTests.java | 77 ++++++------------ .../gametest/MachineGameTests.java | 29 +++---- .../projectnublar/gametest/package-info.java | 5 ++ .../projectnublar/structures/herd_arena.nbt | Bin .../structures/herd_corridor.nbt | Bin .../projectnublar/structures/herd_forest.nbt | Bin .../projectnublar/structures/herd_lowgap.nbt | Bin .../projectnublar/structures/herd_shore.nbt | Bin .../projectnublar/structures/herd_track.nbt | Bin fabric/build.gradle | 7 ++ .../gametest/FabricGameTests.java | 65 +++++++++++++++ fabric/src/main/resources/fabric.mod.json | 3 + .../gametest/ForgeGameTests.java | 66 +++++++++++++++ tools/gametest-templates/make_templates.py | 2 +- 14 files changed, 181 insertions(+), 73 deletions(-) rename {forge => common}/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java (93%) rename {forge => common}/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java (85%) create mode 100644 common/src/main/java/net/dumbcode/projectnublar/gametest/package-info.java rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_arena.nbt (100%) rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_corridor.nbt (100%) rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_forest.nbt (100%) rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_lowgap.nbt (100%) rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_shore.nbt (100%) rename {forge => common}/src/main/resources/data/projectnublar/structures/herd_track.nbt (100%) create mode 100644 fabric/src/main/java/net/dumbcode/projectnublar/gametest/FabricGameTests.java create mode 100644 forge/src/main/java/net/dumbcode/projectnublar/gametest/ForgeGameTests.java diff --git a/forge/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java b/common/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java similarity index 93% rename from forge/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java rename to common/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java index 0b82599b..d53da826 100644 --- a/forge/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java +++ b/common/src/main/java/net/dumbcode/projectnublar/gametest/HerdGameTests.java @@ -1,6 +1,5 @@ package net.dumbcode.projectnublar.gametest; -import net.dumbcode.projectnublar.Constants; import net.dumbcode.projectnublar.api.dinosaur.DinoBehaviourData; import net.dumbcode.projectnublar.api.dinosaur.DinoData; import net.dumbcode.projectnublar.data.BehaviourDataReloadListener; @@ -15,15 +14,12 @@ import net.dumbcode.projectnublar.registry.GeneInit; import net.dumbcode.projectnublar.util.DinoNeedsUtils; import net.minecraft.core.BlockPos; -import net.minecraft.gametest.framework.GameTest; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.WalkTarget; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.gametest.GameTestHolder; -import net.minecraftforge.gametest.PrefixGameTestTemplate; import net.tslat.smartbrainlib.util.BrainUtils; import org.jetbrains.annotations.Nullable; @@ -33,22 +29,24 @@ /** * GameTests for herds (plan B18 and the herd movement redesign). The lead runs them one at a time in a * creative world started from {@code runClient} (never on a dedicated GameTest server). On the GameTest server - * each test is its own batch, so they run one at a time there too. - * Run a test with {@code /test run herdgametests.}. + * each test is its own batch, so they run one at a time there too. The tests have no loader code; the holders + * {@code ForgeGameTests} (Forge) and {@code FabricGameTests} (Fabric) register them. + * Run a test with {@code /test run } on Forge and {@code /test run fabricgametests.} on Fabric, + * where the name is the method name in lower case: *
    - *
  • {@code /test run herdgametests.fivegallimimusformoneherdledbythestrongest}
  • - *
  • {@code /test run herdgametests.twentygallimimusformoneherdoftwenty}
  • - *
  • {@code /test run herdgametests.strongernewcomerleadsatonce}
  • - *
  • {@code /test run herdgametests.deadmemberleavesitsherd}
  • - *
  • {@code /test run herdgametests.grazingherdholdshardminimum}
  • - *
  • {@code /test run herdgametests.grazingmembersstayput}
  • - *
  • {@code /test run herdgametests.smallleadermoveskeepgraze}
  • - *
  • {@code /test run herdgametests.stackedmembersseparate}
  • - *
  • {@code /test run herdgametests.herdtravelsalongtrail}
  • - *
  • {@code /test run herdgametests.herdcrossesforest}
  • - *
  • {@code /test run herdgametests.herdpassescorridor}
  • - *
  • {@code /test run herdgametests.memberneverenterslowgap}
  • - *
  • {@code /test run herdgametests.herdskirtswater}
  • + *
  • {@code fivegallimimusformoneherdledbythestrongest}
  • + *
  • {@code twentygallimimusformoneherdoftwenty}
  • + *
  • {@code strongernewcomerleadsatonce}
  • + *
  • {@code deadmemberleavesitsherd}
  • + *
  • {@code grazingherdholdshardminimum}
  • + *
  • {@code grazingmembersstayput}
  • + *
  • {@code smallleadermoveskeepgraze}
  • + *
  • {@code stackedmembersseparate}
  • + *
  • {@code herdtravelsalongtrail}
  • + *
  • {@code herdcrossesforest}
  • + *
  • {@code herdpassescorridor}
  • + *
  • {@code memberneverenterslowgap}
  • + *
  • {@code herdskirtswater}
  • *
* The arenas {@code herd_track}, {@code herd_forest}, {@code herd_shore}, {@code herd_corridor} and * {@code herd_lowgap} come from {@code tools/gametest-templates/make_templates.py}. {@code herd_arena} (the @@ -82,8 +80,6 @@ * can switch the walk target and restart a path. * */ -@GameTestHolder(Constants.MODID) -@PrefixGameTestTemplate(false) public final class HerdGameTests { /** @@ -95,10 +91,13 @@ public final class HerdGameTests { private static final int FLOOR_CHECK_TICK = 5; /** An animal more than this below {@link #FLOOR_Y} fell through the floor. */ private static final double FLOOR_TOLERANCE = 0.5D; - private static final String ARENA = "herd_arena"; - private static final String TRACK = "herd_track"; - private static final String FOREST = "herd_forest"; - private static final String SHORE = "herd_shore"; + // Template names (data/projectnublar/structures/.nbt), public for the loader holders' @GameTest annotations. + public static final String ARENA = "herd_arena"; + public static final String TRACK = "herd_track"; + public static final String FOREST = "herd_forest"; + public static final String SHORE = "herd_shore"; + public static final String CORRIDOR = "herd_corridor"; + public static final String LOWGAP = "herd_lowgap"; /** * Pinned grazing ticks before counting: spots are picked within 60 ticks (GrazeSchedule.ENTER_STAGGER_TICKS). * At the graze speed (0.049 b/t) a member walks only up to 11.8 blocks toward its spot in the other 240, @@ -144,8 +143,6 @@ public final class HerdGameTests { /** Spec T5: stacked members separate within this many ticks. */ private static final int SEPARATE_TICKS = 100; private static final double APART_TOLERANCE = 0.05D; - private static final String CORRIDOR = "herd_corridor"; - private static final String LOWGAP = "herd_lowgap"; /** Journey goals: open ground inside each arena (tools/gametest-templates/make_templates.py). */ private static final BlockPos GOAL = new BlockPos(56, FLOOR_Y, 8); /** @@ -208,9 +205,7 @@ private HerdGameTests() { /** * Five animals form one herd, and the strongest leads it. - * Run: {@code /test run herdgametests.fivegallimimusformoneherdledbythestrongest} */ - @GameTest(template = ARENA, batch = "fivegallimimusformoneherdledbythestrongest", timeoutTicks = 600) public static void fiveGallimimusFormOneHerdLedByTheStrongest(GameTestHelper helper) { List animals = new ArrayList<>(); for (int i = 0; i < 4; i++) { @@ -236,9 +231,7 @@ public static void fiveGallimimusFormOneHerdLedByTheStrongest(GameTestHelper hel /** * A full herd: the Gallimimus config sets {@code group_size} to 20. Twenty animals end in one herd * whatever pairs form first, because any two partial herds fit together and merge. - * Run: {@code /test run herdgametests.twentygallimimusformoneherdoftwenty} */ - @GameTest(template = ARENA, batch = "twentygallimimusformoneherdoftwenty", timeoutTicks = 1200) public static void twentyGallimimusFormOneHerdOfTwenty(GameTestHelper helper) { List animals = new ArrayList<>(); for (int row = 0; row < 4; row++) { @@ -260,9 +253,7 @@ public static void twentyGallimimusFormOneHerdOfTwenty(GameTestHelper helper) { /** * A stronger animal that joins a pair leads the herd at once. - * Run: {@code /test run herdgametests.strongernewcomerleadsatonce} */ - @GameTest(template = ARENA, batch = "strongernewcomerleadsatonce", timeoutTicks = 600) public static void strongerNewcomerLeadsAtOnce(GameTestHelper helper) { Dinosaur first = hatch(helper, EntityInit.GALLIMIMUS.get(), new BlockPos(8, FLOOR_Y, 12), 0D); Dinosaur second = hatch(helper, EntityInit.GALLIMIMUS.get(), new BlockPos(14, FLOOR_Y, 12), 0D); @@ -282,9 +273,7 @@ public static void strongerNewcomerLeadsAtOnce(GameTestHelper helper) { /** * A member that dies leaves its herd; the survivor stays in a herd of 1. - * Run: {@code /test run herdgametests.deadmemberleavesitsherd} */ - @GameTest(template = ARENA, batch = "deadmemberleavesitsherd", timeoutTicks = 400) public static void deadMemberLeavesItsHerd(GameTestHelper helper) { Dinosaur doomed = hatch(helper, EntityInit.GALLIMIMUS.get(), new BlockPos(8, FLOOR_Y, 12), 0D); Dinosaur survivor = hatch(helper, EntityInit.GALLIMIMUS.get(), new BlockPos(14, FLOOR_Y, 12), 0D); @@ -304,9 +293,7 @@ public static void deadMemberLeavesItsHerd(GameTestHelper helper) { /** * Spec T4: a pinned grazing herd of 20; no pair stays closer than the hard minimum for more than 20 ticks. - * Run: {@code /test run herdgametests.grazingherdholdshardminimum} */ - @GameTest(template = TRACK, batch = "grazing_hard_minimum", timeoutTicks = 3000) public static void grazingHerdHoldsHardMinimum(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); int[][] close = new int[animals.size()][animals.size()]; @@ -336,9 +323,7 @@ public static void grazingHerdHoldsHardMinimum(GameTestHelper helper) { * spots are closer than {@link #GRAZE_SPACING} (4.2), and at least half of the followers hold a spot (so * the spot check cannot pass with no spots). Counting starts after {@link #STAND_SETTLE_TICKS} of pinned * grazing. - * Run: {@code /test run herdgametests.grazingmembersstayput} */ - @GameTest(template = TRACK, batch = "grazing_stay_put", timeoutTicks = 3400) public static void grazingMembersStayPut(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); double[][] last = new double[animals.size()][2]; @@ -398,9 +383,7 @@ public static void grazingMembersStayPut(GameTestHelper helper) { * sampling cannot always place 19 spots 4.2 apart inside the 22-wide arena (Review Focus 1). But at least * {@link #MIN_SPOT_HOLDER_FRACTION} of the followers must hold a spot on every tick after the moves begin, * so the spot check cannot pass with no spots. - * Run: {@code /test run herdgametests.smallleadermoveskeepgraze} */ - @GameTest(template = TRACK, batch = "small_leader_moves", timeoutTicks = 2400) public static void smallLeaderMovesKeepGraze(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); double[][] spots = new double[animals.size()][]; @@ -491,9 +474,7 @@ public static void smallLeaderMovesKeepGraze(GameTestHelper helper) { *
  • A pair counts as apart at {@link #APART_TOLERANCE} under the hard minimum. A separating body stops * when it reaches the minimum, and movement and collision can leave the stop a little short of it.
  • * - * Run: {@code /test run herdgametests.stackedmembersseparate} */ - @GameTest(template = ARENA, batch = "stacked_members", timeoutTicks = 600) public static void stackedMembersSeparate(GameTestHelper helper) { List animals = new ArrayList<>(); for (int i = 0; i < 3; i++) { @@ -529,9 +510,7 @@ public static void stackedMembersSeparate(GameTestHelper helper) { * behind) (30.5 - 11.2) / 0.194 = 100 + stagger 60; total 1163, x 1.3 = 1512. A full 200-tick wait makes * 1263, x 1.3 = 1642, so 1700 (1.46 x the realistic total, 1.35 x with the full wait). The timeout leaves * 1500 ticks to form the herd. - * Run: {@code /test run herdgametests.herdtravelsalongtrail} */ - @GameTest(template = TRACK, batch = "travel_trail", timeoutTicks = 3200) public static void herdTravelsAlongTrail(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); int[][] close = new int[animals.size()][animals.size()]; @@ -558,9 +537,7 @@ public static void herdTravelsAlongTrail(GameTestHelper helper) { * 0.194 = 340 + stagger 60; total 1757, x 1.3 = 2284, so 2400 (1.37 x; the forest is the least certain * estimate, and the limit is not cut below lead decision 18's 2400). The timeout leaves 1600 ticks to form * the herd. - * Run: {@code /test run herdgametests.herdcrossesforest} */ - @GameTest(template = FOREST, batch = "travel_forest", timeoutTicks = 4000) public static void herdCrossesForest(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); boolean[] travelled = new boolean[1]; @@ -596,9 +573,7 @@ public static void herdCrossesForest(GameTestHelper helper) { * through the corridor and 2 blocks either side of it, 6 in 2 open rows west of it, + 1.1 lag), 30 blocks * short of x 44: 30 / 0.194 = 155, so 160 with the file ahead of it, + stagger 60; total 1410, x 1.3 = * 1833, so 1900 (1.35 x). The timeout leaves 1500 ticks to form the herd. - * Run: {@code /test run herdgametests.herdpassescorridor} */ - @GameTest(template = CORRIDOR, batch = "travel_corridor", timeoutTicks = 3400) public static void herdPassesCorridor(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); boolean[] passed = new boolean[animals.size()]; @@ -637,9 +612,7 @@ public static void herdPassesCorridor(GameTestHelper helper) { * path = 175 + stagger 60; total 1168, x 1.3 = 1518. A full 200-tick wait makes 1268, x 1.3 = 1648, so * 1700 (1.46 x the realistic total, 1.34 x with the full wait). The timeout leaves 1500 ticks to form the * herd (after the limit and the 300 ticks of grazing). - * Run: {@code /test run herdgametests.memberneverenterslowgap} */ - @GameTest(template = LOWGAP, batch = "travel_lowgap", timeoutTicks = 3500) public static void memberNeverEntersLowGap(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); boolean[] passed = new boolean[animals.size()]; @@ -689,9 +662,7 @@ public static void memberNeverEntersLowGap(GameTestHelper helper) { * settle 100 + walk-in (the deepest wedge, single file beside the channel, tail 62 behind) (62 - 11.2) / * 0.194 = 262 + stagger 60; total 1477, x 1.3 = 1920, so 2000 (1.35 x). The timeout leaves 1400 ticks to * form the herd. - * Run: {@code /test run herdgametests.herdskirtswater} */ - @GameTest(template = SHORE, batch = "travel_shore", timeoutTicks = 3400) public static void herdSkirtsWater(GameTestHelper helper) { List animals = hatchTwenty(helper, 3); boolean[] travelled = new boolean[1]; diff --git a/forge/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java b/common/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java similarity index 85% rename from forge/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java rename to common/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java index 6df3858b..d927e951 100644 --- a/forge/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java +++ b/common/src/main/java/net/dumbcode/projectnublar/gametest/MachineGameTests.java @@ -7,14 +7,11 @@ import net.dumbcode.projectnublar.registry.ItemInit; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.gametest.framework.GameTest; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.gametest.GameTestHolder; -import net.minecraftforge.gametest.PrefixGameTestTemplate; import java.lang.reflect.Field; @@ -22,22 +19,22 @@ * GameTests for the Sequencer's synthesis start ("Begin") and the energy that reaches it from a creative * generator. The Sequencer is a 2 x 2 x 2 multiblock and only its core block (rows, columns and depth all 0) * has the block entity that stores energy; these tests check whether a generator must touch that core block. - * Each test is its own batch. + * Each test is its own batch and uses the herd arena template ({@code HerdGameTests.ARENA}). The tests have no + * loader code; the holders {@code ForgeGameTests} (Forge) and {@code FabricGameTests} (Fabric) register them. + * Run a test with {@code /test run } on Forge and {@code /test run fabricgametests.} on Fabric, + * where the name is the method name in lower case: *
      - *
    • {@code /test run machinegametests.sequencersynthstartswithgeneratoroncore}: generator against the core, - * all inputs filled; synthesis must start.
    • - *
    • {@code /test run machinegametests.sequencersynthfailswithgeneratoronpart}: generator against a non-core - * part only, all inputs filled; synthesis must NOT start (the test passes when it does not).
    • - *
    • {@code /test run machinegametests.sequencercorereceivesenergy}: generator against the core, no inputs; - * the core must store more than the 32 FE a synthesis tick needs.
    • + *
    • {@code sequencersynthstartswithgeneratoroncore}: generator against the core, all inputs filled; + * synthesis must start.
    • + *
    • {@code sequencersynthfailswithgeneratoronpart}: generator against a non-core part only, all inputs + * filled; synthesis must NOT start (the test passes when it does not).
    • + *
    • {@code sequencercorereceivesenergy}: generator against the core, no inputs; the core must store more + * than the 32 FE a synthesis tick needs.
    • *
    * Every test logs its readings with the prefix {@code [machinetest]}. */ -@GameTestHolder(Constants.MODID) -@PrefixGameTestTemplate(false) public final class MachineGameTests { - private static final String ARENA = "herd_arena"; /** First layer above the arena floor (see {@code HerdGameTests.FLOOR_Y}). */ private static final int FLOOR_Y = 2; /** Core block of the Sequencer. With FACING north the parts extend west (columns), south (depth) and up (rows). */ @@ -58,9 +55,7 @@ private MachineGameTests() { /** * Generator against the core block, all synthesis inputs filled: Begin starts synthesis. - * Run: {@code /test run machinegametests.sequencersynthstartswithgeneratoroncore} */ - @GameTest(template = ARENA, batch = "sequencersynthstartswithgeneratoroncore", timeoutTicks = 200) public static void sequencerSynthStartsWithGeneratorOnCore(GameTestHelper helper) { SequencerBlockEntity sequencer = placeSequencer(helper, GENERATOR_ON_CORE); fillSynthInputs(sequencer); @@ -82,9 +77,7 @@ public static void sequencerSynthStartsWithGeneratorOnCore(GameTestHelper helper /** * Generator against a non-core part only, all synthesis inputs filled: Begin does not start synthesis. * The test passes when synthesis stays off. - * Run: {@code /test run machinegametests.sequencersynthfailswithgeneratoronpart} */ - @GameTest(template = ARENA, batch = "sequencersynthfailswithgeneratoronpart", timeoutTicks = 200) public static void sequencerSynthFailsWithGeneratorOnPart(GameTestHelper helper) { SequencerBlockEntity sequencer = placeSequencer(helper, GENERATOR_ON_PART); fillSynthInputs(sequencer); @@ -105,9 +98,7 @@ public static void sequencerSynthFailsWithGeneratorOnPart(GameTestHelper helper) /** * Generator against the core block, no inputs: the core stores more than one synthesis tick of energy. - * Run: {@code /test run machinegametests.sequencercorereceivesenergy} */ - @GameTest(template = ARENA, batch = "sequencercorereceivesenergy", timeoutTicks = 200) public static void sequencerCoreReceivesEnergy(GameTestHelper helper) { SequencerBlockEntity sequencer = placeSequencer(helper, GENERATOR_ON_CORE); helper.runAfterDelay(SETTLE_TICKS, () -> { diff --git a/common/src/main/java/net/dumbcode/projectnublar/gametest/package-info.java b/common/src/main/java/net/dumbcode/projectnublar/gametest/package-info.java new file mode 100644 index 00000000..cf895e1f --- /dev/null +++ b/common/src/main/java/net/dumbcode/projectnublar/gametest/package-info.java @@ -0,0 +1,5 @@ +/** + * GameTest bodies with no loader code; each loader's holder class ({@code ForgeGameTests}, {@code FabricGameTests}) + * registers them. + */ +package net.dumbcode.projectnublar.gametest; diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_arena.nbt b/common/src/main/resources/data/projectnublar/structures/herd_arena.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_arena.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_arena.nbt diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_corridor.nbt b/common/src/main/resources/data/projectnublar/structures/herd_corridor.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_corridor.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_corridor.nbt diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_forest.nbt b/common/src/main/resources/data/projectnublar/structures/herd_forest.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_forest.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_forest.nbt diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_lowgap.nbt b/common/src/main/resources/data/projectnublar/structures/herd_lowgap.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_lowgap.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_lowgap.nbt diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_shore.nbt b/common/src/main/resources/data/projectnublar/structures/herd_shore.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_shore.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_shore.nbt diff --git a/forge/src/main/resources/data/projectnublar/structures/herd_track.nbt b/common/src/main/resources/data/projectnublar/structures/herd_track.nbt similarity index 100% rename from forge/src/main/resources/data/projectnublar/structures/herd_track.nbt rename to common/src/main/resources/data/projectnublar/structures/herd_track.nbt diff --git a/fabric/build.gradle b/fabric/build.gradle index 355837d0..74526436 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -45,5 +45,12 @@ loom { ideConfigGenerated(true) runDir("run") } + gametest { + server() + setConfigName("Fabric GameTest") + vmArg "-Dfabric-api.gametest" + vmArg "-Dfabric-api.gametest.report-file=${project.buildDir}/junit.xml" + runDir "build/gametest" + } } } diff --git a/fabric/src/main/java/net/dumbcode/projectnublar/gametest/FabricGameTests.java b/fabric/src/main/java/net/dumbcode/projectnublar/gametest/FabricGameTests.java new file mode 100644 index 00000000..5b371c18 --- /dev/null +++ b/fabric/src/main/java/net/dumbcode/projectnublar/gametest/FabricGameTests.java @@ -0,0 +1,65 @@ +package net.dumbcode.projectnublar.gametest; + +import net.dumbcode.projectnublar.Constants; +import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; + +/** + * Registers the GameTests of {@link HerdGameTests} and {@link MachineGameTests} on Fabric, through the + * {@code fabric-gametest} entrypoint in {@code fabric.mod.json}. This class only carries the loader annotations: + * per test, one {@code @GameTest} line and a one-line call to the test body. Fabric uses the template string as + * given, so it holds the {@code projectnublar:} namespace, and names each test + * {@code fabricgametests.}. Fabric makes an instance with the public no-argument + * constructor before each test, so the class declares no constructor. + */ +public class FabricGameTests implements FabricGameTest { + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "fivegallimimusformoneherdledbythestrongest", timeoutTicks = 600) + public void fiveGallimimusFormOneHerdLedByTheStrongest(GameTestHelper helper) { HerdGameTests.fiveGallimimusFormOneHerdLedByTheStrongest(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "twentygallimimusformoneherdoftwenty", timeoutTicks = 1200) + public void twentyGallimimusFormOneHerdOfTwenty(GameTestHelper helper) { HerdGameTests.twentyGallimimusFormOneHerdOfTwenty(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "strongernewcomerleadsatonce", timeoutTicks = 600) + public void strongerNewcomerLeadsAtOnce(GameTestHelper helper) { HerdGameTests.strongerNewcomerLeadsAtOnce(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "deadmemberleavesitsherd", timeoutTicks = 400) + public void deadMemberLeavesItsHerd(GameTestHelper helper) { HerdGameTests.deadMemberLeavesItsHerd(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.TRACK, batch = "grazing_hard_minimum", timeoutTicks = 3000) + public void grazingHerdHoldsHardMinimum(GameTestHelper helper) { HerdGameTests.grazingHerdHoldsHardMinimum(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.TRACK, batch = "grazing_stay_put", timeoutTicks = 3400) + public void grazingMembersStayPut(GameTestHelper helper) { HerdGameTests.grazingMembersStayPut(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.TRACK, batch = "small_leader_moves", timeoutTicks = 2400) + public void smallLeaderMovesKeepGraze(GameTestHelper helper) { HerdGameTests.smallLeaderMovesKeepGraze(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "stacked_members", timeoutTicks = 600) + public void stackedMembersSeparate(GameTestHelper helper) { HerdGameTests.stackedMembersSeparate(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.TRACK, batch = "travel_trail", timeoutTicks = 3200) + public void herdTravelsAlongTrail(GameTestHelper helper) { HerdGameTests.herdTravelsAlongTrail(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.FOREST, batch = "travel_forest", timeoutTicks = 4000) + public void herdCrossesForest(GameTestHelper helper) { HerdGameTests.herdCrossesForest(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.CORRIDOR, batch = "travel_corridor", timeoutTicks = 3400) + public void herdPassesCorridor(GameTestHelper helper) { HerdGameTests.herdPassesCorridor(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.LOWGAP, batch = "travel_lowgap", timeoutTicks = 3500) + public void memberNeverEntersLowGap(GameTestHelper helper) { HerdGameTests.memberNeverEntersLowGap(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.SHORE, batch = "travel_shore", timeoutTicks = 3400) + public void herdSkirtsWater(GameTestHelper helper) { HerdGameTests.herdSkirtsWater(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "sequencersynthstartswithgeneratoroncore", timeoutTicks = 200) + public void sequencerSynthStartsWithGeneratorOnCore(GameTestHelper helper) { MachineGameTests.sequencerSynthStartsWithGeneratorOnCore(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "sequencersynthfailswithgeneratoronpart", timeoutTicks = 200) + public void sequencerSynthFailsWithGeneratorOnPart(GameTestHelper helper) { MachineGameTests.sequencerSynthFailsWithGeneratorOnPart(helper); } + + @GameTest(template = Constants.MODID + ":" + HerdGameTests.ARENA, batch = "sequencercorereceivesenergy", timeoutTicks = 200) + public void sequencerCoreReceivesEnergy(GameTestHelper helper) { MachineGameTests.sequencerCoreReceivesEnergy(helper); } +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 0f5c570a..0b985dc4 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -18,6 +18,9 @@ "entrypoints": { "main": [ "net.dumbcode.projectnublar.ProjectNublarFabric" + ], + "fabric-gametest": [ + "net.dumbcode.projectnublar.gametest.FabricGameTests" ] }, "mixins": [ diff --git a/forge/src/main/java/net/dumbcode/projectnublar/gametest/ForgeGameTests.java b/forge/src/main/java/net/dumbcode/projectnublar/gametest/ForgeGameTests.java new file mode 100644 index 00000000..43920149 --- /dev/null +++ b/forge/src/main/java/net/dumbcode/projectnublar/gametest/ForgeGameTests.java @@ -0,0 +1,66 @@ +package net.dumbcode.projectnublar.gametest; + +import net.dumbcode.projectnublar.Constants; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraftforge.gametest.GameTestHolder; +import net.minecraftforge.gametest.PrefixGameTestTemplate; + +/** + * Registers the GameTests of {@link HerdGameTests} and {@link MachineGameTests} on Forge. This class only carries + * the loader annotations: per test, one {@code @GameTest} line and a one-line call to the test body. Forge finds + * the class by {@code @GameTestHolder}; with {@code @PrefixGameTestTemplate(false)} the template is + * {@code projectnublar: