feat: add scene content stats to the Current Scene debug widget - #9457
Draft
dalkia wants to merge 9 commits into
Draft
feat: add scene content stats to the Current Scene debug widget#9457dalkia wants to merge 9 commits into
dalkia wants to merge 9 commits into
Conversation
Adds per-scene content statistics (entities, triangles, meshes/bodies, geometries, materials, textures, colliders, runtime content size and external content) to the "Current scene" debug widget, shown as current / maxcap (pct%) colored green/yellow/red against hardcoded caps derived from the scene's parcel count. Counting runs in a new scene-world system (SceneContentStatsSystem) gated by a demand flag the widget sets only while expanded, so it costs a single bool check per frame when the debug panel is closed or disabled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Windows and Mac build successful in Unity Cloud! You can find a link to the downloadable artifact below. |
Contributor
Contributor
|
Tests: 23922 passed, 0 failed ✅ |
Deployed-size validation belongs to deploy time (catalyst) and SDK tooling; the runtime-memory measurement compared a different quantity against the 15MB/parcel budget and showed red on deploy-compliant scenes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keep the five caps that exist on the official scene-limitations page (triangles, entities, bodies, materials, textures) and show geometries, colliders and external content as plain counts - their caps were project-invented (geometries only existed in legacy SDK6 docs). The docs define the limits as soft, so exceeding one now renders yellow instead of red. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a third sidebar button to the creator-facing scene debug menu (local scene development / --scene-console) that opens a Scene Metrics panel showing the same content stats as the Current Scene debug widget. Formatting and caps move to a shared SceneContentStatsFormatter in DCL.Profiling so both consumers render identical rows, and the collection demand flag is split per consumer so either UI can drive the scene-world counting system independently. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds get_scene_content_stats to the embedded MCP server so agents and scripts can read the same numbers as the Current Scene debug widget and the scene metrics panel as structured JSON, including the documented soft-limit caps for the scene's parcel count. The tool sets its own demand flag and waits for the scene world to complete a counting pass (CollectionCount stamp), so it returns fresh values even while every stats UI is closed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
get_scene_content_breakdown ranks the current scene's rendered content by triangles, grouped by GLTF source (plus one aggregate row for primitive meshes), reporting instances, renderers and share of the scene total. The stats system fills the breakdown during a normal counting pass when a one-shot flag is set, so it costs nothing unless requested. Answers 'what should I optimize', not just 'over budget'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each breakdown entry now reports the source's unique material count and a draw-call estimate (material slots across renderers, pre-batching), and get_scene_content_breakdown gains a sortBy argument (triangles/materials/drawCalls) so an agent can answer 'where do my 2,000 materials come from' directly. Primitive meshes flow through the same grouping path instead of dedicated accumulators. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Pull Request Description
What does this PR change?
Adds per-scene content statistics to the "Current scene" debug widget so creators and devs can see, at a glance, how close the scene they are standing in is to its limits. Eight new rows appear at the top of the widget. Rows with a documented scene limitation are formatted
current / maxcap (pct%)and colored green (< 80%) or yellow (≥ 80%) — the docs define these as soft limits ("reported as warnings by the Creator Hub... treat them as strong recommendations"), so exceeding one warns but never shows red. Rows without a documented limit are shown as plain counts:EntitiesMap.Count)MeshinstancesIntentionally omitted — Content size. An earlier revision showed a "Content size" row that summed runtime memory of unique meshes + textures (
Profiler.GetRuntimeMemorySizeLong) against the 15MB/parcel budget. It was removed: the deployed-size budget is validated at deploy time (catalyst) and by the SDK tooling, so it is not this client widget's responsibility — and runtime memory is a different quantity anyway (decompressed textures dwarf their deployed size, so the row showed red on deploy-compliant scenes).Caps are hardcoded from the documented Decentraland scene limitations, scaled by parcel count
n— exactly the five formulas on that page: trianglesn×10000, entitiesn×200, bodiesn×300, materialslog2(n+1)×20, textureslog2(n+1)×10. Geometries, colliders and external content have no cap and are shown as plain counts: geometries only had a formula in the legacy SDK6-era docs (dropped from the current page), and colliders/external content were never documented — earlier revisions used project-invented caps for all three, which misrepresented them as official budgets. All caps live in one constants block inDebugViewCurrentSceneSystem.Formatting.cs.Agent/automation surface —
get_scene_content_statsMCP tool. The embedded MCP server gains a read-only tool returning the same stats as structured JSON (values + the documented caps for the scene's parcel count + afreshflag). It sets its own collection-demand flag and waits for the scene world to complete a counting pass (CollectionCountstamp), so it works with every stats UI closed — agents iterating on scenes can assert budgets programmatically instead of reading screenshots. Documented indocs/mcp-automation.md; covered byGetSceneContentStatsToolShould.Creator-facing surface — Scene Metrics panel. The same stats are also shown to creators through a third sidebar button (signal-bars icon) in the scene debug menu at the top right, next to the console and debug-panel buttons. That menu only exists in local scene development mode or with
--scene-console, so this reaches creators previewing their scene without exposing anything to regular players. The panel (MetricsPanelView) renders the identical eight rows; row formatting and caps live in a sharedSceneContentStatsFormatter(DCL.Profiling) so both UIs cannot drift apart.Architecture: a new scene-world system (
SceneContentStatsSystem,SyncedPresentationSystemGroup) counts every 30 frames and writes into a newSceneContentStatspayload onSceneRuntimeMetrics(now exposed to scene-world systems viaECSWorldInstanceSharedDependencies). Collection runs on demand: the debug widget (DebugViewCurrentSceneSystem) and the metrics panel (DebugMenuController) each set their own request flag (RequestedByDebugWidget/RequestedByMetricsPanel) only while visible — with both closed, the scene system does a single bool check per frame and nothing else. Counting is allocation-free (reusedHashSets / scratch list, non-allocGetSharedMaterials).Test Instructions
Steps (standard run):
Expected result:
The "Current scene" debug widget shows the eight new stat rows with colored
current / max (pct%)values for the scene you are standing in.Steps (fresh account):
Expected result:
Same as above after finishing onboarding.
Automation (if applicable):
N/A
Prerequisites
--debug)Test Steps
current / max (pct%)colored green/yellow, uncapped rows (geometries, colliders, external content) as plain counts--scene-consoleonly): click the signal-bars button in the top-right sidebar — a "SCENE METRICS" panel opens with the same eight rows and live values; close it and collection stops (unless the debug widget is also open)--mcp): callget_scene_content_statswith all stats UIs closed — it returns the eight values + caps as JSON withfresh: truewithin ~1sAdditional Testing Notes
Finishedstate, so values grow while a scene streams inQuality Checklist
Code Review Reference
Please review our Branch & PR Standards before submitting. It explains the automated review flow, QA/DEV approval requirements, and what each label does — especially useful for first-time contributors.
🤖 Generated with Claude Code