castle-web-cli 0.4.166 → 0.4.167

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 (85) hide show
  1. package/dist/agent.d.ts +1 -2
  2. package/dist/agent.js +22 -13
  3. package/dist/api.js +16 -1
  4. package/dist/imports.js +19 -4
  5. package/dist/localPaths.d.ts +2 -0
  6. package/dist/localPaths.js +6 -0
  7. package/dist/serve.js +5 -1
  8. package/dist/serveSecurity.d.ts +12 -0
  9. package/dist/serveSecurity.js +42 -0
  10. package/dist/shell/assets/{index-CG9TrvCm.js → index-C8M-p00y.js} +36 -36
  11. package/dist/shell/index.html +1 -1
  12. package/kits/base/castle.json +64 -2
  13. package/kits/base/editors/ImageViewer.js +259 -0
  14. package/kits/base/editors/MediaPlayer.js +90 -0
  15. package/kits/base/editors/imageViewer.css +95 -0
  16. package/kits/base/editors/mediaPlayer.css +58 -0
  17. package/kits/multiplayer-2d/castle.json +1 -1
  18. package/kits/multiplayer-2d/package-lock.json +4 -1
  19. package/kits/multiplayer-3d/castle.json +1 -1
  20. package/kits/multiplayer-3d/package-lock.json +1 -1
  21. package/kits/physics-2d/behaviors/Joints.jsx +11 -5
  22. package/kits/physics-2d/behaviors/Sprite.jsx +6 -21
  23. package/kits/physics-2d/castle.json +1 -61
  24. package/kits/physics-2d/editors/BlueprintLibrary.jsx +8 -68
  25. package/kits/physics-2d/editors/SingleEditor.jsx +3 -10
  26. package/kits/physics-2d/editors/editorRegistry.jsx +36 -2
  27. package/kits/physics-2d/engine/art.js +25 -1
  28. package/kits/physics-2d/engine/artThumbnail.jsx +92 -0
  29. package/kits/physics-2d/engine/files.js +4 -15
  30. package/kits/physics-2d/engine/spriteField.jsx +176 -0
  31. package/kits/physics-2d/engine/ui.module.css +136 -0
  32. package/kits/physics-2d/package-lock.json +5 -0
  33. package/kits/physics-2d/pnpm-lock.yaml +96 -3
  34. package/kits/physics-3d/castle.json +1 -1
  35. package/kits/physics-3d/package-lock.json +1 -1
  36. package/kits/physics-3d/pnpm-lock.yaml +88 -3
  37. package/kits/real-time/castle.json +1 -1
  38. package/kits/real-time/package.json +3 -0
  39. package/kits/turn-based/castle.json +1 -1
  40. package/kits/turn-based/package-lock.json +1 -1
  41. package/package.json +1 -1
  42. package/kits/base/node_modules/.package-lock.json +0 -28
  43. package/kits/base/node_modules/castle-web-fonts/README.md +0 -114
  44. package/kits/base/node_modules/castle-web-fonts/dist/catalog.d.ts +0 -18
  45. package/kits/base/node_modules/castle-web-fonts/dist/catalog.js +0 -142
  46. package/kits/base/node_modules/castle-web-fonts/dist/face.d.ts +0 -1
  47. package/kits/base/node_modules/castle-web-fonts/dist/face.js +0 -52
  48. package/kits/base/node_modules/castle-web-fonts/dist/faces/Bore.d.ts +0 -3
  49. package/kits/base/node_modules/castle-web-fonts/dist/faces/Bore.js +0 -10
  50. package/kits/base/node_modules/castle-web-fonts/dist/faces/CourierPrime.d.ts +0 -3
  51. package/kits/base/node_modules/castle-web-fonts/dist/faces/CourierPrime.js +0 -10
  52. package/kits/base/node_modules/castle-web-fonts/dist/faces/DMSans.d.ts +0 -3
  53. package/kits/base/node_modules/castle-web-fonts/dist/faces/DMSans.js +0 -10
  54. package/kits/base/node_modules/castle-web-fonts/dist/faces/Glacier.d.ts +0 -3
  55. package/kits/base/node_modules/castle-web-fonts/dist/faces/Glacier.js +0 -10
  56. package/kits/base/node_modules/castle-web-fonts/dist/faces/HelicoCentrica.d.ts +0 -3
  57. package/kits/base/node_modules/castle-web-fonts/dist/faces/HelicoCentrica.js +0 -10
  58. package/kits/base/node_modules/castle-web-fonts/dist/faces/Piazzolla.d.ts +0 -3
  59. package/kits/base/node_modules/castle-web-fonts/dist/faces/Piazzolla.js +0 -10
  60. package/kits/base/node_modules/castle-web-fonts/dist/faces/Synco.d.ts +0 -3
  61. package/kits/base/node_modules/castle-web-fonts/dist/faces/Synco.js +0 -10
  62. package/kits/base/node_modules/castle-web-fonts/dist/faces/Tektur.d.ts +0 -3
  63. package/kits/base/node_modules/castle-web-fonts/dist/faces/Tektur.js +0 -10
  64. package/kits/base/node_modules/castle-web-fonts/dist/faces/YatraOne.d.ts +0 -3
  65. package/kits/base/node_modules/castle-web-fonts/dist/faces/YatraOne.js +0 -10
  66. package/kits/base/node_modules/castle-web-fonts/dist/index.d.ts +0 -16
  67. package/kits/base/node_modules/castle-web-fonts/dist/index.js +0 -15
  68. package/kits/base/node_modules/castle-web-fonts/licenses/CC-BY-ND-4.0.txt +0 -393
  69. package/kits/base/node_modules/castle-web-fonts/licenses/FONTS.md +0 -64
  70. package/kits/base/node_modules/castle-web-fonts/licenses/OFL-1.1.txt +0 -95
  71. package/kits/base/node_modules/castle-web-fonts/package.json +0 -47
  72. package/kits/base/node_modules/castle-web-fonts/woff2/Bore.woff2 +0 -0
  73. package/kits/base/node_modules/castle-web-fonts/woff2/CourierPrime.woff2 +0 -0
  74. package/kits/base/node_modules/castle-web-fonts/woff2/DMSans.woff2 +0 -0
  75. package/kits/base/node_modules/castle-web-fonts/woff2/Glacier.woff2 +0 -0
  76. package/kits/base/node_modules/castle-web-fonts/woff2/HelicoCentrica.woff2 +0 -0
  77. package/kits/base/node_modules/castle-web-fonts/woff2/Piazzolla.woff2 +0 -0
  78. package/kits/base/node_modules/castle-web-fonts/woff2/SOURCE.txt +0 -2
  79. package/kits/base/node_modules/castle-web-fonts/woff2/Synco.woff2 +0 -0
  80. package/kits/base/node_modules/castle-web-fonts/woff2/Tektur.woff2 +0 -0
  81. package/kits/base/node_modules/castle-web-fonts/woff2/YatraOne.woff2 +0 -0
  82. package/kits/physics-2d/editors/ImageViewer.jsx +0 -206
  83. package/kits/physics-2d/editors/MediaPlayer.jsx +0 -57
  84. package/kits/physics-2d/editors/mediaFile.js +0 -31
  85. package/kits/physics-2d/editors/mediaViewer.module.css +0 -128
