Skip to content

Feature Index

Every feature of the Rea language, grouped by what it is for and labelled with how far it has actually come. Use this page to answer one question before you write a line: can I rely on this today?

The same badge appears under the feature's own heading in the specification, so a status is never read from two places.

What the statuses mean

StatusCan I use it?What it means
stableYes — build on itReleased and frozen. Only a new MAJOR version of the language may change it. Everything an ordinary paragraph of prose uses is here.
experimentalYes — with a note in your changelogReleased and usable, and most of the language is at this level today. The syntax may still be refined within 1.x, so an update may ask you to adjust.
developmentNot yetDesigned, agreed and actively being built. The syntax below is what it will be, but the engine does not accept it yet.
draftNoSpecified and discussed so the shape of the idea is on record. No implementation has started and the design may still change completely.
cancelledNeverConsidered and deliberately ruled out. Documented so the decision stays visible rather than being rediscovered and re-argued.

A version badge accompanies the status only where there is something to version: stable and experimental features carry the spec version they became available in. A development or draft feature has no version yet, and a cancelled one never will.

Everything marked stable or experimental works in the current engine. Anything below that does not — if a story uses it, the runtime applies graceful degradation and the reader simply never sees it.

156 features across 16 areas of the language. Select a status below to narrow the list.

Text & prose11/11

The markup an ordinary paragraph already uses. This is the frozen core of the language.

  • Once upon a time…

    The defining property of the language — a paragraph of prose is a complete, renderable story with no syntax at all.

  • blank line · trailing \

    Blank-line paragraphs, single-newline hard breaks and the trailing backslash join are part of the frozen prose core.

  • _italic_ · *bold* · _*both*_

    The only two inline markers in the language; nesting and combination are specified and will not change in 1.x.

  • {underline begin}…{end underline}

    Paired commands rather than inline markers, so rarely-used decoration never competes with prose punctuation.

  • {format color="#00f" begin}…{end format}

    Being built now: a general formatting block for colour, size and weight. The syntax is settled but the parser does not accept it yet, so {format} currently renders as plain text.

  • backtick fence

    Backtick fences with the escalating-delimiter nesting rule, plus inline code, are frozen.

  • Headings stable1.0
    # · ## · ### …

    Valid from the first release and unchanged since; unlimited depth, with the platform rendering as many levels as its theme distinguishes.

  • ## The Forest → #the_forest

    The five-step slug rule is frozen, because changing it would silently break every existing link into a heading.

  • = centre · > right · < left

    Prefix alignment and its repeat-for-indent rule are part of the frozen prose core.

  • Blockquotes stable1.0
    | quote · || nested

    Pipe-prefixed quoting with unlimited nesting, frozen since the first release.

  • - · -- · --- · ---- · -----

    Five semantic weights, heaviest first — the same "more characters means lighter" rule headings use.

Links, anchors & media9/9

