Skip to content

Commit 2ee83dc

Browse files
committed
Break the client-loaded chunk wait cycle
1 parent 9b69d9b commit 2ee83dc

3 files changed

Lines changed: 55 additions & 9 deletions

File tree

tools/perf/phase2-protocol-client.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ function markReadyIfComplete () {
169169
}
170170

171171
function sendPlayerLoadedIfReady () {
172-
if (playerLoadedSent || client.state !== 'play' || !positionSeen || !chunkSeen || !chunkBatchSeen) return
172+
// Paper sends the first chunks before client-loaded, but does not close the
173+
// first adaptive batch until that acknowledgement arrives. A renderless
174+
// peer therefore uses receipt of the first chunk as its level-ready proxy;
175+
// waiting for chunk_batch_finished here creates a protocol wait cycle.
176+
if (playerLoadedSent || client.state !== 'play' || !positionSeen || !chunkSeen) return
173177
client.write('player_loaded', {})
174178
playerLoadedSent = true
175179
}

tools/perf/prepare-phase2-protocol-client.sh

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,19 @@ cat > "$output_directory/client-build-manifest.json" <<EOF
151151
}
152152
EOF
153153

154-
PHASE2_MC_PROTOCOL_MODULE="$output_directory/node-minecraft-protocol" \
155-
node -e 'const mc = require(process.env.PHASE2_MC_PROTOCOL_MODULE); if (!mc.supportedVersions.includes("26.1.2")) process.exit(1)'
154+
PHASE2_MC_PROTOCOL_MODULE="$output_directory/node-minecraft-protocol" node <<'NODE'
155+
const path = require('path')
156+
const protocolRoot = process.env.PHASE2_MC_PROTOCOL_MODULE
157+
const protocol = require(protocolRoot)
158+
if (!protocol.supportedVersions.includes('26.1.2')) {
159+
throw new Error('node-minecraft-protocol does not advertise 26.1.2')
160+
}
161+
const dataEntry = require.resolve('minecraft-data', { paths: [protocolRoot] })
162+
const data = require(dataEntry)('26.1.2')
163+
if (data == null || data.version == null || data.version.minecraftVersion !== '26.1.2') {
164+
throw new Error(`minecraft-data did not load 26.1.2 from ${path.dirname(dataEntry)}`)
165+
}
166+
NODE
156167

157168
(
158169
cd "$output_directory"

tools/perf/run-phase2-runtime-once.sh

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ measure_seconds="${PHASE2_MEASURE_SECONDS:-180}"
3434
capture_enabled="${PHASE2_CAPTURE_ENABLED:-0}"
3535
capture_snaplen="${PHASE2_CAPTURE_SNAPLEN:-128}"
3636

37+
[[ "$run_id" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] \
38+
|| { echo "PHASE2_RUN_ID contains unsafe characters" >&2; exit 64; }
39+
3740
case "$variant" in
3841
A|B) ;;
3942
*) echo "PHASE2_VARIANT must be A or B" >&2; exit 64 ;;
@@ -141,6 +144,7 @@ difficulty=peaceful
141144
level-name=phase2-world
142145
level-seed=interactionvisualizer-phase2-fixed
143146
level-type=minecraft:flat
147+
generator-settings={"layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:dirt","height":2},{"block":"minecraft:grass_block","height":1}],"biome":"minecraft:plains"}
144148
max-players=1
145149
max-tick-time=-1
146150
motd=InteractionVisualizer Phase 2
@@ -169,6 +173,24 @@ capture_pid=""
169173
console_open=0
170174
cleanup_complete=0
171175

176+
prune_runtime_payload() {
177+
# Evidence lives in the root logs/state/JSON/pcap files. Paper's downloaded
178+
# runtime, remapped plugin copy and disposable worlds are reproducible inputs
179+
# or test state and otherwise inflate every artifact by hundreds of MB.
180+
rm -rf -- \
181+
"$run_directory/cache" \
182+
"$run_directory/libraries" \
183+
"$run_directory/logs" \
184+
"$run_directory/versions" \
185+
"$run_directory/phase2-world" \
186+
"$run_directory/phase2-world_nether" \
187+
"$run_directory/phase2-world_the_end" \
188+
"$run_directory/plugins/.paper-remapped"
189+
rm -f -- \
190+
"$run_directory/server.jar" \
191+
"$run_directory/plugins/InteractionVisualizer.jar"
192+
}
193+
172194
stop_capture() {
173195
if [[ -n "$capture_pid" ]] && kill -0 "$capture_pid" 2>/dev/null; then
174196
sudo -n kill -INT "$capture_pid" 2>/dev/null || true
@@ -205,6 +227,7 @@ cleanup() {
205227
console_open=0
206228
fi
207229
rm -f -- "$console_fifo"
230+
prune_runtime_payload
208231
return "$exit_status"
209232
}
210233
trap cleanup EXIT
@@ -283,17 +306,25 @@ server_pid=$!
283306

284307
wait_for_log "[InteractionVisualizer] Enabled for Paper 26.1.2!" 240
285308
wait_for_log "Done (" 240
309+
if grep -Fq -- "No key layers in MapLike" "$server_log"; then
310+
echo "Paper rejected the flat-world generator settings" >&2
311+
exit 1
312+
fi
286313

287314
send_console "difficulty peaceful"
288-
send_console "gamerule doMobSpawning false"
289-
send_console "gamerule doWeatherCycle false"
290-
send_console "gamerule doDaylightCycle false"
291-
send_console "gamerule randomTickSpeed 0"
292-
send_console "gamerule spawnRadius 0"
293-
send_console "setworldspawn 0 4 0"
315+
send_console "gamerule minecraft:do_mob_spawning false"
316+
send_console "gamerule minecraft:do_weather_cycle false"
317+
send_console "gamerule minecraft:do_daylight_cycle false"
318+
send_console "gamerule minecraft:random_tick_speed 0"
319+
send_console "gamerule minecraft:spawn_radius 0"
320+
send_console "setworldspawn 0 -60 0"
294321
send_console "weather clear"
295322
send_console "time set day"
296323
sleep 1
324+
if grep -Fq -- "Incorrect argument for command" "$server_log"; then
325+
echo "Paper rejected one of the deterministic-world commands" >&2
326+
exit 1
327+
fi
297328

298329
PHASE2_MC_PROTOCOL_MODULE="$client_root/node-minecraft-protocol" \
299330
PHASE2_SERVER_HOST=127.0.0.1 \

0 commit comments

Comments
 (0)