Start with the smallest source that shows the behavior. Compile it, perform one
operation, then inspect output, state, and trace together. print appends a
runtime log entry; it does not send data to a service or operating-system output
stream.
Check an action and its rollback
Compile the fixture and invoke its Button action. It increments attempts and
prints that transient value before its out-of-bounds indexed read fails. Inspect
the state and output afterward: the diagnostic is present, while attempts
remains 0 and no transient log survives.
Results
No output.
- Executed source spans appear here.
Compilation checks syntax, names, imports, types, fields, calls, operators, conditions, and returns in every body, including unused ones. Try each prepared error source in the editor: the argument fixture has a wrong call argument, the field fixture supplies an unknown constructor field, and the trait fixture breaks a required method signature.
Wrong argument type
Results
No output.
- Executed source spans appear here.
Unknown field
Results
No output.
- Executed source spans appear here.
Incompatible trait method
Results
No output.
- Executed source spans appear here.
Runtime checks cover values and world state that static checking cannot know,
including list bounds, missing components, non-finite arithmetic, and execution
budgets. Diagnostics carry a code, message, and source span. A span is a
half-open UTF-8 byte range: start is included and end excluded. A JavaScript
editor must convert those offsets before selecting UTF-16 text.
Read state and traces
Output shows accepted log entries. Debug shows diagnostics, globals or a selected entity’s components. Trace records accepted source-linked execution with an optional current entity. Selecting a trace entry opens its source file. It resets for each invocation or tick. Step advances a whole simulation tick; it is not a statement debugger. Breakpoints, step into/out, watches, and arbitrary paused-local inspection are not implemented.
Edit exercise
Change values[1] to values[0], press Run, then Fail:
attempts becomes 1 and the output contains 1. Press Fail again and it
becomes 2. Despite its name, the action now succeeds.
Restore values[1] and compile. Compilation starts a fresh run with attempts
at 0. Press Fail twice: each attempt reports an error and leaves that
accepted state unchanged. A failed action preserves state; recompilation
initializes a new world.
Initialization, actions, ticks, and finish are transactional: a failure rolls
back component edits, globals, logs, entity IDs, and lifecycle membership.
Exact limits and host-configurable budgets belong in the
language reference. For native reproduction, run
cargo nextest run -p konjure-lang and cargo test -p konjure-lang --doc; use
the crate-owned fixture source in a focused test so the browser and Rust exercise
the same program.