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,6 +1,8 @@
|
|
|
1
1
|
# ASCIITORIUM Quick Reference
|
|
2
2
|
|
|
3
|
-
> **For LLMs**: This document provides correct usage patterns for ASCIITORIUM
|
|
3
|
+
> **For LLMs**: This document provides correct usage patterns for ASCIITORIUM
|
|
4
|
+
> components. Always refer to the examples here rather than assuming React-like
|
|
5
|
+
> conventions.
|
|
4
6
|
|
|
5
7
|
## Quick Index
|
|
6
8
|
|
|
@@ -35,7 +37,7 @@
|
|
|
35
37
|
- [Keybind](#keybind)
|
|
36
38
|
- [PerfMonitor](#perfmonitor)
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
|
|
39
41
|
|
|
40
42
|
## State Management
|
|
41
43
|
|
|
@@ -118,7 +120,7 @@ count++; // NO! count is a State object
|
|
|
118
120
|
count.value++;
|
|
119
121
|
```
|
|
120
122
|
|
|
121
|
-
|
|
123
|
+
|
|
122
124
|
|
|
123
125
|
## JSX & Props
|
|
124
126
|
|
|
@@ -172,7 +174,7 @@ align="center" // Alignment (layout-specific)
|
|
|
172
174
|
</Text>
|
|
173
175
|
```
|
|
174
176
|
|
|
175
|
-
|
|
177
|
+
|
|
176
178
|
|
|
177
179
|
## Row
|
|
178
180
|
|
|
@@ -215,7 +217,7 @@ align="center" // Alignment (layout-specific)
|
|
|
215
217
|
</Row>
|
|
216
218
|
```
|
|
217
219
|
|
|
218
|
-
|
|
220
|
+
|
|
219
221
|
|
|
220
222
|
## Column
|
|
221
223
|
|
|
@@ -244,7 +246,7 @@ align="center" // Alignment (layout-specific)
|
|
|
244
246
|
|
|
245
247
|
```tsx
|
|
246
248
|
<Column align="center" width="100%" gap={2}>
|
|
247
|
-
<Art
|
|
249
|
+
<Art sprite="logo" />
|
|
248
250
|
<Text>Welcome</Text>
|
|
249
251
|
<Button>Start</Button>
|
|
250
252
|
</Column>
|
|
@@ -262,7 +264,7 @@ align="center" // Alignment (layout-specific)
|
|
|
262
264
|
</Column>
|
|
263
265
|
```
|
|
264
266
|
|
|
265
|
-
|
|
267
|
+
|
|
266
268
|
|
|
267
269
|
## Text
|
|
268
270
|
|
|
@@ -361,7 +363,7 @@ const playerName = new State('Hero');
|
|
|
361
363
|
<Text>{count.value}</Text> // Explicit .value also works
|
|
362
364
|
```
|
|
363
365
|
|
|
364
|
-
|
|
366
|
+
|
|
365
367
|
|
|
366
368
|
## Button
|
|
367
369
|
|
|
@@ -439,7 +441,7 @@ const count = new State(0);
|
|
|
439
441
|
<Button>Very Long Text</Button> // Auto-sizes
|
|
440
442
|
```
|
|
441
443
|
|
|
442
|
-
|
|
444
|
+
|
|
443
445
|
|
|
444
446
|
## Select
|
|
445
447
|
|
|
@@ -553,142 +555,170 @@ const selected = new State("option1");
|
|
|
553
555
|
</Select>
|
|
554
556
|
```
|
|
555
557
|
|
|
556
|
-
|
|
558
|
+
|
|
557
559
|
|
|
558
560
|
## Switch
|
|
559
561
|
|
|
560
562
|
### Basic Usage
|
|
561
563
|
|
|
562
564
|
```tsx
|
|
563
|
-
import { State, Switch } from 'asciitorium';
|
|
565
|
+
import { State, Switch, Case, Default } from 'asciitorium';
|
|
564
566
|
|
|
565
|
-
|
|
566
|
-
const currentView = new State<any>(DashboardComponent);
|
|
567
|
+
const userRole = new State<string>('guest');
|
|
567
568
|
|
|
568
|
-
<Switch
|
|
569
|
+
<Switch condition={userRole}>
|
|
570
|
+
<Case when="admin" create={AdminPanel} />
|
|
571
|
+
<Case when="user" create={UserPanel} />
|
|
572
|
+
<Case when="guest" create={GuestPanel} />
|
|
573
|
+
<Default create={GuestPanel} />
|
|
574
|
+
</Switch>;
|
|
569
575
|
```
|
|
570
576
|
|
|
571
|
-
### Props
|
|
577
|
+
### Props (Switch)
|
|
578
|
+
|
|
579
|
+
| Prop | Type | Default | Description |
|
|
580
|
+
| ----------- | -------------------------------- | ------- | ---------------------------------- |
|
|
581
|
+
| `condition` | `State<string> \| State<number>` | - | State to match against Case values |
|
|
582
|
+
| `width` | `number \| 'fill'` | - | Component width |
|
|
583
|
+
| `height` | `number \| 'fill'` | - | Component height |
|
|
584
|
+
|
|
585
|
+
### Props (Case)
|
|
586
|
+
|
|
587
|
+
| Prop | Type | Description |
|
|
588
|
+
| -------- | ------------------ | ----------------------------------- |
|
|
589
|
+
| `when` | `string \| number` | Value to match against condition |
|
|
590
|
+
| `create` | `any` | Component class/function to create |
|
|
591
|
+
| `with` | `any` | Optional props to pass to component |
|
|
572
592
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
|
576
|
-
|
|
|
577
|
-
| `
|
|
593
|
+
### Props (Default)
|
|
594
|
+
|
|
595
|
+
| Prop | Type | Description |
|
|
596
|
+
| -------- | ----- | ----------------------------------- |
|
|
597
|
+
| `create` | `any` | Component class/function to create |
|
|
598
|
+
| `with` | `any` | Optional props to pass to component |
|
|
578
599
|
|
|
579
600
|
### Common Patterns
|
|
580
601
|
|
|
581
|
-
**Pattern 1:
|
|
602
|
+
**Pattern 1: Simple Conditional Rendering**
|
|
582
603
|
|
|
583
604
|
```tsx
|
|
584
|
-
import { State, Switch,
|
|
605
|
+
import { State, Switch, Case, Default } from 'asciitorium';
|
|
585
606
|
|
|
586
|
-
//
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
class SettingsView extends Component {
|
|
591
|
-
/* ... */
|
|
592
|
-
}
|
|
593
|
-
class ProfileView extends Component {
|
|
594
|
-
/* ... */
|
|
595
|
-
}
|
|
607
|
+
// Function components
|
|
608
|
+
const AdminPanel = () => <Column>Admin View</Column>;
|
|
609
|
+
const UserPanel = () => <Column>User View</Column>;
|
|
610
|
+
const GuestPanel = () => <Column>Guest View</Column>;
|
|
596
611
|
|
|
597
|
-
const
|
|
612
|
+
const userRole = new State<string>('guest');
|
|
598
613
|
|
|
599
614
|
<Column>
|
|
600
|
-
<Button onClick={() => (
|
|
601
|
-
<Button onClick={() => (
|
|
602
|
-
<Button onClick={() => (
|
|
603
|
-
|
|
604
|
-
<Switch
|
|
615
|
+
<Button onClick={() => (userRole.value = 'admin')}>Admin</Button>
|
|
616
|
+
<Button onClick={() => (userRole.value = 'user')}>User</Button>
|
|
617
|
+
<Button onClick={() => (userRole.value = 'guest')}>Guest</Button>
|
|
618
|
+
|
|
619
|
+
<Switch condition={userRole} width="fill" height="fill">
|
|
620
|
+
<Case when="admin" create={AdminPanel} />
|
|
621
|
+
<Case when="user" create={UserPanel} />
|
|
622
|
+
<Case when="guest" create={GuestPanel} />
|
|
623
|
+
<Default create={GuestPanel} />
|
|
624
|
+
</Switch>
|
|
605
625
|
</Column>;
|
|
606
626
|
```
|
|
607
627
|
|
|
608
|
-
**Pattern 2:
|
|
628
|
+
**Pattern 2: Class Components with Props**
|
|
609
629
|
|
|
610
630
|
```tsx
|
|
611
|
-
import { State,
|
|
631
|
+
import { State, Switch, Case, Component } from 'asciitorium';
|
|
612
632
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
}
|
|
633
|
+
class SettingsPanel extends Component {
|
|
634
|
+
constructor(props: { theme: string }) {
|
|
635
|
+
super(props);
|
|
636
|
+
// Use props.theme
|
|
637
|
+
}
|
|
638
|
+
}
|
|
619
639
|
|
|
620
|
-
const
|
|
621
|
-
const selectedComponent = new State<any>(pageMap['home']);
|
|
640
|
+
const currentView = new State<string>('settings');
|
|
622
641
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
642
|
+
<Switch condition={currentView}>
|
|
643
|
+
<Case when="settings" create={SettingsPanel} with={{ theme: 'dark' }} />
|
|
644
|
+
<Case when="profile" create={ProfilePanel} />
|
|
645
|
+
</Switch>;
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**Pattern 3: Navigation with Select**
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
import { State, Select, Option, Switch, Case } from 'asciitorium';
|
|
652
|
+
|
|
653
|
+
const selectedPage = new State<string>('home');
|
|
627
654
|
|
|
628
655
|
<Column>
|
|
629
|
-
<Select selected={
|
|
656
|
+
<Select selected={selectedPage}>
|
|
630
657
|
<Option value="home" label="Home" />
|
|
631
658
|
<Option value="about" label="About" />
|
|
632
659
|
<Option value="contact" label="Contact" />
|
|
633
660
|
</Select>
|
|
634
661
|
|
|
635
|
-
<Switch
|
|
662
|
+
<Switch condition={selectedPage} width="fill" height="fill">
|
|
663
|
+
<Case when="home" create={HomePage} />
|
|
664
|
+
<Case when="about" create={AboutPage} />
|
|
665
|
+
<Case when="contact" create={ContactPage} />
|
|
666
|
+
</Switch>
|
|
636
667
|
</Column>;
|
|
637
668
|
```
|
|
638
669
|
|
|
639
|
-
**Pattern
|
|
640
|
-
|
|
641
|
-
```tsx
|
|
642
|
-
// Using factory functions instead of constructors
|
|
643
|
-
const viewFactory = () => new CustomView({ customProp: 'value' });
|
|
644
|
-
const currentView = new State<any>(viewFactory);
|
|
645
|
-
|
|
646
|
-
<Switch component={currentView} />;
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
**Pattern 4: Component Instances**
|
|
670
|
+
**Pattern 4: Numeric Conditions**
|
|
650
671
|
|
|
651
672
|
```tsx
|
|
652
|
-
|
|
653
|
-
const dashboard = new DashboardView({ width: 80 });
|
|
654
|
-
const settings = new SettingsView({ width: 80 });
|
|
655
|
-
|
|
656
|
-
const currentView = new State<Component>(dashboard);
|
|
673
|
+
const level = new State<number>(1);
|
|
657
674
|
|
|
658
|
-
<
|
|
659
|
-
<
|
|
675
|
+
<Switch condition={level}>
|
|
676
|
+
<Case when={1} create={Level1} />
|
|
677
|
+
<Case when={2} create={Level2} />
|
|
678
|
+
<Case when={3} create={Level3} />
|
|
679
|
+
<Default create={CompletionScreen} />
|
|
680
|
+
</Switch>;
|
|
660
681
|
```
|
|
661
682
|
|
|
662
683
|
### Common Mistakes
|
|
663
684
|
|
|
664
|
-
❌ **WRONG** -
|
|
685
|
+
❌ **WRONG** - Using JSX children
|
|
665
686
|
|
|
666
687
|
```tsx
|
|
667
|
-
<Switch
|
|
688
|
+
<Switch condition={role}>
|
|
689
|
+
<Case when="admin">
|
|
690
|
+
<AdminPanel /> {/* Components persist in memory! */}
|
|
691
|
+
</Case>
|
|
692
|
+
</Switch>
|
|
668
693
|
```
|
|
669
694
|
|
|
670
|
-
✅ **CORRECT** - Using
|
|
695
|
+
✅ **CORRECT** - Using create prop
|
|
671
696
|
|
|
672
697
|
```tsx
|
|
673
|
-
|
|
674
|
-
<
|
|
698
|
+
<Switch condition={role}>
|
|
699
|
+
<Case when="admin" create={AdminPanel} />
|
|
700
|
+
</Switch>
|
|
675
701
|
```
|
|
676
702
|
|
|
677
|
-
❌ **WRONG** -
|
|
703
|
+
❌ **WRONG** - Missing Default fallback
|
|
678
704
|
|
|
679
705
|
```tsx
|
|
680
|
-
|
|
681
|
-
<
|
|
706
|
+
<Switch condition={status}>
|
|
707
|
+
<Case when="loading" create={Spinner} />
|
|
708
|
+
{/* No fallback - nothing shows if status is unknown */}
|
|
709
|
+
</Switch>
|
|
682
710
|
```
|
|
683
711
|
|
|
684
|
-
✅ **CORRECT** -
|
|
712
|
+
✅ **CORRECT** - Including Default
|
|
685
713
|
|
|
686
714
|
```tsx
|
|
687
|
-
|
|
688
|
-
<
|
|
715
|
+
<Switch condition={status}>
|
|
716
|
+
<Case when="loading" create={Spinner} />
|
|
717
|
+
<Default create={ErrorMessage} />
|
|
718
|
+
</Switch>
|
|
689
719
|
```
|
|
690
720
|
|
|
691
|
-
|
|
721
|
+
|
|
692
722
|
|
|
693
723
|
## TextInput
|
|
694
724
|
|
|
@@ -771,73 +801,88 @@ const text = new State('initial');
|
|
|
771
801
|
<Button onClick={() => console.log(inputValue.value)}>Submit</Button>
|
|
772
802
|
```
|
|
773
803
|
|
|
774
|
-
|
|
804
|
+
|
|
775
805
|
|
|
776
806
|
## Art
|
|
777
807
|
|
|
778
808
|
### Basic Usage
|
|
779
809
|
|
|
780
810
|
```tsx
|
|
781
|
-
// Load from file
|
|
782
|
-
<Art
|
|
783
|
-
|
|
784
|
-
// ASCII art from figlet font
|
|
785
|
-
<Art font="standard" text="Hello" />
|
|
811
|
+
// Load sprite from file
|
|
812
|
+
<Art sprite="logo" />
|
|
786
813
|
|
|
787
814
|
// Align center
|
|
788
|
-
<Art
|
|
815
|
+
<Art sprite="banner" align="center" />
|
|
789
816
|
```
|
|
790
817
|
|
|
791
818
|
### Props
|
|
792
819
|
|
|
793
|
-
| Prop | Type | Default | Description
|
|
794
|
-
| -------- | ------------------------------- | -------- |
|
|
795
|
-
| `
|
|
796
|
-
| `
|
|
797
|
-
| `
|
|
798
|
-
| `
|
|
799
|
-
| `
|
|
800
|
-
| `align` | `'left' \| 'center' \| 'right'` | `'left'` | Horizontal alignment |
|
|
801
|
-
| `border` | `boolean` | `false` | Show border |
|
|
820
|
+
| Prop | Type | Default | Description |
|
|
821
|
+
| -------- | ------------------------------- | -------- | ------------------------------------ |
|
|
822
|
+
| `sprite` | `string` | - | Sprite file name (from art/sprites/) |
|
|
823
|
+
| `width` | `number \| 'auto'` | `'auto'` | Component width |
|
|
824
|
+
| `height` | `number \| 'auto'` | `'auto'` | Component height |
|
|
825
|
+
| `align` | `'left' \| 'center' \| 'right'` | `'left'` | Horizontal alignment |
|
|
826
|
+
| `border` | `boolean` | `false` | Show border |
|
|
802
827
|
|
|
803
828
|
### Common Patterns
|
|
804
829
|
|
|
805
|
-
**Pattern 1:
|
|
830
|
+
**Pattern 1: Static Sprite**
|
|
806
831
|
|
|
807
832
|
```tsx
|
|
808
|
-
// Loads from art/logo.art
|
|
809
|
-
<Art
|
|
833
|
+
// Loads from art/sprites/logo.art
|
|
834
|
+
<Art sprite="logo" align="center" />
|
|
810
835
|
```
|
|
811
836
|
|
|
812
|
-
**Pattern 2:
|
|
837
|
+
**Pattern 2: Animated Sprite**
|
|
813
838
|
|
|
814
839
|
```tsx
|
|
815
|
-
|
|
840
|
+
// Loads animated art (auto-plays)
|
|
841
|
+
<Art sprite="beating-heart" width={20} />
|
|
816
842
|
```
|
|
817
843
|
|
|
818
|
-
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
## Banner
|
|
847
|
+
|
|
848
|
+
### Basic Usage
|
|
819
849
|
|
|
820
850
|
```tsx
|
|
821
|
-
//
|
|
822
|
-
<
|
|
851
|
+
// Render text with font
|
|
852
|
+
<Banner font="standard" text="Hello" />
|
|
853
|
+
|
|
854
|
+
// Align center
|
|
855
|
+
<Banner font="shadows" text="Game Over" align="center" />
|
|
823
856
|
```
|
|
824
857
|
|
|
825
|
-
###
|
|
858
|
+
### Props
|
|
826
859
|
|
|
827
|
-
|
|
860
|
+
| Prop | Type | Default | Description |
|
|
861
|
+
| --------------- | ------------------------------- | -------- | --------------------------------- |
|
|
862
|
+
| `font` | `string` | - | Font name (from art/fonts/) |
|
|
863
|
+
| `text` | `string \| State<string>` | - | Text to render with font |
|
|
864
|
+
| `letterSpacing` | `number` | `0` | Additional spacing between chars |
|
|
865
|
+
| `width` | `number \| 'auto'` | `'auto'` | Component width |
|
|
866
|
+
| `height` | `number \| 'auto'` | `'auto'` | Component height |
|
|
867
|
+
| `align` | `'left' \| 'center' \| 'right'` | `'left'` | Horizontal alignment |
|
|
868
|
+
| `border` | `boolean` | `false` | Show border |
|
|
869
|
+
|
|
870
|
+
### Common Patterns
|
|
871
|
+
|
|
872
|
+
**Pattern 1: Title Screen**
|
|
828
873
|
|
|
829
874
|
```tsx
|
|
830
|
-
<
|
|
875
|
+
<Banner font="shadows" text="asciitorium" align="center" />
|
|
831
876
|
```
|
|
832
877
|
|
|
833
|
-
|
|
878
|
+
**Pattern 2: Reactive Text**
|
|
834
879
|
|
|
835
880
|
```tsx
|
|
836
|
-
|
|
837
|
-
<
|
|
881
|
+
const score = new State(0);
|
|
882
|
+
<Banner font="pixel" text={score} letterSpacing={1} />
|
|
838
883
|
```
|
|
839
884
|
|
|
840
|
-
|
|
885
|
+
|
|
841
886
|
|
|
842
887
|
## Keybind
|
|
843
888
|
|
|
@@ -926,7 +971,7 @@ const gameStarted = new State(false);
|
|
|
926
971
|
<Keybind keyBinding="ArrowUp" action={() => moveUp()} />
|
|
927
972
|
```
|
|
928
973
|
|
|
929
|
-
|
|
974
|
+
|
|
930
975
|
|
|
931
976
|
## GameWorld
|
|
932
977
|
|
|
@@ -1055,7 +1100,7 @@ gameWorld.player.value.x += 1; // Bypasses collision detection
|
|
|
1055
1100
|
gameWorld.moveForward(); // Handles collision
|
|
1056
1101
|
```
|
|
1057
1102
|
|
|
1058
|
-
|
|
1103
|
+
|
|
1059
1104
|
|
|
1060
1105
|
## MapView
|
|
1061
1106
|
|
|
@@ -1138,7 +1183,7 @@ gameWorld.player.subscribe((p) => {
|
|
|
1138
1183
|
<MapView mapAsset={gameWorld.mapAsset} player={gameWorld.player} />
|
|
1139
1184
|
```
|
|
1140
1185
|
|
|
1141
|
-
|
|
1186
|
+
|
|
1142
1187
|
|
|
1143
1188
|
## FirstPersonView
|
|
1144
1189
|
|
|
@@ -1216,7 +1261,7 @@ gameWorld.player.subscribe((p) => {
|
|
|
1216
1261
|
<FirstPersonView mapAsset={gameWorld.mapAsset} player={gameWorld.player} />
|
|
1217
1262
|
```
|
|
1218
1263
|
|
|
1219
|
-
|
|
1264
|
+
|
|
1220
1265
|
|
|
1221
1266
|
## PerfMonitor
|
|
1222
1267
|
|
|
@@ -1267,7 +1312,7 @@ const showPerf = new State(false);
|
|
|
1267
1312
|
<PerfMonitor visible={showPerf} />
|
|
1268
1313
|
```
|
|
1269
1314
|
|
|
1270
|
-
|
|
1315
|
+
|
|
1271
1316
|
|
|
1272
1317
|
## Component Lifecycle
|
|
1273
1318
|
|
|
@@ -1307,7 +1352,7 @@ count.subscribe((newValue) => {
|
|
|
1307
1352
|
// No manual cleanup needed in most cases
|
|
1308
1353
|
```
|
|
1309
1354
|
|
|
1310
|
-
|
|
1355
|
+
|
|
1311
1356
|
|
|
1312
1357
|
## Legend System (Game Maps)
|
|
1313
1358
|
|
|
@@ -1368,7 +1413,7 @@ if (tile?.tag === 'door') {
|
|
|
1368
1413
|
}
|
|
1369
1414
|
```
|
|
1370
1415
|
|
|
1371
|
-
|
|
1416
|
+
|
|
1372
1417
|
|
|
1373
1418
|
## Directory Structure
|
|
1374
1419
|
|
|
@@ -1409,7 +1454,7 @@ Example:
|
|
|
1409
1454
|
╚══════════════════╝
|
|
1410
1455
|
```
|
|
1411
1456
|
|
|
1412
|
-
|
|
1457
|
+
|
|
1413
1458
|
|
|
1414
1459
|
## Type Annotations
|
|
1415
1460
|
|
|
@@ -1451,7 +1496,7 @@ const entry: LegendEntry = {
|
|
|
1451
1496
|
};
|
|
1452
1497
|
```
|
|
1453
1498
|
|
|
1454
|
-
|
|
1499
|
+
|
|
1455
1500
|
|
|
1456
1501
|
## Complete Example: Simple Game
|
|
1457
1502
|
|
|
@@ -1522,28 +1567,32 @@ const app = (
|
|
|
1522
1567
|
await app.start();
|
|
1523
1568
|
```
|
|
1524
1569
|
|
|
1525
|
-
|
|
1570
|
+
|
|
1526
1571
|
|
|
1527
1572
|
## Understanding "auto" vs Omitting Props
|
|
1528
1573
|
|
|
1529
|
-
**Key Concept:** In ASCIITORIUM, omitting `width` or `height` props is the same
|
|
1574
|
+
**Key Concept:** In ASCIITORIUM, omitting `width` or `height` props is the same
|
|
1575
|
+
as setting them to `undefined` or `"auto"`.
|
|
1530
1576
|
|
|
1531
1577
|
- `width={40}` → Fixed width of 40 characters
|
|
1532
1578
|
- `width="fill"` → Fill available parent space
|
|
1533
1579
|
- `width="auto"` → Auto-size to content (same as omitting the prop)
|
|
1534
1580
|
- _Omitting width prop_ → Auto-size to content (recommended approach)
|
|
1535
1581
|
|
|
1536
|
-
**Recommendation:** Omit props instead of using `"auto"` for clarity. The type
|
|
1582
|
+
**Recommendation:** Omit props instead of using `"auto"` for clarity. The type
|
|
1583
|
+
system allows `"auto"` but it's unnecessary.
|
|
1537
1584
|
|
|
1538
1585
|
**Component-specific auto-sizing:**
|
|
1539
1586
|
|
|
1540
|
-
- **Text**: Auto-sizes to content length (width) and wrapped lines (height) when
|
|
1541
|
-
|
|
1587
|
+
- **Text**: Auto-sizes to content length (width) and wrapped lines (height) when
|
|
1588
|
+
props omitted
|
|
1589
|
+
- **Button**: Always calculates size based on content (`buttonText.length + 7`
|
|
1590
|
+
for width, `4` for height)
|
|
1542
1591
|
- **Art**: Auto-sizes to loaded art dimensions when props omitted
|
|
1543
1592
|
- **Column**: Auto-sizes to fit children when width omitted
|
|
1544
1593
|
- **Row**: Defaults to `width="fill"`
|
|
1545
1594
|
|
|
1546
|
-
|
|
1595
|
+
|
|
1547
1596
|
|
|
1548
1597
|
## Tips for LLMs
|
|
1549
1598
|
|
|
@@ -1552,12 +1601,16 @@ await app.start();
|
|
|
1552
1601
|
3. **Text newlines use `¶` (pilcrow)** - Not `\n`
|
|
1553
1602
|
4. **Components accept children via JSX or explicit props** - Both patterns work
|
|
1554
1603
|
5. **GameWorld must be awaited** - `await gameWorld.ready` before rendering
|
|
1555
|
-
6. **Keybinds are invisible components** - They never render, just register
|
|
1556
|
-
|
|
1604
|
+
6. **Keybinds are invisible components** - They never render, just register
|
|
1605
|
+
handlers
|
|
1606
|
+
7. **MapView and FirstPersonView are display-only** - Movement logic goes in
|
|
1607
|
+
GameWorld or Keybinds
|
|
1557
1608
|
8. **Legend system drives collision** - Use `isSolid()` for movement validation
|
|
1558
1609
|
9. **No CSS or className** - ASCIITORIUM uses ASCII rendering, not DOM styling
|
|
1559
|
-
10. **Omit width/height props for auto-sizing** - Components have smart defaults
|
|
1610
|
+
10. **Omit width/height props for auto-sizing** - Components have smart defaults
|
|
1611
|
+
(Text/Art/Column size to content, Button calculates from label, Row fills
|
|
1612
|
+
width)
|
|
1613
|
+
|
|
1560
1614
|
|
|
1561
|
-
---
|
|
1562
1615
|
|
|
1563
1616
|
_End of Reference_
|