Skip to content

flowmari/TreasureRun

TreasureRun — A Minecraft Treasure Hunt with Platform-Boundary i18n

TreasureRun is an open-source treasure-hunt mini-game plugin for Minecraft Spigot 1.20.1. Players search for treasure chests, earn points, experience staged visual and audio effects, and compete through persistent rankings.

Beyond the game itself, TreasureRun is also an i18n architecture project: Minecraft's built-in UI text is split between server-controlled surfaces and client-side surfaces. TreasureRun makes that boundary explicit by separating localization responsibilities across Spigot plugin logic, packet-boundary handling, ResourcePack language assets, and an optional client-side sync layer.

What you actually play

TreasureRun is a Spigot 1.20.1 treasure-hunt plugin.

As a player, you join a local Minecraft server, start a treasure run, follow treasure-proximity cues, and explore a prepared demo world with a UFO encounter, a wandering trader scene, moving safe-zone effects, and bilingual outcome messages.

The i18n/platform-boundary work is part of how the project is engineered, but the first-time experience should start with the game: what the player does, what the demo world shows, and how to try it locally.

Engineering highlight: localisation across Minecraft boundaries

TreasureRun includes localisation work because Minecraft text is split across several boundaries: plugin messages, server-to-client packets, ResourcePack language assets, and optional client-side runtime sync.

In practical terms, the project currently implements translated plugin messages, generated ResourcePack language files, packet-localisation support, and a pure Java localisation core that is tested separately from Bukkit, ProtocolLib, Fabric, and Minecraft runtime APIs.

This means the localisation work is not a second gameplay plugin. It is an engineering layer that supports the treasure-hunt plugin while documenting where a Spigot plugin can and cannot control Minecraft UI text.

How localisation is implemented

