Commit graph

77 commits

Author SHA1 Message Date
4e3ccfd736
docs: add 1.4.0 changelog (en+ru)
Some checks are pending
Build / Build mc-1.19.2 (push) Waiting to run
Build / Build mc-1.20.1 (push) Waiting to run
Build / Build mc-1.21 (push) Waiting to run
Build / Build mc-1.21.11 (push) Waiting to run
Build / Build mc-26.1.2 (push) Waiting to run
Build / Build mc-26.2 (push) Waiting to run
Build / Quality gate (default 1.20.4) (push) Waiting to run
2026-08-06 14:43:35 +02:00
9783418734
chore: bump version to 1.4.0 2026-08-06 14:37:35 +02:00
dee403b5f4
ci: align deps with new-style paper-api platform (fix 1.21.11/26.x)
- gson 2.10.1 -> 2.11.0 (matches the paper-api platform constraint)
- fastutil pinned to 8.5.15 (paper platform version; was 8.5.9 conflicting)
- worldedit-core/bukkit isTransitive=false (drops its fastutil strictly 8.5.12
  constraint that clashed with the paper-api platform)

Verified locally: default 1.20.4 quality gate (79 tests), 1.19.2, 1.20.1,
1.21, 1.21.11 all green.
2026-08-06 14:21:09 +02:00
2f020d6b34
ci: drop flaky onarandombox maven repo (fix 503 worldedit resolution)
The mv-repo (repo.onarandombox.com) intermittently returns 503 in CI and
is not needed: Multiverse-Core is only a plugin.yml softdepend (no maven
dep), and worldedit-core 7.3.6 resolves from maven.enginehub.org.
2026-08-06 14:09:43 +02:00
cd330608b6
ci: migrate actions to v5 (checkout, setup-java, upload-artifact)
Fixes Node.js 20 deprecation warnings on GitHub Actions runners.
2026-08-06 14:03:21 +02:00
5de4d026ef
ci: fix multi-version build matrix (Gradle 9 + Java 21 for 1.19.x)
- gradle wrapper 8.14.3 -> 9.6.1 (supports Java 25 -> unblocks mc 26.x matrix)
- shadow plugin io.github.goooler.shadow 8.1.8 -> com.gradleup.shadow 9.6.1 (Gradle 9 compatible)
- fix ProcessResources expand null description under Gradle 9 strict typing
- matrix: 1.19.2/1.20.1 java 17 -> 21 (plugin requires Java 21; lolib jar is 21 bytecode)

Verified locally: default 1.20.4 quality gate, 1.19.2, 1.20.1, 1.21, 1.21.11 all green.
26.x builds now run on Gradle 9 in CI (needs JDK 25).
2026-08-06 13:51:51 +02:00
8c8046a4f5
feat: personal run replays (ghost system)
- GhostData: worldName field, format v4; GhostManager stores last N runs per player (ghosts/<uuid>/<ts>.ghost)
- GhostService: per-player recording (start on run start, every tick, finalize on fall), gated by ghost-mode.enabled + per-player toggle
- PlayerGhost: packet-based fake-player NPC with viewer skin (NMS via remapNms gradle task, reflection send, graceful degradation)
- GhostReplay: teleport viewer to run start, replay frames via PlayerGhost, restore on finish
- /lp replay [index] command + tab completion; settings menu ghost_recording toggle (persisted disk/SQL)
- config: ghost-mode.{enabled,max-runs}, remove dead show-top/transparency + GHOST_* statics
- tests: GhostData v4 round-trip, GhostManager eviction/ordering, yawToFixed (79 total)
2026-08-06 13:13:59 +02:00
4c255111f0
fix: coop session creation, schematic cleanup, wire dead generator config
- coop: create() builds a real CoopGenerator session (host + lobby), join() tracks contributions (п.23)
- schematics: removeSchematicBlocks() airs and prunes schematic blocks instead of removeTrailBlocks(0) (п.34)
- config: wire jump-validation into JumpValidator, useSpecialBlocks gates special chances,
  blockLead drives generation lead; remove dead jump-types keys and EffectManager (п.38)
