Skip to content

1.8.0

Choose a tag to compare

@Emulator000 Emulator000 released this 02 Oct 23:38
· 19 commits to main since this release
1af559d

A system can be handed something, which is the half of an entity's world a script could not reach. A consumer reported it: an opaque handle — a route, a behaviour tree, an input map — enters a script only as a capability parameter, so a fn can take one and a system can take nothing at all. What that cost was the loop. The host kept a route per agent and called a plain function once per agent per step, so the rule stayed in the script and hot-reloadable while the walk over entities moved out — out of the schedule, out of the declared-access checks, and out of step with the query it replaced, by hand.

system Walk {
    uses graph: NavGraph
    writes Placement

    update {
        for e in query<Placement>() {
            let path = navigation.pathOf(graph, e)
            e.Placement.speed = navigation.remaining(path)
        }
    }
}
  • uses name: Type in a system's head, beside reads, writes and after. The type is one a host registered, resolved exactly as a parameter's is, so an unknown name refuses in the same words rather than one path quietly succeeding. The binding is immutable: the host owns the value and a script passes it back rather than looking inside it.
  • A resource is one per type, and the type is what a host is asked for — so two systems naming the same type differently are handed one object, and a script renaming its own binding changes nothing outside its file. Two clauses of one type in one system are refused as what they are: two names for one thing.
  • A system with no uses generates exactly the function it always did. The second parameter appears only where something reads it, so a host may pass it to every system unconditionally and no shipped module gains a byte.
  • The metadata says what to supply. Each system carries its resources by name and type, always present and empty where there are none — the rule the four entity lists already follow, so a host reads a field rather than testing for one.

The other shape this could have taken is refused, and the reason is recorded beside the declaration. A component field holding a handle was the first thing the report asked for, and a component is what a save file holds: its schema carries stable field ids, a prefab gives every field a constant, and a scene load rewrites its entity columns. A host's object satisfies none of the three, so that field would be the one part of a component that silently does not persist.

A handle per entity comes from a capability, which may already return a host type — the host keeps the table, the script keeps the rule.

uses is a soft keyword, so data Stats { uses: i32 } and fn count(uses: i32) go on parsing.

The editor client has to be re-cut for this one. A 1.7.0-era bundled server meets uses and answers DS0133 against the whole system declaration, which is a valid document going red — the first of the two cases in docs/RELEASING.md, and it was measured rather than assumed.