Your first expansion pack

A walk through the workbench from nothing to a shared .lxpack: a small harbour map with a character who talks, a quest, a monster and a boss, a trading card, the checks, a play test and the export. It takes a disc image and a browser; nothing is installed. The screenshots show only the workbench's own forms and the painter's colours - names and textures from the disc stay in your tab.

1. Start from the template

The workbench's New pack box: pack id harbor_tales, name Harbor Tales, and Start from set to the minimal template, with Create and Cancel buttons
New pack ...: an id, a name, and what to start from.

Pick your disc, then New pack .... Give the pack an id (harbor_tales) and a name, and start from the minimal template: one of everything a first pack wires together - a monster made from a retail one, a fight of it, a line of dialogue, a quest to win the fight, and a small sample map with some ground, a few objects and two trigger zones that show the line and start the fight.

The new pack open: the pack bar with Undo, Redo, Download .lxpack, Play in browser and Play here; the section tabs with the Manifest tab open and its format-reference link; the checks panel listing three warnings
The pack bar, one tab per file, and the checks on the right. Each tab opens with a ? to the format reference for the file it edits.

The checks list the pack's three warnings (no description, authors or licence); the Manifest tab fixes them.

2. Place objects, paint the map and add a character

A map opens in Place objects, with the 3D view as the working surface and a palette of objects along the bottom: pictures of what is on your disc, by category, with a search box. Click a picture, and a ghost of the object follows the pointer; click the ground to put it down, R turns it, Esc or a right click stops. Click an object already placed to move, turn, copy or delete it. + New map starts from a small sample you can test-play at once; Fullscreen (F11) gives the builder the whole screen.

The tile painter: a tool bar (paint, fill, pick, select, spawn, exit, trigger, encounters, prop, NPC, sculpt) above an 11 by 6 grid of green floor tiles inside a dark wall ring, two wall pillars, the spawn as a green circle, two orange trigger zones and a purple NPC square
The painter: floor tiles in the legend's colours, walls dark, the spawn green, trigger zones orange, the NPC purple.