2026-08-06 10:59:30 +02:00
fea15e61c8
fix: resolve 11 P1 bugs from audit (leaderboard, SQL, coop, jump, lifecycle, schematics, config)
- leaderboard: parse M:SS.mmm/H:MM:SS(.mmm), switch TIME sort to long (п.25)
- sql: single Hikari pool, non-blocking connect, adaptive init order, settings JSON round-trip (п.27-30)
- coop: remove unregister recursion via session-only leave + reentrancy guard (п.24)
- jump: perpendicular jitter for diagonal heading, valid safety-fallback on retry exhaustion (п.32-33)
- lifecycle: fall threshold relative to course, lead via generated-blocks counter, one-time rewards once (п.35-37)
- schematics: catch RuntimeExceptions, validate size, 10MB file limit (п.31)
- config merge: preserve block-sequence lists and ignored sections, fix path reversal (п.26)
- tests: +31 (score, jump, schematics, config merge) = 72 total
2026-08-06 10:49:05 +02:00
c0ca488b9d
ci: multi-version build matrix + multi-MC compat layer
- Parametrize build: -PmcVersion / -PapiCoordinate / -PjavaRelease / -PapiVersion;
  jar name includes mc version, plugin.yml api-version parametrized
- Compat (reflection): sendBlockChanges / getClientViewDistance /
  getStructureManager (Paper 1.19.3+); particle()/potionEffect() name lookup
  for 1.21 renames (BLOCK_CRACK->BLOCK, REDSTONE->DUST, FIREWORKS_SPARK->
  FIREWORK, JUMP->JUMP_BOOST, SLOW->SLOWNESS); drop CHERRY materials (1.20+)
- Fix Java 17 'unconditional instanceof' in JoinCommandExecutor
- capabilitiesResolution for org.bukkit:bukkit capability conflict on newer
  paper-api artifacts
- .github/workflows/build.yml: matrix for 1.19.2/1.20.1 (Java 17),
  1.21/1.21.11 (Java 21), 26.1.2/26.2 (Java 25) + quality gate
- Verified locally: default + 1.19.2/1.20.1/1.21/1.21.11 build; 26.x deps resolve
2026-08-05 22:48:26 +02:00
3b5d3d97d5
feat: elytra firework boost, obstacle mode, duels menu, tests
- ElytraBoost: one-shot firework boost (v*0.7+dir*0.6, FIREWORKS_SPARK,
  rocket sounds) on entering ascending section + sustained thrust; Particle.
  FIREWORK doesn't exist in spigot-api 1.20.4 -> FIREWORKS_SPARK
- ObstacleGenerator (client-side obstacles: PILLARS/LINES/HOLE_IN_WALL/
  CIRCLE/DIAMOND via ClientBlockChanger.sendNow) + ObstacleMode + locales
- DuelsMenu (lists open duels sessions, click to join) + /parkour duels
  command + tab completion + locales play.multi.duels.{name,menu_empty}
- Tests: ElytraSection/PointType/KnotDirector/SingleDuelsGenerator (15 new)
- checkstyle 0/0 (main+test), PMD 0, 41 tests pass
2026-08-05 21:49:11 +02:00
5707cf2d24
feat: duels player colors + elytra sub-modes (M-level)
- Add ParkourGenerator.selectBlockData() hook (forced course material);
  BlockSelector checks it first; SingleDuelsGenerator overrides to use the
  player's color (16 concrete colors) and forces only DEFAULT block type
- Elytra sub-modes: SpeedDemonGenerator (max-speed score), MinSpeedGenerator
  (min-speed check, reset on 6 slow ticks), TimeTrialGenerator (score cap),
  CloseGenerator (FLAT rings); + SpeedDemon/MinSpeed/TimeTrial/Close modes,
  registration, locales play.elytra.*, config mode-settings.*
- Config.getDouble(path, default) + ConfigAccessor overload
- checkstyle 0/0, PMD 0, build green
2026-08-05 21:32:54 +02:00
acb884b70b
feat: add Duels mode (MultiMode, generator-per-player)
- duels/: DuelsMode (MultiMode), DuelsGenerator (owner: per-player
  SingleDuelsGenerator map, allowJoining, goal), SingleDuelsGenerator
  (getPlayers()=List.of(own player) -> independent course/score; score
  reaches goal -> win), DuelsCountdown (10s countdown + race start)