Everything written in square brackets: navigation, embedded media, and notes hung off a span of text.

  • Links stable1.0
    [display text > target]

    The unified bracket-and-arrow form is the settled answer for every kind of navigation and will not change in 1.x.

  • Custom anchors stable1.0
    [#anchor_name]

    Marks any spot in the prose as a link target, alongside the anchors headings define implicitly.

  • Story-to-story links experimental1.0
    [text > reast://author/story]

    Resolution depends on the hosting platform, so the scheme is published but not yet frozen.

  • [!alt < src] · [>caption < src] · [?caption < src]

    The three media prefixes and the < source arrow are frozen; what a host does with the file is its own business.

  • Media attributes experimental1.0
    [!alt < src, width=800, loop]

    The comma-separated parameter rule is settled; the set of recognised attributes is still growing.

  • Footnotes stable1.0
    [the term > ^A note about it.]

    Inline notes that travel with the text — no separate definition block to keep in sync.

  • [the tower > *nudge**firmer hint]

    Nine hint levels behind a reader-controlled switch; the asterisk-run level syntax is frozen.

  • Part gates experimental1.0
    [[ story/0005-forest.rea ]]

    The automatic, terminal transition between parts of a multi-part story; released, with the in-part :scene suffix still settling.

  • Cross-part links experimental1.0
    [enter the castle > story/0006-castle.rea]

    A normal link whose target is another part file, letting the reader choose to move on by tapping.

Commands & variables10/10

Curly-brace commands, story state, and the data types a variable can hold.

  • Commands experimental1.0
    {name attr=value} · {name begin}…{end name}

    The always-self-closing-or-paired rule and the begin/{end …} pairing are released; individual commands carry their own status.

  • Print shorthand experimental1.0
    You have {player.gold} gold.

    An expression alone inside braces prints its value; released and widely used, but the surrounding expression grammar may still move.

  • Command attributes experimental1.0
    {voice speed=3, emotion="whisper" begin}

    One comma-separated parameter grammar shared by commands, functions, media and arrays.

  • Variables experimental1.0
    {set story.player.gold = 100}

    Available since the first release and in real use, but still in its testing phase — assignment and the mandatory-domain rule may be refined before they are frozen.

  • Domains experimental1.0
    part. · story. · shared. · context.

    Exactly four mandatory domains — part, story, shared, context — each with its own lifetime; heading-scope no longer exists.

  • Context domain experimental1.0
    context.reader.* context.time.* context.device.* context.group.*

    The read-only platform namespace exists under context.*; how many capabilities it exposes depends on the host and is still growing.

  • Data types experimental1.0
    string · integer · float · boolean · array · regex · undefined

    The type set is released, including the always-double-quoted string rule that keeps bare words unambiguous.

  • Arrays experimental1.0
    ["sword", "map"] · [hp=100, dex=8]

    The one collection type, with positional and named items in a single literal; 0-based indexing is settled.

  • datetime("2026-06-15T10:30") · duration("P1DT2H")

    ISO 8601 constructors including * wildcards for time-of-day patterns.

  • @(lat, lng) · circle(p, m) · area(p1, p2, p3) · path(...) · buffer(shape, m) · distance(a, b) · bearing(a, b) · a + b · a - b

    A point is a literal because a story set in a real place writes a great many of them; everything with an extent is an ordinary call on points, so the shapes compose without syntax of their own. Both arguments of @(lat, lng) are expressions, matches asks whether a point is inside an area, and + / - are union and difference. Latitude comes first, radii are in metres.

Expressions & operators4/4

Computing values: arithmetic, comparison, pattern matching, and type handling.

  • Operators & precedence experimental1.0
    + - * / % = != < > and or ! matches in

    The full precedence table is released; single = for equality is a settled decision, not a placeholder.

  • Ternary conditional experimental1.0
    {gold > 0 ? "hopeful" : "dejected"}

    Inline conditional values at the lowest precedence, so nesting needs explicit parentheses.

  • matches /regex/ · "x" in array

    Keyword operators rather than symbols, each with a !-prefixed negation.

  • number(x) · string(x) · boolean(x) · integer(x)

    Implicit coercion inside expressions plus four explicit conversion functions; the "string + anything = string" rule is settled.

Control flow11/11

Conditionals, loops, and state machines.

  • If / else if / else experimental1.0
    {if cond begin} … {else} … {end if}

    The most used command in the language; released and stable in practice, still formally experimental with the rest of the command layer.

  • Switch / case experimental1.0
    {switch expr begin} {case "x"} … {end switch}

    Multi-way branching with a {default} fallback.

  • For loop experimental1.0
    {for item in list, index begin} … {end for}

    Iterates arrays with an optional 0-based index variable.

  • While loop experimental1.0
    {while cond, n begin} … {end while}

    Condition-driven repetition with an optional iteration counter; the runtime bounds it against runaway loops.

  • {break} · {continue}

    Specified alongside the loops but not implemented — a loop currently runs to its natural end. Authors exit early with a condition instead.

  • State machines development
    {state_machine door, initial="locked" begin}

    The parser accepts states, transitions and guards, and the runtime tracks the current state; persistence and sharing across readers are still being built, so it is not offered to authors yet.

  • Event handlers experimental1.3
    {on acquire card="king" begin}

    One flat form for every event in the language. The subject is one attribute — card=, deck=, set=, zone=, state= — and every matching handler runs, least specific first.

  • Single-file stories experimental1.3
    {define manifest …} · {define file "assets/x.webp" begin}

    Everything a .reast holds, expressed in one text file: its own metadata and its own assets, addressed by the same archive-relative paths.

  • Manifest in a bare .rea experimental1.3
    {define manifest title="…", language="sk"}

    Read only as the file’s first command, so a tool can decide whether a .rea carries metadata by reading one line. Forbidden inside a .reast, where manifest.json is sole.

  • Embedded files experimental1.3
    {define file "assets/x.webp" mime="image/webp" begin}

    The identifier is the path, so [!alt < assets/x.webp] works unchanged in both shapes and converting between them is pure inline / write-out.

  • Waiting for a condition experimental1.1
    {wait escape=…, escape_to=… when EXPR begin} … {end wait}

    The story pauses until the expression turns true. The body is what the reader sees while waiting; escape= gives up after a duration and escape_to= sends them somewhere else. Required whenever the expression reads context.*.

Functions & extensibility5/5

Reusable logic inside a story, portable modules that travel in the package, and host-supplied code.

  • Functions experimental1.0
    {function greet(name) begin} … {end function}

    Definition, calls, default parameters and {return} all work; the four calling-context classifications are released but may gain linting rules.

  • Rea extensions (`.rext`) experimental1.0
    {use "extensions/inventory" as inv}

    Declaration-only modules that travel inside the package and are compiled and validated before any prose runs.

  • {use "std/dice" as dice}

    Resolved from inside the engine rather than the archive or the host, so it works offline on any embedder; std/dice is the first module.

  • Host extensions experimental1.0
    {ns.command args} · {ns.fn()}

    JavaScript the embedder registers per player instance; outside the Rea language proper, and a story must declare the namespaces it needs.

  • Events experimental1.0
    {on story_start begin} … {end on}

    The {on …} block and lifecycle events are released; sensor-driven events depend on features that are still in development or draft.

Choices & branching15/15

How a reader moves through the story, and how the story remembers where they have been.

  • Choices experimental1.0
    * [One-time] · + [Sticky]

    One-time and sticky choices, and the before/label/after text rule, are released and in daily use.

  • Conditional choices experimental1.0
    * {gold >= 50} [Bribe the guard]

    A condition in front of the label decides whether the option is offered at all.

  • Hidden choices experimental1.0
    * hidden [&card_id] …

    An option with no button that fires only through free-text input or a real-world activation; released together with exploration menus.

  • Diverts experimental1.0
    -> the_clearing

    The plain jump to a named anchor.

  • Nested choices & gathers experimental1.0
    * * [Deeper] · - gather

    Weave-style nesting where branches reconverge at a gather point of matching depth.

  • Fallback choices experimental1.0
    * ->

    A textless option taken automatically once nothing else remains eligible.

  • Tunnels experimental1.0
    ->-> examine_lock

    Divert into a section that returns to the caller automatically — the mechanism triggered storylets reuse.

  • First-visit content experimental1.0
    {once begin} … {then} … {end once}

    Primary content on the first encounter, an optional fallback on every later one.

  • Varying text experimental1.0
    {a|b|c} · {&cycle} · {!once} · {~shuffle}

    Sequence, cycle, once and shuffle variants driven by visit count; the shuffle draws from the story’s seeded generator, so a replay is reproducible.

  • {label door begin}locked{end label} · {replace door = "open"}

    Labels are parsed and tracked today, but {replace} does not yet rewrite them in place — the in-place update path through the renderer is what is being built.

  • {cycle color begin}red|blue|green{end cycle}

    The cycle values and the exposed variable work; the tap-to-advance affordance in the reader is still being built.

  • {parallel begin} {thread a begin} … {end parallel}

    Independent threads that converge at a rendezvous point. Discussed for cooperative reading but not built — nothing in the parser recognises {parallel} or {thread} yet.

  • Multi-part stories experimental1.0
    manifest.parts + gates + cross-part links

    Parts load on demand, variables accumulate along the path taken, and the saved path rebuilds the scroll-back on resume.

  • {undo enabled=false}

    The runtime keeps a choice-level undo stack, but the {undo} command that lets an author disable it for a puzzle section is specified only — the cooperative rules around it are unresolved.

  • {checkpoint name="before_boss"} · {restore name=…}

    Automatic progress saving works today. Author-declared checkpoints, {restore} and {save enabled=false} are specified but unbuilt, and the cooperative "all readers must agree" rule needs a design pass first.

Cards, decks & exploration9/9

Cards and decks: non-linear, quality-based narrative the story deals out instead of routing to.

  • Cards experimental1.0
    {define card king deck="roles" when … begin} … {end card}

    A card is a face plus a body. Priority, weight, cooldown, tags and the when clause drive selection; deck= is what puts it in a deck, and a card with no deck is what used to be called a storylet.

  • Card face experimental1.4
    {face vertical="60%" begin} **1 gold** {end face}

    What is printed on the card, as against the body, which is what plays. A block rather than an attribute, so it carries bold, italic, links and hints; vertical= places it as a percentage of the card height and horizontal= as a percentage of its width, which turns a band of text into a label on a point of the picture. Three coins that look alike and are worth 1, 2 and 5 differ only here.

  • Card layers experimental1.6
    {layer image="assets/shield.webp", vertical="20%", horizontal="80%", width="18%"}

    A picture stacked over the card's art. Several layers and the face text are one card: they turn, scale and animate together. Positions are percentages of the card, so an overlay lands on the same spot in a thumbnail and full-screen; how solid a layer is belongs to the picture, and a when clause is what turns an overlay on — the shield appears when the reader has one.

  • Card detail experimental1.4
    {detail begin} … {end detail}

    What the reader finds on the back of the card: the author's own prose about it, as long as it needs to be. Not the one-line description a list shows — this is where a reader reads about the Knight without leaving the story. Ordinary content, and never part of the body, so turning a card over never plays it.

  • Decks experimental1.3
    {define deck roles play="consumed", face="down"}

    A named pool of cards with the defaults its cards and its draw sites inherit: scope, return policy, how many are dealt and whether the reader sees the faces.

  • Drawing and playing experimental1.3
    {draw deck="basic"} · {play deck="basic", deal=3 begin}

    {draw} takes a card into the Bag, {play} activates one now, {return card=…} puts one back. Both take a block form carrying a prompt and an {empty} fallback.

  • Triggered storylets experimental1.0
    trigger=scan · match="^REAST-.*"

    A storylet the world deals instead of a deck; it plays as a side path and returns exactly where the reader left off. Which trigger kinds actually fire depends on the reader app and on features still in development.

  • {triggers off} … {triggers on}

    One fence for every interruption: while it is closed a real-world trigger wakes nothing and a card played from the Bag is refused. It travels with a save.

  • Exploration menus experimental1.0
    {menu select=2 begin} … {end menu}

    A choice group that waits for several discoveries instead of one pick; the select=all policy and the menu-beats-storylet priority rule are released.

Cards, inventory & dialogue10/10

Characters, items, actions, custom card sets, the coin wallet, and speaker attribution.

  • Character cards experimental1.0
    [@elena] · {define character elena name="Elena Voss"}

    Tappable character references backed by a definition block with portrait, title and description.

  • Item cards & inventory experimental1.0
    [$golden_key] · {give …} · {take …}

    Items, the reader’s pocket, and the {on acquire item=…} / {on lose item=…} handlers.

  • Action cards experimental1.0
    [&open_the_gate]

    Branch points with visual emphasis, whose description: doubles as the semantic target for free-text input.

  • scan= · mark= · listen=

    The card fields parse and match, but the capture side depends on the reader app: scanning and speech are being built, and mark: signatures need the editor’s drawing tool, which is not shipped yet.

  • Custom card sets experimental1.0
    {define cardset ability name="Ability Cards"}

    Author-declared card categories with shared acquire/lose/use rules and set-level hooks a card may override.

  • Playing a card experimental1.0
    {play ginko}

    Runs every {on use} handler that matches the card, its set’s before its own, and emits a card-played event hosts can observe.

  • {define card_type location, prefix="📍"}

    New bracket prefixes beyond @, $ and &. Specified as a future extension point; custom card *sets* cover most of the need today, so no implementation has started.

  • Typed card properties experimental1.5
    weight=3 · home=@(48.14, 17.10) · story.card.lantern.weight

    An unquoted card attribute that is a complete Rea literal carries a real number, boolean, point or array, read back as story.card.<id>.<prop>. Quoting keeps a value as display text, so the two readings never overlap. The mirror is read-only and holds typed properties only.

  • Coins & wallet experimental1.0
    {earn gold 2} · {spend bronze 3}

    A three-tier wallet with fixed internal names so saves stay portable, and author-renamable labels and ratios.

  • Dialogue attribution experimental1.0
    @elena: "Follow me."

    Links a line of speech to a character card, which is also what lets voice assignment happen automatically.

Input & interaction7/7

Getting something back from the reader: typed answers, buttons, timers, and voice output.

  • Text & numeric input experimental1.0
    {input name=guess, type="number", min=1, max=100}

    Execution pauses until the reader submits; numeric input clamps to its bounds.

  • Free-text action input experimental1.0
    {input type="action", placeholder="What do you do?"}

    The reader types what they want to do and the best-matching option fires, matched entirely on-device so the sentence never leaves it.

  • Text-to-speech development
    {voice speaker="elena", emotion="whisper" begin}

    The command parses and reaches the host as a request, but speech synthesis itself is supplied by the reader app, which is still being built — nothing is spoken today.

  • {audio src=…, loop} · {stop ambient_music}

    Named, controllable background audio. Embedded audio via [?caption < src] works today; the command form that starts and stops a named track is specified only.

  • Buttons draft
    {button label="Continue", target=next_chapter}

    A navigation affordance separate from a choice. Specified, but unbuilt — choices and links cover the same ground, so it has stayed at the bottom of the list.

  • Timers development
    {timer duration=30, on_expire="-> times_up" begin}

    The runtime starts, stops and expires timers; the reader-facing countdown and the accessibility affordances that must accompany a timed choice are still being built.

  • {verbs begin} · {target chest begin}

    Dragging an action word onto a highlighted noun. A well-liked idea from Texture, specified in full but not started; it needs a drag alternative for keyboard and screen-reader users before it can be built.

Cooperative reading9/9

Several readers in one story: roles, shared state, group decisions, and solo degradation.

  • Reader roles development
    {define role captain max=1}

    Roles and role-gated content parse and evaluate; assignment and reassignment need the group session service, which is being built.

  • Shared state development
    {set shared.torch_lit = true}

    The shared. scope is recognised and the sync layer exists in the engine, but propagation between readers needs the platform’s realtime channel, which is not live yet.

  • Group voting development
    {vote timeout=60 begin} … {end vote}

    Parsed, with the solo degradation path already working; tallying across real readers waits on the same realtime channel.

  • {whisper to="captain" begin} · {broadcast begin}

    Role-targeted and group-wide messages; both parse and both degrade to normal text solo, with delivery pending the group session service.

  • {wait readers=all begin} … {end wait}

    Blocks until the other readers arrive, or passes instantly solo; the multi-reader half is not live.

  • {synchronize out} · {synchronize auto="on", interval=5}

    Manual push/pull control over shared state for turn-based stories. Specified, but it only becomes meaningful once automatic sync exists, so nothing is built.

  • {exclusive action="open_chest" begin} · {race timeout=10 begin}

    First-reader-wins primitives with defined disconnection behaviour. Specified in detail; implementation waits on the shared-state layer they depend on.

  • {presence show="cursor" begin} · {react options=[…] begin}

    Seeing where other readers are and reacting with emoji. Specified as a later addition to cooperative reading; nothing built.

  • Solo degradation experimental1.0
    automatic

    Every cooperative construct has a defined single-reader behaviour, so a cooperative story is always playable alone — this part works today even where the multi-reader half does not.

Real-world interaction20/20

Sensors and physical context: location, codes, tags, motion, light, and weather.

  • Context sources experimental1.1
    context.time · context.location · context.weather · context.ext.<ns>

    Each context. subtree is a source with a cadence of its own: time is derived and answers exactly when it next changes, location is a push stream, weather is a shared rate-limited poll. A source starts when the first condition waits on it and stops when the last one leaves.

  • Capability requirements experimental1.0
    {require gps} · {require nfc optional} · world.has("nfc")

    Declaring what a story needs, and checking at runtime what it actually got, so every sensor path has a written fallback.

  • Location experimental
    context.location matches circle(@(lat, lng), metres)

    Testing the reader’s position against an area in an ordinary expression. The host’s position reading is coerced to a point, so matches takes it directly against a circle, a polygon or a buffered path.

  • Waypoints experimental1.1
    {waypoint old_bridge, circle(@(48.14, 17.10), 50) begin}

    Geocaching-style named places gated on arrival. A waypoint is a {wait} plus a place on the map: hint= is its waiting text, its body is arrival content, and the same scheduler decides both.

  • Map images & pins development
    {map id bounds="…" begin} … {pin id at=… begin} … {end map}

    An author-supplied image anchored to real GPS bounds by two point literals, with each pin positioned by an at: point expression. Parsed into structured nodes; the projection renderer in the reader is the remaining piece.

  • Multi-stage routes experimental1.1
    {route treasure_hunt, waypoints="a, b", sequential begin}

    A trail through waypoints declared elsewhere. Its progress is derived from those waypoints rather than tracked separately, and its complete: line renders where the block stands, once every stage is done.

  • Geo-fencing zones experimental1.1
    {zone dark_forest, area(…)} · {on enter zone="dark_forest" begin}

    The whenever form of a wait: the same area expression, decided on every edge. The block renders the content of the edge the reader last crossed, and an edge’s commands run as it fires.

  • Time & date context experimental1.0
    world.hour · world.weekday · world.season

    The one real-world input that needs no permission and no sensor, so it is the safest to build a story on.

  • Weather draft
    world.weather · world.temperature

    Specified down to the permission tier (approximate, IP-based location — never GPS), but no weather provider is wired up, so the values are never populated.

  • {scan type="qr", pattern="^REAST-.*" begin}

    The blocking form that stops the story until a code arrives. Specified; the non-blocking paths — a scan: card field or trigger: scan — are the ones being built instead, because a blocking scan strands a reader who cannot find the code.

  • NFC tags development
    {nfc target="reast:chapter5" begin} · {nfc read, name=tag begin}

    The command reaches the host as a capability request; the reader app half, and the QR fallback for devices without NFC, are being built.

  • {capture type="photo", name=reader_photo begin}

    Specified with a per-use permission tier and preview requirement. Not started — the privacy review has to come before the code.

  • {on shake, intensity=2 begin} · world.tilt.x

    Shake, tilt and compass events. Specified with browser-support fallbacks; no implementation yet.

  • world.light

    Reading room brightness in lux for darkness-gated scenes. Specified, but browser support is thin enough that the time-of-day fallback may end up being the whole feature.

  • {vibrate 200} · {vibrate pattern=[100, 50, 100]}

    The command parses and emits a host request; the reader app must honour it, and its visual-pulse fallback for devices without a motor is still being built.

  • Proximity draft
    {on proximity "near" begin}

    Holding the device close to an object. Specified; not started.

  • Voice input development
    {listen language="en", name=spoken_word begin}

    The command reaches the host as a request for a transcript. Recognition runs on the reader’s device and is never stored or transmitted — that reader app is what is being built.

  • dice("2d6+3") · d20adv · 4d6kh3

    The compact tabletop notation is specified but the dice() built-in is unimplemented. Use {use "std/dice"} instead, which is released and covers the common rolls.

  • {challenge night_vigil begin} require: … timeout: 30m

    Several sensor conditions combined into one gated moment. Specified as the capstone of real-world interaction; it cannot start before the sensors it combines do.

  • Sensor permission tiers experimental1.0
    none · low · medium · high

    The four-tier model, ephemeral-by-default rule and "authors never see raw coordinates" guarantee are binding on every sensor feature above, whatever its own status.

Localization & formatting6/6

Grammatically correct text and locale-aware numbers and dates, driven by CLDR.

  • Pluralization experimental1.0
    {plural(n, one="{} coin", other="{} coins")}

    CLDR categories resolved through Intl.PluralRules for the host locale, so no per-language table is baked into the engine.

  • Text selection experimental1.0
    {select(pronoun, he="his", she="her", other="their")}

    Key-based text variation for gender, role or any other categorical value.

  • Number formatting experimental1.0
    {formatNumber(value, "sk", style="currency")}

    Delegates to Intl.NumberFormat, falling back to the plain string form on any error.

  • Ordinal numbers experimental1.0
    {ordinal(3)} · {ordinal(n, one="{}.")}

    English suffixes only for en* locales; every other locale gets the formatted number, because Intl carries no ordinal spell-out data and inventing suffixes would be wrong.

  • Date & time functions experimental1.0
    {formatDate(value, "long")} · {dateDiff(a, b, "d")}

    Host-supplied clock, locale and time zone, with formatting through Intl.DateTimeFormat; the style enum is the whole surface, with no author-facing token strings.

  • Fantasy calendars development
    {calendar(world.date, month="Frost,Bloom,…")}

    Mapping real date components onto invented month and weekday names. The signature is settled and the surrounding locale built-ins already ship; calendar() itself is the one still being written.

Authoring & diagnostics9/9

Comments, escaping, error behaviour, and the tools an author uses while writing.

  • Comments stable1.0
    {comment …} · {comment begin} … {end comment}

    One syntax, single-line and paired. Only the exact {comment begin} opens a block, so begin inside a comment is just a word — which is what the retired {// …} form needed a special lexer mode for.

  • \{not a command\} · {raw begin} … {end raw}

    The backslash escape and the raw block are frozen — without them a story could never quote its own syntax.

  • automatic

    A reader never sees an error: an unknown command is skipped whole, missing media falls back, an unclosed block auto-closes. The author hears about every one of them on a separate channel of coded records. This is a language guarantee, not a runtime detail, so it is frozen.

  • TODO markers stable1.0
    {todo …} · {todo begin} … {end todo}

    A comment that reports itself: hidden from the reader like {comment}, and raised as style/todo on the author channel, so reast validate and the editor list every one.

  • [!map < media/map.png, fallback="media/low.png"]

    A second source tried before the platform’s own placeholder. Specified; the attribute is currently parsed and ignored.

  • Captions draft
    {caption "A hand-drawn map"}

    Descriptive captions attached to the preceding block. Specified and needed for accessibility conformance, but not built — alt text carries the load today.

  • {lock type="soft", key=… begin}

    Soft, hard and conditional locks, with the AES-GCM and PBKDF2 model fully specified. Nothing is implemented; a hard lock in particular needs the server side that does not exist yet.

  • External API access experimental1.0
    manifest `allowed_urls`, referenced by alias

    URLs live in the manifest and never in .rea text, so every external call is declared and auditable; the alias call surface is still settling.

  • random() · shuffle() · std/dice

    Every draw comes from a generator the runtime owns and the save file carries, so restoring a save continues the identical sequence. The seed(n) testing function is not implemented — pin the seed through the host engine option instead.

Packaging & distribution15/15

File types, the archive layout, the manifest, and how a package reaches a reader.

  • UTF-8 plain text, no metadata

    A story file is pure text and carries no metadata at all — that separation is what keeps a .rea readable in any editor, and it is frozen.

  • `.rext` extension module experimental1.0
    declaration-only Rea

    Functions, top-level constants, {use} and comments only — any prose node anywhere in the file is a load error.

  • `.reast` package experimental1.0
    ZIP: manifest.json + story/ + assets/

    Both layouts — packaged (with a manifest) and flat (a single entry file, no metadata) — load today.

  • `manifest.json` experimental1.0
    one canonical shape, no short forms

    Carries every piece of metadata a .rea file deliberately does not; unknown fields are preserved and ignored, so the schema can grow without breaking readers.

  • preset variables for one session

    Per-session configuration (player count, difficulty, scenario variant) injected into the story’s variable space. The file format is settled; the platform side that reads it is being built.

  • GitHub repository import experimental1.0
    https://github.com/owner/repo

    An unzipped package in a public repository loads like a .reast file, making Git tags and branches a natural versioning mechanism.

  • manifest `integrity` · Ed25519 signature

    Per-file SHA-256 verification is implemented; the Ed25519 author-signature chain and its key distribution are still being built.

  • manifest `loading`, `preload`, `locked`

    Downloading a long story part by part. Specified; today every part of a package arrives with the archive.

  • per-file hashes from manifest `integrity`

    Re-downloading only the files that changed. The hashes it would use already exist for tamper detection; the update path itself is unbuilt.

  • manifest `build` + META-REA/names.json

    A lossless source transformation for distribution. Specified, including the name map that keeps it debuggable; no build tool implements it yet.

  • Reader tab bar development
    manifest `reader.tabBar`

    An opt-in bottom bar with up to five sections ordered by thumb distance. The manifest shape is settled; the reader UI is being built.

  • Core · Standard · Platform

    Three declared levels so an implementer can ship a partial engine honestly; frozen, because the whole point is that the label means the same thing everywhere.

  • manifest `rea: "1.0"`

    MAJOR.MINOR versioning with the forward-compatibility rules a parser must honour. Frozen with the 1.0 release.

  • domain.name, any Unicode except space and dot

    Frozen so that a non-English author can name state in their own alphabet and be certain it keeps working.

  • Accessibility experimental1.0
    WCAG 2.2 Level AA

    The author-facing obligations (alt text, meaningful choice text) are in force now; several platform-side criteria depend on features that are still in development.

Deliberately not in Rea6/6

Constructs that were considered and ruled out. Listed so the decision stays visible instead of being rediscovered.

  • — none —

    Ruled out during the 1.0 design: interactive stories do not use list formatting, and * and - are already the choice and gather markers. Choices fill the role naturally.

  • Table markup cancelled
    — none —

    Ruled out for 1.0: a data table is not a storytelling construct, and adding one would drag column alignment and cell spanning into a prose language.

  • — none —

    Permanently excluded. Raw markup injection would make every story an XSS surface and would let one author’s markup break another host’s rendering.

  • CSS styling cancelled
    — none —

    Permanently excluded. Visual presentation belongs to the platform theme so that reader preferences — contrast, font size, dark mode — can never be overridden by a story.

  • — none —

    Permanently excluded. A story is untrusted content; embedding JavaScript or any other language would destroy the sandbox. Sandboxed .rext extensions and host-supplied extensions cover the real need.

  • try / catch cancelled
    — none —

    Ruled out with the error model: all recovery is implicit, because a reader must never be shown a failure and an author should never have to write one.

Reading the index

  • Click a status in the legend to narrow the list; click it again, or "show all", to clear.
  • A group title links to the part of the specification that documents it in full.
  • A feature name links to its own section, where the same badge appears with the same wording. The cancelled entries are the exception: they have no syntax to document, so they live together under What Rea intentionally omits.

If a feature you need is draft or development, the specification section still describes it completely — that is what makes it possible to design a story around its eventual arrival. Just do not ship against it.