- command: replace /lp alias with /lpk (LuckPerms conflict, p.144);
parkour alias kept; docs/changelog/javadoc updated
- lint p.169: restructure last 69 void early-returns into if-blocks and
helpers; ReturnCount is now an error gate (0 violations)
- lint p.170: Throwable->RuntimeException on 3 boundaries; narrow 5
catches to concrete types; document 14 intentional boundary catches
- scheduler p.21: add runTimerAsync to the facade (Bukkit + Folia
backends); MetricsCacheStore and duels go through the facade, no
BukkitRunnable/Bukkit.getScheduler outside scheduler/ (archunit
freeze-store emptied); drop the unverified Folia badge from README
- tracker: mark p.26-29/32-33 done (fixed in fea15e6, verified)
- ElytraGenerator no longer hardcodes Modes.elytra(): the mode is passed
through the constructor (canonical (session, pointType, mode) plus two
convenience overloads); CloseGenerator/MinSpeed/Obstacle/SpeedDemon/
TimeTrial now declare their own mode, so getMode() is reachable
- Session.ChatType gets next(); ParkourUser gets setChatType(); SettingsMenu
gains a chat-scope cycle button (slot 15) so LOBBY_ONLY/PLAYERS_ONLY are
no longer dead branches
- ChatTypeTest covers the cycle order and wrap-around
- TODO.md: PROGRESS-8 records both fixes
checkstyle 0 error / 135 warning, PMD 0, tests 96/0 fail (1 skipped)
- ParkourUser/ParkourPlayer/GeneratorState public mutable fields -> private + short accessors
- per-player settings extracted to player/data/PlayerSettings (ParkourPlayer 188 -> 96 lines,
PMD-counted methods 20 -> 9); this is what fixed the TooManyMethods violation that the
encapsulation itself introduced — by decomposition, not by lowering the threshold
- disk storage reads and writes the same canonical 12-key map as the SQL JSON column;
legacy key names normalized on read, @Expose dropped from domain classes
- 39 settings call sites rewritten across 7 files
- HiddenField backlog cleared (Config, ObstacleGenerator, GhostService, Leaderboard,
PagedMenu, Reward, ParticleData, World)
- checkstyle ratchet: VisibilityModifier, HiddenField, EmptyLineSeparator and
MissingDeprecated flipped to error once their counters hit zero; suppressions.xml empty
- javac -Xmaxwarns raised so NullAway/Error Prone counts are honest
(baseline 165/289, now 164/265)
checkstyle 0 errors / 135 warnings, PMD 0 violations, tests 94/0 fail, ./gradlew check green.
TODO.md: items 30 and 107 updated, new items 167-170, ПРОГРЕСС-6/7 recorded.
Option was a facade of 45 public static fields kept in sync with the four
sections by syncFields(); the sections themselves also exposed public static
mutable fields. 88 VisibilityModifier violations in one place and two owners
for every value.
- Option keeps only init(boolean) (the reload entry ConfigLoader calls);
the mirrors, syncFields() and the unused @Deprecated initStyles are gone
- sections hold private static state behind fluent accessors (OptionSQL.enabled(),
OptionGeneration.cleanupInterval(), OptionGeneral.goBackLocation()); the two
Option.SQL = false writes become OptionSQL.disable()
- collection/location accessors hand out unmodifiable views and a Location copy,
so no caller can mutate loaded config state
- ParticleShape promoted from nested enum to config/options/ParticleShape
- delete 17 never-read generation probability fields and initGenerationProbabilities():
live weights come from advanced.* via GeneratorProfileManager/GenerationProfileLoader;
min-y/max-y guard moved 1:1 into initBounds()
- rewrite 63 Option.<FIELD> reads in 19 files to the section accessors
- validateConfigs() now checks the paths the code actually consumes
(advanced.distance/height/type weights) instead of the dead generation.normal.*
- ParkourRestrictionListener.onChat: getOrDefault(CHAT, true) instead of unboxing
a Boolean that may be absent
checkstyle 0 errors / 329 -> 240 warnings (VisibilityModifier 163 -> 75);
config/options itself is clean. Dead config keys found on the way are filed as
TODO items 164-166. ./gradlew check green: PMD 0, 94 tests, NullAway unchanged.
Checkstyle is now a ratchet: severity="error" only for rules that are at
zero violations, design-debt rules report as warnings and must be flipped
to error as soon as their backlog hits zero (tracked in TODO.md).
- thresholds tightened: MethodLength 80->40, CyclomaticComplexity 20->15,
NestedIfDepth 3->2, ParameterNumber 7->5; new rules ReturnCount(5),
FinalClass, HiddenField, VisibilityModifier; MagicNumber and
FinalLocalVariable promoted from warning to error (both clean)
- suppressions.xml emptied: 45 legacy entries removed, never add back
- fixed 102 baseline violations (431->329): FinalClass in 37 classes,
WhitespaceAround in 11 files
- TODO.md: Task 1 done (lolib removed, smoke test passed) and Task 2
baseline recorded (red report, per-package list, next steps)
- 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
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.
- 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
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.
- Fix locale 'true' bug with sanitization at all levels:
* ConfigAccessor.getString() - force String.valueOf()
* Option.java - sanitize LANG defaults from config
* PlayerSettingsManager - sanitize on settings load
* SQLDataMapper - sanitize on SQL load
* StorageDisk - sanitize on JSON load
* SQLMigrationManager - SQL migration to fix DB
- Fix parkour first block position:
* Island.java - spawn 6 blocks forward + 1 up from center
* GeneratorCleanup.java - same position after fall/reset
- Add spawn-location config option at top of config.yml
- Fix locale default value parsing (Boolean → String)
- Move first block 3 blocks ahead after fall to avoid platform overlap
- Reduce initial generation from 5 to 3 blocks for better spacing