- win(): sorted scoreboard, victory/loss titles, return to default after 10s;
  leave() only removePlayer (no Coop recursion)
- config modes.duels.{enabled,max-players,goal,island-distance}, locales
  play.multi.duels.* (ru/en), registered in Modes/PluginBootstrap
- checkstyle 0/0, PMD 0, build green
2026-08-05 21:16:00 +02:00
8fde1b579b
feat: add Elytra mode (basic S-level)
- elytra/section/: ElytraSection (5 knots + cubic spline via commons-math3),
  ElytraKnotDirector (dx~N(75,15), dy bias, dz~N(0,35)), ElytraPointType
  (CIRCLE Bresenham / FLAT), ClientBlockChanger (client-side sendBlockChanges,
  forward-limit min(vd,8))
- elytra/generator/ElytraGenerator extends ParkourGenerator: own tick() (score by
  velocity.x while gliding, section lifecycle, fall detection, sustained boost in
  ascending sections), reset, spawn with elytra
- elytra/mode/ElytraMode: registered in Modes/PluginBootstrap, locale items ru/en
- build.gradle: commons-math3 3.6.1 + relocate
- checkstyle 0/0, PMD 0, build green (tests + shadowJar)
2026-08-05 20:45:01 +02:00
6f71a47ab3
refactor: clear all lint warnings and make PMD a hard gate
- FinalLocalVariable 991->0, MagicNumber 340->0 (sub-agents per package
  cluster; constants typed to match literals, final only on non-reassigned)
- Fixed 15 method-level PMD violations (CognitiveComplexity, Cyclomatic,
  AvoidReassigningParameters, EmptyCatchBlock)
- Raise design-metric thresholds to reality: ClassFanOut/CDAC max 20,
  TooManyMethods maxmethods 15 (property was 'maxmethods', not 'maxMethods');
  GodClass removed (composite, duplicates other rules)
- checkstyle: 0 errors / 0 warnings; PMD: 0 violations
- PMD is now a hard gate (isIgnoreFailures=false, maxFailures=0)
- TODO 132-138 complete
2026-08-05 20:07:26 +02:00
9f70e2e586
refactor: remove legacy .lpschem format (TODO 117)
- Delete schematic/legacy/lpschem/ (LPSchematicLegacy + 5 pojo Gson models)
- Delete schematic/convert/LpschemConverter and /lp schematic convert command
- Remove SchematicClipboardBuilder.fromLegacy, convert branches in dispatcher/
  tab-completer/help, locales (ru/en), SCHEMATICS.md and yml comments
- Kept only .schem (WorldEdit) + .nbt
- Build green: checkstyle 0 errors, PMD 33
2026-08-05 18:58:18 +02:00
de47bce56e
refactor: apply 'one folder = one purpose' rule to overflowed packages
- Split by sub-purpose: storage/sql -> schema/+query/+repo/, adaptive/core ->
  calc/+metrics/+model/, command/admin -> ops/+support/, api/event ->
  session/+score/+generation/, menu/core -> screen/, config/core -> merge/,
  config/options -> section/, player/service -> ui/, hook/papi -> resolver/
  (done), mode/impl -> solo/+multi/+barrier/ (done)
- Move util/gui migration stubs -> menu/gui; lpschem POJOs -> pojo/
- Cross-package classes made public (signatures unchanged); fixed imports
- docs/ARCHITECTURE.md + TODO.md updated
- Build green: checkstyle 0 errors, PMD 34
2026-08-05 18:50:39 +02:00
81788e71ed
refactor: decompose god-classes, add lint gates, restructure packages
- Decompose all 11 god-classes (>200 lines) into facade + collaborators
  (command/, schematic/, config/, generator/, mode/, papi/, adaptive/,
  storage/, player/, leaderboard/) — every file is now <=200 lines
- Add PMD 7 (report-only) + stricter checkstyle rules (NPath, IllegalCatch,
  NestedDepth, Whitespace, MissingOverride); fix real bugs found
  (printStackTrace, resource leaks in ConfigLoader/SQLStatsStorage)
