
BoatRacing
An F1‑style ice boat racing plugin for Paper with a clean, vanilla‑like GUI. Manage teams, configure tracks with the built‑in BoatRacing selection tool, run timed races with checkpoints, pit area penalties, and a guided setup wizard.
Оцените первым
814
9
Список изменений
Changelog
1.1.6 — 17/06/2026
Added
- Admin Race checkpoint editor UI: added checkpoint management directly in the race admin inventory with paginated listing and in-place actions (add from selection, replace, remove, move up/down).
- Admin Race pitstop quick controls: added mandatory pitstop quick-set actions (
0/1/2) plus custom anvil input from the race admin inventory. - Setup selection particle visualizer: added built-in wand selection wireframe rendering using particles, configurable under
setup.selection-visualizer.*(enabled,period-ticks,particle,spacing,max-particles-per-player,view-distance,show-only-with-wand). - Explicit track+laps placeholders: added lap-scoped variants for comparative panels:
%boatracing_track_best_player_laps_<track>_<laps>%,%boatracing_track_best_time_laps_<track>_<laps>%,%boatracing_track_best_time_ms_laps_<track>_<laps>%, plus%boatracing_track_top_1|2|3_player|time|time_ms_laps_<track>_<laps>%. - Stats placeholders by track and laps: added best-race/best-lap variants for viewer and top contexts scoped by track and by track+laps (for example
%boatracing_player_best_race_laps_<track>_<laps>%and%boatracing_top_player_best_race_name_laps_<track>_<laps>%). - Forfeit command (
/boatracing race forfeit): players can abandon a running race without stopping it for others. Permissionboatracing.race.forfeit(default: true). Contributed by @MC-MrBirdy in #3. - DNF results display: forfeited players appear as
DNF {player} (forfeited)at the bottom of race results, separated from finishers. Finishers keep normal positions and rewards; forfeited players do not receive rewards or win/loss stats. - Practice ghost replay (advanced vanilla MVP): solo practice sessions now capture sample paths and replay the best recorded ghost alongside the current run. Ghost entities (boat + armorstand) use no-collision rules, are hidden from other players, and interpolate smoothly with angular rotation.
- PracticeGhostManager: new manager class for ghost persistence per track and lap count, using the DocumentStore backend. Ghosts are stored in
practice-ghosts.yml. - DocumentStore persistence layer: new pluggable storage interface with three backends — YAML files (
YamlFileDocumentStore), local SQLite (JdbcDocumentStorewith SQLite dialect), and remote MySQL (JdbcDocumentStorewith MySQL dialect). Backend selected viaconfig.yml→database.mode. - DocumentStoreFactory: resolves the active store implementation from config and provides automatic legacy-YAML migration on first load when switching to SQLite/MySQL.
- Database config section: new
databaseblock inconfig.ymlwith mode (YAML/SQLITE/MYSQL), table name, SQLite file path, and MySQL connection settings. - Practice ghost config section: new
practice.ghostblock inconfig.ymlwith enable toggle, sample/playback tick rates, minimum distance filter, sample cap, and name display option. - Practice leave command:
/boatracing race practice leave <track>(andexitalias) to cleanly exit a practice session. Also handles disconnect/quit/kick viaPlayerQuitEventandPlayerKickEventhandlers. - AnvilGUI 26.1/26.2 compatibility: switched from upstream
net.wesjd:anvilgui:1.10.12-SNAPSHOTto thefeeeedox/AnvilGUIfork via JitPack. AddedWrapper26_R1_LocalShimas compatibility fallback for 26.1 close-event handling. ExtendedVersionMatcherwith 1.19.x mappings,26.1.2, and26.2/26.2.1→26_R2entries, loading nativeWrapper26_R2from the fork on 26.2. - Race result forfeited message: added
race.results.forfeitedkey to all 16 bundled language files with translations.
Changed
- Track-scoped Admin Race actions: race/setup operations in Admin Race GUI now resolve the active track session explicitly, so edits and status reflect the selected track context.
- GUI setup persistence path: laps/pitstops/checkpoint edits issued from Admin Race GUI now write through track configuration overrides as part of the same action flow.
- Setup override synchronization:
/boatracing setup setlaps <n>and/boatracing setup setpitstops <n>now also update the active in-memory race session for the selected track when that session already exists. - Setup command docs clarity: README setup command descriptions now state that laps/pitstops overrides apply immediately without restart/reload.
- Lap-context track records/placeholders: track bests are now stored and resolved per lap count (
bestTimesByLaps), preventing 2-lap records from overriding 3-lap placeholders (and vice versa) across%boatracing_track_best_*%,%boatracing_track_top_*%, and%boatracing_player_track_best%. - Selection visualizer edge distribution: particle allocation is now balanced across all box edges and visibility culling is performed against the full selection box distance, reducing inconsistent partial rendering.
- Forfeit broadcast scoping:
forfeit()now usesraceAudience()(participants + admins) instead of globalbroadcast()for the{player} forfeitedmessage in competitive mode. Practice mode forfeits show a privateYou left the practice sessionmessage only to the runner. - TeamManager, StatsManager, PracticeStatsManager refactored: all three managers now read/write through
DocumentStoreinstead of directFile+YamlConfiguration.save/load. Legacy YAML files are automatically migrated to the database on first load when using SQLite/MySQL mode. - config.yml restructured with section header comments and new
database/practice.ghostblocks. - Race state marking:
RaceStatenow includes aforfeitedflag.forfeit()marks the state instead of removing it, socheckAllFinished()triggers correctly andannounceResults()can display the player as DNF. - Project version: bumped to 1.1.6. Minecraft support range extended from 26.1 → 26.2.
Fixed
- Stale per-track override reads in existing sessions: race settings load now refreshes track data before reading
racing.*overrides, preventing old values from being reused in cached track sessions. setlapsruntime mismatch: fixed issue where/boatracing setup setlaps <n>acknowledged the new value but/boatracing race open <track>could still open registration with a previous lap count until server restart.setpitstopsruntime mismatch: fixed equivalent stale-value behavior for per-trackmandatory-pitstopsafter/boatracing setup setpitstops <n>.- Track setup editability after creation: added granular setup editing commands so admins can remove one start/light by index (
removestart,removelight) and clear finish/default pit (clearfinish,clearpit) without rebuilding the whole track config. - Admin Race GUI i18n regression: removed newly introduced hardcoded user-facing strings and routed checkpoint/pitstop/editor labels, lore, and action feedback through message keys.
- Localized coverage gap for new GUI keys: added missing
gui.race.*keys for all bundled locales so non-EN bundles no longer miss editor/pagination/pitstop texts. - Stats tab-complete DataConverter spam: player-name suggestions for
/boatracing stats <player>no longer rely onOfflinePlayer#getName()in tab-complete paths, avoiding repeated Paper 1.21Failed to convert json to nbt/MalformedJsonExceptionconsole errors on malformed legacy playerdata. - Setup wand text key fallback: fixed wand name/lore rendering when message bundles store those entries under
setup.usage.*; setup wand now resolves localized text instead of showing raw key strings. - Selection wireframe truncation under tight budgets: fixed abrupt edge cutoffs in large selections when particle limits are reached.
- DocumentStore initialization order:
DocumentStoreFactory.create()now runs beforeTeamManagerinstantiation inonEnable(), so TeamManager receives a valid store reference instead of null (which caused silent team data loss). - Scoreboard DataConverter spam on Paper 26.1+: replaced remaining
OfflinePlayer#getName()calls in the scoreboard timer and result name resolution withsafeOfflineName()that reads the player profile via reflection, avoidingFailed to convert json to nbtconsole errors from malformed legacy playerdata. - SimpleScore sidebar reclamation during races: the scoreboard timer now periodically re-hides SimpleScore (every ~2 seconds) during active races and practice sessions, preventing the external sidebar from overwriting the BoatRacing race display mid-session.
leavePractice()vehicle cleanup: changed from per-playercleanupRaceVehicleForPlayer()to fullcleanupRaceVehicles()for consistency.- Removed unused
{track}placeholder fromrace.practice.leftmessage call inleavePractice(). - Runtime JDBC driver loading: SQLite and MySQL drivers are no longer shaded into the JAR. On first startup, the plugin downloads the required JDBC JARs (
sqlite-jdbc,mysql-connector-j,slf4j-api,slf4j-simple) from Maven Central with SHA-256 checksum verification and caches them inplugins/BoatRacing/lib/. If the libs are unavailable (no internet, download failure, checksum mismatch) the plugin falls back gracefully to YAML mode. This keeps the plugin JAR at ~675 KB instead of ~18 MB. - Practice forfeit no longer shows results header:
forfeit()in practice mode now callsstopRace(false)instead ofcheckAllFinished()→stopRace(true), skipping theResults:/DNF display since there is no competitive outcome for a forfeited practice run. - SQL injection hardening in JdbcDocumentStore: the
database.tableconfig value is now sanitized to[A-Za-z0-9_]before use in DDL statements, preventing injection through the table name. - Ghost collision team name bounds: UUID substring extraction for the no-collision team name now uses
Math.min(9, uuidStr.length())to guard against edge cases. - Checkpoint/finish line fast-crossing detection:
tickPlayer()now uses ray-AABB segment intersection to detect when a boat passes through a checkpoint or finish region between movement ticks, preventing missed crossings at high boat speeds (ice boats, speed boosts). - Countdown cancellation on practice leave:
clearCountdownLock()now cancels the scheduled countdown timer tasks, so leaving practice during pre-start lights no longer allows the countdown to continue and start a race. - Hardcoded usage message removed: the practice leave usage text now uses the
race.usage.practice-leavemessage key across all language bundles. - SimpleScore sidebar flickering: the scoreboard timer now re-hides SimpleScore immediately on the first tick instead of waiting 2 seconds, preventing brief sidebar takeover at race/practice start.
Stats Persistence
stats.yml(competitive aggregate) storesplayerWins.stats.yml(competitive aggregate) storesteamWins.stats.yml(competitive aggregate) storesplayerPositions.stats.yml(competitive aggregate) storesplayerBestRace(global per player).stats.yml(competitive aggregate) storesplayerBestLap(global per player).stats.yml(competitive aggregate) storesplayerBestRaceByTrack(per player and track).stats.yml(competitive aggregate) storesplayerBestLapByTrack(per player and track).stats.yml(competitive aggregate) storesplayerBestRaceByTrackLaps(per player, track, and lap count).stats.yml(competitive aggregate) storesplayerBestLapByTrackLaps(per player, track, and lap-context).practice-stats.yml(practice telemetry) remains separate and stores run/lap/sector best/last per player and track.
Docs
- Added 1.1.6 release notes and QA coverage in README, CHANGELOG, and CHECKLIST (including checkpoint editor, pitstops GUI checks, forfeit, ghost replay, and DocumentStore features).
- Removed 26.1 snapshot warning from README (26.2 is now fully supported).
Файлы
BoatRacing-1.1.6.jar(676.92 KiB)
ОсновнойМетаданные
Канал релиза
Release
Номер версии
1.1.6
Загрузчики
BukkitFoliaPaperPurpurSpigot
Версии игры
1.19–26.2, 26w14a
Загрузок
12
Дата публикации
17.06.2026