@@ -26,15 +26,27 @@ importers:
26
26
  '@dimforge/rapier3d-compat':
27
27
  specifier: ^0.19.2
28
28
  version: 0.19.3
29
+ '@dnd-kit/core':
30
+ specifier: ^6.3.1
31
+ version: 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
32
+ '@dnd-kit/modifiers':
33
+ specifier: ^9.0.0
34
+ version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
35
+ '@dnd-kit/sortable':
36
+ specifier: ^10.0.0
37
+ version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
38
+ '@dnd-kit/utilities':
39
+ specifier: ^3.2.2
40
+ version: 3.2.2(react@19.2.8)
29
41
  '@fortawesome/free-solid-svg-icons':
30
42
  specifier: ^5.15.4
31
43
  version: 5.15.4
32
44
  '@lezer/highlight':
33
45
  specifier: ^1.2.3
34
46
  version: 1.2.3
35
- castle-web-sdk:
36
- specifier: file:../../sdk
37
- version: file:../../sdk
47
+ castle-web-fonts:
48
+ specifier: ^1.0.0
49
+ version: 1.0.0
38
50
  codemirror:
39
51
  specifier: ^6.0.2
40
52
  version: 6.0.2
@@ -51,6 +63,9 @@ importers:
51
63
  specifier: ^0.180.0