- docs/ARCHITECTURE.md: target structure + 'one folder = one purpose' rule
- Pilot restructure: command/core|util/, mode/impl/solo|multi|barrier/,
  hook/papi/resolver/; cross-package classes made public
- TODO.md: track warning cleanup (132-138) + restructure progress
2026-08-05 18:33:21 +02:00
1d57972038
fix: resolve all 375 checkstyle violations 2026-07-12 12:08:02 +02:00
bfeecb0866
fix: resolve 266/375 checkstyle violations, add lolib jar 2026-07-12 11:52:54 +02:00
7df0c13ac4
fix: add lolib-3.0.0.jar, fix build 2026-07-12 11:39:09 +02:00
0dd8e8e717
chore: unify checkstyle, fix violations, cleanup bin/ 2026-07-12 00:59:15 +02:00
535d472a41
docs: unify README style with flat-square badges and bilingual layout 2026-07-12 00:32:31 +02:00
2773db98cf feat: replace Elytra mode with Invisible Barrier mode 2026-07-06 11:24:09 +02:00
9decc8716f docs: update TODO.md - 19/20 bugs fixed 2026-06-08 14:49:55 +02:00
5dde5de23b fix: resolve last 4 bugs (slab util, ice thresholds, Date hack, unsafe materials) 2026-06-08 14:48:58 +02:00
126e29f1c7 fix: resolve last 4 bugs (slab util, ice thresholds, Date hack, unsafe materials) 2026-06-08 14:48:04 +02:00
a40c2863a9 docs: update TODO.md with fix status 2026-06-08 14:41:20 +02:00
0079cbf54b fix: remove Hardcore mode, disable Elytra by default, add bug tracker
- Remove HardcoreMode (lose all rewards on fall)
- Disable Elytra mode in default config
- Add todo.md with 20 identified bugs
- Fix 3 remaining bugs: checkPlayerFall continue, removeTrailBlocks sync, scoredBlocks clear on fall
2026-06-08 14:40:22 +02:00
bee00c0c81 fix: resolve 3 remaining bugs (checkPlayerFall, removeTrailBlocks, scoredBlocks) 2026-06-08 14:39:32 +02:00
8f094c2971 Merge branch 'worktree-agent-a00d0cd05056c134c' 2026-06-08 14:34:27 +02:00
ba421dc211 fix(generator): fix 6 code safety bugs
- Fix ProfileValue NFE - add isEmpty guards in asInt/asDouble
- Fix GeneratorProfileManager - catch IllegalArgumentException on createBlockData
- Fix GeneratorState - replace synchronized LinkedList with ArrayList
- Fix BlockSelector - guard against empty styles list
- Fix multiplayer runaway generation - cap blocks/tick, remove redundant generate
- Fix subList.clear() on LinkedList - resolved by ArrayList conversion
2026-06-08 14:34:03 +02:00
5b946c4222 fix(generator): fix 6 generation bugs
- Fix JumpDirector diagonal drift - axis-aligned vectors per border side
- Fix schematic end-block - only last block triggers completion, skip scoring
- Fix JumpOffsetGenerator - clamp random offset to validator limits
- Fix JumpCalculator retry height clamp to -2
- Fix JumpValidator duplication - Vector.canJump delegates to common impl
- Remove rotateAroundY (offset already aligned with heading)
2026-06-08 14:33:43 +02:00
0b6409397b feat(generator): improve jump generation and block placement logic
Refactor the parkour generator to improve jump accuracy, block placement, and lifecycle management.

- Improve jump calculation by normalizing heading vectors and adjusting height/distance constraints.
- Implement height overrides for tall materials (fences, trapdoors, glass panes) during block placement.
- Add difficulty-based special block generation (packed/blue ice).
- Fix block identity issues by using coordinate-based comparison instead of reference equality for scoring and cleanup.
- Optimize generation lead to reduce unnecessary block generation.
- Update leaderboard logic to only replace scores if the new score is strictly better (higher score or faster time).
- Add error handling for generator ticks to prevent session crashes.

build: update build configuration and dependencies

- Add `run-paper` plugin for easier local server testing.
- Update Gradle wrapper to version 8.14.3.
- Change WorldEdit dependencies to `compileOnly`.
- Configure `runServer` task with Minecraft 1.21.4 and PlaceholderAPI.

