create-asciitorium 0.1.45 → 0.1.47
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 +187 -134
- package/dist/templates/base/public/art/README.md +23 -96
- package/dist/templates/base/public/art/font/README.md +113 -0
- package/dist/templates/base/public/art/fonts/README.md +113 -0
- package/dist/templates/base/public/art/maps/README.md +87 -190
- package/dist/templates/base/public/art/materials/README.md +81 -207
- package/dist/templates/base/public/art/sounds/README.md +9 -0
- package/dist/templates/base/public/art/sprites/README.md +136 -0
- package/dist/templates/base/src/main.tsx +4 -4
- package/dist/templates/base/src/reference-validation.tsx +1 -1
- package/package.json +1 -1
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
# Materials
|
|
1
|
+
# Asciitorium Materials
|
|
2
2
|
|
|
3
|
-
This directory contains ASCII art
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `wireframe.art`: A complex wireframe pattern demonstrating layered first-person perspective rendering
|
|
3
|
+
This directory contains ASCII art material files for the **FirstPersonView** and
|
|
4
|
+
**MapView** components. Materials define the visual appearance of walls, floors,
|
|
5
|
+
and other environmental surfaces with depth-based layering.
|
|
8
6
|
|
|
9
7
|
## Material File Format
|
|
10
8
|
|
|
11
|
-
Material files use
|
|
9
|
+
Material files use the `.art` extension and follow a structured format with
|
|
10
|
+
metadata separators:
|
|
12
11
|
|
|
13
12
|
### File Structure
|
|
14
13
|
|
|
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:
|
|
14
|
+
#### Wall Material
|
|
23
15
|
|
|
24
|
-
```
|
|
16
|
+
```txt
|
|
25
17
|
§ {"kind":"material","usage":"first-person"}
|
|
26
18
|
¶ {"layer":"here","position":"left","x":-1}
|
|
27
19
|
|╲
|
|
@@ -41,11 +33,9 @@ Here's a section from `wireframe.art` showing the layered format:
|
|
|
41
33
|
|____________|
|
|
42
34
|
```
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
#### Ground Material
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```text
|
|
38
|
+
```txt
|
|
49
39
|
§ {"kind":"material","usage":"first-person","placement":"ground"}
|
|
50
40
|
¶ {"layer":"here","position":"center"}
|
|
51
41
|
⎽ ⎽
|
|
@@ -59,221 +49,105 @@ Here's an example from `bone.art` showing placement for ground materials:
|
|
|
59
49
|
‥
|
|
60
50
|
```
|
|
61
51
|
|
|
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
|
|
52
|
+
### Key Components
|
|
53
|
+
|
|
54
|
+
1. **File Header** (`§` separator)
|
|
55
|
+
- Must start with `§ {"kind":"material"}`
|
|
56
|
+
- Indicates this is a material asset
|
|
57
|
+
- Defines material properties:
|
|
58
|
+
- `usage`: Rendering context (`"first-person"`, `"top-down"`,
|
|
59
|
+
`"side-scroller"`)
|
|
60
|
+
- `placement`: Surface type (`"scenery"` [default], `"ground"`,
|
|
61
|
+
`"ceiling"`)
|
|
62
|
+
- `onEnterSound`: Sound file to play when player enters tile (e.g.,
|
|
63
|
+
`"splash.mp3"`)
|
|
64
|
+
- `onExitSound`: Sound file to play when player exits tile
|
|
65
|
+
- `ambientSound`: Looping sound while visible (future feature)
|
|
66
|
+
|
|
67
|
+
2. **Layer Sections** (`¶` separator)
|
|
68
|
+
- Each layer begins with `¶` followed by JSON metadata
|
|
69
|
+
- Layer metadata:
|
|
70
|
+
- `layer`: Depth layer (`"here"`, `"near"`, `"middle"`, `"far"`)
|
|
71
|
+
- `position`: Horizontal alignment (`"left"`, `"center"`, `"right"`)
|
|
72
|
+
- `x`: Horizontal offset for precise positioning
|
|
73
|
+
- Layer content follows immediately after the metadata line
|
|
74
|
+
|
|
75
|
+
3. **Layer Content**
|
|
76
|
+
- ASCII art representation of the material at that depth
|
|
77
|
+
- Each layer can be any width/height
|
|
78
|
+
- Blank lines are preserved
|
|
79
|
+
- Multiple layers create perspective depth
|
|
80
|
+
|
|
81
|
+
**Tips:**
|
|
82
|
+
|
|
83
|
+
- `"here"` layer is closest to viewer (immediate foreground)
|
|
84
|
+
- `"far"` layer is furthest (distant background)
|
|
85
|
+
- Use box drawing characters for structure: `|`, `─`, `╱`, `╲`, `╭`, `╮`, `╯`,
|
|
86
|
+
`╰`
|
|
87
|
+
- Each layer can have left/center/right positioned elements with x-offsets for
|
|
88
|
+
perspective alignment
|
|
89
|
+
|
|
90
|
+
## Using Materials in Your App
|
|
106
91
|
|
|
107
92
|
Materials are referenced in map legends through the `asset` property:
|
|
108
93
|
|
|
94
|
+
### Map Legend Entry
|
|
95
|
+
|
|
109
96
|
```json
|
|
110
97
|
{
|
|
111
98
|
"chars": ["#"],
|
|
112
|
-
"kind": "material",
|
|
113
99
|
"name": "wireframe-wall",
|
|
114
100
|
"solid": true,
|
|
115
|
-
"
|
|
101
|
+
"material": "wireframe"
|
|
116
102
|
}
|
|
117
103
|
```
|
|
118
104
|
|
|
119
|
-
The system
|
|
120
|
-
|
|
121
|
-
## Relationship with Legend Entities
|
|
122
|
-
|
|
123
|
-
The architecture separates visual presentation (materials) from gameplay behavior (legend entities):
|
|
124
|
-
|
|
125
|
-
### Materials Handle
|
|
105
|
+
The system loads the corresponding `wireframe.art` file and renders the
|
|
106
|
+
appropriate layer based on viewing context and distance.
|
|
126
107
|
|
|
127
|
-
|
|
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)
|
|
108
|
+
## Technical Details
|
|
131
109
|
|
|
132
|
-
###
|
|
110
|
+
### Loading
|
|
133
111
|
|
|
134
|
-
|
|
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)
|
|
112
|
+
Materials are loaded asynchronously via the `AssetManager`:
|
|
138
113
|
|
|
139
|
-
|
|
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
|
-
}
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
This design allows:
|
|
174
|
-
|
|
175
|
-
- **Reusable materials**: Same door material can be used for locked/unlocked/magic doors
|
|
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
|
|
179
|
-
|
|
180
|
-
### Example: Puddle with Sound
|
|
181
|
-
|
|
182
|
-
Ground materials can also use `onEnterSound` for footstep sounds:
|
|
183
|
-
|
|
184
|
-
**Material file** (`puddle.art`):
|
|
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
|
-
}
|
|
114
|
+
```typescript
|
|
115
|
+
const materialAsset = await AssetManager.getMaterial('wireframe');
|
|
208
116
|
```
|
|
209
117
|
|
|
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
|
|
118
|
+
### Caching
|
|
229
119
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
- **ambientSound**: Looping sound while material is visible (future feature)
|
|
120
|
+
Material assets are cached on first load - subsequent uses of the same material
|
|
121
|
+
reuse the cached data.
|
|
233
122
|
|
|
234
|
-
###
|
|
123
|
+
### Sound System
|
|
235
124
|
|
|
236
|
-
|
|
125
|
+
Materials support sound playback through properties in the file header (`§`):
|
|
237
126
|
|
|
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)
|
|
127
|
+
- **Sound files location**: `art/sounds/` directory
|
|
128
|
+
- **Supported formats**: MP3
|
|
129
|
+
- **Environment**: Sounds only play in web mode (not CLI)
|
|
130
|
+
- **onEnterSound**: Plays once when player steps onto tile with this material
|
|
131
|
+
- **onExitSound**: Plays once when player steps off tile
|
|
245
132
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
You can control sound globally through the `SoundManager`:
|
|
133
|
+
Control sounds globally via `SoundManager`:
|
|
249
134
|
|
|
250
135
|
```typescript
|
|
251
136
|
import { SoundManager } from 'asciitorium';
|
|
252
137
|
|
|
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();
|
|
138
|
+
SoundManager.setEnabled(false); // Disable all sounds
|
|
139
|
+
SoundManager.setEnabled(true); // Re-enable sounds
|
|
140
|
+
SoundManager.playSound('custom-sound.mp3'); // Play manually
|
|
267
141
|
```
|
|
268
142
|
|
|
269
|
-
|
|
143
|
+
### Layer System
|
|
270
144
|
|
|
271
|
-
|
|
145
|
+
The layering system creates first-person perspective depth:
|
|
272
146
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
5. Follow ASCII art best practices for readability
|
|
147
|
+
- **here**: Immediate foreground (closest to viewer)
|
|
148
|
+
- **near**: Close objects with full detail
|
|
149
|
+
- **middle**: Mid-distance objects with moderate detail
|
|
150
|
+
- **far**: Distant objects with minimal detail
|
|
278
151
|
|
|
279
|
-
|
|
152
|
+
Each layer can have left, center, and right positioned elements with specific
|
|
153
|
+
x-offsets for proper perspective alignment.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Sounds Directory
|
|
2
|
+
|
|
3
|
+
This directory contains audio assets in MP3 format used throughout the
|
|
4
|
+
application.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
Sound files can be referenced in material definitions, sprite definitions, or
|
|
9
|
+
played programmatically through the application's audio system.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Asciitorium Sprites
|
|
2
|
+
|
|
3
|
+
This directory contains ASCII sprite files for the **Art** component. Sprites
|
|
4
|
+
allow you to display static or animated ASCII art via the Art component.
|
|
5
|
+
|
|
6
|
+
## Sprite File Format
|
|
7
|
+
|
|
8
|
+
Sprite files use the `.art` extension and follow a structured format with
|
|
9
|
+
metadata separators:
|
|
10
|
+
|
|
11
|
+
### File Structure
|
|
12
|
+
|
|
13
|
+
#### Simple Static Sprite (no metadata)
|
|
14
|
+
|
|
15
|
+
``` txt
|
|
16
|
+
▄█▀█▄ ▄███▄
|
|
17
|
+
▐█░██████████▌
|
|
18
|
+
██▒█████████
|
|
19
|
+
▀████████▀
|
|
20
|
+
▀██▀
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
#### Animated Sprite with Metadata
|
|
24
|
+
|
|
25
|
+
``` txt
|
|
26
|
+
§ {"kind":"sprite","loop":true,"default-frame-rate":100}
|
|
27
|
+
¶ {"duration":1000}
|
|
28
|
+
▄█▀█▄ ▄███▄
|
|
29
|
+
▐█░██████████▌
|
|
30
|
+
██▒█████████
|
|
31
|
+
▀████████▀
|
|
32
|
+
▀██▀
|
|
33
|
+
¶
|
|
34
|
+
▄█▀▄ ▄██▄
|
|
35
|
+
▐█░████████▌
|
|
36
|
+
██▒███████
|
|
37
|
+
▀██████▀
|
|
38
|
+
▀▀
|
|
39
|
+
¶
|
|
40
|
+
▄█▀▄▄██▄
|
|
41
|
+
▐█░██████▌
|
|
42
|
+
██▒█████
|
|
43
|
+
▀████▀
|
|
44
|
+
▀▀
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Key Components
|
|
48
|
+
|
|
49
|
+
1. **File Header** (`§` separator) - Optional
|
|
50
|
+
- Must start with `§ {"kind":"sprite"}`
|
|
51
|
+
- Indicates this is a sprite asset
|
|
52
|
+
- Defines default animation settings:
|
|
53
|
+
- `default-frame-rate`: Default duration in milliseconds for each frame
|
|
54
|
+
- `loop`: Whether animation loops (true/false)
|
|
55
|
+
- `transparent`: Single character to treat as transparent (e.g., `" "`)
|
|
56
|
+
|
|
57
|
+
2. **Frame Sections** (`¶` separator) - Optional
|
|
58
|
+
- Each frame begins with `¶` followed by optional JSON metadata
|
|
59
|
+
- Frame metadata (all optional):
|
|
60
|
+
- `duration`: Override default frame duration in milliseconds
|
|
61
|
+
- `sound`: Sound ID to play when frame displays
|
|
62
|
+
- Frame content follows immediately after the metadata line
|
|
63
|
+
- If no metadata needed, use `¶` alone
|
|
64
|
+
|
|
65
|
+
3. **Frame Content**
|
|
66
|
+
- ASCII art representation of the sprite frame
|
|
67
|
+
- Each frame can be any width/height
|
|
68
|
+
- Blank lines are preserved
|
|
69
|
+
- Maximum sprite dimensions determined by largest frame
|
|
70
|
+
|
|
71
|
+
**Tips:**
|
|
72
|
+
|
|
73
|
+
- Files without `§` or `¶` are treated as single-frame static sprites
|
|
74
|
+
- Empty lines within frames are preserved for vertical spacing
|
|
75
|
+
- The first line after frame metadata is part of the sprite (no automatic
|
|
76
|
+
trimming)
|
|
77
|
+
- All frames should have consistent dimensions for best results
|
|
78
|
+
- Use the `transparent` property to define overlay sprites
|
|
79
|
+
|
|
80
|
+
## Using Sprites in Your App
|
|
81
|
+
|
|
82
|
+
### Basic Usage (Async Loading)
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<Art sprite="balloon" />
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### With Reactive State
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { State } from 'asciitorium';
|
|
92
|
+
|
|
93
|
+
const playerSprite = new State<string>(defaultArt);
|
|
94
|
+
|
|
95
|
+
<Art content={playerSprite} />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Available Props
|
|
99
|
+
|
|
100
|
+
- `sprite`: Name of sprite file (without `.art` extension) to load asynchronously
|
|
101
|
+
- `content`: String or `State<string>` for inline sprite content
|
|
102
|
+
- `children`: Alternative way to provide inline content
|
|
103
|
+
- Plus all standard component props: `position`, `border`, `align`, `style`,
|
|
104
|
+
etc.
|
|
105
|
+
|
|
106
|
+
## Technical Details
|
|
107
|
+
|
|
108
|
+
### Loading
|
|
109
|
+
|
|
110
|
+
Sprites are loaded asynchronously via the `AssetManager`:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const spriteAsset = await AssetManager.getSprite('mysprite');
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Caching
|
|
117
|
+
|
|
118
|
+
Sprite assets are cached on first load - subsequent uses of the same sprite
|
|
119
|
+
reuse the cached data.
|
|
120
|
+
|
|
121
|
+
### Animation System
|
|
122
|
+
|
|
123
|
+
The Art component automatically:
|
|
124
|
+
|
|
125
|
+
- Parses sprite metadata and frames
|
|
126
|
+
- Schedules frame transitions based on duration
|
|
127
|
+
- Handles looping vs. one-shot playback
|
|
128
|
+
- Requests renders when frames change
|
|
129
|
+
- Cleans up timers when component is destroyed
|
|
130
|
+
|
|
131
|
+
### Dimension Calculation
|
|
132
|
+
|
|
133
|
+
Component dimensions are automatically calculated from the largest frame:
|
|
134
|
+
|
|
135
|
+
- Width: Maximum line length across all frames
|
|
136
|
+
- 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
|
|
@@ -291,7 +291,7 @@ Line 3
|
|
|
291
291
|
<Column gap={1}>
|
|
292
292
|
<Text>If art/asciitorium.art exists, it should render below:</Text>
|
|
293
293
|
{/* Uncomment if you have art files:
|
|
294
|
-
<Art
|
|
294
|
+
<Art sprite="asciitorium" align="center" />
|
|
295
295
|
*/}
|
|
296
296
|
<Text>Art test skipped (no art files in template)</Text>
|
|
297
297
|
</Column>
|