Skip to content

SDK: add literal containers and variable-key lookups - #235

Open
robknight wants to merge 10 commits into
mainfrom
sdk-container-literals
Open

SDK: add literal containers and variable-key lookups#235
robknight wants to merge 10 commits into
mainfrom
sdk-container-literals

Conversation

@robknight

Copy link
Copy Markdown
Collaborator

This adds first-class container literals and variable-key lookups to the SDK, making it practical to represent lookup tables directly in Rhai scripts.

Rhai arrays and maps now convert recursively to pod2 Arrays and Dictionaries, while the new free-standing set_of function constructs Sets. Scripts can query these containers with array_get, dict_get, or obj.get, including when the key is a variable.

Key changes

  • Add recursive Array, Dictionary, and Set literal conversion.
  • Add variable-key lookups backed by containment statements.
  • Allow SDK-generated variables to be used inline.
  • Allow var to name literals without creating wildcards.
  • Snapshot statement and write arguments before later object mutations.
  • Validate container kinds, lookup key types, and literal lookups during Load where possible.
  • Report invalid field access as script errors instead of panicking.
  • Render container literals deterministically, with commitment fallbacks for sparse arrays.
  • Update the SDK documentation and regression coverage.
  • Add the nanoverse example plugin to demonstrate lookup tables, witness arithmetic, state-header access, subactions, and related SDK features.

These changes let authenticated object data select rows from literal tables without requiring a separate action for every row. Player-selected choices can remain separate actions, while data-selected behavior can be expressed compactly through constrained lookups.

Convert Rhai arrays and object maps recursively into pod2 Array and
Dictionary values, and add set_of for constructing Sets. Reject
variables inside container literals because their values are
unavailable during Load.

Render supported containers as Podlang literals, falling back to
commitments when no literal representation exists.

Add dict_get and array_get to bind entries with containment
statements. Keys may be variables, allowing a literal container to
serve as a lookup table and its returned dictionary fields to be
read directly.
Register variables returned by SDK methods as soon as they are
created, so callers can use them inline without first binding them
with var. Rename generated variables in place when a script assigns
a name, preserving wildcard order.

Treat var bindings of literal values like ordinary Rhai bindings
instead of creating wildcards. Route ArgHandle.get through dict_get
and report invalid literal field access as a script error rather
than panicking.
Statement and Intro instructions retained mutable references to
their arguments, so later object updates changed the values used
during replay.

Capture OperationArg values when each instruction is recorded
and replay those snapshots during proof construction. This keeps
containment statements and their bound values aligned with the
pre-update object state.
Check known container kinds and array index types during Load,
and resolve fully literal lookups immediately. This prevents kind
mismatches and missing rows from producing invalid predicates.

Validate field access whenever the value is available and return
script errors instead of panicking. Also promote Rhai booleans to
pod2 integer values in container literals.
Container kind metadata may identify the same raw value as multiple
container kinds. Render a literal only when its kind is unambiguous;
otherwise render its commitment.

This prevents nested container text from claiming the wrong kind
while preserving the raw value used by the verifier.
Reuse shared helpers for Rhai array conversion and Ref extraction
instead of repeating dynamic-value promotion paths.

Update the SDK documentation and tests to cover variable container
lookups, named literals, boolean elements, and ambiguous container
rendering.
Set and Update instructions retained mutable references to written
values, allowing later object mutations to change the values replayed
during proof construction. Capture OperationArg values when each
write is recorded.

Reuse the shared literal-entry resolver and remove redundant work
from literal container lookups.
set_of constructs a value and does not access action state. Register
it as a free Rhai function and return the pod2 Set directly, allowing
helper functions to build Set-containing tables without receiving
action.

Register the Set type name for clearer Rhai errors and keep invalid
field access on Set values as a script error.
Add string validation for dictionary keys while retaining integer
validation for array indexes. Represent lookup kinds explicitly so
Load reports container and key errors before generating predicates.

For raw values accepted as multiple container kinds, render the
first supported form in deterministic order: set, dictionary, then
array. Continue using commitments for sparse arrays.

Refresh the SDK documentation and tests to match these rules.
Add a compact plugin demonstrating literal containers, variable-key
lookups, native statements, witness arithmetic, state-header access,
subactions, and object field reads.

Document how authenticated data can select table rows while
player-selected choices remain separate actions. Include the generated
Podlang and current planner limitations.
@robknight
robknight requested a review from dhvanipa August 26, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant