create-asciitorium 0.1.47 → 0.1.48

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.
Files changed (34) hide show
  1. package/dist/templates/base/public/art/README.md +72 -0
  2. package/dist/templates/base/public/art/fonts/README.md +2 -0
  3. package/dist/templates/base/public/art/maps/README.md +2 -0
  4. package/dist/templates/base/public/art/materials/README.md +2 -0
  5. package/dist/templates/base/public/art/sounds/README.md +2 -0
  6. package/dist/templates/base/public/art/sprites/README.md +2 -0
  7. package/dist/templates/base/vite.config.ts +12 -1
  8. package/package.json +1 -1
  9. package/dist/templates/base/public/art/ART-DESIGN-SPEC.md +0 -375
  10. package/dist/templates/base/public/art/font/README.md +0 -113
  11. package/dist/templates/base/public/art/font/pencil.art +0 -168
  12. package/dist/templates/base/public/art/maps/example/README.md +0 -62
  13. package/dist/templates/base/public/art/maps/example/legend.json +0 -29
  14. package/dist/templates/base/public/art/maps/example/map.art +0 -21
  15. package/dist/templates/base/public/art/materials/bone.art +0 -11
  16. package/dist/templates/base/public/art/materials/door-wooden.art +0 -154
  17. package/dist/templates/base/public/art/materials/wall-brick.art +0 -128
  18. package/dist/templates/base/public/art/materials/wall-wireframe.art +0 -128
  19. package/dist/templates/base/public/art/sounds/door-close.mp3 +0 -0
  20. package/dist/templates/base/public/art/sounds/door-open.mp3 +0 -0
  21. package/dist/templates/base/public/art/sounds/taps.mp3 +0 -0
  22. package/dist/templates/base/public/art/sprites/asciitorium.art +0 -6
  23. package/dist/templates/base/public/art/sprites/balloon.art +0 -126
  24. package/dist/templates/base/public/art/sprites/beating-heart.art +0 -49
  25. package/dist/templates/base/public/art/sprites/castle.art +0 -4
  26. package/dist/templates/base/public/art/sprites/component-icon.art +0 -6
  27. package/dist/templates/base/public/art/sprites/eyes.art +0 -61
  28. package/dist/templates/base/public/art/sprites/firework.art +0 -58
  29. package/dist/templates/base/public/art/sprites/heart.art +0 -5
  30. package/dist/templates/base/public/art/sprites/multi-select-test.art +0 -6
  31. package/dist/templates/base/public/art/sprites/nav-basics.art +0 -5
  32. package/dist/templates/base/public/art/sprites/pyramid.art +0 -5
  33. package/dist/templates/base/public/art/sprites/welcome.art +0 -7
  34. package/dist/templates/base/src/reference-validation.tsx +0 -307
@@ -2,6 +2,78 @@
2
2
 
3
3
  This directory contains asciitorium art assets for the asciitorium framework. They are organized into categories: fonts, maps, materials, sounds, and sprites.
4
4
 
