test: pre-generate the nether chunks the nether test touches - #4037
Closed
u9g wants to merge 1 commit into
Closed
Conversation
u9g
force-pushed
the
test/cheap-nether-gen
branch
from
August 31, 2026 14:08
1c62f28 to
bee5a11
Compare
Member
|
CI fails |
u9g
force-pushed
the
test/cheap-nether-gen
branch
from
September 4, 2026 18:16
bee5a11 to
b78bc29
Compare
The nether test's duration on CI swings 4-23s across version groups because portal travel generates the destination nether chunks synchronously while the test's clock runs, tripping the duration regression gate. Forceload those chunks (7x7 around nether 0,0) during server setup instead, before the bot connects: /forceload add blocks the server main thread until the chunks are FULL on every version (ServerLevel.setChunkForced calls getChunk), so issued any later it starves in-test 5s timeouts. With generation out of the way the tp to the nether roof lands while the client is still streaming pre-tp positions; the server rolls each one back (moved too quickly) and silently drops use_item packets until the last rollback is confirmed (handleUseItemOn requires awaitingPositionFromClient == null), which lost the sign placement. Settle with chat-echo round trips until one completes with no new forcedMove: the echo proves the server processed every packet sent before it, confirms included.
u9g
force-pushed
the
test/cheap-nether-gen
branch
from
September 4, 2026 21:11
b78bc29 to
d343efd
Compare
Member
Author
|
Closing: profiling shows the forceload only relocates the nether generation from the test into server setup (2-7s added to setup vs 2-6s removed from the test locally), while all four servers on a CI runner then stall at the same moment during startup — the 32s freeze on 1.18.2/1.19 that killed the bot's login on every run here. The nether test noise is better handled in the duration comparison than by pre-generating chunks. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
netherexternal test's duration swings wildly on CI because the nether is full noise generation (level-type=FLATonly applies to the overworld). Measured across one CI run: 3.7-4.7s (1.8.8-1.11.2), 9.5-14.4s (1.20.2-1.21.1), 10.9-22.6s (1.16.5-1.19), 14-18.7s (1.21.8-26.1). That variance trips the new duration-regression gate from #4028 (>1.5x and >5s over master's baseline) on unrelated PRs.Mechanism (from Mojang-mapped sources)
PortalForcer.createPortal, whose destination scan reads block states across a 33x33-block spiral — each ungenerated chunk it touches is noise-generated synchronously on the main thread while the test's clock runs. The test then waits on the chunks around nether (0,128,0) (waitForChunksToLoad+ the block-below poll), which stream at server view-distance 8. Both costs are nether gen centered on nether (0,~,0)./forceload addis itself synchronous on every version:ServerLevel.setChunkForcedcallsgetChunk, blocking the main thread until the chunks are FULL (1.16.5ServerLevel.java:1240, same in 1.21.8). Issued while tests run it starves their 5s timeouts (reproduced on 1.16.5:resetState's teleport times out). So the warm-up runs in the server-setup hook before the bot connects — status pings are answered from the network thread with a cached response, so the stall lands harmlessly inside the hook's 120s budget. 7x7 chunks around nether (0,0) covers the portal scan and every chunk the test's waits touch; the rest of the view-distance ring streams in without blocking anything the test waits on./tp 0 128 0exposed a race the gen delay used to hide: the tp lands while the client is still streaming pre-tp positions, the server rolls each one back ("moved too quickly"), and while any rollback awaits its confirm the server silently dropsuse_itempackets (ServerGamePacketListenerImpl.handleUseItemOnrequiresawaitingPositionFromClient == null— 1.16.5 line 1019), losing the sign placement (reproduced 2/3 on 1.14.4). The test now settles with chat-echo round trips until one completes with no newforcedMove: the echo proves the server processed every packet sent before it, teleport confirms included, so a placement can no longer be dropped. Event-driven, no sleeps.Change
test/externalTest.js:execute in minecraft:the_nether run forceload add -48 -48 63 63from the server console during setup, gated onsupportFeature('hasExecuteCommand')(1.14+; older versions have no forceload but their nether gen is already the cheap pre-1.16 kind).test/externalTests/nether.js: position-settle loop before placing the sign.Timings (local, nether test, 2-3 runs each)
Beyond the raw drop, the test's duration no longer depends on noise-gen throughput, which is what actually varies across CI runners. The pre-existing sign-spot flake (blocked sign position) is separate and addressed by #4021.