Gate readiness on stable viewport frames
This commit is contained in:
@@ -343,6 +343,7 @@ async fn run_live(
|
||||
{
|
||||
live.vision.set_generation(status.generation);
|
||||
record_session_observation(&live.observability, &event);
|
||||
print_ready(&live, status.generation);
|
||||
return Ok::<(), CliError>(());
|
||||
}
|
||||
Some(
|
||||
@@ -529,32 +530,7 @@ async fn run_live(
|
||||
status.agent_ready,
|
||||
);
|
||||
if status.agent_ready {
|
||||
let world = live
|
||||
.world_loop
|
||||
.as_ref()
|
||||
.and_then(metacrate_game_loop::LoopHandle::latest_world);
|
||||
let world_sequence = world.as_ref().map_or(0, |world| world.sequence);
|
||||
let primitives = world
|
||||
.as_ref()
|
||||
.map_or(0, |world| world.value.primitives.len());
|
||||
let avatars = world.as_ref().map_or(0, |world| world.value.avatars.len());
|
||||
let dropped_world_events = live
|
||||
.world_loop
|
||||
.as_ref()
|
||||
.map_or(0, metacrate_game_loop::LoopHandle::dropped_world_events);
|
||||
let frames = live
|
||||
.vision
|
||||
.viewport_stats()
|
||||
.map_or(0, |stats| stats.completed_frames);
|
||||
println!(
|
||||
"READY generation={} world_sequence={} world_primitives={} world_avatars={} dropped_world_events={} viewport_frames={} viewport_target_fps=10",
|
||||
status.generation,
|
||||
world_sequence,
|
||||
primitives,
|
||||
avatars,
|
||||
dropped_world_events,
|
||||
frames
|
||||
);
|
||||
print_ready(&live, status.generation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,14 +665,21 @@ async fn prepare_live_framework(
|
||||
generation,
|
||||
libremetaverse_types::compat::CancellationToken::default(),
|
||||
);
|
||||
let mut stable_after_frame = 0;
|
||||
let mut observed_missed_deadlines = 0;
|
||||
loop {
|
||||
if live
|
||||
.vision
|
||||
.viewport_stats()
|
||||
.is_some_and(|stats| stats.completed_frames >= 2 && stats.render_errors == 0)
|
||||
if let Some(stats) = live.vision.viewport_stats() {
|
||||
if stats.missed_frame_deadlines != observed_missed_deadlines {
|
||||
observed_missed_deadlines = stats.missed_frame_deadlines;
|
||||
stable_after_frame = stats.completed_frames;
|
||||
}
|
||||
if stats.completed_frames.saturating_sub(stable_after_frame) >= 2
|
||||
&& stats.render_errors == 0
|
||||
&& stats.last_render <= metacrate_game_loop::DEFAULT_VIEWPORT_FRAME_INTERVAL
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(20)).await;
|
||||
}
|
||||
})
|
||||
@@ -705,7 +688,7 @@ async fn prepare_live_framework(
|
||||
readiness.mark_ready(generation);
|
||||
let stats = live.vision.viewport_stats().unwrap_or_default();
|
||||
println!(
|
||||
"INITIALIZED generation={} viewport_frames={} last_render_ms={} missed_deadlines={} world_state=stable",
|
||||
"INITIALIZED generation={} viewport_frames={} last_render_ms={} warmup_missed_deadlines={} world_state=stable viewport_state=stable",
|
||||
generation,
|
||||
stats.completed_frames,
|
||||
stats.last_render.as_millis(),
|
||||
@@ -714,6 +697,30 @@ async fn prepare_live_framework(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
fn print_ready(live: &LiveInteractions, generation: u64) {
|
||||
let world = live
|
||||
.world_loop
|
||||
.as_ref()
|
||||
.and_then(metacrate_game_loop::LoopHandle::latest_world);
|
||||
let world_sequence = world.as_ref().map_or(0, |world| world.sequence);
|
||||
let primitives = world
|
||||
.as_ref()
|
||||
.map_or(0, |world| world.value.primitives.len());
|
||||
let avatars = world.as_ref().map_or(0, |world| world.value.avatars.len());
|
||||
let dropped_world_events = live
|
||||
.world_loop
|
||||
.as_ref()
|
||||
.map_or(0, metacrate_game_loop::LoopHandle::dropped_world_events);
|
||||
let frames = live
|
||||
.vision
|
||||
.viewport_stats()
|
||||
.map_or(0, |stats| stats.completed_frames);
|
||||
println!(
|
||||
"READY generation={generation} world_sequence={world_sequence} world_primitives={primitives} world_avatars={avatars} dropped_world_events={dropped_world_events} viewport_frames={frames} viewport_target_fps=10"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "live-grid")]
|
||||
struct LiveInteractions {
|
||||
interaction: metacrate_grid_agent::InteractionHandle,
|
||||
|
||||
@@ -40,7 +40,9 @@ INITIALIZING generation=N waiting_for=world_state,viewport target_fps=10
|
||||
|
||||
The framework gate opens only after the region-scoped world state exists, the
|
||||
first scene/assets have converged, and at least two complete viewport frames
|
||||
have been published without render errors. The terminal then emits
|
||||
have been published after the last missed deadline, within the frame budget,
|
||||
and without render errors. One-time warm-up misses are reported separately and
|
||||
do not contaminate the post-`READY` stability window. The terminal then emits
|
||||
`INITIALIZED ...` followed by one unambiguous `READY ...` line when the session
|
||||
and agent services are released. The default readiness allowance is two
|
||||
minutes; the measured scene convergence window was about 30.05 seconds.
|
||||
|
||||
Reference in New Issue
Block a user