5
+ ## Asset Resolution and Library Assets
6
+
7
+ The asciitorium framework uses a **fallback resolution system** for assets:
8
+
9
+ 1. **Project Assets First**: `public/art/{type}/{name}.art` in your project
10
+ 2. **Library Assets Fallback**: `node_modules/asciitorium/public/art/{type}/{name}.art`
11
+
12
+ This means you automatically have access to all library assets without copying them!
13
+
14
+ ### Using Library Assets
15
+
16
+ The asciitorium library includes starter assets:
17
+
18
+ **Materials**: `wall-brick`, `wall-wireframe`, `bone`, `door-wooden`
19
+ **Sprites**: `beating-heart`, `balloon`, `castle`, `eyes`, `firework`, `heart`, `pyramid`, `welcome`, and more
20
+ **Fonts**: `marker`, `pencil`, `pixel`, `shadows`
21
+ **Maps**: `example` (with legend)
22
+ **Sounds**: `door-open.mp3`, `door-close.mp3`, `taps.mp3`
23
+
24
+ Simply reference them by name - no need to copy files:
25
+
26
+ ```typescript
27
+ import { AssetManager, Art, Banner } from 'asciitorium';
28
+
29
+ // Use library sprite
30
+ <Art sprite="beating-heart" />
31
+
32
+ // Use library font
33
+ <Banner font="shadows" text="Hello" />
34
+
35
+ // Use library material (in map legend)
36
+ const materialAsset = await AssetManager.getMaterial('wall-brick');
37
+ ```
38
+
39
+ ### Customizing Assets
40
+
41
+ **To use library asset as-is**: Just reference it by name (nothing to do!)
42
+
43
+ **To customize a library asset**:
44
+ 1. Copy the asset from `node_modules/asciitorium/public/art/{type}/{name}.art`
45
+ 2. Paste into your project's `public/art/{type}/{name}.art`
46
+ 3. Edit as desired
47
+ 4. Your version now takes precedence over the library version
48
+
49
+ **To create custom assets**:
50
+ 1. Create a new `.art` file in `public/art/{type}/{custom-name}.art`
51
+ 2. Follow the format documented in the type-specific README
52
+ 3. Reference by name in your code
53
+
54
+ ### Asset Updates
55
+
56
+ When you run `npm update asciitorium`:
57
+ - Library assets are automatically updated in `node_modules/asciitorium/public/art/`
58
+ - Your project assets in `public/art/` are never touched
59
+ - Any library assets you haven't overridden get the latest improvements
60
+ - Any assets you've copied to your project stay as-is (your responsibility to update)
61
+
62
+ **Best Practice**: Only copy library assets to your project if you need to customize them. Use library assets directly whenever possible to benefit from automatic updates.
63
+
64
+ ### Listing Available Library Assets
65
+
66
+ To see all available library assets, check:
67
+ ```bash
68
+ ls node_modules/asciitorium/public/art/materials/
69
+ ls node_modules/asciitorium/public/art/sprites/
70
+ ls node_modules/asciitorium/public/art/fonts/
71
+ ls node_modules/asciitorium/public/art/maps/
72
+ ls node_modules/asciitorium/public/art/sounds/
73
+ ```
74
+
75
+ Or view the latest assets in the [asciitorium repository](https://github.com/tgruby/asciitorium/tree/main/packages/asciitorium/public/art).
76
+
5
77
  ## Asset Loading
6
78
 
7
79
  Assets are automatically loaded and cached by `AssetManager` using reactive
@@ -1,5 +1,7 @@
1
1
  # Asciitorium Fonts
2
2
 
3
+ > **Note**: This directory is empty by default. The asciitorium library includes starter assets in `node_modules/asciitorium/public/art/fonts/` that are automatically available without copying. See the main [art/README.md](../README.md) for details on using and customizing library assets.
4
+
3
5
  This directory contains ASCII font files for the **Banner** component. Fonts
4
6
  allow you to display large, stylized text using ASCII art characters.
5
7
 
@@ -1,5 +1,7 @@
1
1
  # Asciitorium Maps
2
2
 
3
+ > **Note**: This directory is empty by default. The asciitorium library includes starter assets in `node_modules/asciitorium/public/art/maps/` that are automatically available without copying. See the main [art/README.md](../README.md) for details on using and customizing library assets.
4
+
3
5
  This directory contains map layouts and legends for the **MapView** and
4
6
  **FirstPersonView** components. Maps use ASCII characters for layout, with JSON
5
7
  legends defining character properties.
@@ -1,5 +1,7 @@
1
1
  # Asciitorium Materials
2
2
 
3
+ > **Note**: This directory is empty by default. The asciitorium library includes starter assets in `node_modules/asciitorium/public/art/materials/` that are automatically available without copying. See the main [art/README.md](../README.md) for details on using and customizing library assets.
4
+
3
5
  This directory contains ASCII art material files for the **FirstPersonView** and
4
6
  **MapView** components. Materials define the visual appearance of walls, floors,
5
7
  and other environmental surfaces with depth-based layering.
@@ -1,5 +1,7 @@
1
1
  # Sounds Directory
2
2
 
3
+ > **Note**: This directory is empty by default. The asciitorium library includes starter assets in `node_modules/asciitorium/public/art/sounds/` that are automatically available without copying. See the main [art/README.md](../README.md) for details on using and customizing library assets.
4
+
3
5
  This directory contains audio assets in MP3 format used throughout the
4
6
  application.
5
7
 
@@ -1,5 +1,7 @@
1
1
  # Asciitorium Sprites
2
2
 
3
+ > **Note**: This directory is empty by default. The asciitorium library includes starter assets in `node_modules/asciitorium/public/art/sprites/` that are automatically available without copying. See the main [art/README.md](../README.md) for details on using and customizing library assets.
4
+
3
5
  This directory contains ASCII sprite files for the **Art** component. Sprites
4
6
  allow you to display static or animated ASCII art via the Art component.
5
7
 
@@ -1,4 +1,5 @@
1
1
  import { defineConfig, Plugin } from 'vite';
2
+ import path from 'path';
2
3
 
3
4
  // Minimal virtual shim for Node built-ins on the web build
4
5
  function nodeBuiltinsShim(): Plugin {
@@ -26,14 +27,24 @@ function nodeBuiltinsShim(): Plugin {
26
27
  }
27
28
 
28
29
  export default defineConfig({
29
- esbuild: {
30
+ esbuild: {
30
31
  target: 'esnext',
31
32
  jsx: 'automatic',
32
33
  jsxImportSource: 'asciitorium',
33
34
  },
34
35
  build: { target: 'esnext' },
35
36
  plugins: [nodeBuiltinsShim()],
37
+ resolve: {
38
+ alias: {
39
+ // Alias /lib-assets to node_modules/asciitorium/public for library asset fallback
40
+ '/lib-assets': path.resolve(__dirname, 'node_modules/asciitorium/public'),
41
+ },
42
+ },
36
43
  server: {
37
44
  port: 5173,
45
+ fs: {
46
+ // Allow serving files from node_modules/asciitorium
47
+ allow: ['..'],
48
+ },
38
49
  },
39
50
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-asciitorium",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "private": false,
5
5
  "description": "Scaffold a Vite + TypeScript project prewired for asciitorium (web + cli).",
6
6
  "bin": {
@@ -1,375 +0,0 @@
1
- # Art Asset Format Specification
2
-
3
- This document defines the metadata format for ASCII art assets in asciitorium, including fonts, materials, and sprites.
4
-
5
- ## Overview
6
-
7
- Art assets use a text-based format that combines:
8
-
9
- - **Section headers** (`§`) defining global asset properties
10
- - **Layer/frame separators** (`¶`) with metadata for each section
11
- - **ASCII art content** following each separator
12
-
13
- ## Design Goals
14
-
15
- 1. **Human-readable**: Artists should be able to read and write metadata without tooling
16
- 2. **Simple**: Use standard JSON format with flat key-value structure
17
- 3. **No nesting**: Flat data structures only - no nested objects or arrays
18
- 4. **Consistent**: Same format works for materials, sprites, and font asset types
19
- 5. **Extensible**: Easy to add new properties without breaking existing assets
20
-
21
- ## Format Syntax
22
-
23
- ### File Header (`§`)
24
-
25
- The file header appears once at the beginning of the file and defines the asset type and global properties.
26
-
27
- **Format:**
28
-
29
- ```json
30
- § {"key":"value","key":"value"}
31
- ```
32
-
33
- **Example:**
34
-
35
- ```json
36
- § {"kind":"material","usage":"first-person","placement":"scenery"}
37
- ```
38
-
39
- ### Layer/Frame Separator (`¶`)
40
-
41
- Separates different layers (materials), characters (fonts) or frames (sprites) with section-specific metadata.
42
-
43
- **Format:**
44
-
45
- ```json
46
- ¶ {"key":"value","key":"value"}
47
- [ASCII art content follows]
48
- ```
49
-
50
- **Example:**
51
-
52
- ```json
53
- ¶ {"layer":"here","pos":"center"}
54
- |‽‽‽‽‽‽‽|
55
- |‽‽‽‽‽‽‽|
56
- ```
57
-
58
- ## Parsing Rules
59
-
60
- ### JSON Format
61
-
62
- 1. **Parse as JSON**: Standard JSON.parse() after removing separator character
63
- 2. **Primitive values only**: All values must be strings, numbers, or booleans
64
- 3. **No nesting**: Objects must be flat - no nested objects or arrays
65
- 4. **Empty metadata**: Empty separator `¶` or `§` is valid (inherits defaults)
66
-
67
- ### Single-Frame Sprites
68
-
69
- If a file does not start with a `§` file header, it is assumed to be a single-frame sprite with no metadata:
70
-
71
- ```txt
72
- ___
73
- / \
74
- | o |
75
- \___/
76
- ```
77
-
78
- This is equivalent to:
79
-
80
- ```json
81
- § {"kind":"sprite","loop":"false"}
82
-
83
- ___
84
- / \
85
- | o |
86
- \___/
87
- ```
88
-
89
- ### Empty Separators
90
-
91
- A separator with no metadata is valid for sprites:
92
-
93
- ```txt
94
-
95
- [ASCII art content]
96
- ```
97
-
98
- This inherits defaults or indicates a frame with no special properties.
99
-
100
- ## Font Assets
101
-
102
- Fonts define ASCII art representations of characters for rendering text in stylized formats.
103
-
104
- ### File Header Properties
105
-
106
- | Key | Values | Required | Description |
107
- | ------ | ------ | -------- | --------------------- |
108
- | `kind` | `font` | Yes | Asset type identifier |
109
-
110
- ### Character Separator Properties
111
-
112
- | Key | Values | Required | Description |
113
- | ----------- | ------ | -------- | ----------------------------------- |
114
- | `character` | string | Yes | The character this glyph represents |
115
-
116
- ### Font Example
117
-
118
- ``` json
119
- § {"kind":"font"}
120
- ¶ {"character":"a"}
121
-
122
- ╭─╮
123
- ╭─┤
124
- ╰─╰
125
-
126
- ¶ {"character":"b"}
127
-
128
- ├─╮
129
- │ │
130
- ╯─╯
131
-
132
- ¶ {"character":"c"}
133
-
134
- ╭─╮
135
-
136
- ╰─╯
137
- ```
138
-
139
- ### Font Design Rules
140
-
141
- - Each character glyph should have consistent height (including leading/trailing blank lines)
142
- - Characters can have variable width
143
- - Blank lines before/after the glyph art create vertical spacing
144
- - The `character` property must be a single character (letter, number, punctuation, etc.)
145
- - Fonts are typically loaded by name and used to render styled text
146
-
147
- ## Sprite Assets
148
-
149
- Sprites define animated ASCII art with multiple frames.
150
-
151
- ### File Header Properties
152
-
153
- | Key | Values | Required | Description |
154
- | -------------------- | --------------- | -------- | ------------------------------------------ |
155
- | `kind` | `sprite` | Yes | Asset type identifier |
156
- | `loop` | `true`, `false` | No | Whether animation loops (default: `false`) |
157
- | `default-frame-rate` | number (ms) | No | Default frame duration in milliseconds (default is 250 if none is supplied) |
158
-
159
- ### Frame Separator Properties
160
-
161
- | Key | Values | Required | Description |
162
- | ---------- | ----------- | -------- | ---------------------------------- |
163
- | `duration` | number (ms) | No | Frame duration (overrides default) |
164
- | `sound` | filename | No | Sound to play when frame displays |
165
- | `event` | string | No | Custom event name to trigger |
166
-
167
- ### Sprite Example
168
-
169
- ```
170
- § {"kind":"sprite","loop":true,"default-frame-rate":120}
171
- ¶ {"duration":1000}
172
- _ _ _ _
173
- __ _ ___ ___(_|_) |_ ___ _ __(_)_ _ _ __ ___
174
- / _` / __|/ __| | | __/ _ \| '__| | | | | '_ ` _ \
175
- | (_| \__ \ (__| | | || (_) | | | | |_| | | | | | |
176
- \__,_|___/\___|_|_|\__\___/|_| |_|\__,_|_| |_| |_|
177
- ¶ {"duration":500}
178
- . _ * _ * .
179
- __ _ ___ ___(_|_).|_ * _ __(_)_ _ * __
180
- / _` / __|/ _ . | __/ . \ '__| | | | ' ` \ .
181
- | (_| \__ (__| *|.| || (_) | * | | |_| *| | | │ .
182
- \__,_|___/\__ ._|_|\__\ * /|_| .|\__ |_| |_│
183
-
184
- * _ * . * . *
185
- __ * (_|_) . * _ __ . . __
186
- / ` __| | __/ * \ '__| * ` \
187
- | * * \__ | | || (_) | . | * * | | │
188
- . .|___/ |_| \__\___/|_| . . |_| . |_│
189
- ```
190
-
191
- ### Animation Control
192
-
193
- - **loop:true**: Animation repeats from first frame after last frame
194
- - **loop:false**: Animation plays once and stops on last frame
195
-
196
- ## Material Assets
197
-
198
- Materials define visual representations at different distances in first-person view.
199
-
200
- ### File Header Properties
201
-
202
- | Key | Values | Required | Description |
203
- | -------------- | ------------------------------------------- | -------- | --------------------------------- |
204
- | `kind` | `material` | Yes | Asset type identifier |
205
- | `usage` | `first-person`, `top-down`, `side-scroller` | Yes | Rendering context |
206
- | `placement` | `scenery`, `ground`, `ceiling` | No | Surface type (default: `scenery`) |
207
- | `onEnterSound` | filename | No | Sound when player enters tile |
208
- | `onExitSound` | filename | No | Sound when player exits tile |
209
- | `ambientSound` | filename | No | Looping sound near this material |
210
-
211
- ### Layer Separator Properties
212
-
213
- | Key | Values | Required | Description |
214
- | ------- | ------------------------------- | -------- | ------------------------------- |
215
- | `layer` | `here`, `near`, `middle`, `far` | Yes | Distance layer |
216
- | `pos` | `left`, `center`, `right` | Yes | Horizontal position |
217
- | `x` | number | No | Horizontal offset for alignment |
218
-
219
- ### Material Example
220
-
221
- ```
222
- § {"kind":"material","usage":"first-person","placement":"scenery","onEnterSound":"door-open.mp3","onExitSound":"door-close.mp3"}
223
- ¶ {"layer":"here","pos":"left"}
224
-
225
- ┊╲
226
- ╲┊ ╲
227
- ¶ {"layer":"here","pos":"center"}
228
- |‽‽‽‽‽‽‽‽‽‽|
229
- |‽‽‽‽‽‽‽‽‽‽|
230
- |‽‽‽‽‽‽‽‽‽‽|
231
- ¶ {"layer":"here","pos":"right"}
232
-
233
- ╱┊
234
- ╱ ┊╱
235
- ¶ {"layer":"near","pos":"center"}
236
- …… ……… ……… …
237
- ┊……┊………┊………┊…┊
238
- ┊┊…╭───────╮…┊
239
- ┊……|┋┋┋┋┋┋┋|…┊
240
- ¶ {"layer":"middle","pos":"center"}
241
- … … ……
242
- ┊…┊…┊……┊
243
- ┊…╭──╮…┊
244
- ┊…|┋┋|…┊
245
- ¶ {"layer":"far","pos":"center"}
246
- ……
247
- ┊……┊
248
- ┊||┊
249
- ```
250
-
251
- ### Layer System
252
-
253
- Materials use a layered perspective system that adapts to different usage contexts:
254
-
255
- #### First-Person Usage
256
-
257
- - **here**: Immediate foreground (player is on this tile)
258
- - **near**: Close distance (1-2 tiles away)
259
- - **middle**: Mid distance (3-5 tiles away)
260
- - **far**: Far distance (6+ tiles away)
261
-
262
- #### Side-Scroller Usage (Parallax Layers)
263
-
264
- - **here**: Interactive elements (platforms player stands on, walls player collides with)
265
- - **near**: Foreground elements (close platforms, foreground decorations)
266
- - **middle**: Midground elements (trees, buildings, mid-distance scenery)
267
- - **far**: Background elements (mountains, clouds, distant scenery)
268
-
269
- #### Top-Down Usage
270
-
271
- - **here**: Ground level elements (floors, paths the player walks on)
272
- - **near**: Low obstacles and ground decorations
273
- - **middle**: Medium height elements (furniture, props)
274
- - **far**: Tall elements and ceiling details
275
-
276
- Each layer can have `left`, `center`, and `right` positioned elements for additional composition control.
277
-
278
- ### Sound Triggers
279
-
280
- Sound properties are defined once in the file header and apply to the entire material:
281
-
282
- - **onEnterSound**: Plays once when player steps onto the tile
283
- - **onExitSound**: Plays once when player leaves the tile
284
- - **ambientSound**: Looping sound while material is visible (future feature)
285
-
286
- Sound files must be placed in `art/sounds/` directory.
287
-
288
- ### Side-Scroller Material Example
289
-
290
- Here's an example of materials for a side-scrolling platformer game:
291
-
292
- **Ground Platform:**
293
-
294
- ```
295
- § {"kind":"material","usage":"side-scroller","placement":"ground","onEnterSound":"step.mp3"}
296
- ¶ {"layer":"here","pos":"center"}
297
- ═══════════════════════
298
- ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
299
- ```
300
-
301
- **Brick Wall:**
302
-
303
- ```
304
- § {"kind":"material","usage":"side-scroller","placement":"scenery"}
305
- ¶ {"layer":"here","pos":"center"}
306
- █▓▒░█▓▒░█▓▒░
307
- ░▒▓█░▒▓█░▒▓█
308
- █▓▒░█▓▒░█▓▒░
309
- ░▒▓█░▒▓█░▒▓█
310
- ```
311
-
312
- **Background Mountain (Parallax):**
313
-
314
- ```
315
- § {"kind":"material","usage":"side-scroller","placement":"scenery"}
316
- ¶ {"layer":"far","pos":"center"}
317
- /\
318
- / \
319
- / \
320
- / \
321
- / \
322
- ¶ {"layer":"middle","pos":"center"}
323
- /\ /\
324
- / \/ \
325
- / \
326
- ¶ {"layer":"near","pos":"center"}
327
- /\/\
328
- / \
329
- ```
330
-
331
- In side-scrollers, the layer system naturally supports parallax scrolling where `far` layers move slower than `here` layers, creating depth perception.
332
-
333
- ## Validation Rules
334
-
335
- ### Required Properties
336
-
337
- - File header MUST have `kind` property
338
- - Material layers MUST have `layer` and `pos` properties
339
- - Sprite frames MAY omit all properties (inherits defaults)
340
-
341
- ### No Nesting Rule
342
-
343
- - All values MUST be primitives (string, number, or boolean)
344
- - Nested objects are NOT allowed
345
- - Arrays are NOT allowed
346
- - This keeps the format simple and predictable
347
-
348
- **Invalid (nested object):**
349
-
350
- ```json
351
- { "onEnter": { "sound": "door.mp3" } }
352
- ```
353
-
354
- **Valid (flat structure with primitives):**
355
-
356
- ```json
357
- { "onEnterSound": "door.mp3", "duration": 1000, "loop": true }
358
- ```
359
-
360
- ### Value Constraints
361
-
362
- - **layer**: Must be one of `here`, `near`, `middle`, `far`
363
- - **pos**: Must be one of `left`, `center`, `right`
364
- - **placement**: Must be one of `scenery`, `ground`, `ceiling`
365
- - **usage**: Must be one of `first-person`, `top-down`, `side-scroller`
366
- - **loop**: Must be boolean `true` or `false`
367
- - **duration**: Must be positive number (milliseconds)
368
- - **default-frame-rate**: Must be positive number (milliseconds)
369
- - **x**: Must be number (integer)
370
-
371
- ### Sound File References
372
-
373
- - Sound properties contain filename only (no path)
374
- - Files resolved relative to `art/sounds/` directory
375
- - Format: `"onEnterSound":"door-open.mp3"` not `"onEnterSound":"art/sounds/door-open.mp3"`
@@ -1,113 +0,0 @@
1
- # Asciitorium Fonts
2
-
3
- This directory contains ASCII font files for the **Banner** component. Fonts
4
- allow you to display large, stylized text using ASCII art characters.
5
-
6
- ## Font File Format
7
-
8
- Font files use the `.art` extension and follow a structured format with metadata
9
- separators:
10
-
11
- ### File Structure
12
-
13
- ``` txt
14
- § {"kind":"font"}
15
- ¶ {"character":"A"}
16
- ╭─╮
17
- │ │
18
- ├─┤
19
- ╵ ╵
20
-
21
- ¶ {"character":"a"}
22
-
23
- ╭─╮
24
- ╭─┤
25
- ╰─╰
26
-
27
- ¶ {"character":["b", "B"]}
28
-
29
- ├─╮
30
- │ │
31
- ╯─╯
32
- ```
33
-
34
- ### Key Components
35
-
36
- 1. **File Header** (`§` separator)
37
- - Must start with `§ {"kind":"font"}`
38
- - Indicates this is a font asset
39
-
40
- 2. **Glyph Sections** (`¶` separator)
41
- - Each glyph begins with `¶ {"character":"x"}` where `x` is the character
42
- - Character can be a single string: `"a"`
43
- - Or an array for multiple mappings: `["b", "B"]` (both lowercase and
44
- uppercase)
45
- - Glyph content follows immediately after the metadata line
46
-
47
- 3. **Glyph Content**
48
- - ASCII art representation of the character
49
- - Each glyph can be any width/height
50
- - Vertical positioning is preserved (blank lines matter!)
51
- - Maximum font height is determined by the tallest glyph
52
-
53
- **Tips:**
54
-
55
- - Empty lines within glyphs are preserved to maintain vertical alignment
56
- - The first line after the glyph metadata is part of the character (no automatic
57
- trimming)
58
- - Map multiple characters to the same glyph using arrays:
59
- `{"character":["a","A"]}`
60
- - All glyphs should have consistent height for best results (pad with empty
61
- lines if needed)
62
-
63
- ## Using Fonts in Your App
64
-
65
- ### Basic Usage
66
-
67
- ```tsx
68
- <Banner font="pencil" text="asciitorium" />
69
- ```
70
-
71
- ### With Letter Spacing
72
-
73
- ```tsx
74
- <Banner font="marker" text="HELLO" letterSpacing={1} />
75
- ```
76
-
77
- ### With Reactive State
78
-
79
- ```tsx
80
- import { State } from 'asciitorium';
81
-
82
- const titleText = new State<string>("Welcome");
83
-
84
- <Banner font="shadows" text={titleText} align="center" />
85
- ```
86
-
87
- ### Available Props
88
-
89
- - `font` (required): Name of the font file (without `.art` extension)
90
- - `text`: String or `State<string>` to render
91
- - `letterSpacing`: Additional spacing between characters (default: 0)
92
- - Plus all standard component props: `position`, `border`, `align`, `style`,
93
- etc.
94
-
95
- ## Technical Details
96
-
97
- ### Loading
98
-
99
- Fonts are loaded asynchronously via the `AssetManager`:
100
-
101
- ```typescript
102
- const fontAsset = await AssetManager.getFont('myfont');
103
- ```
104
-
105
- ### Caching
106
-
107
- Font assets are cached on first load - subsequent uses of the same font reuse
108
- the cached data.
109
-
110
- ### Fallback Rendering
111
-
112
- If a character is not found in the font, the Banner component renders the
113
- character itself as a single-width glyph on the top line.