Map settings opens the tile painter and the map's forms in a drawer beside the view. Open its Map settings box and pick a base scene: the map borrows its textures, meshes and characters, and the floor stays yours. Paint with the legend's characters (# wall, . floor), then pick the NPC tool and click a tile. The NPC's form picks its model from the base scene's characters, its line (welcome) and its id (harbor_master, the key a quest's talk objective names).

The Dialog tab: the line welcome with its speaker and text, and under it the row check showing each text-box row as the game draws it
The Dialog tab: a line and its row check. No retail text box wraps, so a row past 36 characters is flagged.

3. Write a quest

The Quests tab holds the template's quest: an objective (win first_fight), a reward (100 gold) and whether it starts by itself. Add a talk objective on harbor_master and the quest asks the player to speak to your NPC first.

The Quests tab: the quest list beside the selected quest's form - title, description, start and complete hooks, prerequisites, an objective to defeat first_fight, and a 100 gold reward
Every picker offers only the ids the pack defines.

4. Make a monster and a boss

On the Battle tab a monster is a retail one with new numbers: each stat is the base's, a value, or a multiplier, with the retail number beside it, read from your disc. + Boss turns a formation into a once-only boss fight with its own music, an intro and outro cutscene and rewards; Boss script on its monster gives it phases. Fight in 3D starts the fight in the preview.

The Bosses section of the Battle tab: a boss over first_fight with its music, intro and outro cutscene pickers, reward gold, no escape and once only, and a Fight in 3D button
A boss: its formation, music, intro and outro cutscenes and rewards.

5. Add a card

The Cards tab: sell prices per rarity, a new card with its name, rarity, element, art and four sides, and the Boosters, Drops, Starter deck and Dealers sections
+ Card: four sides, an element, a rarity and a retail monster as its art.

Boosters, drop rules and a dealer make the card collectable; Card faces in 3D shows them as the engine draws them.

6. Read the checks

The checks panel after the fight was renamed: errors under quests.toml and the map file naming a formation that is not there, beside the three manifest warnings
Renaming the fight breaks the quest's objective and the map's trigger.
The quest's objective opened by clicking the error: kind defeat_formation, its formation shown as first_fight (not defined), the box outlined
Clicking the check opens the Quests tab on the objective it names; its formation reads not defined.

Every edit re-runs the validator with your disc resolving each coordinate. A check names its file and field; clicking it opens the tab, selects the item and focuses the field, and F8 steps through them. A pack with an error does not export.

7. Play it

Play this map opens the play page on the map the Maps tab is on; while that tab is open, the next Play this map (or Live, every edit) reloads the pack in place with the player where they stand. The 3D view draws the map the way the engine builds it, with walls, zones and NPCs as see-through volumes under View, and Fullscreen (F11) takes it edge to edge. Both draw your disc's textures, so they are not pictured here.

8. Export and share

The pack bar after a download: Harbor Tales, version 0.1.0, autosaved, with Download .lxpack, TOML files, Share, Play in browser and Play here
The pack bar: download, the TOML files, Share, and the two ways to play.

Save .lxpack (Ctrl+S) writes the bundle - this one is under 2 KB, because it holds no game data. Anyone with their own disc opens it on the play page (Load expansion) or in the native port with --expansion. Share sets a cover, compares against an older .lxpack for a changelog and a version bump, downloads the editable sources as a zip, and adds the pack to the play page's library. The Files tab gives each TOML file on its own, for a pack kept as a folder.

The Files tab listing the exported battle.toml, cards.toml, dialog.toml, maps/first_map.toml, pack.toml and quests.toml with their sizes, the map file open on its TOML: its name, floor heights and base scene town01
What the bundle holds: TOML that names disc content by number.

On the workbench

  1. Pick your discThe workbench reads its monsters, items, scenes and music for the pickers. Nothing is uploaded, and no name from the disc is written into the pack: a picker writes the coordinate ({ kind = "monster", id = 109 }), never the name beside it.
  2. Start from somethingLoad the sample pack (the project's example pack, written to learn from), a .lxpack, a pack folder of your own, or start a new pack: empty, from the minimal template, or as a clone of the sample pack.
  3. Edit section by sectionOne tab per file. The checks panel re-runs the validator after every edit with your disc resolving every coordinate; clicking an issue opens its tab and focuses the field. Undo and redo cover the whole pack, Find lists every place an id or a retail coordinate is used, Rename changes an id with every reference to it (previewed, one undo step), and the Flow tab draws the pack's progression as a graph with what the player cannot reach, flags read and never set, and rewards nothing grants marked on it.
  4. Lay out a mapIn Build, a map opens in Place objects with a palette of real objects off your disc along the bottom. Map settings opens the tile painter: paint tiles from the legend, place spawns, exits, trigger and encounter zones, props and NPCs, and turn on Heights to see which cells the floor slopes across. The Detail layer under the painter dresses the floor - decorations, scatter brushes, edge runs, decals, animated materials, lights, fog and particles - each a list form whose tile fields pick on the canvas. For an outdoor map, open the Terrain box and sculpt with the Sculpt tool (K): hills, ridges, levelled pads, a shoreline under water (terrain).
  5. See it in 3DA map opens in the 3D view, which draws it the way the engine builds it - props, decorations, lights, fog and all - with the tile grid at its corner heights (ramps tinted) and walls, zones, triggers, spawns and NPCs as see-through volumes you can toggle. Map settings puts the painter and the forms in a drawer beside it, and Fullscreen takes it edge to edge. It rebuilds a moment after each edit, and the volumes follow an edit at once while it does; a click in 3D selects the tile in the painter, and Walk from selection drops you onto it with the game's camera. Switch the Edit bar to Select to move, turn and scale props, NPCs, spawns, lamps, emitters and zones with gizmos right in the picture (snapped to the tile or a 32-unit grid, Shift for free), to Sculpt to brush the terrain, or to Paint to lay ground materials - every edit lands in the painter and in undo. A cutscene's timeline draws its camera path there, scrubbed frame by frame.
  6. Try itPlay this map opens the play page on the map you are editing; while that tab is open, Play this map again (or Live) reloads your edits into it in place, with the player where they stand. Play pack opens the play page with the pack loaded, from the start.
  7. Share itSave .lxpack, or take the TOML files one at a time on the Files tab for a pack kept as a folder.

The working pack autosaves in the browser, so closing the tab loses nothing; a returning visitor who loads the disc is offered to resume. A file you did not edit exports as the bytes it was loaded from, comments included. Page reference: expansion-workbench.md.

By hand

The smallest pack is a manifest. Each section is a file of its own, and everything in it is optional:

# pack.toml
id = "tower"
name = "The Tower"
version = "0.1.0"
authors = ["you"]
license = "CC-BY-4.0"

# battle.toml - a retail monster with new numbers
[monsters.ironhide_ogre]
base = { kind = "monster", id = 109 }
name = "Ironhide Ogre"
hp = { mul = 3.5 }          # scale the base monster's
exp = { mul = 6.0 }

[formations.ogre_pack]
label = "Ironhide Ogres"
monsters = ["ironhide_ogre", "ironhide_ogre", "ironhide_ogre"]

[[encounters]]
scene = "chitei2"            # Jette's Fortress keeps its fights, mixes these in
retail_weight = 3
formations = [{ formation = "ogre_pack", weight = 1 }]
To addWriteReference
Monsters, fights, bossesbattle.tomlbattles
A level curve, rewards, enemy scalingprogression.tomlprogression
Quests and challengesquests.tomlquests
Things people saydialog.tomldialogue
Scripted scenes: walks, camera moves, fades, branching talkscutscenes.tomlcutscenes
Trading cards and dealerscards.tomlcards
Poker, duels, golf, races, prop huntmodes.tomlmodes
A new placemaps/<id>.tomlmaps

Ids are lowercase [a-z0-9_] (cards and mode instances may use -), unique within their kind across the pack, and never carry a : where they are defined. A file under assets/ must be a PNG, glTF, Ogg, WAV or text file - nothing taken from the disc (the rule).

Check and bundle from the command line

asset expansion validate my-pack            # every issue, with file and field
asset expansion validate my-pack --strict   # warnings fail too
asset expansion bundle my-pack -o my-pack.lxpack   # refuses a pack with errors
asset expansion info my-pack.lxpack [--json]
asset expansion unbundle my-pack.lxpack -o my-pack-copy/

None of these reads a disc, so they range-check coordinates without confirming them; the engine and the workbench check them against a real disc. Then play it: legaia-engine play-window --disc "$LEGAIA_DISC_BIN" --expansion my-pack, adding --map <id> to walk straight onto a map (playing a pack).

Add --expansion-watch and the window reloads the pack in place each time you save a file of it, rebuilding the map you stand on with you where you stood; End does the same by hand. A pack with an error is refused and the running one stays, with the reason on the notice line.

Things that catch people out

  • One version of each base monster per fight. A pack monster fights under its base monster's id, so a formation cannot hold a pack variant beside the retail monster it is built on (battles).
  • Four monsters at once. A battle has four monster seats; more enemies come in waves.
  • Heights are corner heights. A raised block of tiles slopes down along its high-X and high-Z edges; turn on the workbench's Heights overlay to see where (tiers).
  • An NPC needs a base scene with characters. Its model is one of the base scene's placements; a base scene with none is a check on the NPC.
  • An entrance needs a free tile. Pick a rectangle the retail walk reaches and no retail door shares, and give it a requires gate if it should open later in the game (entrances).
  • Dialogue rows are short. No retail text box wraps; keep a row within 36 characters, and the workbench's dialog check shows every row page by page.

The sample pack is the worked example of all of it.