@origingame/engine 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/og.mjs +1 -1
- package/dist/web/origin-engine.d.ts +255 -5
- package/dist/web/origin-engine.js +1584 -125
- package/dist/web/origin-engine_bg.wasm +0 -0
- package/dist/web/origin-engine_bg.wasm.d.ts +80 -3
- package/dist/web-publish/origin-engine-lanes.js +1288 -82
- package/dist/web-publish/origin-engine-lanes_bg.wasm +0 -0
- package/dist/web-publish/origin-engine.d.ts +199 -6
- package/dist/web-publish/origin-engine.js +1285 -79
- package/dist/web-publish/origin-engine_bg.wasm +0 -0
- package/dist/web-publish/origin-engine_bg.wasm.d.ts +65 -4
- package/dist/web-publish-2d/origin-engine-lanes.js +1285 -79
- package/dist/web-publish-2d/origin-engine-lanes_bg.wasm +0 -0
- package/dist/web-publish-2d/origin-engine.d.ts +198 -5
- package/dist/web-publish-2d/origin-engine.js +1282 -76
- package/dist/web-publish-2d/origin-engine_bg.wasm +0 -0
- package/dist/web-publish-2d/origin-engine_bg.wasm.d.ts +64 -3
- package/knowledge/README.md +2 -1
- package/knowledge/guides/three-to-og.md +393 -0
- package/knowledge/knowledge.json +2 -1
- package/knowledge/looks/catalogue.json +40 -40
- package/knowledge/package.json +3 -2
- package/knowledge/scaffold/distribution.json +14 -0
- package/knowledge/scaffold/origin-engine.json +2 -2
- package/knowledge/scaffold/template/README.md +2 -1
- package/knowledge/scaffold/template/assets/audio/sting.ogt +10 -0
- package/knowledge/scaffold/template/assets/timelines/intro.ogt +101 -0
- package/knowledge/scaffold/template/assets/timelines/narration.srt +11 -0
- package/knowledge/scaffold/template/host.d.ts +46 -0
- package/knowledge/scaffold/template/package.json +1 -1
- package/knowledge/scaffold/template/project.ogt +1 -1
- package/knowledge/scaffold/template/src/main.ts +1 -1
- package/knowledge/scaffold/template/tests/frames.ts +134 -0
- package/knowledge/scaffold/template/tests/intro.og.ts +65 -0
- package/knowledge/scaffold/template/tests/smoke.og.ts +30 -36
- package/knowledge/scaffold/template/tsconfig.json +1 -1
- package/knowledge/scripts/mount.ts +2 -1
- package/knowledge/scripts/validate.ts +159 -31
- package/knowledge/skills/og-audio/SKILL.md +2 -2
- package/knowledge/skills/og-build/SKILL.md +29 -7
- package/knowledge/skills/og-core/SKILL.md +31 -5
- package/knowledge/skills/og-feel/SKILL.md +2 -2
- package/knowledge/skills/og-game/SKILL.md +1331 -16
- package/knowledge/skills/og-i18n/SKILL.md +7 -7
- package/knowledge/skills/og-model/SKILL.md +374 -0
- package/knowledge/skills/og-platform-sdk/SKILL.md +2 -1
- package/knowledge/skills/og-taste/SKILL.md +82 -73
- package/knowledge/skills/og-ui/SKILL.md +80 -58
- package/knowledge/wiki/ai.md +20 -20
- package/knowledge/wiki/anim.md +392 -41
- package/knowledge/wiki/atmosphere.md +36 -13
- package/knowledge/wiki/audio.md +18 -18
- package/knowledge/wiki/camera.md +19 -13
- package/knowledge/wiki/commands.md +19 -13
- package/knowledge/wiki/debug.md +414 -0
- package/knowledge/wiki/game.md +8 -8
- package/knowledge/wiki/i18n.md +7 -7
- package/knowledge/wiki/index.md +317 -8
- package/knowledge/wiki/input.md +47 -47
- package/knowledge/wiki/load.md +238 -70
- package/knowledge/wiki/math.md +2607 -0
- package/knowledge/wiki/nav.md +34 -34
- package/knowledge/wiki/net.md +340 -0
- package/knowledge/wiki/path.md +402 -0
- package/knowledge/wiki/physics.md +95 -95
- package/knowledge/wiki/platform.md +463 -29
- package/knowledge/wiki/probe.md +681 -67
- package/knowledge/wiki/reflect.md +29 -17
- package/knowledge/wiki/render.md +4993 -1998
- package/knowledge/wiki/rng.md +14 -14
- package/knowledge/wiki/shapes.md +727 -0
- package/knowledge/wiki/stream.md +15 -15
- package/knowledge/wiki/system.md +8 -8
- package/knowledge/wiki/systems.md +2 -2
- package/knowledge/wiki/terrain.md +24 -20
- package/knowledge/wiki/tilemap.md +13 -13
- package/knowledge/wiki/time.md +4 -4
- package/knowledge/wiki/timeline.md +396 -0
- package/knowledge/wiki/transform.md +8 -8
- package/knowledge/wiki/tween.md +17 -17
- package/knowledge/wiki/ui.md +560 -654
- package/knowledge/wiki/video.md +157 -0
- package/knowledge/wiki/world.md +36 -36
- package/package.json +4 -3
- package/schema/api.schema.json +28151 -19640
- package/shell/page.ts +26 -2
- package/shell/platform.ts +51 -0
- package/shell/player.ts +15 -2
- package/shell/transport.ts +6 -0
- package/src/depth.ts +71 -0
- package/src/e6.ts +32 -1
- package/src/env.d.ts +5 -1
- package/src/generated/abi.ts +226 -4
- package/src/geom.ts +260 -0
- package/src/index.ts +32 -4
- package/src/light.ts +18 -0
- package/src/math.ts +622 -0
- package/src/node/index.ts +17 -0
- package/src/node/playtest-run.ts +115 -18
- package/src/node/polish.ts +13 -3
- package/src/node/render.ts +291 -0
- package/src/node/run.ts +86 -5
- package/src/p2.ts +19 -1
- package/src/platform-local.ts +2 -0
- package/src/playtest.ts +65 -4
- package/src/runtime.ts +100 -9
- package/src/targets.ts +28 -0
- package/src/trace.ts +169 -0
- package/src/ui-kit/huds.ts +34 -34
- package/src/ui-kit/menus.ts +12 -12
- package/src/ui-kit/settings.ts +11 -2
- package/src/ui-kit/store.ts +18 -18
- package/src/ui-kit/story.ts +6 -4
- package/src/ui-kit/util.ts +8 -8
- package/src/web/shell.ts +59 -1
- package/src/web/worker.ts +105 -4
- package/types/bindings.json +9368 -6619
- package/types/index.d.ts +16377 -11520
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: og-taste
|
|
3
|
-
description: Art direction for a game on Origin Engine — choosing a style from the premise (genre, mood, era, audience) out of a 37-style catalogue and binding it as a look (post stack, stylisation, material defaults,
|
|
3
|
+
description: Art direction for a game on Origin Engine — choosing a style from the premise (genre, mood, era, audience) out of a 37-style catalogue and binding it as a look (post stack, stylisation, material defaults, the UI style) with a palette and a type ramp; composition and hierarchy on the play surface, colour, typography, motion, feedback and consistency; atmosphere (fog, sky, time of day, weather, water); the anti-patterns that make a game look like a web form; and the checklist to run (with og run captures and dump_ui) before calling a game done. Use when starting a game's look, building or reviewing any screen or HUD, or when a game "works but looks generic".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
A game is judged in its first second, before anyone reads a word. The
|
|
7
|
-
engine's UI is correct by default and characterless by default:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
engine's UI is correct by default and characterless by default: its
|
|
8
|
+
placeholder style, `prototype`, is greys and square corners meant to be
|
|
9
|
+
replaced, and the game's UI never borrows the Origin platform's look. This
|
|
10
|
+
skill is how to give a game a look of its own and keep it consistent. The
|
|
11
|
+
mechanics are og-ui's (styles, motion and sounds are og-ui §6) and the amounts of game feel
|
|
11
12
|
og-feel's; this is the taste.
|
|
12
13
|
|
|
13
14
|
## What works
|
|
@@ -57,11 +58,16 @@ for a new game and writes the result (`--look <slug>` names it instead):
|
|
|
57
58
|
`assets/looks/<game>.ogt` extending the preset, named by `GameDesc.look`,
|
|
58
59
|
with a README section on changing it. For a game that exists, write the
|
|
59
60
|
same file by hand (§12) and add `look: "looks/<game>.ogt"` to `og.game`.
|
|
60
|
-
The entry also names the palette rules, the asset specs and the
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
The entry also names the palette rules, the asset specs and the UI style
|
|
62
|
+
its preset carries (the look's `ui` line, §12), so a game that extends a
|
|
63
|
+
preset is dressed by it from the first frame. The game's UI follows the
|
|
64
|
+
game's art, never the Origin platform's: without a style it draws in the
|
|
65
|
+
engine's placeholder `prototype` (greys, near-square corners, a cyan focus
|
|
66
|
+
ring), and `og polish` warns when a game ships in it. The six built-in
|
|
67
|
+
styles in the engine's `templates/styles/` are starting points, not the
|
|
68
|
+
only looks:
|
|
69
|
+
|
|
70
|
+
| Style | Premises it fits | Signature | Start look (§12) |
|
|
65
71
|
|---|---|---|---|
|
|
66
72
|
| `pixel` | platformers, roguelikes, retro shooters, jam games | square frames, 2 px bevels, hard shadows, a bitmap face | `16bit-pixel` |
|
|
67
73
|
| `cartoon` | casual, match-3, party, kids, idle | thick outlines, cream panels, squash on press, pops | `bold-comic-illustration` |
|
|
@@ -70,88 +76,90 @@ that matches it. Then pick **one** starting skin. The six packs in the engine's
|
|
|
70
76
|
| `paper` | narrative, puzzle, cosy, mystery, word games | off-white sheets, ink outlines, soft shadows, one red | `pencil-hatching` |
|
|
71
77
|
| `neon` | arcade, rhythm, racing, synthwave | dark glass, glowing tubes, italic display | `neon-vector` |
|
|
72
78
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
```text
|
|
80
|
+
ui "fantasy" # in the game's look: a built-in style by slug
|
|
81
|
+
ui "styles/harbour/style.ogt" # or the game's own
|
|
76
82
|
```
|
|
77
83
|
|
|
78
|
-
Make it the game's own by changing the
|
|
79
|
-
to individual calls: copy the
|
|
80
|
-
`assets/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
Make it the game's own by changing the style file, never by passing colours
|
|
85
|
+
to individual calls: copy the built-in's directory into the game's
|
|
86
|
+
`assets/styles/<game>/` (`cp -R .../templates/styles/fantasy
|
|
87
|
+
assets/styles/<game>`) and name it in the look (`ui
|
|
88
|
+
"styles/<game>/style.ogt"`). Nothing in it needs rewriting: the ids in a
|
|
89
|
+
style file are read relative to the file first (`atlas "atlas.png"`, `body
|
|
90
|
+
"Newsreader-Medium.ttf"`), then from `assets/`. A style is complete: it
|
|
91
|
+
names every palette role and the four radii (`small`, `control`, `bar`,
|
|
92
|
+
`panel`), so nothing of it comes from anywhere else. Then change `palette`
|
|
93
|
+
(start with `primary`, `backdrop`, `panel`, `ink`), `radius`, `ramp` and
|
|
94
|
+
`fonts` (any OFL font beside the style file), and redraw the atlas if the
|
|
95
|
+
frames should change (`og style pack`, og-ui §6). A game that shows Chinese,
|
|
96
|
+
Japanese or Korean adds a `fallback` font to its style (or its string
|
|
97
|
+
table's `fonts` line, og-i18n). For a quick re-colour without a copy,
|
|
98
|
+
`og.ui.configure(world, { primaryColor })` derives the primary's hover,
|
|
99
|
+
pressed and soft tones and the ink on it. The art direction of the world
|
|
100
|
+
(sprites, backgrounds) and the style must agree: a pixel-art world in a
|
|
94
101
|
neon UI reads as two games.
|
|
95
102
|
|
|
96
103
|
## 2. Composition and hierarchy
|
|
97
104
|
|
|
98
105
|
- **What the eye reads first**: decide the one thing per screen (the score on
|
|
99
106
|
results, Play on the title, the health on a HUD) and make it the biggest,
|
|
100
|
-
the brightest or the only
|
|
107
|
+
the brightest or the only thing in the primary colour. If two things compete,
|
|
101
108
|
shrink one.
|
|
102
109
|
- **The play surface is the hero**: a HUD sits in the corners and edges
|
|
103
110
|
(anchors `topLeft`, `topRight`, `bottom`), never across the middle. Keep
|
|
104
111
|
the centre third free during play.
|
|
105
|
-
- **HUD weight**: at most three HUD groups visible at once; each is a
|
|
106
|
-
with an icon and a number, not a panel with labels. Move rarely needed
|
|
112
|
+
- **HUD weight**: at most three HUD groups visible at once; each is a HUD box
|
|
113
|
+
(`frame: "hud"`) with an icon and a number, not a panel with labels. Move rarely needed
|
|
107
114
|
information behind pause.
|
|
108
115
|
- **Safe area**: everything interactive inside `og.ui.frameViewport().safeArea`
|
|
109
116
|
plus the density gutter; anchors do this for you, absolute positions do not.
|
|
110
117
|
- **Phone vs desktop**: on `phonePortrait` the thumb zone is the bottom third:
|
|
111
118
|
primary actions go there, touch controls at least 44 CSS px apart; titles
|
|
112
|
-
shrink one step (`
|
|
119
|
+
shrink one step (`xl2` instead of `xl3`). On desktop, menus sit
|
|
113
120
|
centred or left, never full-width.
|
|
114
121
|
- **Grouping**: spacing does the grouping. Related things are `space.sm`
|
|
115
122
|
apart, groups `space.lg` or more. Do not draw a box around everything.
|
|
116
123
|
|
|
117
124
|
## 3. Colour
|
|
118
125
|
|
|
119
|
-
- **Limited palette**: a ground (`
|
|
120
|
-
with a muted ink, **one
|
|
121
|
-
palette; a
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
- **Limited palette**: a ground (`backdrop`), one or two surfaces (`panel`,
|
|
127
|
+
`panelRaised`), one ink (`ink`) with a muted ink (`inkMuted`), **one
|
|
128
|
+
primary**, and the status colours. That is the whole palette; a style
|
|
129
|
+
declares these and the roles derived from them.
|
|
130
|
+
- **One primary**, used for the one primary action per screen, earned stars,
|
|
131
|
+
the player's own row and focus. If everything is primary, nothing is.
|
|
124
132
|
- **Value before hue**: check the screen in greyscale. Text, the primary
|
|
125
133
|
button and the player character must separate from their ground by value
|
|
126
134
|
alone (body text at least 4.5:1; the packs' test enforces it for theirs:
|
|
127
135
|
every label ink, every button label in every state, a text field's
|
|
128
|
-
placeholder, which draws in `
|
|
129
|
-
|
|
136
|
+
placeholder, which draws in `inkFaint` on the field's frame, and a
|
|
137
|
+
primary badge, `highlight` on `primarySoft` over a panel (the results
|
|
130
138
|
screen's "New best"), and a status badge in each of `success`, `warn`,
|
|
131
139
|
`danger` and `info` (the tone's own ink on its 16 % tint), so a copied
|
|
132
|
-
|
|
140
|
+
style whose `inkFaint`, `control`, `highlight`, `primarySoft` or a status
|
|
133
141
|
colour moves must keep those pairs at 4.5:1 too. The status colours are
|
|
134
142
|
also the meters', toasts' and status dots' colours: on a cream panel they
|
|
135
|
-
are deep (the cartoon
|
|
136
|
-
read 1.63:1), on a dark one light (a red under a dark
|
|
143
|
+
are deep (the cartoon style's warn is `#7b5102`, not a bright amber that
|
|
144
|
+
read 1.63:1), on a dark one light (a red under a dark style's panel is a
|
|
137
145
|
salmon such as `#ff8080`). Make them for the panels; a badge placed on
|
|
138
|
-
the other side of the scale (a light
|
|
146
|
+
the other side of the scale (a light style's badge straight on its dark
|
|
139
147
|
stage) moves its own ink towards white or black until it reads there,
|
|
140
148
|
and the neutral badge does the same on its `fill`, so neither needs a
|
|
141
|
-
second palette. A game's
|
|
149
|
+
second palette. A game's own style is held to the same bars: the
|
|
142
150
|
engine's `pack_contrast.rs` measures the archetypes' and examples'
|
|
143
|
-
|
|
151
|
+
styles too, and their fixes were value, not hue (pathguard's lantern
|
|
144
152
|
orange deepened under a cream label, sparkorb's gold to a burnished
|
|
145
153
|
amber under its cream ink, lampdive's plum fill darkened under its
|
|
146
154
|
placeholder, Lantern Vale's status colours taken back to the fantasy
|
|
147
|
-
|
|
155
|
+
style's deep ones);
|
|
148
156
|
it also reads the primary and secondary labels from a rendered frame,
|
|
149
157
|
where thin strokes may never reach their colour: a pixel font's one-pixel
|
|
150
|
-
strokes fall between pixels and took half their ink, so the pixel
|
|
158
|
+
strokes fall between pixels and took half their ink, so the pixel style
|
|
151
159
|
thickens them with `textWeight body 0.5` and cooks DotGothic16 at
|
|
152
|
-
`px_range 8`; a copy of the
|
|
160
|
+
`px_range 8`; a copy of the style made before that needs both lines).
|
|
153
161
|
- Saturated colour on large areas tires the eye: keep saturation for small
|
|
154
|
-
things (the
|
|
162
|
+
things (the primary, icons, effects) and keep grounds calmer.
|
|
155
163
|
- Status colours mean status: never use `danger` red as decoration.
|
|
156
164
|
|
|
157
165
|
## 4. Typography
|
|
@@ -163,22 +171,22 @@ neon UI reads as two games.
|
|
|
163
171
|
- **Numerals**: scores, timers, prices and stats in the numeric role
|
|
164
172
|
(`font: "mono"`), so digits do not jitter as they count; big scores in the
|
|
165
173
|
display face. Count them with `og.ui.counter`, never by setting text.
|
|
166
|
-
- **A ramp, not sizes**: use the
|
|
174
|
+
- **A ramp, not sizes**: use the style's steps (`xl3`, `xl`, `body`,
|
|
167
175
|
`meta`); three or four steps per screen at most. Each step carries its
|
|
168
|
-
tracking (display sizes tighten
|
|
176
|
+
tracking (display sizes tighten; a style's `ramp` line
|
|
169
177
|
takes it as its fourth number after the CJK leading), and it is applied
|
|
170
178
|
to Latin text only.
|
|
171
|
-
- Headings get `heading: true` so the
|
|
179
|
+
- Headings get `heading: true` so the style's flourish frames them.
|
|
172
180
|
|
|
173
181
|
## 5. Motion
|
|
174
182
|
|
|
175
183
|
- Every change of state moves; nothing pops in or out without a transition
|
|
176
184
|
unless reduced motion is on.
|
|
177
|
-
- **Durations 120 to 300 ms** for UI (the
|
|
185
|
+
- **Durations 120 to 300 ms** for UI (the style's `durations`), up to 700 ms
|
|
178
186
|
for a screen transition, longer only for rewards. **Never linear**: ease
|
|
179
187
|
out on arrival, ease in on exit.
|
|
180
188
|
- **Anticipation and follow-through**: a press squashes before the action
|
|
181
|
-
(`press` in the
|
|
189
|
+
(`press` in the style), a reward overshoots and settles (`pop`, `motion.pop`).
|
|
182
190
|
- **Stagger**: a panel's controls arrive one after another (`motion.stagger`
|
|
183
191
|
30–60 ms), not all at once.
|
|
184
192
|
- **Screens change through a transition** (`og.ui.screenTransition`): fade
|
|
@@ -190,22 +198,22 @@ neon UI reads as two games.
|
|
|
190
198
|
## 6. Feedback
|
|
191
199
|
|
|
192
200
|
Every input is answered **on the same tick** (og-feel §1) by a visual and a
|
|
193
|
-
sound: hover (the
|
|
201
|
+
sound: hover (the style's lift or highlight), press (squash, the `press`
|
|
194
202
|
sound), success (a toast, a burst, `success`), refusal (a disabled button
|
|
195
203
|
shakes and plays `error` by itself; a wrong answer or a locked door shakes
|
|
196
204
|
its element with `og.ui.shake` and the `error` sound; never silently ignore
|
|
197
205
|
a press, and never shake the camera for it). Hand the UI its sounds with
|
|
198
206
|
`og.ui.configure(world, { sounds: { hover, press, open, close, success, error } })`
|
|
199
|
-
or the
|
|
207
|
+
or the style's `sound` lines. Results land with a count-up, stars with a
|
|
200
208
|
`og.ui.burst`, rewards with a pop.
|
|
201
209
|
|
|
202
210
|
## 7. Consistency
|
|
203
211
|
|
|
204
|
-
- **One
|
|
205
|
-
- **One radius scale**: the
|
|
206
|
-
- **One shadow direction**: the
|
|
212
|
+
- **One style per game.** Every screen, dialog and HUD uses it.
|
|
213
|
+
- **One radius scale**: the style's `radius`; never pass radii by hand.
|
|
214
|
+
- **One shadow direction**: the style's shadows all fall the same way (down);
|
|
207
215
|
in-world shadows should agree.
|
|
208
|
-
- **One icon set**: the
|
|
216
|
+
- **One icon set**: the style's `icons`; do not mix icon styles.
|
|
209
217
|
- **One transition kind** for screen changes, one entrance for dialogs.
|
|
210
218
|
|
|
211
219
|
## 8. Atmosphere
|
|
@@ -255,15 +263,16 @@ Each of these is a defect, not a style choice:
|
|
|
255
263
|
- the HUD as a toolbar: a full-width bar of labelled boxes across the top;
|
|
256
264
|
- labels instead of icons on the HUD ("Health: 72/100" instead of a heart
|
|
257
265
|
and a bar);
|
|
258
|
-
- every colour saturated, or every button in the
|
|
266
|
+
- every colour saturated, or every button in the primary colour;
|
|
259
267
|
- a settings-page layout (left-aligned form rows) for a title screen.
|
|
260
268
|
|
|
261
269
|
## 10. The checklist before a game is done
|
|
262
270
|
|
|
263
271
|
Run each item; each is checkable from a scripted run.
|
|
264
272
|
|
|
265
|
-
1. **A
|
|
266
|
-
from a command, or read it in a playtest through
|
|
273
|
+
1. **A style is configured**: `og.ui.theme(world).style` is not empty and
|
|
274
|
+
not `prototype` (log it from a command, or read it in a playtest through
|
|
275
|
+
a `facts` field).
|
|
267
276
|
2. **Title, pause and results screens captured**: `og run --headless --commands
|
|
268
277
|
"0.5:show:title;1.5:screenshot:title.png;…"` (with the game's own commands);
|
|
269
278
|
look at each capture in greyscale: the one thing per screen reads first.
|
|
@@ -277,7 +286,7 @@ Run each item; each is checkable from a scripted run.
|
|
|
277
286
|
`og run --size 1170x2532`) and check in `dump_ui` that every control is at
|
|
278
287
|
least 44 × 44 CSS px and nothing leaves the safe area.
|
|
279
288
|
6. **Text legible**: body text at 13 px or more in `dump_ui` heights (a line
|
|
280
|
-
of at least 16 px); the
|
|
289
|
+
of at least 16 px); the style passes 4.5:1 (the built-ins' test, or the same
|
|
281
290
|
check over your atlas).
|
|
282
291
|
7. **Motion present**: captures 100 ms apart after `show:` differ (an
|
|
283
292
|
entrance), and a score `dump_ui` text read twice during the results
|
|
@@ -290,7 +299,7 @@ Run each item; each is checkable from a scripted run.
|
|
|
290
299
|
10. **Reduced motion**: with `reducedMotion: true` the captures show fades
|
|
291
300
|
only, and nothing is missing.
|
|
292
301
|
11. **CJK**: switch the language to Chinese in settings and capture: no
|
|
293
|
-
missing-glyph boxes (the
|
|
302
|
+
missing-glyph boxes (the style's or the string table's fallback font covers it).
|
|
294
303
|
12. **None of section 9** is visible in any capture.
|
|
295
304
|
13. **`og polish .` scores taste 90 or more** where it applies, and every
|
|
296
305
|
finding left is one you read in the frames and can name a reason for
|
|
@@ -303,7 +312,7 @@ occupancy, screen transitions, UI sounds, locale keys) from the frames, the
|
|
|
303
312
|
UI trees and the run's audio, with og-feel's measures beside it; og-build §5
|
|
304
313
|
is the one list of its measures, thresholds and fixes. The numbers cannot
|
|
305
314
|
judge a style: read the frames before changing anything, and fix the cause
|
|
306
|
-
in the
|
|
315
|
+
in the style or the template, never per call.
|
|
307
316
|
|
|
308
317
|
## 12. Style catalogue: looks
|
|
309
318
|
|
|
@@ -311,7 +320,7 @@ A style is chosen once per game and then held by data, not by habit: the
|
|
|
311
320
|
**look** (`assets/looks/<game>.ogt`, an `.ogt` of `type look`) binds the
|
|
312
321
|
frame's whole treatment (tone mapping and exposure, the post stack, the
|
|
313
322
|
stylisation primitives, material defaults such as toon shading and
|
|
314
|
-
outlines, fog and sky, the UI
|
|
323
|
+
outlines, fog and sky, the UI style and the antialiasing) in one diffable
|
|
315
324
|
file. The engine ships the primitives and the presets; the taste is in
|
|
316
325
|
which one you pick and how you tune it.
|
|
317
326
|
|
|
@@ -320,7 +329,7 @@ describes 37 styles in four families (pixel and retro, paint and line,
|
|
|
320
329
|
shape and material, 3D rendering). For each: a one-line descriptor, three
|
|
321
330
|
checks a critic can judge on a captured frame, the premises it fits
|
|
322
331
|
(genre, mood, era, audience, as §1 asks them), the preset it maps to, the
|
|
323
|
-
|
|
332
|
+
UI style (`ui`), palette constraints, asset specs (logical resolution, sprite
|
|
324
333
|
scale, face budget, outline width, texture density) and an art-bible
|
|
325
334
|
direction. Match the premise's four answers against `premise`, shortlist
|
|
326
335
|
two, and choose by the checks you can actually hold for the whole game.
|
|
@@ -344,7 +353,7 @@ version 1
|
|
|
344
353
|
---
|
|
345
354
|
name "Harbour at dusk"
|
|
346
355
|
extends "anime-cel-3d" # the preset's slug (templates/looks/<slug>.ogt)
|
|
347
|
-
|
|
356
|
+
ui "styles/harbour/style.ogt" # the game's own UI style (the preset names a built-in)
|
|
348
357
|
RenderSettings {
|
|
349
358
|
toneMapping agx
|
|
350
359
|
exposure 1.1
|
|
@@ -455,8 +464,8 @@ middle ground.
|
|
|
455
464
|
|
|
456
465
|
Name it in the game (`og.game({ look: "looks/harbour.ogt", … })`) and it
|
|
457
466
|
is applied after the first scene spawns and before `start` runs (so
|
|
458
|
-
`start` may still change any field, and reads the look's
|
|
459
|
-
`og.render.look(world)?.
|
|
467
|
+
`start` may still change any field, and reads the look's UI style from
|
|
468
|
+
`og.render.look(world)?.style`); switch looks at a tick with
|
|
460
469
|
`og.load.look` and `og.render.applyLook` (a flashback, a photo mode, an
|
|
461
470
|
area's mood). A look's `MaterialStyle` reaches every lit material that
|
|
462
471
|
leaves the field at its default; a material that must stay as made (a
|
|
@@ -492,7 +501,7 @@ in its style step (`docs/platform-asks.md` in the engine repository): the
|
|
|
492
501
|
catalogue entry chosen from the premise, the look written, and the
|
|
493
502
|
entry's three checks handed to the critic that reads the frames.
|
|
494
503
|
|
|
495
|
-
| Slug | Family | Style | Support |
|
|
504
|
+
| Slug | Family | Style | Support | UI |
|
|
496
505
|
|---|---|---|---|---|
|
|
497
506
|
| `expressionist-painting` | Paint and line | Expressionist paint | content | `paper` |
|
|
498
507
|
| `bold-comic-illustration` | Paint and line | Bold comic illustration | full | `fantasy` |
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: og-ui
|
|
3
|
-
description: Game screens and HUDs on Origin Engine with og.ui — which screen template to pick (title, pause, settings, five HUDs, cutscene, shop, inventory, level select, results, leaderboard, tutorial, loading, dialogs, toasts), how to feed it data and read what it answers, the widget set beneath, focus for keyboard and gamepad, accessibility (the screen-reader mirror), phones, touch gestures and the safe area, text (fields, text areas, selection and the clipboard, input methods, ellipsis, kerning, shaping, font fallback), and the look:
|
|
3
|
+
description: Game screens and HUDs on Origin Engine with og.ui — which screen template to pick (title, pause, settings, five HUDs, cutscene, shop, inventory, level select, results, leaderboard, tutorial, loading, dialogs, toasts), how to feed it data and read what it answers, the widget set beneath, focus for keyboard and gamepad, accessibility (the screen-reader mirror), phones, touch gestures and the safe area, text (fields, text areas, selection and the clipboard, input methods, ellipsis, kerning, shaping, font fallback), and the look: UI styles (a look's `ui` line, the six built-ins, the game's own) and how their frames tile, count-ups, bursts, shakes, screen transitions and UI sounds. Use when building or changing menus, HUDs or any UI in a project with a project.ogt.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
`og.ui` is the engine's immediate-mode UI: a system describes the tree every
|
|
7
|
-
tick, the engine lays it out, draws it in the
|
|
8
|
-
|
|
7
|
+
tick, the engine lays it out, draws it in the game's UI style (a look's
|
|
8
|
+
`ui` line; the `prototype` placeholder without one, never the platform's
|
|
9
|
+
tokens) and answers the probe (`dump_ui`, `touch_move_to`, `move_to_text`). The API
|
|
9
10
|
reference is `reference/ui.md`; this skill is how to use it well.
|
|
10
11
|
|
|
11
12
|
## What works
|
|
@@ -14,7 +15,7 @@ Two games written from this package alone (`examples/lantern-vale`,
|
|
|
14
15
|
`examples/hollowbell`) used the main menu, pause, cutscene, shop and
|
|
15
16
|
results templates (the results with a localised Best and New best) and a
|
|
16
17
|
text field with input-method composition, and none needed wiring beyond
|
|
17
|
-
its desc; a
|
|
18
|
+
its desc; a style copied into the game restyled every screen, and
|
|
18
19
|
`og polish` measured taste 99 for both. The Kestrel Stair
|
|
19
20
|
(`examples/kestrel-stair`) used the cutscene, tutorial overlay,
|
|
20
21
|
inventory with drag and drop, level select, leaderboard with its honest
|
|
@@ -50,14 +51,14 @@ if (r.closed) state.screen = "map";
|
|
|
50
51
|
Screenshots of every template at desktop (1280×720) and on a phone in portrait
|
|
51
52
|
(390×844 at 3×) are in the engine repository under `templates/ui-kit/screens/`;
|
|
52
53
|
the full-size reference frames are `crates/og-ui/references/metal/kit-*.png`,
|
|
53
|
-
and every style pack's screens on a phone `kit-
|
|
54
|
+
and every style pack's screens on a phone `kit-style-<pack>-phone.png`.
|
|
54
55
|
|
|
55
56
|
| The game needs | Call | It answers |
|
|
56
57
|
|---|---|---|
|
|
57
58
|
| A title screen | `og.ui.mainMenu(id, { title, subtitle, items, footer, instant })` (`instant` while it is the screen the game opens on: §6) | `selected`: the item id |
|
|
58
59
|
| Pause | `og.ui.pauseMenu(id, { open, items })` (Resume, Settings, Quit by default) | `selected`; Back answers `resume` |
|
|
59
|
-
| Settings | `og.ui.settingsScreen(id, { open, settings, languages, onChange, onSave })` | the new `GameSettings`, `changed`, `closed` |
|
|
60
|
-
| A platformer HUD | `og.ui.platformerHud(id, { lives, maxLives, coins, score, level, timeLeft, touch })` (what it is not given it does not draw: `maxLives: 0` no hearts, no `coins` or `score` no
|
|
60
|
+
| Settings | `og.ui.settingsScreen(id, { open, settings, languages, world, onChange, onSave })` (with `world`, a new graphics preset is applied: `og.render.applyQuality`) | the new `GameSettings`, `changed`, `closed` |
|
|
61
|
+
| A platformer HUD | `og.ui.platformerHud(id, { lives, maxLives, coins, score, level, timeLeft, touch })` (what it is not given it does not draw: `maxLives: 0` no hearts, no `coins` or `score` no box for them; the words `pauseLabel`, `jumpLabel` from the string table, og-i18n §2) | `paused`, `moveX`, `action: "jump"` |
|
|
61
62
|
| A shooter HUD | `og.ui.shooterHud(id, { health, armor, ammo, reserve, abilities, map, touch })` (the words `killsLabel`, `fireLabel`, `pauseLabel`) | `paused`, `action` (ability id, `fire`), stick |
|
|
62
63
|
| A puzzle HUD | `og.ui.puzzleHud(id, { level, score, target, stars, moves, timeLeft })` (the words `movesLabel`, `targetLabel` with `{target}`, `pauseLabel`) | `paused` |
|
|
63
64
|
| An idle or incremental HUD | `og.ui.idleHud(id, { currencies, generators })` (the words `tapLabel`, `levelLabel` with `{level}`, `rateLabel` with `{rate}`, `pauseLabel`) | `action: "tap"` or `"buy:<id>"` |
|
|
@@ -118,13 +119,15 @@ wire. On a Mac (`Viewport.macKeys`: the web shell sets it from the
|
|
|
118
119
|
browser's platform, a native host on macOS) Cmd+A, C, X, Z are the
|
|
119
120
|
shortcuts, Cmd+←/→ go to the line's ends, Option+←/→ (and
|
|
120
121
|
Option+Backspace or Delete) move by words, and Ctrl takes the emacs keys
|
|
121
|
-
(A/E the line's ends, F/B a character, N/P a line, D/H delete one, K
|
|
122
|
-
the paragraph's end, U to its start, W the word before
|
|
122
|
+
(A/E the line's ends, F/B a character, N/P a line, D/H delete one, K
|
|
123
|
+
kills to the paragraph's end, U to its start, W the word before, Y yanks
|
|
124
|
+
what they killed, T transposes); elsewhere Ctrl
|
|
123
125
|
takes the shortcuts and moves by words. Words are Unicode's (UAX #29):
|
|
124
126
|
`can't` is one, each Chinese character is one, Thai moves a cluster at a
|
|
125
127
|
time. The caret and Backspace step over a whole grapheme cluster (`é`
|
|
126
|
-
typed as e and an accent, an emoji with its skin tone), and ←/→ move
|
|
127
|
-
|
|
128
|
+
typed as e and an accent, an emoji with its skin tone), and ←/→ move on
|
|
129
|
+
screen: in Hebrew or Arabic ← goes on in the text, and across the edge of
|
|
130
|
+
a Hebrew word in a Latin line the caret goes where the arrow points. A double click selects a word and a triple
|
|
128
131
|
click the line, Shift+Z or Y redoes (typing undoes a word at a time, an
|
|
129
132
|
input method's commit at a time), and a drag past an area's edge scrolls
|
|
130
133
|
it. A text the game sets starts the field's undo history again. Script a
|
|
@@ -143,9 +146,9 @@ its own names `coin`, `gear`, `fire`…, and every kit screen draws them) loads
|
|
|
143
146
|
{ font } })`; `og.ui.icon(id, "heart", { size, tint })` and `[icon=heart]`
|
|
144
147
|
then draw crisp distance-field glyphs at any size in their ink. A texture
|
|
145
148
|
grid (`icons: { texture, columns, rows, names }`) still works for painted
|
|
146
|
-
icons. Icons sit in `
|
|
147
|
-
|
|
148
|
-
`fire-flame`, the
|
|
149
|
+
icons. Icons sit in `inkMuted` or `inkFaint` (icons stay neutral; colour
|
|
150
|
+
is for state). Sets name their icons differently (iconoir's `coins` and
|
|
151
|
+
`fire-flame`, the style grids' `coin` and `fire`): an unknown name draws an
|
|
149
152
|
empty slot and warns, so a template that may meet either asks
|
|
150
153
|
`og.ui.hasIcon(name)` first and draws its fallback, or names an icon twice
|
|
151
154
|
in its set (`icon "coin" "coins"`). A path's `stroke-linejoin` is kept
|
|
@@ -256,7 +259,11 @@ phone), down past it. Every HUD template and any HUD built from
|
|
|
256
259
|
`og.ui.anchor` groups gets this; a corner drawn another way (screen
|
|
257
260
|
sprites, a row placed by hand) reads `covered` itself, so put a game's own
|
|
258
261
|
HUD in anchored groups. Preview it
|
|
259
|
-
with `og.ui.previewViewport(world, { ..., covered: { x: 12, y: 12, width: 40, height: 40 } })
|
|
262
|
+
with `og.ui.previewViewport(world, { ..., covered: { x: 12, y: 12, width: 40, height: 40 } })`,
|
|
263
|
+
or give a native run the page's cover from outside the game with the
|
|
264
|
+
command `cover:12,12,40,40` (`og run --setup cover:12,12,40,40`; a
|
|
265
|
+
playtest's `setup: "cover:12,12,40,40"`, og-build §6), `cover:none`
|
|
266
|
+
clearing it.
|
|
260
267
|
`og.ui.frameViewport().breakpoint` is `phonePortrait`, `phoneLandscape`,
|
|
261
268
|
`tablet` or `desktop`; templates rearrange themselves by it (tabs become a
|
|
262
269
|
select, side panels move under, touch controls appear when `touch` is set).
|
|
@@ -284,46 +291,60 @@ fingers with `touch_start` for the first and `touch:1:down:<x,y>` /
|
|
|
284
291
|
`touch:1:move:<x,y>` / `touch:1:up` for the second
|
|
285
292
|
(`templates/ui-kit/tests/gestures.og.ts`).
|
|
286
293
|
|
|
287
|
-
## 6.
|
|
288
|
-
|
|
289
|
-
The
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
294
|
+
## 6. Styles: the look of the game's UI, motion, transitions, sounds
|
|
295
|
+
|
|
296
|
+
The game's UI follows the game's art, never the Origin platform's look:
|
|
297
|
+
the engine has no house style to fall back on. Without a style a UI draws
|
|
298
|
+
in **prototype**, the engine's placeholder: greys, near-square corners and
|
|
299
|
+
a cyan focus ring, meant to be replaced. `og polish` warns when a game
|
|
300
|
+
ships in it. A **style** (`og.load.style`, an `.ogt` of `type style`) is
|
|
301
|
+
complete: its scheme, every palette role (`backdrop`, `panel`, `ink`,
|
|
302
|
+
`inkMuted`, `primary`, `focus`, `hud`, `danger`, ...), the four radii
|
|
303
|
+
(`small`, `control`, `bar`, `panel`), the type ramp, durations, fonts and
|
|
304
|
+
icons. It dresses every element class in nine-slice frames from its atlas
|
|
305
|
+
(panel, card, button with hover, pressed and disabled, field, slot,
|
|
306
|
+
tooltip, HUD box, progress track and fill), with ornaments (panel corners,
|
|
307
|
+
the divider, a heading flourish), a panel texture, shadows and glows,
|
|
308
|
+
press squash and hover lift, entrances and sounds. Choosing one is
|
|
309
|
+
og-taste §1.
|
|
310
|
+
|
|
311
|
+
The usual way in is the game's look (og-taste §12): its `ui` line names
|
|
312
|
+
the style, and every catalogue preset already names one. `ui "pixel"` is a
|
|
313
|
+
built-in style by slug (`pixel`, `cartoon`, `fantasy`, `scifi`, `paper`,
|
|
314
|
+
`neon`; `og cook` bundles the one a look names). `ui
|
|
315
|
+
"styles/<name>/style.ogt"` is the game's own, and a game's
|
|
316
|
+
`assets/styles/<slug>/style.ogt` wins over the built-in of that slug.
|
|
317
|
+
To make one from a built-in, copy `templates/styles/<slug>/` of the
|
|
318
|
+
engine repository into the game's `assets/styles/<name>/` and change it
|
|
319
|
+
at will: a style's ids are read relative to its file first, then from
|
|
320
|
+
`assets/`. A style file must name every palette role and all four radii;
|
|
321
|
+
`og cook` lists the ones missing. Loading one by hand:
|
|
302
322
|
|
|
303
323
|
```ts
|
|
304
|
-
const
|
|
324
|
+
const style = og.load.style(world, "styles/fantasy/style.ogt"); // atlas, fonts, icons load with it
|
|
305
325
|
og.ui.configure(world, {
|
|
306
|
-
|
|
307
|
-
contrast: "high", // still applies over a
|
|
326
|
+
style: style.ok ? style.value : null,
|
|
327
|
+
contrast: "high", // still applies over a style
|
|
308
328
|
reducedMotion: settings.reducedMotion, // every motion becomes a fade
|
|
309
329
|
sounds: { hover, press, open, close, success, error }, // og.load.sound handles, played on the ui bus
|
|
310
330
|
});
|
|
311
|
-
og.ui.configure(world, { reducedMotion: true }); // later, from the settings: the
|
|
331
|
+
og.ui.configure(world, { reducedMotion: true }); // later, from the settings: the style, fonts and sounds stay
|
|
332
|
+
og.ui.configure(world, { primaryColor: "#e0553b" }); // re-colour the style's primary; hover, pressed and the ink on it follow
|
|
312
333
|
```
|
|
313
334
|
|
|
314
335
|
`configure` takes a partial UiDesc: a field left out keeps the value the
|
|
315
|
-
last call gave it (or the
|
|
316
|
-
`og.render.applyLook`), and `null` clears one (`
|
|
317
|
-
|
|
336
|
+
last call gave it (or the style a look applied, `GameDesc.look` and
|
|
337
|
+
`og.render.applyLook`), and `null` clears one (`style: null` is the
|
|
338
|
+
prototype style again). A UI left with no font at all warns that it draws
|
|
318
339
|
no text.
|
|
319
340
|
|
|
320
|
-
A
|
|
341
|
+
A style's `slice` line says how a frame's edges and centre fill: `stretch`
|
|
321
342
|
(the default), `repeat` (tiled at the art's size from the corner, the last
|
|
322
343
|
tile cut) or `round` (a whole number of tiles resized to fit, as CSS
|
|
323
344
|
`round`): tile patterned borders (a rope, a rivet row, a pixel bevel),
|
|
324
345
|
stretch plain ones. `glass <part> <blur> <fill> [tint]` makes a part glass:
|
|
325
346
|
the game behind it blurred (`blur` CSS px), tinted by the part's fill, under
|
|
326
|
-
its frame drawn at `fill` opacity (the scifi
|
|
347
|
+
its frame drawn at `fill` opacity (the scifi style's dialogs:
|
|
327
348
|
`glass panel 16 0.85 0.15`). Glass blurs the scene and the UI drawn under
|
|
328
349
|
it (a HUD under a glass dialog); it costs a frame copy and a blur pyramid
|
|
329
350
|
when any is on screen (about 0.8 ms at 1280×720 on an M4 Pro), and one more
|
|
@@ -335,43 +356,44 @@ translucent fills (secondary buttons, chips, tracks) flat. Your own
|
|
|
335
356
|
see-through overlays should follow: read `og.ui.frameTheme().reducedTransparency`
|
|
336
357
|
(and `reducedMotion`) and draw them opaque.
|
|
337
358
|
|
|
338
|
-
A
|
|
359
|
+
A style of the game's own art: draw each part as a nine-patch PNG
|
|
339
360
|
(`panel.9.png`, `button.9.png`, `buttonHover.9.png`, ..., `soft.9.png`: the
|
|
340
361
|
art inside a one-pixel border whose top row and left column mark in opaque
|
|
341
362
|
black what stretches) and any ornament as a plain PNG (`corner.png`,
|
|
342
|
-
`divider.png`, `flourish.png`, `tile.png`) in the
|
|
343
|
-
`og
|
|
344
|
-
writes the
|
|
345
|
-
regions, keeping every other line (palette, fonts, a slice's `tint` or
|
|
363
|
+
`divider.png`, `flourish.png`, `tile.png`) in the style's directory, then
|
|
364
|
+
`og style pack assets/styles/<name>`: it packs them into `atlas.png` and
|
|
365
|
+
writes the style file's `atlas`, `slice` and `soft` lines and the ornaments'
|
|
366
|
+
regions, keeping every other line (palette, radii, fonts, a slice's `tint` or
|
|
346
367
|
`repeat`). Re-run it after redrawing a part.
|
|
347
368
|
|
|
348
|
-
Never pass hex colours for chrome: use `{ token: "
|
|
349
|
-
`"
|
|
350
|
-
palette answers them. A container that should look like a HUD
|
|
351
|
-
card takes `frame: "
|
|
352
|
-
take `heading: true`. Without a
|
|
369
|
+
Never pass hex colours for chrome: use `{ token: "primary" }`, `"inkMuted"`,
|
|
370
|
+
`"panel"` and the type steps (`xl3`, `xl`, `meta`); the style's
|
|
371
|
+
palette answers them. A container that should look like a HUD box or a
|
|
372
|
+
card takes `frame: "hud"` (or `"card"`, `"slot"`…) in its desc; titles
|
|
373
|
+
take `heading: true`. Without a frame atlas both are plain fills at the
|
|
374
|
+
style's radii.
|
|
353
375
|
|
|
354
376
|
Motion and juice, all by the tick and in the UI state:
|
|
355
377
|
|
|
356
378
|
| Want | Call |
|
|
357
379
|
|---|---|
|
|
358
|
-
| A score, coins or a reward counting up | `og.ui.counter(id, value, { from: 0, font: "display", step: "
|
|
380
|
+
| A score, coins or a reward counting up | `og.ui.counter(id, value, { from: 0, font: "display", step: "xl3" })` |
|
|
359
381
|
| Sparks when a star or reward lands | `og.ui.burst({ count: 10 })` right after the element |
|
|
360
382
|
| A panel or item popping in | `og.ui.transition(id, show, { kind: "pop" })` (also `fade`, `slideUp`…, `scale`) |
|
|
361
383
|
| A change of game screen | `const s = og.ui.screenTransition("Screens", state.screen, { kind: "iris" }).shown;` then build `s` (`fade`, `wipe`, `iris`, `dissolve`, `slide`; a colour or a texture) |
|
|
362
|
-
| A wrong answer, a locked door, a refused purchase | `og.ui.shake({ sound: true })` right after the element, once, on the tick it happens: it swings three times and comes to rest by itself (the
|
|
384
|
+
| A wrong answer, a locked door, a refused purchase | `og.ui.shake({ sound: true })` right after the element, once, on the tick it happens: it swings three times and comes to rest by itself (the style's `motion.shake`, else 6 px), with the `error` sound |
|
|
363
385
|
|
|
364
386
|
`screenTransition` keeps the previous screen in `shown` for the closing
|
|
365
387
|
half of its duration, switches at full cover, then reveals the new one.
|
|
366
388
|
Build `shown`, not the requested screen; `dump_ui` therefore lists the old
|
|
367
389
|
screen until the midpoint. The cover itself does not block input. A new
|
|
368
|
-
panel's own
|
|
390
|
+
panel's own style entrance starts when that panel is first built, and
|
|
369
391
|
ignores presses until it arrives (§4): the closing half of a wipe plus
|
|
370
392
|
that entrance explains why a press just after the switch can be lost.
|
|
371
393
|
|
|
372
|
-
|
|
394
|
+
Styles add the rest themselves: dialog and panel entrances with staggered
|
|
373
395
|
controls, hover lift and press squash on springs (the `hoverSpring 1 350` and `pressSpring 0.55 120` lines of a
|
|
374
|
-
|
|
396
|
+
style's `motion` block: damping ratio and response in ms; below 1 bounces), eased progress bars, toasts flying in,
|
|
375
397
|
a shake and the error sound on a press of a disabled button. Reduced motion
|
|
376
398
|
keeps every shake still and turns the rest into fades. The screen the game
|
|
377
399
|
opens on is built settled (`instant: true` on its `mainMenu`, `anchor` or
|
|
@@ -388,7 +410,7 @@ scripts are shaped (Arabic joins, Devanagari conjuncts) and every font's
|
|
|
388
410
|
kerning pairs apply. What a game sets:
|
|
389
411
|
|
|
390
412
|
```ts
|
|
391
|
-
og.ui.label("Quest", quest.text, { width: { kind: "grow" }, maxLines: 2, ellipsis: true, color: { token: "
|
|
413
|
+
og.ui.label("Quest", quest.text, { width: { kind: "grow" }, maxLines: 2, ellipsis: true, color: { token: "inkMuted" } }); // cut with … on the last line
|
|
392
414
|
og.ui.label("Gold", gold, { font: "rounded", step: "xl", nowrap: true }); // body, display, mono or rounded
|
|
393
415
|
```
|
|
394
416
|
|
|
@@ -430,7 +452,7 @@ script text with `type:`, not `key_down`.
|
|
|
430
452
|
|
|
431
453
|
Fonts (the one rule for every label, field and button):
|
|
432
454
|
|
|
433
|
-
1. The role's font (body, display, mono, rounded; the
|
|
455
|
+
1. The role's font (body, display, mono, rounded; the style's or
|
|
434
456
|
`og.ui.configure`'s) when it has every character: the whole label in it.
|
|
435
457
|
2. Else the first of the locale's fonts (its string table's `fonts` line)
|
|
436
458
|
that has every character: the whole label in that face, its Latin and
|
|
@@ -439,9 +461,9 @@ Fonts (the one rule for every label, field and button):
|
|
|
439
461
|
3. Else run by run: each run of the label from the first font that has it,
|
|
440
462
|
the role's font first, then the locale's fonts, `UiDesc.fallbackFonts`
|
|
441
463
|
(a Hebrew or Devanagari face, a CJK face cooked with `runtime true`) and
|
|
442
|
-
the
|
|
464
|
+
the style's `fallback`; a letter and its accents stay in one face. A
|
|
443
465
|
CJK-only subset (lantern-vale's `tools/subset-font.py`) gives this: the
|
|
444
|
-
Latin in the
|
|
466
|
+
Latin in the style's face, the Chinese in Noto, on one line.
|
|
445
467
|
|
|
446
468
|
So choose by the subset: keep Latin in the CJK subset for one face per
|
|
447
469
|
label, leave it out to keep the game's Latin face beside CJK. Tracking
|