Debug Tables (Dense Numerical Instrument) is real-time developer tool for inspecting the dense data used by the renderer.
Intended to make the RenderTable/EntityTable rendering pipeline visible rather than treating it as a black box.
Open it from:
Debug → Debug Tables
The Debug menu also contains Project Overview… and Validate All Connections…, providing map-level, I/O-level and dense-rendering diagnostics in one place.
Fio's renderer does not normally need to reconstruct authored objects in order to render the world. The runtime publishes dense numerical state through:
RenderTable — dense brush/render-projection stateEntityTable — dense entity stateDebug Tables exposes those structures directly.
The window is read-only. It does not create a second world representation and does not modify the rendering pipeline.
The tool reads the published render-state snapshot used by the live editor/runtime.
The Pipeline tab shows the current dense execution path:
World / LogicThread
↓
RenderTable + EntityTable
↓
visible integer slots
↓
renderer key generation / sorting
↓
contiguous runs
↓
instanced GL submission
It also reports:
The tool deliberately does not invent CPU stage timings. It reports only measurements that are actually available from the published state and renderer statistics.
The RENDERTABLE tab provides direct read-only access to the NumPy arrays held by the live RenderTable.
Select any available array from the ARRAY selector to inspect its rows and values.
Each array view reports its:
The table contains dense render information such as transforms, classification flags, texture identifiers, UV state, colours, geometry identifiers and special-material state.
This is the actual numerical representation consumed by the renderer; the Debug Tables window does not translate it back into Brush objects for display.
The ENTITYTABLE tab performs the same inspection for the live EntityTable.
This exposes the dense numerical representation of renderable entities, including fields used to classify and submit models, sprites and Effects.
This makes it possible to inspect the data that reaches the renderer without relying on the original authored Thing representation.
The KEY MICROSCOPE shows the logical render-key stream generated from the visible RenderTable rows.
For the cube-brush path, the logical key layout is:
[ texture-name-id: 32 bits | cube-face: 3 bits ]
The tool:
The display includes:
For example:
RENDER-KEY MICROSCOPE
Logical key layout: [ texture-name-id:32 | cube-face:3 ]
visible cube rows 1,024
drawable faces 5,781
contiguous runs 47
RUNS
000 rows 0- 143 n=144 key=0x0000000123 tex= 36 face=3
001 rows 144- 287 n=144 key=0x0000000243 tex= 72 face=3
...
This makes batching behaviour directly inspectable instead of relying on a single draw-call count.
The microscope displays the logical brush key.
The logical key uses texture-name-id so the numerical projection remains independent of OpenGL resource handles.
At the renderer boundary, the texture-name ID is resolved to the corresponding GL texture ID, which is used by the renderer's final brush key.
Therefore the microscope intentionally shows the key one step before the GL-resource resolution boundary.
Enable FOLLOW SELECTION to trace the currently selected object through the dense representation.
When the selected object has an ID, Debug Tables resolves that ID against the live tables and can show:
authored ID
↓
RenderTable row
↓
logical render key
↓
render run
For entity rows it can also show:
authored ID
↓
EntityTable row
↓
sprite-key
This allows a specific object selected in the editor to be followed into the numerical rendering pipeline.
If an ID cannot be found, the tool reports:
ID NOT PRESENT IN RENDERTABLE OR ENTITYTABLE
This is useful for diagnosing stale projections, missing rows, selection mismatches and unexpected classification.
The MEMORY tab lists every NumPy array in both tables.
For each field it reports:
TABLE / FIELD
SHAPE
DTYPE
BYTES
Both live row count and allocated capacity matter here.
Fio's dense tables retain allocated storage beyond the current live row count, so the displayed byte count represents the actual NumPy allocation rather than an estimate based only on populated rows.
Debug Tables refreshes automatically while open.
The raw array views expose the currently published tables. The window therefore follows the runtime's published render-state boundary rather than independently rebuilding scene state.
The window can also be manually refreshed with Refresh.
Use Export to save a complete numerical debug snapshot as a ZIP archive.
The exported format is:
fio-debug-tables-v1
The archive can contain:
manifest.json
pipeline.json
pipeline.txt
RenderTable/
EntityTable/
visible_brush_slots.npy
KeyMicroscope/
key_microscope.json
key_microscope.txt
memory.json
memory.txt
follow_selection.txt
The RenderTable and EntityTable arrays are exported as NumPy .npy files.
The arrays are exported at their full allocated capacity rather than being truncated. The live row count and live shape are recorded separately in the memory metadata.
This makes the export useful for offline analysis as well as immediate debugging.
Debug Tables is particularly useful when investigating:
It is also useful when developing the renderer itself: the numerical data can be inspected before changing the rendering code, making it possible to determine whether a problem originates in projection, classification, key generation, batching or GL submission.
Debug Tables is deliberately built around the same dense representation used by the renderer.
It does not maintain a parallel debug scene, duplicate the world model or convert the tables back into collections of authored objects.
The purpose is simple:
What the renderer sees should be inspectable.
That makes the dense rendering pipeline observable all the way from an authored object's identity through table rows and packed keys to the renderer's submission statistics.