|
|
||
|---|---|---|
| .. | ||
| calls.ludic | ||
| cmd_load.ludic | ||
| cmd_world.ludic | ||
| cmds.ludic | ||
| computed.ludic | ||
| draw.ludic | ||
| events.ludic | ||
| font.ludic | ||
| images.ludic | ||
| input.ludic | ||
| input_keys.ludic | ||
| inspect.ludic | ||
| json.ludic | ||
| line.ludic | ||
| main.ludic | ||
| mock.ludic | ||
| num.ludic | ||
| out.ludic | ||
| protocol-v1.md | ||
| README.md | ||
| smoke.py | ||
| smoke.txt | ||
ludic ui-preview
A game's ludic.ui components, previewed for a studio (a UI editor) without the game: ludic.ui
itself, with a backend that records its draw calls instead of drawing them, and component classes
the studio describes over stdin. No game code is built, nothing touches a GPU, nothing opens a
network connection. It is the toolchain's own program, shipped prebuilt as bin/ludic-ui-preview.
ludic ui-preview [--font DIR] # the host on stdin/stdout; DIR holds the game's font.json
The wire protocol is protocol-v1.md, frozen: every request, every reply and
every line format. smoke.txt is a scripted session with what each reply must contain, and smoke.py runs it
(python3 tools/ui-preview/smoke.py tools/ui-preview/smoke.txt bin/ludic-ui-preview).
What it does
- Components are mocks.
loadregisters aUiClassnamed as the component, with the template and styles the studio sends (unsaved text is fine), or changes that class in place. Its model is the story's (model), with the props its parent's tag gives it and whatever its templatesets laid over it; its functions answer from the story's table (calls). A component tag the studio has not sent yet is an empty class until it is. - The frame is ludic.ui's own.
frame tsets the interface clock tot, hands over the input the studio sent (input ...), and callsui_show: build, cascade, layout, pointer and focus, draw, then the actions a press ran. The draw list is everyUiBackendcall in painting order. - Text is measured as the game measures it.
font DIR(or--font DIR) reads the samefont.jsonludic.render3d's overlay reads, and the width of a run is the overlay's sum of glyph advances at the font's whole-pixel size; eachtextline carries it, so the studio fits its own rendering to the game's line breaks. - Languages are the game's:
locale <file.po>translates every drawn text with ludic.i18n. - Natives (a radar, a dial) are game code, so a
nativeline is a box for the studio to fill. - Inspection:
tree,box <id>(box and computed style) andrules <id>(the matching rules, each with the file and line its selector was written on).
ludic.ui additions it relies on
All additive, and none changes what a game draws:
UiClass.make_of- a constructor handed the class, so one host function makes every mock.UiBackend.said- template errors to the host instead ofprint;UiBackend.emitted- everyemit, for the host's log.UiRule.textandUiRule.at- a rule's selector as written andfile:line. A stylesheet's comments keep their line breaks when stripped, so lines count true; a component's own styles are read under its.lsspath.inspect.ludic:ui_root,ui_find,ui_rules_of,ui_rule_value,ui_building,ui_class_load,ui_file_forget,ui_errors_clear;class.ludic:ui_class;ui_nine_cuts_intoexported.
Limits in v1
- An error's column is not known (
colis 0): ludic.ui records a file and line per element and per rule, not a column. A malformed XML file is read leniently by the runtime's parser and does not report a syntax error. - In a GAME build a component's styles have their
@imports inlined by the compiler, so a rule's line there counts in the inlined text; in the host the studio sends the file as written, and lines are the file's. - A declaration's value is given as written only when it is plain text; one with
{...}holes is""inrules(its computed result is inbox). - Images are referenced, not decoded: the studio draws them from its own copies of the game's files
and atlases, and says a picture's natural size with
imagewhenobject-fitneeds it.