52
64
  version: 0.180.0
53
65
  devDependencies:
66
+ castle-web-sdk:
67
+ specifier: file:../../sdk
68
+ version: file:../../sdk
54
69
  eslint:
55
70
  specifier: ^9.0.0
56
71
  version: 9.39.5
@@ -114,6 +129,34 @@ packages:
114
129
  '@dimforge/rapier3d-compat@0.19.3':
115
130
  resolution: {integrity: sha512-mMVdSj1PRTT108s9Swbu2GQOmHbn8kbJANRV5xfczL3s0T4vkgZAuoMRgvBzQcHanpKusbC0ZJj6z3mC3aj3vg==}
116
131
 
132
+ '@dnd-kit/accessibility@3.1.1':
133
+ resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
134
+ peerDependencies:
135
+ react: '>=16.8.0'
136
+
137
+ '@dnd-kit/core@6.3.1':
138
+ resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==}
139
+ peerDependencies:
140
+ react: '>=16.8.0'
141
+ react-dom: '>=16.8.0'
142
+
143
+ '@dnd-kit/modifiers@9.0.0':
144
+ resolution: {integrity: sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==}
145
+ peerDependencies:
146
+ '@dnd-kit/core': ^6.3.0
147
+ react: '>=16.8.0'
148
+
149
+ '@dnd-kit/sortable@10.0.0':
150
+ resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==}
151
+ peerDependencies:
152
+ '@dnd-kit/core': ^6.3.0
153
+ react: '>=16.8.0'
154
+
155
+ '@dnd-kit/utilities@3.2.2':
156
+ resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
157
+ peerDependencies:
158
+ react: '>=16.8.0'
159
+
117
160
  '@eslint-community/eslint-utils@4.10.1':
118
161
  resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==}
119
162
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -303,6 +346,9 @@ packages:
303
346
  resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
304
347
  engines: {node: '>=6'}
305
348
 
349
+ castle-web-fonts@1.0.0:
350
+ resolution: {integrity: sha512-amFts4vVJjaXKNQkh2DMMmxYHafCYczAOvme70n+0WX8fsTqJACh6r6MzND94l89Q6LFoIyrCm+cLh3S1Usy0w==}
351
+
306
352
  castle-web-sdk@file:../../sdk:
307
353
  resolution: {directory: ../../sdk, type: directory}
308
354
 
@@ -855,6 +901,9 @@ packages:
855
901
  token-stream@1.0.0:
856
902
  resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==}
857
903
 
904
+ tslib@2.8.1:
905
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
906
+
858
907
  type-check@0.4.0:
859
908
  resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
860
909
  engines: {node: '>= 0.8.0'}
@@ -969,6 +1018,38 @@ snapshots:
969
1018
 
970
1019
  '@dimforge/rapier3d-compat@0.19.3': {}
971
1020
 
1021
+ '@dnd-kit/accessibility@3.1.1(react@19.2.8)':
1022
+ dependencies:
1023
+ react: 19.2.8
1024
+ tslib: 2.8.1
1025
+
1026
+ '@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)':
1027
+ dependencies:
1028
+ '@dnd-kit/accessibility': 3.1.1(react@19.2.8)
1029
+ '@dnd-kit/utilities': 3.2.2(react@19.2.8)
1030
+ react: 19.2.8
1031
+ react-dom: 19.2.8(react@19.2.8)
1032
+ tslib: 2.8.1
1033
+
1034
+ '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
1035
+ dependencies:
1036
+ '@dnd-kit/core': 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
1037
+ '@dnd-kit/utilities': 3.2.2(react@19.2.8)
1038
+ react: 19.2.8
1039
+ tslib: 2.8.1
1040
+
1041
+ '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
1042
+ dependencies:
1043
+ '@dnd-kit/core': 6.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
1044
+ '@dnd-kit/utilities': 3.2.2(react@19.2.8)
1045
+ react: 19.2.8
1046
+ tslib: 2.8.1
1047
+
1048
+ '@dnd-kit/utilities@3.2.2(react@19.2.8)':
1049
+ dependencies:
1050
+ react: 19.2.8
1051
+ tslib: 2.8.1
1052
+
972
1053
  '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5)':
