Fix critical gameplay bugs in rewrite-v2

1. Fixed locale loading - changed from async to sync
   - Locales now load synchronously on startup
   - Prevents GUI showing stone items before locales load

2. Fixed infinite falling bug
   - Added player teleport to spawn in processFall()
   - Players now respawn correctly after falling

3. Fixed parkour generation not working
   - Added missing tick cycle in SessionStateManager
   - Generator now ticks every server tick (50ms)
   - Parkour blocks now generate continuously

All three major bugs fixed and tested.
This commit is contained in:
loki 2026-04-09 12:07:07 +02:00
parent e5dd567ca9
commit c142d21a26
3 changed files with 58 additions and 20 deletions

View file

@ -101,24 +101,20 @@ public class Locales {
private static void loadLocalesAsync() {
Plugin plugin = LoParkour.getPlugin();
Scheduler.get(plugin).runAsync(() -> {
try {
FileConfiguration embedded = YamlConfiguration.loadConfiguration(
new InputStreamReader(plugin.getResource("locales/en.yml"), StandardCharsets.UTF_8));
try {
FileConfiguration embedded = YamlConfiguration.loadConfiguration(
new InputStreamReader(plugin.getResource("locales/en.yml"), StandardCharsets.UTF_8));
Map<String, FileConfiguration> loaded = loadFromDisk(embedded);
Map<String, FileConfiguration> loaded = loadFromDisk(embedded);
Scheduler.get(plugin).run(() -> {
synchronized (locales) {
locales.clear();
locales.putAll(loaded);
}
LoParkour.log("Locales reloaded successfully (" + loaded.size() + " locales)");
});
} catch (Exception ex) {
plugin.getLogger().severe("Error while loading locale files: " + ex.getMessage());
synchronized (locales) {
locales.clear();
locales.putAll(loaded);
}
});
LoParkour.log("Locales loaded successfully (" + loaded.size() + " locales)");
} catch (Exception ex) {
plugin.getLogger().severe("Error while loading locale files: " + ex.getMessage());
}
}
@NotNull

View file

@ -94,6 +94,13 @@ public class LifecycleEventManager {
generator.registerScore(time, difficulty, generator.state.score);
// Teleport players back to spawn before reset
for (ParkourPlayer player : generator.getPlayers()) {
if (generator.state.playerSpawn != null) {
player.teleport(generator.state.playerSpawn);
}
}
// Reset generator state
generator.reset(true);
}

View file

@ -1,8 +1,11 @@
package dev.loki.loparkour.session;
import dev.loki.loparkour.LoParkour;
import dev.loki.loparkour.generator.ParkourGenerator;
import dev.loki.loparkour.player.ParkourUser;
import dev.loki.loparkour.world.Divider;
import dev.lolib.scheduler.Scheduler;
import dev.lolib.scheduler.ScheduledTask;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -20,6 +23,7 @@ public class SessionStateManager {
private Location spawnLocation;
private Session.Visibility visibility = Session.Visibility.PUBLIC;
private final Map<ParkourUser, Boolean> mutedUsers = new HashMap<>();
private ScheduledTask tickTask = null;
public SessionStateManager(@NotNull Session session) {
this.session = session;
@ -38,12 +42,18 @@ public class SessionStateManager {
// Build island at spawn location
generator.island.build(spawnLocation);
// Start tick cycle for generator
startTickCycle();
}
/**
* Clean up session resources.
*/
public void cleanup() {
// Stop tick cycle
stopTickCycle();
if (session.generator != null) {
session.generator.reset(false);
}
@ -52,6 +62,31 @@ public class SessionStateManager {
mutedUsers.clear();
}
/**
* Start tick cycle for generator.
*/
private void startTickCycle() {
if (session.generator == null || tickTask != null) {
return;
}
tickTask = Scheduler.get(LoParkour.getPlugin()).runTimer(() -> {
if (session.generator != null) {
session.generator.tick();
}
}, 0, 1); // Run every tick (1 = 50ms)
}
/**
* Stop tick cycle.
*/
private void stopTickCycle() {
if (tickTask != null) {
tickTask.cancel();
tickTask = null;
}
}
/**
* Set session visibility.
*/