TreasureRun handles localisation in several layers:

  1. Players choose a language in the in-game language GUI.
  2. The selected language is stored per player in player_languages.yml.
  3. Plugin-owned messages are loaded from src/main/resources/languages/*.yml.
  4. Minecraft locale codes are mapped through src/main/resources/lang-map.yml.
  5. ResourcePack language JSON files provide Minecraft translation-key assets.
  6. When ProtocolLib is available, reachable outgoing JSON text components are passed through PacketI18nJsonLocalizer.
  7. The pure Java localisation core is tested separately from Bukkit, ProtocolLib, Fabric, and Minecraft runtime APIs.
  8. The optional Fabric client mod can receive the selected language code and reload client-side language resources.

This does not mean a Spigot plugin can control every Minecraft UI string. The project documents the boundary between plugin-owned messages, reachable packet text, ResourcePack assets, and client-only UI.

Demo

Gameplay demo

TreasureRun runs locally on Minecraft Spigot 1.20.1. This short gameplay demo shows the current gameplay loop: language selection, treasure hunting, score/ranking feedback, and visual reward effects. The prepared demo world also includes a wandering-trader bonus interaction: players can craft Special Emeralds from diamonds and use them in a custom trade.

TreasureRun gameplay demo

Watch the 48-second gameplay demo: https://youtu.be/kIOhBeODh8k

Optional fallback: Download the MP4 demo

What makes the demo world fun

The prepared demo world is more than a flat test map. It includes a UFO encounter, a wandering trader with two llamas, a moving safe zone around them, colder and more fragile terrain outside that zone, proximity-based heartbeat and cracking-ice cues, a yellow-to-amber trail like an ancient path through history, and 158 short encouragement quotes woven into each run.

See What to Look For in the Demo World for the full tester-facing guide.

Platform-boundary i18n demo

TreasureRun also demonstrates a platform-boundary i18n approach. The existing 23-language i18n GIF is kept here so reviewers can see the technical theme directly after the gameplay demo.

TreasureRun standard UI i18n demo

Run the Game Locally

Requirements

  • Java 17
  • Docker Desktop
  • Minecraft Java Edition 1.20.1

Start an isolated local server

Set your Minecraft Java username so that the local development server can grant you permission to run game commands:

./scripts/contributor-up.sh YourMinecraftName

If you prefer environment variables, TREASURERUN_OPS=YourMinecraftName ./scripts/contributor-up.sh still works.

For example:

TREASURERUN_OPS=flowmari ./scripts/contributor-up.sh

Then connect from Minecraft Java Edition 1.20.1:

localhost:25575

Once you are in the server, try the basic gameplay commands:

/lang
/gamestart normal
/gameRank

The full command list is in docs/COMMANDS.md.

The startup script:

  1. runs the default Gradle build;
  2. starts isolated MySQL 8 and Spigot 1.20.1 containers;
  3. grants operator permissions to your local player;
  4. installs the newly built TreasureRun plugin JAR;
  5. restarts the local server with TreasureRun loaded.

Stop the local development runtime while keeping its world and database volumes:

./scripts/contributor-down.sh

Reset the local development runtime completely:

./scripts/contributor-down.sh --volumes

This is a one-command local runtime setup. Fresh Clone QuickStart PASS evidence is documented in docs/external/FRESH_CLONE_QUICKSTART_EVIDENCE.md; one recorded local fresh-clone measurement completed startup successfully in 39s.

Contributing: Start Here

For most gameplay, documentation, and translation changes, run:

./gradlew clean build

Docker and MySQL are not required for the default build.

When working on the database boundary or the ranking API, run the optional Docker-backed integration tests:

./gradlew integrationTest
./gradlew -p ranking-api integrationTest

These deeper tests are still part of the project. They are simply kept out of the regular contributor workflow unless they are relevant to the change.

Good Places to Start Modifying the Project

Goal Start here
Explore gameplay flow and commands src/main/java/plugin/TreasureRunMultiChestPlugin.java
Explore staged game effects src/main/java/plugin/GameStageManager.java
Improve plugin-owned translations src/main/resources/languages/*.yml
Review language selection and mapping src/main/resources/lang-map.yml
Understand the packet-level i18n boundary src/main/java/plugin/LocalizedPacketMessageProtocolListener.java
Work on platform-independent JSON localization src/main/java/plugin/i18n/PacketI18nJsonLocalizer.java
Review the leaderboard read API ranking-api/

Why TreasureRun Is Technically Interesting

Minecraft's built-in UI text is split across server-controlled and client-controlled surfaces.

TreasureRun treats that split as an architecture boundary rather than a string-replacement problem, with localization responsibilities separated across four cooperating layers:

Layer Responsibility
ProtocolLib boundary adapter Observes and rewrites reachable server-to-client translatable packet content
ResourcePack language layer Provides Minecraft standard translation-key assets
Fabric runtime language sync Applies the selected client language and reloads resources without a restart
Pure Java packet localizer Keeps JSON localization behavior testable without platform-specific dependencies

The local game setup above is intended for playing with and modifying the Spigot plugin. Testing the full standard-UI i18n path additionally requires ProtocolLib, resource-pack behavior, and the optional Fabric language-sync mod.

How the Components Fit Together

TreasureRun is not built as a thin Minecraft client that sends gameplay events to a separate gameplay backend.

The current architecture is:

Component Responsibility
Spigot plugin Runs gameplay and owns ranking writes, MySQL access, Flyway migrations, and score repositories
ranking-api/ Provides a separate read-only REST API for leaderboard data through GET /api/v1/rankings/all-time
Fabric Mod Supports optional client-side language switching and resource reload for the advanced i18n demo

In short, the plugin owns gameplay and writes, while ranking-api/ provides a versioned read-only view of leaderboard data.

For a more precise architectural summary:

The Spigot plugin is the system of record for gameplay and ranking writes, including MySQL access, Flyway migrations, and score repositories. ranking-api exposes a separate read-only HTTP boundary over the same database through a versioned API and an OpenAPI-verified contract.

Build and Verification

Default build

./gradlew clean build

This is the regular contributor workflow. It excludes integration tests that require Docker-backed MySQL execution.

Optional integration verification

./gradlew integrationTest
./gradlew -p ranking-api integrationTest

These tasks verify:

  • plugin-side MySQL persistence behavior;
  • Ranking API reads over real HTTP;
  • Flyway-managed schema application;
  • OpenAPI public contract behavior;
  • disposable MySQL 8 execution through Testcontainers.

Continuous Integration

The Ranking API integration workflow remains visible on pull requests. Docker-backed verification runs when a pull request changes the relevant backend boundary.

Documentation

Start with:

The full README that existed before this contributor-focused entrance was introduced is preserved at:

Project Status

  • Stage: alpha / portfolio open-source project
  • Minecraft target: Spigot 1.20.1
  • Java version: 17
  • License: MIT

Fresh-clone QuickStart PASS is documented, Good first issues are open, and controlled alpha feedback collection has started. The next milestone is to respond to real alpha feedback with a small follow-up PR before broader community publication.

About

Minecraft Spigot 1.20.1 treasure-hunt mini-game plugin with 23-language i18n, ResourcePack/Fabric localization, Docker runtime validation, and MySQL rankings.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors