create-asciitorium 0.1.46 → 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.
- package/dist/templates/base/ASCIITORIUM_REFERENCE.md +45 -30
- package/dist/templates/base/public/art/README.md +82 -83
- package/dist/templates/base/public/art/fonts/README.md +115 -0
- package/dist/templates/base/public/art/maps/README.md +89 -190
- package/dist/templates/base/public/art/materials/README.md +82 -206
- package/dist/templates/base/public/art/sounds/README.md +11 -0
- package/dist/templates/base/public/art/sprites/README.md +138 -0
- package/dist/templates/base/src/main.tsx +4 -4
- package/dist/templates/base/vite.config.ts +12 -1
- package/package.json +1 -1
- package/dist/templates/base/public/art/ART-DESIGN-SPEC.md +0 -375
- package/dist/templates/base/public/art/font/pencil.art +0 -168
- package/dist/templates/base/public/art/maps/example/README.md +0 -62
- package/dist/templates/base/public/art/maps/example/legend.json +0 -29
- package/dist/templates/base/public/art/maps/example/map.art +0 -21
- package/dist/templates/base/public/art/materials/bone.art +0 -11
- package/dist/templates/base/public/art/materials/door-wooden.art +0 -154
- package/dist/templates/base/public/art/materials/wall-brick.art +0 -128
- package/dist/templates/base/public/art/materials/wall-wireframe.art +0 -128
- package/dist/templates/base/public/art/sounds/door-close.mp3 +0 -0
- package/dist/templates/base/public/art/sounds/door-open.mp3 +0 -0
- package/dist/templates/base/public/art/sounds/taps.mp3 +0 -0
- package/dist/templates/base/public/art/sprites/asciitorium.art +0 -6
- package/dist/templates/base/public/art/sprites/balloon.art +0 -126
- package/dist/templates/base/public/art/sprites/beating-heart.art +0 -49
- package/dist/templates/base/public/art/sprites/castle.art +0 -4
- package/dist/templates/base/public/art/sprites/component-icon.art +0 -6
- package/dist/templates/base/public/art/sprites/eyes.art +0 -61
- package/dist/templates/base/public/art/sprites/firework.art +0 -58
- package/dist/templates/base/public/art/sprites/heart.art +0 -5
- package/dist/templates/base/public/art/sprites/multi-select-test.art +0 -6
- package/dist/templates/base/public/art/sprites/nav-basics.art +0 -5
- package/dist/templates/base/public/art/sprites/pyramid.art +0 -5
- package/dist/templates/base/public/art/sprites/welcome.art +0 -7
- package/dist/templates/base/src/reference-validation.tsx +0 -307
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
# Materials
|
|
1
|
+
# Asciitorium Materials
|
|
2
2
|
|
|
3
|
-
This directory
|
|
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
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
This directory contains ASCII art material files for the **FirstPersonView** and
|
|
6
|
+
**MapView** components. Materials define the visual appearance of walls, floors,
|
|
7
|
+
and other environmental surfaces with depth-based layering.
|
|
8
8
|
|
|
9
9
|
## Material File Format
|
|
10
10
|
|
|
11
|
-
Material files use
|
|
11
|
+
Material files use the `.art` extension and follow a structured format with
|
|
12
|
+
metadata separators:
|
|
12
13
|
|
|
13
14
|
### File Structure
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
1. **Metadata line**: JSON configuration starting with `¶`
|
|
18
|
-
2. **ASCII art**: The visual representation using text characters
|
|
19
|
-
|
|
20
|
-
### Example Material
|
|
21
|
-
|
|
22
|
-
Here's a section from `wireframe.art` showing the layered format:
|
|
16
|
+
#### Wall Material
|
|
23
17
|
|
|
24
|
-
```
|
|
18
|
+
```txt
|
|
25
19
|
§ {"kind":"material","usage":"first-person"}
|
|
26
20
|
¶ {"layer":"here","position":"left","x":-1}
|
|
27
21
|
|╲
|
|
@@ -41,11 +35,9 @@ Here's a section from `wireframe.art` showing the layered format:
|
|
|
41
35
|
|____________|
|
|
42
36
|
```
|
|
43
37
|
|
|
44
|
-
|
|
38
|
+
#### Ground Material
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```text
|
|
40
|
+
```txt
|
|
49
41
|
§ {"kind":"material","usage":"first-person","placement":"ground"}
|
|
50
42
|
¶ {"layer":"here","position":"center"}
|
|
51
43
|
⎽ ⎽
|
|
@@ -59,221 +51,105 @@ Here's an example from `bone.art` showing placement for ground materials:
|
|
|
59
51
|
‥
|
|
60
52
|
```
|
|
61
53
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
- **Perspective lines**: `╱`, `╲` for diagonal depth
|
|
102
|
-
- **Solid fills**: `_` for horizontal surfaces
|
|
103
|
-
- **Spacing**: Careful use of spaces for proper alignment and depth
|
|
104
|
-
|
|
105
|
-
## Usage in Maps
|
|
54
|
+
### Key Components
|
|
55
|
+
|
|
56
|
+
1. **File Header** (`§` separator)
|
|
57
|
+
- Must start with `§ {"kind":"material"}`
|
|
58
|
+
- Indicates this is a material asset
|
|
59
|
+
- Defines material properties:
|
|
60
|
+
- `usage`: Rendering context (`"first-person"`, `"top-down"`,
|
|
61
|
+
`"side-scroller"`)
|
|
62
|
+
- `placement`: Surface type (`"scenery"` [default], `"ground"`,
|
|
63
|
+
`"ceiling"`)
|
|
64
|
+
- `onEnterSound`: Sound file to play when player enters tile (e.g.,
|
|
65
|
+
`"splash.mp3"`)
|
|
66
|
+
- `onExitSound`: Sound file to play when player exits tile
|
|
67
|
+
- `ambientSound`: Looping sound while visible (future feature)
|
|
68
|
+
|
|
69
|
+
2. **Layer Sections** (`¶` separator)
|
|
70
|
+
- Each layer begins with `¶` followed by JSON metadata
|
|
71
|
+
- Layer metadata:
|
|
72
|
+
- `layer`: Depth layer (`"here"`, `"near"`, `"middle"`, `"far"`)
|
|
73
|
+
- `position`: Horizontal alignment (`"left"`, `"center"`, `"right"`)
|
|
74
|
+
- `x`: Horizontal offset for precise positioning
|
|
75
|
+
- Layer content follows immediately after the metadata line
|
|
76
|
+
|
|
77
|
+
3. **Layer Content**
|
|
78
|
+
- ASCII art representation of the material at that depth
|
|
79
|
+
- Each layer can be any width/height
|
|
80
|
+
- Blank lines are preserved
|
|
81
|
+
- Multiple layers create perspective depth
|
|
82
|
+
|
|
83
|
+
**Tips:**
|
|
84
|
+
|
|
85
|
+
- `"here"` layer is closest to viewer (immediate foreground)
|
|
86
|
+
- `"far"` layer is furthest (distant background)
|
|
87
|
+
- Use box drawing characters for structure: `|`, `─`, `╱`, `╲`, `╭`, `╮`, `╯`,
|
|
88
|
+
`╰`
|
|
89
|
+
- Each layer can have left/center/right positioned elements with x-offsets for
|
|
90
|
+
perspective alignment
|
|
91
|
+
|
|
92
|
+
## Using Materials in Your App
|
|
106
93
|
|
|
107
94
|
Materials are referenced in map legends through the `asset` property:
|
|
108
95
|
|
|
96
|
+
### Map Legend Entry
|
|
97
|
+
|
|
109
98
|
```json
|
|
110
99
|
{
|
|
111
100
|
"chars": ["#"],
|
|
112
|
-
"kind": "material",
|
|
113
101
|
"name": "wireframe-wall",
|
|
114
102
|
"solid": true,
|
|
115
|
-
"
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
The system will load the corresponding `wireframe.art` file and render the appropriate layer based on the viewing context and distance.
|
|
120
|
-
|
|
121
|
-
## Relationship with Legend Entities
|
|
122
|
-
|
|
123
|
-
The architecture separates visual presentation (materials) from gameplay behavior (legend entities):
|
|
124
|
-
|
|
125
|
-
### Materials Handle
|
|
126
|
-
|
|
127
|
-
- **Visual representation** at different distances (layer system)
|
|
128
|
-
- **Ambient sounds** tied to proximity (howling when near a wolf wall)
|
|
129
|
-
- **Transition sounds** when moving between layers (door creaking as you approach)
|
|
130
|
-
- **Distance-based events** (footsteps on different floor types)
|
|
131
|
-
|
|
132
|
-
### Legend Entities Handle
|
|
133
|
-
|
|
134
|
-
- **Interactions** (opening doors, picking up items, talking to NPCs)
|
|
135
|
-
- **Game state** (is door locked/unlocked, enemy health, treasure quantity)
|
|
136
|
-
- **Collision detection** (solid vs passable)
|
|
137
|
-
- **Gameplay behaviors** (enemy AI, trap triggers, puzzle mechanics)
|
|
138
|
-
|
|
139
|
-
### Example: Door Material + Entity
|
|
140
|
-
|
|
141
|
-
**Material file** (`door-wooden.art`):
|
|
142
|
-
|
|
143
|
-
```text
|
|
144
|
-
§ {"kind":"material","usage":"first-person","placement":"scenery","onEnterSound":"door-open.mp3","onExitSound":"door-close.mp3"}
|
|
145
|
-
¶ {"layer":"here","position":"center"}
|
|
146
|
-
[ASCII art for door at immediate distance - plays open sound when player steps onto this tile, close sound when leaving]
|
|
147
|
-
¶ {"layer":"near","position":"center"}
|
|
148
|
-
[ASCII art for door at near distance]
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
**Legend entry** (references the material):
|
|
152
|
-
|
|
153
|
-
```json
|
|
154
|
-
{
|
|
155
|
-
"chars": ["o"],
|
|
156
|
-
"kind": "material",
|
|
157
|
-
"entity": "door",
|
|
158
|
-
"variant": "wooden",
|
|
159
|
-
"name": "Wooden Door",
|
|
160
|
-
"solid": false,
|
|
161
|
-
"asset": "material/door-wooden",
|
|
162
|
-
"state": {
|
|
163
|
-
"locked": false,
|
|
164
|
-
"open": false
|
|
165
|
-
},
|
|
166
|
-
"interactions": {
|
|
167
|
-
"onInteract": "toggle-door",
|
|
168
|
-
"onMelee": "bash-door"
|
|
169
|
-
}
|
|
103
|
+
"material": "wireframe"
|
|
170
104
|
}
|
|
171
105
|
```
|
|
172
106
|
|
|
173
|
-
|
|
107
|
+
The system loads the corresponding `wireframe.art` file and renders the
|
|
108
|
+
appropriate layer based on viewing context and distance.
|
|
174
109
|
|
|
175
|
-
|
|
176
|
-
- **Instance-specific behavior**: Each door on the map can have different state (some locked, some open)
|
|
177
|
-
- **Separation of concerns**: Artists focus on materials, game designers focus on legend entities
|
|
178
|
-
- **Sensory cohesion**: Sounds/visuals stay together in material files
|
|
110
|
+
## Technical Details
|
|
179
111
|
|
|
180
|
-
###
|
|
112
|
+
### Loading
|
|
181
113
|
|
|
182
|
-
|
|
114
|
+
Materials are loaded asynchronously via the `AssetManager`:
|
|
183
115
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
```text
|
|
187
|
-
§ {"kind":"material","usage":"first-person","placement":"ground","onEnterSound":"splash.mp3"}
|
|
188
|
-
¶ {"layer":"here","position":"center"}
|
|
189
|
-
~~~~
|
|
190
|
-
~~~~~~
|
|
191
|
-
~~~~~~~~
|
|
192
|
-
~~~~~~
|
|
193
|
-
~~~~
|
|
194
|
-
¶ {"layer":"near","position":"center"}
|
|
195
|
-
~~
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**Legend entry**:
|
|
199
|
-
|
|
200
|
-
```json
|
|
201
|
-
{
|
|
202
|
-
"chars": ["~"],
|
|
203
|
-
"kind": "material",
|
|
204
|
-
"name": "puddle",
|
|
205
|
-
"solid": false,
|
|
206
|
-
"asset": "material/puddle"
|
|
207
|
-
}
|
|
116
|
+
```typescript
|
|
117
|
+
const materialAsset = await AssetManager.getMaterial('wireframe');
|
|
208
118
|
```
|
|
209
119
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
- Gravel paths (`crunch.mp3`)
|
|
213
|
-
- Creaky floorboards (`creak.mp3`)
|
|
214
|
-
- Grass (`rustle.mp3`)
|
|
215
|
-
- Snow (`snow-step.mp3`)
|
|
216
|
-
|
|
217
|
-
## Sound System
|
|
218
|
-
|
|
219
|
-
Materials support sound playback through properties in the section header (`§`). Sounds are automatically triggered by the GameWorld when the player moves.
|
|
220
|
-
|
|
221
|
-
### Sound File Requirements
|
|
222
|
-
|
|
223
|
-
- **Location**: Place sound files in `art/sounds/` directory relative to your project root
|
|
224
|
-
- **Formats**: MP3, WAV, and other browser-supported audio formats
|
|
225
|
-
- **Environment**: Sounds only play in web environments (browser), not in CLI mode
|
|
226
|
-
- **Reference**: Use filename in section header: `{"onEnterSound":"filename.mp3"}`
|
|
227
|
-
|
|
228
|
-
### Sound Properties
|
|
120
|
+
### Caching
|
|
229
121
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
- **ambientSound**: Looping sound while material is visible (future feature)
|
|
122
|
+
Material assets are cached on first load - subsequent uses of the same material
|
|
123
|
+
reuse the cached data.
|
|
233
124
|
|
|
234
|
-
###
|
|
125
|
+
### Sound System
|
|
235
126
|
|
|
236
|
-
|
|
127
|
+
Materials support sound playback through properties in the file header (`§`):
|
|
237
128
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
6. When the player leaves the tile, `onExitSound` plays (if defined)
|
|
244
|
-
7. Sounds play once per tile entry/exit (moving onto the same tile repeatedly will retrigger both sounds)
|
|
129
|
+
- **Sound files location**: `art/sounds/` directory
|
|
130
|
+
- **Supported formats**: MP3
|
|
131
|
+
- **Environment**: Sounds only play in web mode (not CLI)
|
|
132
|
+
- **onEnterSound**: Plays once when player steps onto tile with this material
|
|
133
|
+
- **onExitSound**: Plays once when player steps off tile
|
|
245
134
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
You can control sound globally through the `SoundManager`:
|
|
135
|
+
Control sounds globally via `SoundManager`:
|
|
249
136
|
|
|
250
137
|
```typescript
|
|
251
138
|
import { SoundManager } from 'asciitorium';
|
|
252
139
|
|
|
253
|
-
// Disable all sounds
|
|
254
|
-
SoundManager.setEnabled(
|
|
255
|
-
|
|
256
|
-
// Re-enable sounds
|
|
257
|
-
SoundManager.setEnabled(true);
|
|
258
|
-
|
|
259
|
-
// Check if sounds are enabled
|
|
260
|
-
const enabled = SoundManager.isEnabled();
|
|
261
|
-
|
|
262
|
-
// Manually play a sound
|
|
263
|
-
SoundManager.playSound('custom-sound.mp3');
|
|
264
|
-
|
|
265
|
-
// Clear sound cache
|
|
266
|
-
SoundManager.clearCache();
|
|
140
|
+
SoundManager.setEnabled(false); // Disable all sounds
|
|
141
|
+
SoundManager.setEnabled(true); // Re-enable sounds
|
|
142
|
+
SoundManager.playSound('custom-sound.mp3'); // Play manually
|
|
267
143
|
```
|
|
268
144
|
|
|
269
|
-
|
|
145
|
+
### Layer System
|
|
270
146
|
|
|
271
|
-
|
|
147
|
+
The layering system creates first-person perspective depth:
|
|
272
148
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
5. Follow ASCII art best practices for readability
|
|
149
|
+
- **here**: Immediate foreground (closest to viewer)
|
|
150
|
+
- **near**: Close objects with full detail
|
|
151
|
+
- **middle**: Mid-distance objects with moderate detail
|
|
152
|
+
- **far**: Distant objects with minimal detail
|
|
278
153
|
|
|
279
|
-
|
|
154
|
+
Each layer can have left, center, and right positioned elements with specific
|
|
155
|
+
x-offsets for proper perspective alignment.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Sounds Directory
|
|
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
|
+
|
|
5
|
+
This directory contains audio assets in MP3 format used throughout the
|
|
6
|
+
application.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
Sound files can be referenced in material definitions, sprite definitions, or
|
|
11
|
+
played programmatically through the application's audio system.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Asciitorium Sprites
|
|
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
|
+
|
|
5
|
+
This directory contains ASCII sprite files for the **Art** component. Sprites
|
|
6
|
+
allow you to display static or animated ASCII art via the Art component.
|
|
7
|
+
|
|
8
|
+
## Sprite File Format
|
|
9
|
+
|
|
10
|
+
Sprite files use the `.art` extension and follow a structured format with
|
|
11
|
+
metadata separators:
|
|
12
|
+
|
|
13
|
+
### File Structure
|
|
14
|
+
|
|
15
|
+
#### Simple Static Sprite (no metadata)
|
|
16
|
+
|
|
17
|
+
``` txt
|
|
18
|
+
▄█▀█▄ ▄███▄
|
|
19
|
+
▐█░██████████▌
|
|
20
|
+
██▒█████████
|
|
21
|
+
▀████████▀
|
|
22
|
+
▀██▀
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### Animated Sprite with Metadata
|
|
26
|
+
|
|
27
|
+
``` txt
|
|
28
|
+
§ {"kind":"sprite","loop":true,"default-frame-rate":100}
|
|
29
|
+
¶ {"duration":1000}
|
|
30
|
+
▄█▀█▄ ▄███▄
|
|
31
|
+
▐█░██████████▌
|
|
32
|
+
██▒█████████
|
|
33
|
+
▀████████▀
|
|
34
|
+
▀██▀
|
|
35
|
+
¶
|
|
36
|
+
▄█▀▄ ▄██▄
|
|
37
|
+
▐█░████████▌
|
|
38
|
+
██▒███████
|
|
39
|
+
▀██████▀
|
|
40
|
+
▀▀
|
|
41
|
+
¶
|
|
42
|
+
▄█▀▄▄██▄
|
|
43
|
+
▐█░██████▌
|
|
44
|
+
██▒█████
|
|
45
|
+
▀████▀
|
|
46
|
+
▀▀
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Key Components
|
|
50
|
+
|
|
51
|
+
1. **File Header** (`§` separator) - Optional
|
|
52
|
+
- Must start with `§ {"kind":"sprite"}`
|
|
53
|
+
- Indicates this is a sprite asset
|
|
54
|
+
- Defines default animation settings:
|
|
55
|
+
- `default-frame-rate`: Default duration in milliseconds for each frame
|
|
56
|
+
- `loop`: Whether animation loops (true/false)
|
|
57
|
+
- `transparent`: Single character to treat as transparent (e.g., `" "`)
|
|
58
|
+
|
|
59
|
+
2. **Frame Sections** (`¶` separator) - Optional
|
|
60
|
+
- Each frame begins with `¶` followed by optional JSON metadata
|
|
61
|
+
- Frame metadata (all optional):
|
|
62
|
+
- `duration`: Override default frame duration in milliseconds
|
|
63
|
+
- `sound`: Sound ID to play when frame displays
|
|
64
|
+
- Frame content follows immediately after the metadata line
|
|
65
|
+
- If no metadata needed, use `¶` alone
|
|
66
|
+
|
|
67
|
+
3. **Frame Content**
|
|
68
|
+
- ASCII art representation of the sprite frame
|
|
69
|
+
- Each frame can be any width/height
|
|
70
|
+
- Blank lines are preserved
|
|
71
|
+
- Maximum sprite dimensions determined by largest frame
|
|
72
|
+
|
|
73
|
+
**Tips:**
|
|
74
|
+
|
|
75
|
+
- Files without `§` or `¶` are treated as single-frame static sprites
|
|
76
|
+
- Empty lines within frames are preserved for vertical spacing
|
|
77
|
+
- The first line after frame metadata is part of the sprite (no automatic
|
|
78
|
+
trimming)
|
|
79
|
+
- All frames should have consistent dimensions for best results
|
|
80
|
+
- Use the `transparent` property to define overlay sprites
|
|
81
|
+
|
|
82
|
+
## Using Sprites in Your App
|
|
83
|
+
|
|
84
|
+
### Basic Usage (Async Loading)
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<Art sprite="balloon" />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### With Reactive State
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import { State } from 'asciitorium';
|
|
94
|
+
|
|
95
|
+
const playerSprite = new State<string>(defaultArt);
|
|
96
|
+
|
|
97
|
+
<Art content={playerSprite} />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Available Props
|
|
101
|
+
|
|
102
|
+
- `sprite`: Name of sprite file (without `.art` extension) to load asynchronously
|
|
103
|
+
- `content`: String or `State<string>` for inline sprite content
|
|
104
|
+
- `children`: Alternative way to provide inline content
|
|
105
|
+
- Plus all standard component props: `position`, `border`, `align`, `style`,
|
|
106
|
+
etc.
|
|
107
|
+
|
|
108
|
+
## Technical Details
|
|
109
|
+
|
|
110
|
+
### Loading
|
|
111
|
+
|
|
112
|
+
Sprites are loaded asynchronously via the `AssetManager`:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const spriteAsset = await AssetManager.getSprite('mysprite');
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Caching
|
|
119
|
+
|
|
120
|
+
Sprite assets are cached on first load - subsequent uses of the same sprite
|
|
121
|
+
reuse the cached data.
|
|
122
|
+
|
|
123
|
+
### Animation System
|
|
124
|
+
|
|
125
|
+
The Art component automatically:
|
|
126
|
+
|
|
127
|
+
- Parses sprite metadata and frames
|
|
128
|
+
- Schedules frame transitions based on duration
|
|
129
|
+
- Handles looping vs. one-shot playback
|
|
130
|
+
- Requests renders when frames change
|
|
131
|
+
- Cleans up timers when component is destroyed
|
|
132
|
+
|
|
133
|
+
### Dimension Calculation
|
|
134
|
+
|
|
135
|
+
Component dimensions are automatically calculated from the largest frame:
|
|
136
|
+
|
|
137
|
+
- Width: Maximum line length across all frames
|
|
138
|
+
- Height: Maximum number of lines across all frames
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
App,
|
|
3
3
|
Art,
|
|
4
|
-
|
|
4
|
+
Banner,
|
|
5
5
|
Column,
|
|
6
6
|
Text,
|
|
7
7
|
PerfMonitor,
|
|
@@ -25,14 +25,14 @@ const app = (
|
|
|
25
25
|
<Keybind keyBinding="p" action={togglePerfMonitor} />
|
|
26
26
|
|
|
27
27
|
<Column style={{ align: 'center', gap: 1, width: '100%' }}>
|
|
28
|
-
<
|
|
29
|
-
<
|
|
28
|
+
<Banner font="pencil" text="Welcome to" align="center" />
|
|
29
|
+
<Banner font="shadows" text="asciitorium" align="center" />
|
|
30
30
|
|
|
31
31
|
<Text style={{ align: 'center', gap: 1 }}>
|
|
32
32
|
Edit src/main.tsx and save to reload.
|
|
33
33
|
</Text>
|
|
34
34
|
|
|
35
|
-
<Art
|
|
35
|
+
<Art sprite="beating-heart" width={20} align="center" />
|
|
36
36
|
|
|
37
37
|
<Text style={{ align: 'center', gap: 1 }}>
|
|
38
38
|
Press [P] to toggle performance monitor
|
|
@@ -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
|
});
|