refactor(03-06): remove debug logs + efficiency pass

Log cleanup:
- Drop redundant INFO "Gravity Flip enabled" in setup() (substantive version at
  start() remains as the single startup line).
- Drop INFO "debug enter/exit notifier ENABLED" (the notifier itself emits per
  region transition; extra startup noise not needed).
- Remove dead back-compat GravityApplier ctors that accepted an infoHandler
  Consumer (no callers post-03-06; debug logs already stripped).
- Clean stale javadoc referencing removed [DBG npc.woken]/[DBG npc.ctrlNull]
  one-shot logs.
- Also ship the pre-staged cleanup work: RegionEnterNotifier gated behind
  GRAVITYFLIP_DEBUG_NOTIFY env var, GravityApplier infoHandler field removed,
  tick logs stripped.

Efficiency:
- RegionVisualizer.resolveParticleId now memoises the requested->resolved
  mapping in a ConcurrentHashMap, eliminating the ParticleSystem.getAssetMap()
  lookup on every tick emission per region. Warn-once semantics preserved via
  warnedInvalidIds. Fail-open path (AssetMap unavailable in tests) intentionally
  does not populate the cache.
- Document in GravityApplier javadoc why Pass 1 + Pass 2 cannot be fused:
  restore requires the complete currentlyInRegion set before diffing against
  previouslyInverted.

Considered but not applied:
- ParticleEdgeEmitter.edgePoints caching per (box, density): throttled to
  >=100ms refresh and typical <20 regions => alloc pressure negligible;
  premature without measurement.
- Reusing RegionRegistry snapshot in RegionEnterNotifier: notifier is
  opt-in/off-by-default, so its independent ECS scan has zero prod cost.

Tests: ./gradlew clean build green, no test changes required.
This commit is contained in:
2026-04-23 16:43:07 +02:00
parent beba729115
commit 1e47f4e846
7 changed files with 219 additions and 54 deletions
@@ -7,6 +7,7 @@ import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.util.Config;
import com.mythlane.gravityflip.command.DumpParticlesCommand;
import com.mythlane.gravityflip.config.GravityFlipConfig;
import com.mythlane.gravityflip.debug.RegionEnterNotifier;
import com.mythlane.gravityflip.physics.FallDamageGuard;
import com.mythlane.gravityflip.physics.FallDamageSuppressorSystem;
import com.mythlane.gravityflip.physics.GravityApplier;
@@ -67,8 +68,6 @@ public class GravityFlipPlugin extends JavaPlugin {
getEntityStoreRegistry().registerSystem(new FallDamageSuppressorSystem(
fallDamageGuard,
th -> getLogger().at(Level.WARNING).withCause(th).log("fallDamageSuppressor handle failed")));
getLogger().at(Level.INFO).log("Gravity Flip enabled");
}
@Override
@@ -78,13 +77,21 @@ public class GravityFlipPlugin extends JavaPlugin {
this.registry = new RegionRegistry(cfg, configHolder);
this.gravityApplier = new GravityApplier(
th -> getLogger().at(Level.WARNING).withCause(th).log("gravityApply failed"),
msg -> getLogger().at(Level.INFO).log("%s", msg),
fallDamageGuard);
this.regionVisualizer = new RegionVisualizer(
th -> getLogger().at(Level.WARNING).withCause(th).log("regionVisualize failed"));
this.tickLoop = new RegionTickLoop(registry, gravityApplier, regionVisualizer, th ->
getLogger().at(Level.WARNING).withCause(th).log("detectTick failed"));
// Debug enter/exit notifier — opt-in via env var GRAVITYFLIP_DEBUG_NOTIFY (or sysprop
// gravityflip.debugNotify). Emits chat + INFO log on every region transition. Off by
// default to keep prod chat/logs clean.
if (isDebugNotifyEnabled()) {
this.tickLoop.setEnterNotifier(new RegionEnterNotifier(registry,
th -> getLogger().at(Level.WARNING).withCause(th).log("regionEnterNotify failed"),
msg -> getLogger().at(Level.INFO).log("%s", msg)));
}
// Lazy world resolution — see setup() comment.
this.tickLoop.startWithDelay(2_000L, () -> {
Universe u = Universe.get();
@@ -122,6 +129,21 @@ public class GravityFlipPlugin extends JavaPlugin {
}
}
/**
* Env var {@code GRAVITYFLIP_DEBUG_NOTIFY=1} or sysprop {@code -Dgravityflip.debugNotify=true}
* enables the chat + log enter/exit notifier. Off by default — debug tool only.
*/
private static boolean isDebugNotifyEnabled() {
return truthy(System.getenv("GRAVITYFLIP_DEBUG_NOTIFY"))
|| truthy(System.getProperty("gravityflip.debugNotify"));
}
private static boolean truthy(String v) {
if (v == null) return false;
String s = v.trim().toLowerCase();
return s.equals("1") || s.equals("true") || s.equals("yes") || s.equals("on");
}
@Override
protected void shutdown() {
// Plan 03-05 : clear des debug shapes cote clients AVANT tickLoop.stop().