Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

FW Paint (fw-paint-fabric)

A client-side mod for Minecraft 26.3 — for Fabric and NeoForge — that paints with blocks: solid extrude/fill, colour/brightness gradients, and 3D noise patterns. This README is the developer/build guide; user-facing documentation lives in docs/curseforge-description.md.

Requirements

What Version Notes
JDK 25 (Temurin recommended) Minecraft 26.3 requires Java 25
Minecraft 26.3 pinned in gradle.properties
Fabric Loader 0.19.3+ pinned in gradle.properties
Fabric API 0.160.6+26.3 compile dep; also needed in any Fabric instance running the jar
Fabric Loom 1.17-SNAPSHOT Gradle plugin; 26.x ships unobfuscated, Loom runs non-remapping
NeoForge 26.3.0.3-beta pinned in gradle.properties (neo_version)
ModDevGradle 2.0.141 NeoForge's Gradle plugin (moddev_version)
Gradle — none needed; the wrapper (gradlew) downloads itself

Installing JDK 25:

  • Windows: winget install EclipseAdoptium.Temurin.25.JDK — Gradle auto-detects it from C:\Program Files\Eclipse Adoptium\. (Gradle's daemon-JVM auto-download does not work on Windows, so install the JDK yourself.)
  • Linux (Debian/Ubuntu): sudo apt install temurin-25-jdk (Adoptium repo) or download from adoptium.net. Any JDK 25 works; the build uses a Java 25 toolchain.

Module layout (multiloader)

All game code is loader-free and lives in common/ — 26.x ships unobfuscated with Mojang names, so the exact same compiled classes run on both loaders. fabric/ and neoforge/ are thin shells: an entrypoint class each (~80 lines) that registers keybinds and forwards tick / render / input events into the common core, plus the loader metadata file. Each loader jar bundles common's classes and assets, so the shipped jars are self-contained.

Build

# Linux / macOS / Git Bash
./gradlew build

# Windows (cmd / PowerShell)
gradlew.bat build
  • Outputs: fabric/build/libs/fw-paint-fabric-<version>.jar and neoforge/build/libs/fw-paint-neoforge-<version>.jar.
  • build also runs the unit tests; a red build means failing tests, not just compile errors.
  • First build downloads Minecraft + dependencies for both loaders — allow a few minutes and disk space under ~/.gradle / %USERPROFILE%\.gradle.

Run the dev client

./gradlew runClient             # Fabric (alias for :fabric:runClient)
./gradlew :neoforge:runClient   # NeoForge

Launches Minecraft 26.3 with the mod loaded (offline dev session; Realms/auth warnings in the log are normal). Each loader keeps its own world/config under fabric/run/ and neoforge/run/.

Tests

./gradlew test

Unit tests live in common/ and cover the pure, Minecraft-free maths: gradient ordering/deviation (GradientRampTest), texture pixel analysis (TextureStatsTest), noise (NoiseTest), flood fill (FloodFillTest), marker-segment geometry (NoisePlacerTest), palette band maths (PaletteMathTest), and the palette model/store (PaletteTest, PaletteStoreNamingTest). Anything touching Minecraft classes is exercised via runClient, not tests.

Install the jar into a real instance

Copy the jar matching the instance's loader into its mods/ folder:

  • Fabric: fw-paint-fabric-<version>.jar — the instance must also contain Fabric API for 26.3.
  • NeoForge: fw-paint-neoforge-<version>.jar — no other dependency.

The mod is client-side only; servers need nothing.

Versioning & releases

  • The version lives in gradle.properties (mod_version) — bump it there; both fabric.mod.json and neoforge.mods.toml pick it up at build time.
  • CI (.github/workflows/build.yml): every push builds + tests and uploads both jars as the fw-paint-jars artifact. Releases are automatic: a push to master whose mod_version has no matching v<version> tag yet creates the tag and publishes a GitHub Release with both jars attached (body from docs/release-notes/v<version>.md) — so merging a version-bump PR is the release action. Manually pushing a v* tag still works too.
  • Repo rulesets: master is PR-only (no direct pushes, no deletes, no force-pushes — no bypass), and new branches must match feature/*, release/*, fix/*, or chore/*.

Project layout

common/src/main/java/co/fax/wang/
  Gradient.java          loader-free core: keybinds, tick driving, shared state
  GradientScreen.java    the K screen (Paint / Solid / Palette / Finder / Settings / Help tabs)
  PaletteEditScreen.java the palette editor       PaletteListPanel.java  the Palette tab's rows
  PatternEditScreen.java the pattern editor       PatternThumb.java  mini pattern renderer
  PaletteChoice.java     resolves the active palette into placeable ramps (Automatic segments etc.)
  PatternChoice.java     pattern press state + Oklab-neighbour variation
  HelpPanel.java         in-game manual           UiIcons.java  shared pixel-art glyphs
  HudOverlay.java        helper-text + palette-row HUD   HudPlacementScreen.java  move-the-text screen
  MarkerManager.java     marker modes/persistence + in-world rendering
  PaintPlacer.java       unified Single/Face/3D placement for all paint types
  GradientCaches.java    session memory           NoisePlacer.java  marked-region geometry
  GradientRamp.java      gradient-order maths     BlockTextures.java / TextureStats.java  texture analysis
  BlockPlacement.java    multiplayer-safe placing
  Noise.java / NoiseType.java / FloodFill.java / CurveFunction.java / FaceOverlay.java
  PlacementMode.java / PaintType.java / SolidMatch.java / GradientMode.java / GradientSource.java
  palette/               the v2 model: Palette, PaletteSegment, PaletteStore (fw-paint-palettes.json),
                         PaletteMath, PatternMath, AutoMode, PaletteOrder, PaletteKind,
                         PatternTiling, SizingMode, MissingBlockPolicy
  config/GradientConfig.java + config/ConfigManager.java   Gson config -> config/gradient.json
common/src/test/java/co/fax/wang/   unit tests (pure maths only)
fabric/src/main/java/co/fax/wang/fabric/GradientFabric.java       Fabric entrypoint
neoforge/src/main/java/co/fax/wang/neoforge/GradientNeoForge.java NeoForge entrypoint
fabric-26.2-mod-starter.md   26.2 API migration notes (worth reading before touching GUI/render code)

Gotchas

  • 26.x is unobfuscated — no mappings/remapping; Loom runs in non-remapping mode and NeoForge uses the same Mojang names, which is what makes the shared common/ module possible. Don't add mapping-dependent tooling.
  • 26.2 renamed/replaced several APIs (GuiGraphics → GuiGraphicsExtractor, setScreen → setScreenAndShow, HUD/keybind registration) — see fabric-26.2-mod-starter.md before porting snippets from older versions.
  • Nothing in common/ may import loader classes — its compile classpath contains only the vanilla jar, so a stray net.fabricmc/net.neoforged import fails the build by design.
  • Config is plain Gson with defaults for every field, so adding config fields is backwards-compatible; removing/renaming needs a migration (see ConfigManager.migrateLegacyTools).

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages