Checkpoint current interactive fiction state

This commit is contained in:
2026-05-14 21:17:43 +02:00
parent c745efd1d2
commit 873049f7e6
183 changed files with 13755 additions and 1459 deletions
+94
View File
@@ -0,0 +1,94 @@
# Story Markup
The story stream supports plain paragraphs plus a small set of structural and media cues.
## Inline Text
Markdown emphasis is supported inside paragraphs and headings:
- `*italic*` or `_italic_`
- `**bold**` or `__bold__`
- `***bold italic***` or `___bold italic___`
SmartyPants processing still runs after markup parsing, so straight quotes, apostrophes, and dashes are converted typographically before layout and hyphenation.
## Paragraphs And Sections
Plain narrative is rendered paragraph by paragraph. Each ordinary paragraph uses the normal first-line indent, and adjacent paragraphs are not separated by a blank line.
Use an explicit section marker when the next paragraph should begin a new text block:
```text
::section
The first paragraph of the section begins here.
The second paragraph begins here.
```
- The first paragraph after `::section` is not horizontally indented.
- It gets one line of vertical separation from previous content.
- Following paragraphs use the normal first-line indent.
Paragraphs are separated by one or more blank lines. Single newlines inside a paragraph are normalized to spaces.
## Chapters
Use:
```text
::chapter[The House on the Hill]
The first paragraph begins here.
The second paragraph begins here.
```
The chapter heading is rendered in the same font and size as block text, centered and italic. The first following paragraph is unindented and marked for a three-line drop cap. Following paragraphs are indented normally.
## Images
Image blocks are parsed, queued, and emitted as future media blocks, but image rendering is not implemented yet.
```text
::image[widescreen](mansion-rain.jpg)
::image[portrait](portrait-letter.jpg)
```
`widescreen` means 100% page width and 50% page height. `portrait` means 100% page width and 100% page height. Filenames are relative to the future image directory.
## Sound Effects
Sound effects can appear inside regular paragraphs:
```text
The door opens {{sfx:door-creak.ogg}} and the hall exhales.
```
The marker is removed from displayed text and TTS text. It is preserved as a timed cue and emitted when the word animation reaches the marker position. Actual preload and playback are not implemented yet.
The animation engine emits `story:media-cue` with `type: "sfx"`, `filename`, `wordIndex`, and `delay`.
## Music
Music can be queued as a block:
```text
::music[crossfade, loop, lead=4](rain-theme.ogg)
```
It can also be placed inline:
```text
The candles gutter. {{music:cut:danger.ogg}} Something moves upstairs.
```
Supported modes are:
- `queue`: play after the current track finishes.
- `crossfade`: crossfade from the current track to the new one.
- `cut`: stop the current track and start the new one immediately.
- `loop` or `once`: whether the track repeats.
- `lead=<seconds>`: how long the music plays alone before the next text/TTS paragraph starts.
Inline music markers emit `story:media-cue`. Block music directives emit `story:media-block`; block directives also delay the following paragraph when `lead` is set.