973
1054
  dependencies:
974
1055
  eslint: 9.39.5
@@ -1170,6 +1251,8 @@ snapshots:
1170
1251
 
1171
1252
  callsites@3.1.0: {}
1172
1253
 
1254
+ castle-web-fonts@1.0.0: {}
1255
+
1173
1256
  castle-web-sdk@file:../../sdk: {}
1174
1257
 
1175
1258
  chalk@4.1.2:
@@ -1754,6 +1837,8 @@ snapshots:
1754
1837
 
1755
1838
  token-stream@1.0.0: {}
1756
1839
 
1840
+ tslib@2.8.1: {}
1841
+
1757
1842
  type-check@0.4.0:
1758
1843
  dependencies:
1759
1844
  prelude-ls: 1.2.1
@@ -15,5 +15,5 @@
15
15
  "autoUpdateWhenImported": true,
16
16
  "deckId": "xFVr-afOLuUQ",
17
17
  "cardId": "w6G45sy3_P_m",
18
- "publishedVersion": "2026-09-02T05:55:19.420Z"
18
+ "publishedVersion": "2026-09-05T00:07:38.909Z"
19
19
  }
@@ -10,5 +10,8 @@
10
10
  "castle-web-sdk": "file:../../sdk",
11
11
  "eslint": "^9.0.0",
12
12
  "prettier": "^3.8.3"
13
+ },
14
+ "dependencies": {
15
+ "castle-web-fonts": "^1.0.0"
13
16
  }
14
17
  }
@@ -28,7 +28,7 @@
28
28
  "autoUpdateWhenImported": true,
29
29
  "deckId": "K6-Xs7dCoMVi",
30
30
  "cardId": "Kh_08IYATpC3",
