Repository navigation
Conversation
Contract change (authorized): System.render's declaration takes
`order?: Index<{ readonly sorted: true; readonly key: readonly Component.Key[] }>`.
With it, the body's `tables` holds exactly one table whose `count` is every
matching row across archetypes (has/not apply) and whose `bind` makes instance
i the i-th of them in the index's order. Shader accessors keep their names and
`fn name(row: u32)` signatures; `row` is the position in the order and
`ecs_count()` the instance count. Gpu.wgsl emits, for an ordered system, the
record `struct EcsTable { ecs_rows, ecs_order, ecs_tables, ecs_shift }` and an
`ecs_address` helper; unordered output is unchanged. A non-sorted or unknown
index is a type error and throws at creation; a run whose matching archetype
holds more rows than 32 bits name beside its slot fails in its report.
Implementation: an order block of one u32 per instance (slot above the
record's shift, row below) and a tables block of each slot's column word
addresses, both heap blocks through uploadIndexes. The order is listed and
written only when the index's `changed` tick or a new `moved` tick (an entry
relocated with its key unchanged) moves, or the matches grow; the tables block
only when an address changes; the record only when a word does. An unchanged
run writes nothing and allocates nothing.
Numbers, chromium: gpu ordered render unchanged 50K 0.030-0.036 ms a run
(unordered two tables 0.045-0.049); gpu ordered render one key 50K
0.268-0.294 ms (listing 50K entries 0.17 ms, 200 KB write 0.07 ms).
Tests: render-order.browser.test.ts (two archetypes interleaved in depth,
has/not, despawn row move, spawn, key change, a hidden entity shown, one
table when nothing matches, writes only on change, ordered WGSL compiles),
system.type-test.ts (sorted, hash, unknown and non-index orders), a creation
check in create.test.ts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Adds
ordertoSystem.render, so one draw covers several archetypes in an index's order. A 2D editor needs this to blend translucent shapes, images and text back to front.Contract change
System.render's declaration takesorder?: Index<{ sorted: true; key: Component.Key[] }>, constrained asSystem.create'sorderis. A hash index or a value that isn't an index is a type error, and throws at creation.order, the body'stablesholds exactly one table, even when nothing matches. Itscountis every matching row across archetypes, with has/not applied, and itsbindmakes instanceithe i-th of them in index order.fn name(row: u32), androwis the position in the order.Gpu.wgslemits a different record and anecs_addresshelper for an ordered system. Its output for unordered systems is unchanged byte for byte.Performance (chromium, 50K entities in two archetypes)
An unchanged frame writes nothing to the GPU and allocates nothing. A changed key rebuilds the order list (0.17 ms) and writes its 200 KB (0.07 ms).
Tests
render-order.browser.test.ts, covering:pnpm run buildandpnpm testinpackages/ecspass: 134 files and 1010 tests.🤖 Generated with Claude Code