Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit44fd9e59bd

README.md

yaml.module

YAML decode + encode for authored engine content. Pure Luau, no engine dependencies — a general parsing library, not data-system plumbing.

local Yaml = require("@builtin::modules.yaml")

local doc = Yaml.decode(vfs.read(path))
vfs.write(path, Yaml.encode(doc))

Supported subset

  • Block mappings (key: value) and block sequences (- item), nested to any depth.
  • Compact sequence-of-mapping entries (- path: x / kind: y).
  • Flow collections — { a: 1, b: 2 } and [1, 2, 3] — single line.
  • Plain scalars with type inference: ~ / null → nil, true / false → boolean, numeric literals → number, everything else → string.
  • Single- and double-quoted strings ('' escapes a literal quote inside a single-quoted string; \n \t \r \\ \" inside a double-quoted one). A quote opens a quoted scalar where a scalar begins — after key:, after a - entry marker, or inside a flow collection — so a plain scalar carries an apostrophe as data (note: the world's rules). Quoted keys are read in flow mappings.
  • # comments — honored outside quotes, so a # inside a quoted string is kept as data.
  • Literal (|) and folded (>) block scalars, with a chomping indicator (- strips the final newline, + keeps every trailing blank line, none keeps one newline) and an indentation indicator (1-9: the content's indent past the parent's), in either order (|-, >+, |2, >1-). A block scalar's content is literal text: quotes (balanced or not), #, key: value and --- inside it are data.
  • An optional leading --- document marker.

Loud-error contract

Constructs outside the subset above raise instead of misparsing: anchors/aliases (&, *), tags (!), directives (%), multi-document streams (a second ---), a block-scalar header it cannot read (|x, |-+, |0), tab indentation, and inconsistent indentation (both block structure and block-scalar bodies). Every error carries the offending line number (yaml: line N: ...), so a bad config points straight at the line to fix.

Tab indentation is rejected everywhere — including block-scalar body lines whose leading whitespace contains a tab. A tab after the first non-space character of a line is content and passes through.

API

  • Yaml.decode(text: string): any — decode a YAML document into a Luau value (table, scalar, or nil for an empty document). Raises on malformed input or an unsupported construct.
  • Yaml.decodeWithComments(text: string): (any, boolean) — decode as decode does, and report whether the text carries a comment by the decoder's own rule: a # at a line's start or after whitespace, outside a quoted scalar and outside a block scalar. Re-encoding the value drops such comments, so an editor that writes a document back reads this first.
  • Yaml.encode(value: table): string — encode a Luau table as YAML (block style, two-space indent, alphabetically sorted keys). Raises on values YAML can't represent (functions, userdata, non-string mapping keys).

A top-level empty table encodes to an empty document, which decodes back to nil (the YAML empty-document ambiguity).