31
- "publishedVersion": "2026-09-02T05:55:21.391Z",
31
+ "publishedVersion": "2026-09-05T00:07:41.510Z",
32
32
  "server": {
33
33
  "main": "code/server/index.js",
34
34
  "maxPlayers": 8,
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "../../sdk": {
31
31
  "name": "castle-web-sdk",
32
- "version": "0.4.23",
32
+ "version": "0.4.26",
33
33
  "dev": true,
34
34
  "devDependencies": {
35
35
  "eslint": "^9.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-cli",
3
- "version": "0.4.166",
3
+ "version": "0.4.167",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castle-web": "./dist/index.js"
@@ -1,28 +0,0 @@
1
- {
2
- "name": "base",
3
- "lockfileVersion": 3,
4
- "requires": true,
5
- "packages": {
6
- "../../sdk": {
7
- "name": "castle-web-sdk",
8
- "version": "0.4.22",
9
- "dev": true,
10
- "devDependencies": {
11
- "eslint": "^9.0.0",
12
- "jscpd": "^4.0.5",
13
- "typescript": "^5.0.0",
14
- "typescript-eslint": "^8.0.0"
15
- }
16
- },
17
- "node_modules/castle-web-fonts": {
18
- "version": "1.0.0",
19
- "resolved": "https://registry.npmjs.org/castle-web-fonts/-/castle-web-fonts-1.0.0.tgz",
20
- "integrity": "sha512-amFts4vVJjaXKNQkh2DMMmxYHafCYczAOvme70n+0WX8fsTqJACh6r6MzND94l89Q6LFoIyrCm+cLh3S1Usy0w==",
21
- "license": "SEE LICENSE IN licenses/FONTS.md"
22
- },
23
- "node_modules/castle-web-sdk": {
24
- "resolved": "../../sdk",
25
- "link": true
26
- }
27
- }
28
- }
@@ -1,114 +0,0 @@
1
- # castle-web-fonts
2
-
3
- The nine typefaces the Castle Classic engine gives its text tool, as web fonts
4
- a Castle deck can use. Same faces, same names: a deck asking for `Piazzolla`
5
- here gets what a Classic card asking for `Piazzolla` gets.
6
-
7
- ```js
8
- import { installTektur } from 'castle-web-fonts';
9
-
10
- installTektur(); // now: font-family: 'Tektur'
11
- ```
12
-
13
- Install what you name, then use the family name in CSS. Two or three faces is
14
- normal — one for body and UI, one display face for titles.
15
-
16
- ## The faces
17
-
18
- | face | character | good for | woff2 |
19
- |---|---|---|---:|
20
- | `DMSans` | clean geometric sans, low contrast | body, UI, HUD | 27 KB |
21
- | `Piazzolla` | sturdy text serif, readable at length | body text, narrative, prose-heavy decks | 81 KB |
22
- | `CourierPrime` | monospace typewriter serif | code, terminals, typewriter effects | 28 KB |
23
- | `Tektur` | condensed squarish techno | sci-fi, arcade, HUD numerals | 31 KB |
24
- | `Bore` | very heavy wide grotesque | impact headlines, scores, big titles | 12 KB |
25
- | `Synco` | light wide geometric, unusual joins | retro-modernist titles | 12 KB |
26
- | `Glacier` | slanted condensed hand-cut italic | informal, energetic display | 13 KB |
27
- | `HelicoCentrica` | blackletter-flavored roman, pointed serifs | medieval, fantasy, ornate | 78 KB |
28
- | `YatraOne` | high-contrast brushy display (also Devanagari) | bold headlines, South Asian text | 89 KB |
29
-
30
- Each has one weight and one style, as in Classic. Ask for bold or italic and the
31
- browser synthesizes it.
32
-
33
- ## `install<Face>(): Promise<string>`
34
-
35
- Registers the face and resolves with its CSS family name. Idempotent — repeat
36
- calls return the first call's promise, so calling it from several modules is
37
- fine.
38
-
39
- The bytes are a `data:` URI inside the module, so there is no network fetch: no
40
- CORS, no round trip, nothing to go wrong offline, and the face is available on
41
- the first frame. That matters because a published deck is a single HTML file
42
- served from an origin that is never castle.xyz — `castle-deck://` in the iOS
43
- app, `*.decks.castle.games` on Android.
44
-
45
- **Awaiting it matters before drawing to a canvas.** Canvas 2D does not trigger a
46
- font load, so `ctx.font = '20px Piazzolla'` before the face is ready silently
47
- falls back to the default and never repaints when the font arrives:
48
-
49
- ```js
50
- import { installPiazzolla } from 'castle-web-fonts';
51
-
52
- const family = await installPiazzolla();
53
- ctx.font = `20px ${family}`;
54
- ```
55
-
56
- In CSS it matters less — the browser reflows when the face lands.
57
-
58
- ## `FACES`, `FACE_NAMES`, `faceInfo(name)`
59
-
60
- The catalog: each face's `name`, `label`, `character`, `goodFor`, `credit`,
61
- `copyright`, `url`, and `license`. **Metadata only — no font bytes**, so a font
62
- picker can list every face without pulling any of them into the bundle.
63
-
64
- ## One named export per face, never a lookup
65
-
66
- A deck pays for exactly the faces it names, because each face is a named export
67
- backed by its own module and there is no other way to reach the bytes. Adding a
68
- tenth face, or a fiftieth, costs every existing deck zero.
69
-
70
- That property is fragile and worth stating plainly:
71
-
72
- ```js
73
- // Fine. Inlines Tektur, 41 KB.
74
- import { installTektur } from 'castle-web-fonts';
75
-
76
- // NOT fine. Inlines all nine, 495 KB, in every deck that does this.
77
- const FONTS = { Tektur: installTektur, Bore: installBore, /* ... */ };
78
- FONTS[themeName]();
79
- ```
80
-
81
- No bundler can prove which key a lookup reads, so it keeps every face. Declaring
82
- `"sideEffects": false` does not rescue it. `npm run check` builds a real
83
- single-file bundle and counts the inlined faces, so a regression fails there
84
- rather than in someone's deck.
85
-
86
- If a font name has to come from data — a theme file, a saved setting — resolve
87
- that name to an `install` call at build time, not at runtime. The physics-2d kit
88
- does this by generating a one-line module when the deck's font is picked.
89
-
90
- ## Licensing
91
-
92
- Eight faces are [OFL 1.1](licenses/OFL-1.1.txt), which permits woff2 conversion
93
- and redistribution. Bore is [CC BY-ND 4.0](licenses/CC-BY-ND-4.0.txt), where
94
- conversion is a permitted technical modification under §2(a)(4) — but
95
- **subsetting Bore is not**, since dropping glyphs makes a derivative work. It is
96
- 12 KB whole.
97
-
98
- Per-face notices, verbatim from each font's own name table, are in
99
- [licenses/FONTS.md](licenses/FONTS.md).
100
-
101
- ## Development
102
-
103
- `woff2/*.woff2` are converted from the TrueType files in a `ghost` checkout
104
- (`core/assets/`), which is where the C++ engine bakes them in from — those are
105
- the source of truth for which faces exist:
106
-
107
- ```bash
108
- npm run convert -- --ghost ../../ghost # ttf -> woff2/
109
- npm run build # woff2/ -> dist/
110
- npm run check # lint + build + bundle-size invariant
111
- ```
112
-
113
- `convert` is deliberately not part of the build: a ghost checkout is not
114
- something a `castle-web-fonts` build may assume.
@@ -1,18 +0,0 @@
1
- export interface CastleFace {
2
- /** CSS family name, e.g. 'Piazzolla'. Also the `install<Name>` suffix and the `woff2/<Name>.woff2` stem. */
3
- name: string;
4
- /** Human name, e.g. 'Courier Prime'. */
5
- label: string;
6
- /** Source filename in a ghost checkout's core/assets/. */
7
- ttf: string;
8
- /** What the face looks like, in a phrase. */
9
- character: string;
10
- /** What it suits. */
11
- goodFor: string;
12
- /** Designer / foundry attribution. */
13
- credit: string;
14
- license: 'OFL-1.1' | 'CC-BY-ND-4.0';
15
- }
16
- export declare const FACES: CastleFace[];
17
- export declare const FACE_NAMES: string[];
18
- export declare function faceInfo(name: string): CastleFace | undefined;
@@ -1,142 +0,0 @@
1
- // The nine faces the Castle Classic engine offers its text tool, as web fonts.
2
- //
3
- // This list is the package: everything else -- the per-face modules, the woff2
4
- // conversion, the docs table -- is generated from or checked against it. The
5
- // `name` of a face is three things at once, deliberately: its CSS family, the
6
- // suffix of its `install<Name>` export, and the stem of its `woff2/<Name>.woff2`
7
- // file. They match Classic's own registry names (ghost/core/src/behaviors/
8
- // text_fonts.cpp), so a deck asking for `Piazzolla` here gets the same face a
9
- // Classic card asking for `Piazzolla` gets.
10
- //
11
- // `character` and `goodFor` are what an agent picking a face reads instead of
12
- // seeing a specimen, and what the physics-2d picker prints on its cards. Keep
13
- // them one short phrase each.
14
- //
15
- // This module carries NO font bytes, so importing it costs a deck nothing --
16
- // the picker UI and the docs generator both want the metadata alone.
17
-
18
- /**
19
- * @typedef {object} CastleFace
20
- * @property {string} name CSS family name, e.g. 'Piazzolla'.
21
- * @property {string} label Human name, e.g. 'Courier Prime'.
22
- * @property {string} ttf Source filename in a ghost checkout's core/assets/.
23
- * @property {string} character What the face looks like, in a phrase.
24
- * @property {string} goodFor What it suits.
25
- * @property {string} credit Designer / foundry attribution.
26
- * @property {'OFL-1.1' | 'CC-BY-ND-4.0'} license
27
- * @property {string} copyright The notice embedded in the font's own name table, verbatim.
28
- * @property {string} url Where the face is published.
29
- */
30
-
31
- /** @type {CastleFace[]} */
32
- export const FACES = [
33
- {
34
- name: 'DMSans',
35
- label: 'DM Sans',
36
- ttf: 'DMSans-Medium.ttf',
37
- character: 'clean geometric sans, low contrast',
38
- goodFor: 'body, UI, HUD',
39
- credit: 'Colophon Foundry',
40
- license: 'OFL-1.1',
41
- copyright: "Copyright 2014-2017 Indian Type Foundry (info@indiantypefoundry.com) with Reserved Font Name 'Poppins'. Copyright 2019 Google LLC.",
42
- url: 'https://github.com/googlefonts/dm-fonts',
43
- },
44
- {
45
- name: 'Piazzolla',
46
- label: 'Piazzolla',
47
- ttf: 'Piazzolla.ttf',
48
- character: 'sturdy text serif, readable at length',
49
- goodFor: 'body text, narrative, prose-heavy decks',
50
- credit: 'Juan Pablo del Peral for Huerta Tipográfica',
51
- license: 'OFL-1.1',
52
- copyright: 'Copyright 2018 The Piazzolla Project Authors (https://github.com/huertatipografica/piazzolla)',
53
- url: 'https://github.com/huertatipografica/piazzolla',
54
- },
55
- {
56
- name: 'CourierPrime',
57
- label: 'Courier Prime',
58
- ttf: 'CourierPrime-Regular.ttf',
59
- character: 'monospace typewriter serif',
60
- goodFor: 'code, terminals, typewriter effects',
61
- credit: 'Alan Dague-Greene for John August',
62
- license: 'OFL-1.1',
63
- copyright: 'Copyright (c) 2013, Quote-Unquote Apps (http://quoteunquoteapps.com), with Reserved Font Name Courier Prime.',
64
- url: 'https://quoteunquoteapps.com/courierprime/',
65
- },
66
- {
67
- name: 'Tektur',
68
- label: 'Tektur',
69
- ttf: 'Tektur.ttf',
70
- character: 'condensed squarish techno',
71
- goodFor: 'sci-fi, arcade, HUD numerals',
72
- credit: 'Adam Jagosz',
73
- license: 'OFL-1.1',
74
- copyright: 'Copyright 2020 The Tektur Project Authors (https://www.github.com/hyvyys/Tektur)',
75
- url: 'https://github.com/hyvyys/Tektur',
76
- },
77
- {
78
- name: 'Bore',
79
- label: 'Bore',
80
- ttf: 'Bore.ttf',
81
- character: 'very heavy wide grotesque',
82
- goodFor: 'impact headlines, scores, big titles',
83
- credit: 'Austin Stahl',
84
- license: 'CC-BY-ND-4.0',
85
- copyright: 'Copyright © 2021 by Austin Stahl. All rights reserved.',
86
- url: 'https://www.austinstahl.com/bore-download',
87
- },
88
- {
89
- name: 'Synco',
90
- label: 'Synco',
91
- ttf: 'Synco.ttf',
92
- character: 'light wide geometric, unusual joins',
93
- goodFor: 'retro-modernist titles',
94
- credit: 'Ariel Martín Pérez for Altiplano',
95
- license: 'OFL-1.1',
96
- copyright: 'Copyright © 2020 by Raphaël Verona | Altiplano Typefaces. All rights reserved.',
97
- url: 'https://fontesk.com/synco-font/',
98
- },
99
- {
100
- name: 'Glacier',
101
- label: 'Glacier',
102
- ttf: 'Glacier.ttf',
103
- character: 'slanted condensed hand-cut italic',
104
- goodFor: 'informal, energetic display',
105
- credit: 'Quentin Juhel',
106
- license: 'OFL-1.1',
107
- copyright: 'Copyright (c) 2020, Quentin Juhel (https://juhel-quentin.fr), with Reserved Font Name Glacier.',
108
- url: 'https://fontesk.com/glacier-typeface/',
109
- },
110
- {
111
- name: 'HelicoCentrica',
112
- label: 'Helico Centrica',
113
- ttf: 'HelicoCentrica.ttf',
114
- character: 'blackletter-flavored roman, pointed serifs',
115
- goodFor: 'medieval, fantasy, ornate',
116
- credit: 'Toby Le Rhone',
117
- license: 'OFL-1.1',
118
- copyright: 'Copyright (c) Toby le Rhone, 2015. No rights reserved.',
119
- url: 'https://fontesk.com/helico-centrica-roman-font/',
120
- },
121
- {
122
- name: 'YatraOne',
123
- label: 'Yatra One',
124
- ttf: 'YatraOne.ttf',
125
- character: 'high-contrast brushy display (also Devanagari)',
126
- goodFor: 'bold headlines, South Asian text',
127
- credit: 'Catherine Leigh Schmidt',
128
- license: 'OFL-1.1',
129
- copyright: 'Copyright 2014 The Yatra Project Authors.',
130
- url: 'https://github.com/cathschmidt/yatra-one',
131
- },
132
- ];
133
-
134
- /** Every face's CSS family name, in catalog order. */
135
- export const FACE_NAMES = FACES.map((face) => face.name);
136
-
137
- /** One face's metadata by CSS family name, or undefined. Metadata only -- this
138
- * cannot install anything, precisely because a name-keyed install would pull
139
- * every face into the bundle (see the README). */
140
- export function faceInfo(name) {
141
- return FACES.find((face) => face.name === name);
142
- }
@@ -1 +0,0 @@
1
- export declare function installFace(family: string, source: string): Promise<string>;
@@ -1,52 +0,0 @@
1
- // Registering one face with the document.
2
- //
3
- // The bytes arrive as a `data:` URI baked into the calling face module, so this
4
- // never touches the network: no CORS, no round trip, and the face is usable on
5
- // the first frame. That matters because a Castle deck is published as a single
6
- // HTML file and runs from origins that are never castle.xyz -- `castle-deck://`
7
- // in the iOS app, `*.decks.castle.games` on Android.
8
-
9
- const installs = new Map();
10
-
11
- /**
12
- * Register `family` from a woff2 `data:` URI and resolve with the family name
13
- * once it is ready to draw with. Idempotent: repeat calls for the same family
14
- * return the first call's promise.
15
- *
16
- * Awaiting matters for canvas: `ctx.font` does not trigger a font load, so
17
- * drawing before the face is ready silently falls back to the default and never
18
- * repaints. In CSS it matters less -- the browser reflows when the face lands.
19
- *
20
- * @param {string} family
21
- * @param {string} source A `data:font/woff2;base64,...` URI.
22
- * @returns {Promise<string>}
23
- */
24
- export function installFace(family, source) {
25
- const existing = installs.get(family);
26
- if (existing) return existing;
27
- const install = load(family, source);
28
- // Fire-and-forget is the documented common case (`installTektur()` with no
29
- // await), so mark the promise handled here. Awaiting callers still see the
30
- // rejection -- this is the same promise object, not a swallowing wrapper.
31
- install.catch(() => {});
32
- installs.set(family, install);
33
- return install;
34
- }
35
-
36
- async function load(family, source) {
37
- // Server-side rendering, a worker, a test runner: nothing to register the
38
- // face with, and no text to draw either. Resolve rather than throw so a
39
- // deck's top-level `installX()` doesn't take the module down with it.
40
- if (typeof document === 'undefined' || typeof FontFace === 'undefined') return family;
41
- // `swap`, so the block period never applies: a face still loading renders in
42
- // the fallback rather than as nothing. With a data: URI that window is
43
- // sub-frame anyway, but invisible text is the worse way to lose the race.
44
- const face = new FontFace(family, `url("${source}") format("woff2")`, { display: 'swap' });
45
- // ADDED BEFORE LOADED, and the order carries weight: `document.fonts.ready`
46
- // only waits for faces the set already holds, so adding after the load would
47
- // leave it resolving early -- and that promise is how a host waits for every
48
- // face a deck registered, including ones it can't know the names of.
49
- document.fonts.add(face);
50
- await face.load();
51
- return family;
52
- }
@@ -1,3 +0,0 @@
1
- /** Install Bore (very heavy wide grotesque) and resolve with its CSS
2
- * family name, `'Bore'`. Awaiting it matters before drawing to a canvas. */
3
- export declare function installBore(): Promise<string>;
@@ -1,10 +0,0 @@
1
- // Bore -- Austin Stahl, CC-BY-ND-4.0. Generated by scripts/build.mjs.
2
- import { installFace } from '../face.js';
3
-
4
- const SOURCE =
5
- 'data:font/woff2;base64,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';
6
-
7
- /** Install Bore and resolve with its CSS family name, 'Bore'. */
8
- export function installBore() {
9
- return installFace('Bore', SOURCE);
10
- }
@@ -1,3 +0,0 @@
1
- /** Install Courier Prime (monospace typewriter serif) and resolve with its CSS
2
- * family name, `'CourierPrime'`. Awaiting it matters before drawing to a canvas. */
3
- export declare function installCourierPrime(): Promise<string>;