Стабилизировать ботов при медленном рендеринге

This commit is contained in:
2026-08-18 17:20:04 +03:00
parent 88a1ba9b34
commit 650bfb3533
3 changed files with 138 additions and 11 deletions
@@ -68,6 +68,41 @@ public final class LevelPlaytestBotTest {
assertTrue(result.diagnostic(), result.diagnostic().contains("allDoorsOpen=false"));
}
@Test
public void slowRenderingUsesSimulationElapsedBudgetsInsteadOfHostTime() {
SlowRenderingDriver driver = new SlowRenderingDriver(true);
LevelPlaytestBot.Scenario scenario = LevelPlaytestBot.Scenario
.builder(1, "Slow rendering")
.step("Reach simulated checkpoint", 200L, LevelPlaytestBot.Input.right(),
GameView.AutomationSnapshot::completed)
.build();
LevelPlaytestBot.Result result = new LevelPlaytestBot().run(driver, scenario, 500L);
assertTrue(result.diagnostic(), result.completed());
assertTrue("The host clock must be allowed to outrun simulated gameplay",
driver.wallMillis > 500L);
assertEquals(96L, driver.simulationMillis);
}
@Test
public void frozenSimulationStopsAtWallClockWatchdogWithDiagnostic() {
SlowRenderingDriver driver = new SlowRenderingDriver(false);
LevelPlaytestBot.Scenario scenario = LevelPlaytestBot.Scenario
.builder(1, "Frozen rendering")
.step("Wait for simulation", 1_000L, LevelPlaytestBot.Input.right(),
GameView.AutomationSnapshot::completed)
.build();
LevelPlaytestBot.Result result = new LevelPlaytestBot().run(driver, scenario, 5_000L);
assertFalse(result.completed());
assertEquals("Wait for simulation", result.lastStep());
assertTrue(result.diagnostic(), result.diagnostic().contains("wall-clock watchdog"));
assertTrue(result.diagnostic(), result.diagnostic().contains("simulationElapsed=0"));
assertTrue(result.diagnostic(), result.diagnostic().contains("wallElapsed=120000"));
}
@Test
public void levelFiveUsesTheGenericNamedScenario() {
LevelFiveDriver driver = new LevelFiveDriver();
@@ -160,6 +195,50 @@ public final class LevelPlaytestBotTest {
}
}
private static final class SlowRenderingDriver implements LevelPlaytestBot.Driver {
private final boolean advancesSimulation;
private long wallMillis;
private long simulationMillis;
private boolean movingRight;
private boolean completed;
SlowRenderingDriver(boolean advancesSimulation) {
this.advancesSimulation = advancesSimulation;
}
@Override
public void startLevel(int oneBasedLevelNumber) {
wallMillis = 0L;
simulationMillis = 0L;
movingRight = false;
completed = false;
}
@Override
public void setInput(boolean moveLeft, boolean moveRight, boolean jump) {
movingRight = moveRight;
}
@Override
public GameView.AutomationSnapshot snapshot() {
return new GameView.AutomationSnapshot(
completed, true, false, false, movingRight,
1, simulationMillis, 130f, 760f, 0, 0);
}
@Override
public void waitForNextDecision(long millis) {
wallMillis += advancesSimulation ? 1_000L : 60_000L;
if (advancesSimulation) simulationMillis += millis;
if (movingRight && simulationMillis >= 96L) completed = true;
}
@Override
public long currentTimeMillis() {
return wallMillis;
}
}
private static final class LevelFiveDriver implements LevelPlaytestBot.Driver {
private int startedLevel;
private long nowMillis;