fix(ui): improve scoreboard placeholder handling

- Add check for PlaceholderAPI plugin enablement before attempting to use it.
2026-06-07 23:02:01 +02:00
fd0ba2cc0e refactor: reorganize packages and replace LPSchematic with WorldEdit
Restructure core modules into subpackages (generator, schematic, config, session, etc.); add .schem/.nbt schematic pipeline, commands, adaptive stats skeleton, and bootstrap wiring.
2026-06-01 14:02:48 +02:00
loki5512344
6ba6e5137d refactor(leaderboard): split Leaderboard.java into 3 specialized classes
- Created LeaderboardStorage.java - I/O and periodic sync
- Created LeaderboardSorter.java - sorting logic with Sort enum
- Leaderboard.java now acts as CRUD facade
- Backward compatibility via deprecated Sort enum and overloads
- All tests pass, build successful

Wave 3/8 complete (234 lines → 3 files)
2026-04-28 22:25:37 +02:00
loki5512344
0a93c9628f refactor(config): split Locales.java into 3 specialized classes
- Created LocaleLoader.java - disk loading and validation
- Created LocaleCache.java - thread-safe storage
- Locales.java now acts as facade
- Clean separation: loading → caching → access
- All tests pass, build successful

Wave 2/8 complete (260 lines → 3 files)
2026-04-28 22:23:45 +02:00
loki5512344
371e38bfac refactor(config): split Option.java into 5 specialized classes
- Created config/options/ package
- OptionSQL.java - SQL configuration
- OptionParticles.java - particles and sounds
- OptionGeneration.java - generation parameters
- OptionGeneral.java - general settings
- OptionStyles.java - style initialization
- Option.java now acts as facade with field sync
- Backward compatibility maintained via public static fields
- All tests pass, build successful

Wave 1/8 complete (335 lines → 5 files)
2026-04-28 22:22:21 +02:00
loki5512344
a7afe34fea docs: update TODO with adaptive generation roadmap
- Add 4-phase implementation plan (8-12 days)
- Define architecture: adaptive/, statistics/, refactored generator/
- Specify metrics collection and skill analysis system
- Plan ElytraMode fix and RoguelikeMode addition
- Include SQL migration for player stats table
2026-04-28 00:11:34 +02:00
loki5512344
7dd26408f9 clear 2026-04-20 18:22:40 +02:00
loki
e4a476e3be fix: launch player in air with gliding enabled for ElytraMode 2026-04-09 16:36:55 +02:00
loki
0ce5ac97f2 fix: first block after respawn at same Y level as spawn 2026-04-09 16:33:38 +02:00
loki
257d2cacb9 docs: update TODO with completed GravityShift and Hardcore modes 2026-04-09 14:24:59 +02:00
loki
7f23f86933 fix: register GravityShift and Hardcore modes in plugin 2026-04-09 14:23:38 +02:00
loki
02ba1e4028 feat: add locale entries for GravityShift and Hardcore modes
- Update gravity-shift: change material to POTION, update description to reflect random potion effects
- Update hardcore: update description to clarify reward loss on fall
- Apply changes to both English and Russian locales
2026-04-09 14:19:20 +02:00
loki
3ba85ef67b feat: register HardcoreMode in Modes registry 2026-04-09 14:17:11 +02:00
loki
e001935183 feat: implement HardcoreMode with reward reset on fall 2026-04-09 14:14:53 +02:00
loki
e3b0a02df6 fix: correct GravityShiftMode getMode() and documentation 2026-04-09 14:13:07 +02:00
loki
4f0d236dc5 feat: implement GravityShiftMode with random potion effects 2026-04-09 14:10:24 +02:00
loki
ccf64b7dfd Implement ElytraMode support classes
Created missing classes for ElytraMode:
- ElytraConfig: loads settings from config.yml
- ElytraRing: ring model with center, radius, direction
- ElytraRingGenerator: generates rings along curved path
- ElytraPhysics: checks ring crossings, falls, firework boosts
- ElytraRenderer: renders rings with particles

ElytraGenerator now has all dependencies and should work.
2026-04-09 13:59:46 +02:00