Add the dialog role and the interaction affordances the free-interaction
layer depends on: Setup.interactions, Package.dialogs, and the Interaction,
DialogAction, and Dialog types. Wire the dialog role through the zod
schemas, package collection (with duplicate checking), and vite
serialization, and update the tabletop serializedToPackage and test
fixtures to carry dialogs.
Group the bgm spec cluster under docs/bgm and move dev logs and plans under docs/status, add an overview index, and update cross-references in the docs, README, and source comments.
A definition is identified by role.type and named role.type.lang
(package.lang for packages). Code blocks declare it via role= on the
info string; real files by their filename. Blocks and files without a
matching role.type are ignored. file= still overrides the auto-name.
Relative asset and $variants paths now resolve against the markdown
file's directory (baseDir) rather than the virtual name. Same role.type
with different ids groups under one name; duplicate type#id still
errors. Migrate fixtures and example games to role=.
Parse role.type#id from the fence info string and merge it into each
parsed object, erroring on conflicts with the content. id on the info
string can't combine with $variants. Auto-named blocks now hash their
content instead of the info string, so identical blocks dedupe.
Expand $variants to accept an array of csv paths, concatenating their
rows. Detect a path by a .csv suffix on the first line instead of a
newline, so inline csv and paths are self-documenting and the rule
applies uniformly to single values and array elements.
Replace the face/back boolean with a three-state facing (face, back,
standing) seeded from setup placements. Parts now orient about the
anchor at the resting face/edge, so back-down parts sit on the table
instead of below it and standing parts rest on their bottom edge.
Replace the path->parts setup map with an ordered list of placements, each moving its parts to a path. Entries apply in order, so a part listed in a later placement ends up on that placement's path.
The default include is now resolved relative to the package
declaration's directory, so the explicit root-relative patterns are
redundant. Drop them in favor of the default.
The default include matched every yaml across the games root, so a
package could absorb a sibling game's defs (e.g. two game#main setups).
Resolve patterns against the package declaration's directory instead;
a leading slash marks a pattern as root-relative.
Candidates now carry their own stacking strategy, inheriting the route's
when absent, so the default tilt applies consistently. Drop the now
redundant explicit tilt from the poker deck.
Normalize the games root to POSIX separators so the HMR path guard
matches on Windows, and watch the real on-disk markdown files (which
defMap.files omits in favor of their virtual code blocks) so edits
trigger a re-collect instead of a manual restart.
Replace the per-part lift with a local Y-axis tilt that fans the stack,
and add zStart/zEnd to ramp the stack's height across the curve so it
arches in 3D. Update the poker deck and docs accordingly.
Vite 8 (rolldown) changed buildStart to take (this, options), so the
test's one-arg call failed typecheck. Add an ambient declaration for the
fixture's virtual bgm modules so its entry typechecks in the editor.
Add a SerializedPackage type for the JSON the plugin emits, and tests
that assert the maps serialize to plain objects, that the packages module
returns every package, and that buildStart watches def files. Add a
second fixture package to exercise multi-package collection.
Rename the plugin's virtual modules to virtual:bgm/packages and
virtual:bgm/package/<id> so they read as plugin-provided modules rather
than real packages. Update the unit and build integration tests.
Move the bgm vite plugin into the package so it can be tested in
isolation from the web app. Serve each package as a JSON module,
serializing its maps, and verify resolution through a real vite build
against a self-contained fixture.
Parse yaml/json/toml and markdown code blocks into packages, expanding
$variants via typed-csv and collecting parts, surfaces, and setups by
include patterns. Ships zod validation, a vitest config, and 16 tests.