lecodes-cli 0.19.0 → 0.20.0

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 (270) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +1069 -396
  3. package/package.json +14 -13
  4. package/runtime/scene-harness.json +1 -1
  5. package/runtime/sdk-types.json +1 -1
  6. package/runtime/web/assets/Roboto-Variable-DHm9jpd-.woff2 +0 -0
  7. package/runtime/web/assets/__vite-browser-external-BIHI7g3E.js +1 -0
  8. package/runtime/web/assets/basis-C64VHDVD.js +1 -0
  9. package/runtime/web/assets/basis_transcoder-VXdx5NbI.wasm +0 -0
  10. package/runtime/web/assets/createViewerLite-BvHobVhp.js +852 -0
  11. package/runtime/web/assets/draco-BiISTFcR.js +118 -0
  12. package/runtime/web/assets/draco_decoder-DsQ12WqX.wasm +0 -0
  13. package/runtime/web/assets/index-CfNCCBjN.js +2 -0
  14. package/runtime/web/assets/mapViewImpl-B2JcES8l.js +810 -0
  15. package/runtime/web/assets/maplibre-gl-worker-CJfwIrte.js +8 -0
  16. package/runtime/web/assets/neutral_ibl128-D-lzdkLN.ktx +0 -0
  17. package/runtime/web/assets/worker-Caf-yYEI.js +2 -0
  18. package/runtime/web/embed.html +32 -0
  19. package/runtime/web/embed.js +171 -0
  20. package/src/api.ts +302 -0
  21. package/src/browserAuth.ts +87 -0
  22. package/src/cmgenTool.ts +104 -0
  23. package/src/commands/app.ts +896 -0
  24. package/src/commands/appAndroid.ts +603 -0
  25. package/src/commands/appDesktop.ts +339 -0
  26. package/src/commands/appDesktopMac.ts +470 -0
  27. package/src/commands/appIcon.ts +187 -0
  28. package/src/commands/appShared.ts +542 -0
  29. package/src/commands/appTemplates.ts +907 -0
  30. package/src/commands/appTemplatesAndroid.ts +599 -0
  31. package/src/commands/appTemplatesGradlew.ts +9 -0
  32. package/src/commands/assets.ts +28 -0
  33. package/src/commands/clone.ts +60 -0
  34. package/src/commands/compile.ts +253 -0
  35. package/src/commands/create.ts +59 -0
  36. package/src/commands/design.ts +863 -0
  37. package/src/commands/designTemplates.ts +11 -0
  38. package/src/commands/desktop.ts +127 -0
  39. package/src/commands/dev.ts +236 -0
  40. package/src/commands/diff.ts +59 -0
  41. package/src/commands/init.ts +191 -0
  42. package/src/commands/install.ts +198 -0
  43. package/src/commands/lightmap.ts +290 -0
  44. package/src/commands/link.ts +147 -0
  45. package/src/commands/login.ts +24 -0
  46. package/src/commands/navmesh.ts +225 -0
  47. package/src/commands/pn.ts +305 -0
  48. package/src/commands/projectTemplates.ts +130 -0
  49. package/src/commands/pull.ts +109 -0
  50. package/src/commands/push.ts +173 -0
  51. package/src/commands/render.ts +416 -0
  52. package/src/commands/scene.ts +148 -0
  53. package/src/commands/shaders.ts +157 -0
  54. package/src/commands/status.ts +29 -0
  55. package/src/commands/test.ts +371 -0
  56. package/src/commands/thumbs.ts +178 -0
  57. package/src/commands/types.ts +87 -0
  58. package/src/commands/update.ts +190 -0
  59. package/src/compile/assetIcons.ts +214 -0
  60. package/src/compile/collect.ts +46 -0
  61. package/src/compile/collectLocal.ts +37 -0
  62. package/src/compile/designCompile.ts +104 -0
  63. package/src/compile/fonts.ts +156 -0
  64. package/src/compile/headlessBundle.ts +129 -0
  65. package/src/compile/nativeStack.ts +21 -0
  66. package/src/compile/projectCompile.ts +109 -0
  67. package/src/compile/sceneCompile.ts +113 -0
  68. package/src/compile/screenEntry.ts +127 -0
  69. package/src/compile/shaders.ts +245 -0
  70. package/src/config.ts +42 -0
  71. package/src/designMeta.ts +35 -0
  72. package/src/desktopRenderer.ts +545 -0
  73. package/src/desktopScript.ts +276 -0
  74. package/src/dev/clientTemplates.ts +160 -0
  75. package/src/dev/devServer.ts +333 -0
  76. package/src/dev/webRunner.ts +22 -0
  77. package/src/dev/wsServer.ts +144 -0
  78. package/src/distRoot.ts +20 -0
  79. package/src/ignore.ts +163 -0
  80. package/src/index.ts +494 -0
  81. package/src/lecodes-3d-editor.d.ts +41 -0
  82. package/src/lecodes-assets.d.ts +7 -0
  83. package/src/lecodes-design.d.ts +191 -0
  84. package/src/lecodes-renderer.d.ts +131 -0
  85. package/src/localFiles.ts +144 -0
  86. package/src/manifest.ts +46 -0
  87. package/src/matcTool.ts +137 -0
  88. package/src/peers.ts +40 -0
  89. package/src/project.ts +61 -0
  90. package/src/projectEnv.ts +94 -0
  91. package/src/qrcode-terminal.d.ts +9 -0
  92. package/src/releases.ts +125 -0
  93. package/src/serverDiff.ts +78 -0
  94. package/src/textDiff.ts +103 -0
  95. package/src/types.ts +0 -0
  96. package/src/util.ts +146 -0
  97. package/runtime/sdk/animate/animate.ts +0 -238
  98. package/runtime/sdk/animate/bezier.ts +0 -138
  99. package/runtime/sdk/animate/easings.ts +0 -126
  100. package/runtime/sdk/canvas/Canvas.ts +0 -305
  101. package/runtime/sdk/compile/aspectMacro.ts +0 -86
  102. package/runtime/sdk/compile/assetIconMacro.ts +0 -384
  103. package/runtime/sdk/compile/assetMacro.ts +0 -146
  104. package/runtime/sdk/compile/assetName.ts +0 -50
  105. package/runtime/sdk/compile/bundler.ts +0 -287
  106. package/runtime/sdk/compile/compileProject.ts +0 -129
  107. package/runtime/sdk/compile/detectEntry.ts +0 -128
  108. package/runtime/sdk/compile/fontMacro.ts +0 -459
  109. package/runtime/sdk/compile/fontRegistry.ts +0 -78
  110. package/runtime/sdk/compile/header.ts +0 -67
  111. package/runtime/sdk/compile/index.ts +0 -100
  112. package/runtime/sdk/compile/libraryImports.ts +0 -52
  113. package/runtime/sdk/compile/liteMaterial.ts +0 -247
  114. package/runtime/sdk/compile/sceneEditor.ts +0 -88
  115. package/runtime/sdk/compile/serverSplit.ts +0 -233
  116. package/runtime/sdk/compile/serverTypes.ts +0 -227
  117. package/runtime/sdk/compile/sfnt.ts +0 -98
  118. package/runtime/sdk/compile/shaderSchema.ts +0 -202
  119. package/runtime/sdk/compile/shaderTargets.ts +0 -81
  120. package/runtime/sdk/compile/sourcemap.ts +0 -25
  121. package/runtime/sdk/core/Aspect.ts +0 -568
  122. package/runtime/sdk/core/InspectorUI.ts +0 -212
  123. package/runtime/sdk/core/StateMachine.ts +0 -308
  124. package/runtime/sdk/core/color.ts +0 -66
  125. package/runtime/sdk/core/compWrite.ts +0 -42
  126. package/runtime/sdk/core/events.ts +0 -38
  127. package/runtime/sdk/core/fields.ts +0 -120
  128. package/runtime/sdk/core/registry.ts +0 -23
  129. package/runtime/sdk/core/signals.ts +0 -277
  130. package/runtime/sdk/core/time.ts +0 -84
  131. package/runtime/sdk/g2/Camera2D.ts +0 -40
  132. package/runtime/sdk/g2/CharacterController2D.ts +0 -276
  133. package/runtime/sdk/g2/Node2D.ts +0 -267
  134. package/runtime/sdk/g2/OneWay2D.ts +0 -66
  135. package/runtime/sdk/g2/Physics2D.ts +0 -346
  136. package/runtime/sdk/g2/Scene2D.ts +0 -209
  137. package/runtime/sdk/g2/Shape2D.ts +0 -259
  138. package/runtime/sdk/g2/Sprite.ts +0 -89
  139. package/runtime/sdk/g2/SpriteAnimation.ts +0 -171
  140. package/runtime/sdk/g2/SpriteSheet.ts +0 -166
  141. package/runtime/sdk/g2/Texture2D.ts +0 -47
  142. package/runtime/sdk/g2/Tilemap.ts +0 -41
  143. package/runtime/sdk/g2/Tileset.ts +0 -71
  144. package/runtime/sdk/g2/Trigger2D.ts +0 -77
  145. package/runtime/sdk/g2/autotile.ts +0 -433
  146. package/runtime/sdk/g2/cells.ts +0 -91
  147. package/runtime/sdk/g2/defineScene2d.ts +0 -381
  148. package/runtime/sdk/g2/groups2d.ts +0 -106
  149. package/runtime/sdk/g2/loop.ts +0 -50
  150. package/runtime/sdk/g2/scenarios2d.ts +0 -69
  151. package/runtime/sdk/g2/touch.ts +0 -83
  152. package/runtime/sdk/gl/Camera.ts +0 -160
  153. package/runtime/sdk/gl/CameraPlace.ts +0 -52
  154. package/runtime/sdk/gl/CharacterController.ts +0 -238
  155. package/runtime/sdk/gl/Gearbox.ts +0 -212
  156. package/runtime/sdk/gl/Geometry.ts +0 -279
  157. package/runtime/sdk/gl/IK.ts +0 -193
  158. package/runtime/sdk/gl/InstancedMesh.ts +0 -132
  159. package/runtime/sdk/gl/Light.ts +0 -107
  160. package/runtime/sdk/gl/Lightmap.ts +0 -256
  161. package/runtime/sdk/gl/Material.ts +0 -260
  162. package/runtime/sdk/gl/Mesh.ts +0 -83
  163. package/runtime/sdk/gl/Model.ts +0 -124
  164. package/runtime/sdk/gl/NavAgent.ts +0 -337
  165. package/runtime/sdk/gl/NavMesh.ts +0 -397
  166. package/runtime/sdk/gl/Node.ts +0 -350
  167. package/runtime/sdk/gl/Noise.ts +0 -30
  168. package/runtime/sdk/gl/Particles.ts +0 -676
  169. package/runtime/sdk/gl/Physics.ts +0 -222
  170. package/runtime/sdk/gl/Plane.ts +0 -53
  171. package/runtime/sdk/gl/Ragdoll.ts +0 -270
  172. package/runtime/sdk/gl/Ray.ts +0 -16
  173. package/runtime/sdk/gl/Scene.ts +0 -486
  174. package/runtime/sdk/gl/Shape.ts +0 -409
  175. package/runtime/sdk/gl/Terrain.ts +0 -1092
  176. package/runtime/sdk/gl/Texture.ts +0 -63
  177. package/runtime/sdk/gl/Trigger.ts +0 -45
  178. package/runtime/sdk/gl/Vehicle.ts +0 -473
  179. package/runtime/sdk/gl/Wheel.ts +0 -240
  180. package/runtime/sdk/gl/animation/AnimationClip.ts +0 -204
  181. package/runtime/sdk/gl/animation/Animator.ts +0 -120
  182. package/runtime/sdk/gl/animation/Layer.ts +0 -31
  183. package/runtime/sdk/gl/animation/Loop.ts +0 -30
  184. package/runtime/sdk/gl/animation/Playback.ts +0 -44
  185. package/runtime/sdk/gl/animation/core.ts +0 -336
  186. package/runtime/sdk/gl/controls.ts +0 -95
  187. package/runtime/sdk/gl/physicsEvents.ts +0 -20
  188. package/runtime/sdk/gl/scenarios.ts +0 -291
  189. package/runtime/sdk/gl/state.ts +0 -6
  190. package/runtime/sdk/gl/terrainMesh.ts +0 -219
  191. package/runtime/sdk/gl/touch.ts +0 -68
  192. package/runtime/sdk/inject.ts +0 -197
  193. package/runtime/sdk/math/Mathf.ts +0 -118
  194. package/runtime/sdk/math/mat4.ts +0 -278
  195. package/runtime/sdk/math/quat.ts +0 -232
  196. package/runtime/sdk/math/vec.ts +0 -255
  197. package/runtime/sdk/net/codec.ts +0 -119
  198. package/runtime/sdk/net/core.ts +0 -384
  199. package/runtime/sdk/net/index.ts +0 -181
  200. package/runtime/sdk/net/replication.ts +0 -622
  201. package/runtime/sdk/plugins/camera.ts +0 -81
  202. package/runtime/sdk/plugins/geolocation.ts +0 -123
  203. package/runtime/sdk/plugins/oauth.ts +0 -61
  204. package/runtime/sdk/plugins/permission.ts +0 -7
  205. package/runtime/sdk/plugins/push.ts +0 -132
  206. package/runtime/sdk/plugins/qr.ts +0 -73
  207. package/runtime/sdk/plugins/service.ts +0 -47
  208. package/runtime/sdk/runtime/app.ts +0 -101
  209. package/runtime/sdk/runtime/appEvents.ts +0 -54
  210. package/runtime/sdk/runtime/channel.ts +0 -61
  211. package/runtime/sdk/runtime/clipboard.ts +0 -20
  212. package/runtime/sdk/runtime/datetime.ts +0 -329
  213. package/runtime/sdk/runtime/device.ts +0 -293
  214. package/runtime/sdk/runtime/fetch.ts +0 -77
  215. package/runtime/sdk/runtime/files.ts +0 -23
  216. package/runtime/sdk/runtime/input.ts +0 -175
  217. package/runtime/sdk/runtime/media.ts +0 -111
  218. package/runtime/sdk/runtime/misc.ts +0 -16
  219. package/runtime/sdk/runtime/net.ts +0 -36
  220. package/runtime/sdk/runtime/rpc.ts +0 -218
  221. package/runtime/sdk/runtime/service.ts +0 -83
  222. package/runtime/sdk/runtime/share.ts +0 -9
  223. package/runtime/sdk/runtime/storage.ts +0 -13
  224. package/runtime/sdk/runtime/touch.ts +0 -76
  225. package/runtime/sdk/scene/defineScene.ts +0 -1353
  226. package/runtime/sdk/scene/editorPlugins.ts +0 -110
  227. package/runtime/sdk/scene/gizmos.ts +0 -148
  228. package/runtime/sdk/scene/grammar.ts +0 -120
  229. package/runtime/sdk/scene/material.ts +0 -188
  230. package/runtime/sdk/server/auth/appConfig.ts +0 -12
  231. package/runtime/sdk/server/auth/global.ts +0 -80
  232. package/runtime/sdk/server/auth/host.ts +0 -318
  233. package/runtime/sdk/server/auth/models.ts +0 -83
  234. package/runtime/sdk/server/auth/types.ts +0 -50
  235. package/runtime/sdk/server/channel.ts +0 -56
  236. package/runtime/sdk/server/context.ts +0 -36
  237. package/runtime/sdk/server/db/defineDb.ts +0 -237
  238. package/runtime/sdk/server/db/fields.ts +0 -132
  239. package/runtime/sdk/server/db/httpTransport.ts +0 -93
  240. package/runtime/sdk/server/db/index.ts +0 -7
  241. package/runtime/sdk/server/db/marci/query.ts +0 -412
  242. package/runtime/sdk/server/db/types.ts +0 -202
  243. package/runtime/sdk/server/errors.ts +0 -12
  244. package/runtime/sdk/server/host.ts +0 -74
  245. package/runtime/sdk/server/inject.ts +0 -13
  246. package/runtime/sdk/server/runtime.ts +0 -133
  247. package/runtime/sdk/server/validate.ts +0 -87
  248. package/runtime/sdk/ui/NativeView.ts +0 -142
  249. package/runtime/sdk/ui/UI.ts +0 -39
  250. package/runtime/sdk/ui/UIBottomSheet.ts +0 -139
  251. package/runtime/sdk/ui/UIButton.ts +0 -101
  252. package/runtime/sdk/ui/UIContainer.ts +0 -60
  253. package/runtime/sdk/ui/UIImage.ts +0 -83
  254. package/runtime/sdk/ui/UIInput.ts +0 -185
  255. package/runtime/sdk/ui/UIModal.ts +0 -139
  256. package/runtime/sdk/ui/UINode.ts +0 -830
  257. package/runtime/sdk/ui/UIPager.ts +0 -362
  258. package/runtime/sdk/ui/UIPopover.ts +0 -100
  259. package/runtime/sdk/ui/UIScreen.ts +0 -123
  260. package/runtime/sdk/ui/UIScrollable.ts +0 -87
  261. package/runtime/sdk/ui/UISpacer.ts +0 -14
  262. package/runtime/sdk/ui/UITabs.ts +0 -236
  263. package/runtime/sdk/ui/UIText.ts +0 -51
  264. package/runtime/sdk/ui/UIVideo.ts +0 -88
  265. package/runtime/sdk/ui/UIVirtualizedList.ts +0 -241
  266. package/runtime/sdk/ui/UIWidget.ts +0 -127
  267. package/runtime/sdk/ui/fonts.ts +0 -13
  268. package/runtime/sdk/ui/presentable.ts +0 -117
  269. package/runtime/sdk/ui/router.ts +0 -132
  270. package/runtime/sdk/ui/theme.ts +0 -84
@@ -1,166 +0,0 @@
1
- // Sprite sheets as data: one `.sprite.ts` file per image, `export default defineSpriteSheet({...})`.
2
- // ONE model: every named entry is a region of the image (a rect), optionally SLICED into an
3
- // animation grid, optionally carrying named clips over that grid — so game code (and the scene
4
- // editor) reference frames by NAME and never hardcode rects:
5
- //
6
- // import props from './props.sprite'
7
- // import hero from './hero.sprite'
8
- // scene.add(props.make('tree_orange', { position: [80, 144], layer: 1 }))
9
- // scene.add(props.make('water', { position: [0, 0] })) // sliced, loops on its own
10
- // const player = hero.make('hero', { clip: 'idle', layer: 1 })
11
- // player.anim.play('walk', inputVector)
12
- //
13
- // A sheet describes ART only — rects, slices, clips, anchors. World semantics (colliders, bodies)
14
- // are the SCENE's job: attach Shape2D / Physics2D / Trigger2D aspects to the placed node (a
15
- // `.scene2d.ts` `aspects:` list, or `.aspect(...)` in code). Each tool owns its own part.
16
- //
17
- // The texture loads lazily on the first make()/load(); sprites created before it resolves get their
18
- // texture/frame applied on arrival (the world size is known up front from the rect / slice cell, so
19
- // layout doesn't wait). The sprite editor reads and writes these files — hand edits are preserved
20
- // (see packages/scene-doc).
21
-
22
- import { type Vec2Like } from "../math/vec"
23
- import { Sprite } from "./Sprite"
24
- import { SpriteAnimation, type Clip } from "./SpriteAnimation"
25
- import { Texture2D } from "./Texture2D"
26
-
27
- /**
28
- * A named region of the image. Just a rect is a static sprite; `slice` subdivides the rect into an
29
- * animation grid ([cols, rows] — the cell is rect size / counts); `clips` names frame runs over
30
- * that grid (local, row-major). A sliced entry with NO clips loops all of its cells in order.
31
- */
32
- export type SheetSprite = {
33
- /** Pixel rect [x, y, w, h] in the image. */
34
- rect?: [number, number, number, number]
35
- /** Subdivide the rect into an animation grid: [cols, rows]. */
36
- slice?: [number, number]
37
- /** Playback fps for this sprite's animation (defaults to the sheet fps, then 12). */
38
- fps?: number
39
- /** Named clips over the local grid (see SpriteAnimation). Omit to loop every cell. */
40
- clips?: Record<string, Clip>
41
- /** Facing names in local-row order for `perDirection` clips (compass tokens: S/SE/E/…). */
42
- directions?: string[]
43
- /** Overrides the sheet anchor. */
44
- anchor?: Vec2Like
45
- }
46
-
47
- export type SpriteSheetDef = {
48
- /** The image URL — write `asset('./sheet.png')`. */
49
- image: string
50
- /** Default pivot for every sprite made from this sheet ([0.5, 1] = feet, for Y-sorted worlds). */
51
- anchor?: Vec2Like
52
- /** Default fps for sliced sprites / clips that don't override it. */
53
- fps?: number
54
- /** The named sprites. */
55
- sprites?: Record<string, SheetSprite>
56
- }
57
-
58
- export type SpriteMakeOptions = {
59
- position?: Vec2Like
60
- layer?: number
61
- /** Overrides the sheet/sprite anchor. */
62
- anchor?: Vec2Like
63
- /** Start this clip immediately (sliced sprites with clips). */
64
- clip?: string
65
- /** Initial facing for `perDirection` clips. */
66
- direction?: string
67
- }
68
-
69
- /** The name a sliced-but-clipless sprite's implicit everything-loop plays under. */
70
- const LOOP_ALL = "all"
71
-
72
- export class SpriteSheet {
73
- private _def: SpriteSheetDef
74
- private _tex: Texture2D | null = null
75
- private _loading: Promise<Texture2D> | null = null
76
-
77
- constructor(def: SpriteSheetDef) {
78
- this._def = def
79
- }
80
-
81
- /** The sheet definition (read-only by convention — the editor owns the file). */
82
- get def(): SpriteSheetDef { return this._def }
83
-
84
- /** The loaded texture, or null before load() resolves. */
85
- get texture(): Texture2D | null { return this._tex }
86
-
87
- /** Load the sheet's texture (idempotent). make() starts this automatically. */
88
- load(): Promise<Texture2D> {
89
- if (!this._loading) {
90
- this._loading = Texture2D.load(this._def.image).then((tex) => { this._tex = tex; return tex })
91
- }
92
- return this._loading
93
- }
94
-
95
- /** Names of the sheet's sprites. */
96
- get spriteNames(): string[] { return Object.keys(this._def.sprites ?? {}) }
97
-
98
- /** Build a named sprite; starting a clip hands back the animation handle. */
99
- make(name: string, opts: SpriteMakeOptions & { clip: string }): Sprite & { anim: SpriteAnimation }
100
- make(name: string, opts?: SpriteMakeOptions): Sprite
101
- make(name: string, opts: SpriteMakeOptions = {}): Sprite {
102
- const def = this._def
103
- const named = def.sprites?.[name]
104
- if (!named) {
105
- throw new Error(`SpriteSheet.make(): unknown sprite "${name}" (have: ${this.spriteNames.join(", ") || "none"})`)
106
- }
107
- const rect = named.rect
108
- const slice = named.slice
109
-
110
- const sprite = new Sprite({
111
- anchor: opts.anchor ?? named.anchor ?? def.anchor,
112
- layer: opts.layer,
113
- position: opts.position,
114
- })
115
-
116
- // The world size is known without the texture (the rect, or its slice cell) — set it up front
117
- // so layout, Y-sort and colliders are correct even while the image is still loading.
118
- if (rect) sprite.size = slice ? [ rect[2] / slice[0], rect[3] / slice[1] ] : [ rect[2], rect[3] ]
119
-
120
- // sliced sprite: all animation flows through SpriteAnimation, anchored at the rect's origin.
121
- // No clips declared = one implicit clip looping every cell (animated tiles).
122
- if (rect && slice) {
123
- const [ cols, rows ] = slice
124
- const clips = named.clips && Object.keys(named.clips).length > 0
125
- ? named.clips
126
- : { [LOOP_ALL]: Array.from({ length: cols * rows }, (_, i) => i) }
127
- const animOpts: Partial<SpriteAnimation> = {
128
- size: [ rect[2] / cols, rect[3] / rows ],
129
- cols,
130
- origin: [ rect[0], rect[1] ],
131
- clips,
132
- }
133
- const fps = named.fps ?? def.fps
134
- if (fps !== undefined) animOpts.fps = fps
135
- if (named.directions) animOpts.directions = named.directions
136
- sprite.aspect(SpriteAnimation, animOpts)
137
- const start = opts.clip ?? (named.clips ? undefined : LOOP_ALL)
138
- if (start) (sprite as Sprite & { anim: SpriteAnimation }).anim.play(start, opts.direction)
139
- }
140
-
141
- // texture + frame: now if loaded, else on arrival
142
- if (this._tex) this._applyTexture(sprite, named, this._tex)
143
- else this.load().then((tex) => this._applyTexture(sprite, named, tex))
144
- return sprite
145
- }
146
-
147
- /** The pixel rect [x, y, w, h] of a named sprite's REGION (the whole rect, sliced or not). */
148
- rectOf(name: string): [number, number, number, number] | null {
149
- const rect = this._def.sprites?.[name]?.rect
150
- return rect ? [ ...rect ] : null
151
- }
152
-
153
- private _applyTexture(sprite: Sprite, named: SheetSprite, tex: Texture2D): void {
154
- sprite.texture = tex // native resets UV/size; the Sprite setter re-applies our explicit size
155
- const rect = named.rect
156
- if (rect) {
157
- const [ cw, ch ] = named.slice ? [ rect[2] / named.slice[0], rect[3] / named.slice[1] ] : [ rect[2], rect[3] ]
158
- sprite.setFramePx(rect[0], rect[1], cw, ch) // cell 0 (or the whole static rect)
159
- }
160
- const anim = (sprite as Partial<{ anim: SpriteAnimation }>).anim
161
- if (anim) anim.define()
162
- }
163
- }
164
-
165
- /** Declare a sprite sheet (the default export of a `.sprite.ts` file). */
166
- export const defineSpriteSheet = (def: SpriteSheetDef): SpriteSheet => new SpriteSheet(def)
@@ -1,47 +0,0 @@
1
- // A GPU texture decoded natively by creator-2d (stb_image). Load from a URL (or an already-fetched
2
- // response); the raw file bytes are handed to the engine, which decodes + uploads them.
3
-
4
- // Internal SDK code imports injected globals explicitly (the bare-global inject is only for USER
5
- // code; here `fetch` would otherwise resolve to the node/bun ambient one).
6
- import { fetch, type FetchResponse, type File } from "../runtime/fetch"
7
-
8
- export class Texture2D {
9
- /** Native texture handle. */
10
- readonly id: number
11
- readonly width: number
12
- readonly height: number
13
-
14
- constructor(id: number, width: number, height: number) {
15
- this.id = id
16
- this.width = width
17
- this.height = height
18
- }
19
-
20
- // Wrap a Canvas's baked surface as a texture (RGBA8, already rasterized → synchronous, no decode).
21
- // Structural type avoids a Canvas import cycle (Canvas imports Texture2D).
22
- static fromCanvas(canvas: { _bakeSurface(): number, width: number, height: number, pixelRatio: number }): Texture2D {
23
- const surfaceId = canvas._bakeSurface()
24
- const texId = _creator2d.createTextureFromCanvas(surfaceId)
25
- return new Texture2D(texId, Math.round(canvas.width * canvas.pixelRatio), Math.round(canvas.height * canvas.pixelRatio))
26
- }
27
-
28
- // Accepts a URL, an already-fetched response, or a File (e.g. from Canvas.toFile() / openFilePicker) —
29
- // anything backed by a host buffer. The buffer's encoded bytes are decoded + uploaded by the engine.
30
- static load(source: string | FetchResponse | File): Promise<Texture2D> {
31
- if (typeof source === "string") {
32
- return fetch(source, { useOnce: true }).then((resp) => {
33
- if (resp.status >= 400) {
34
- return Promise.reject(new Error(`Failed to fetch texture from ${source}. HTTP ${resp.status}`))
35
- }
36
- return Texture2D.load(resp)
37
- })
38
- }
39
- return new Promise<Texture2D>((resolve, reject) => {
40
- _creator2d.createTexture((source as any)._id, (id, w, h) => resolve(new Texture2D(id, w, h)), reject)
41
- })
42
- }
43
-
44
- destroy(): void {
45
- _creator2d.destroyTexture(this.id)
46
- }
47
- }
@@ -1,41 +0,0 @@
1
- // A tilemap node. The grid is uploaded once and rendered natively with per-frame view culling; the
2
- // node's position is the bottom-left of the map. Edit cells with setTile.
3
-
4
- import { Node2D } from "./Node2D"
5
- import type { Texture2D } from "./Texture2D"
6
-
7
- export type TilemapOptions = {
8
- texture: Texture2D
9
- /** Map grid size (in tiles). */
10
- cols: number
11
- rows: number
12
- /** On-screen cell size in world units — a single number (square) or [w, h]. */
13
- tile: number | [number, number]
14
- /** Atlas grid: how the texture is sliced into tiles, [atlasCols, atlasRows]. */
15
- atlas: [number, number]
16
- /** Row-major tile indices into the atlas (-1 = empty), length cols*rows. Row 0 is the top row. */
17
- data: number[] | Int32Array
18
- }
19
-
20
- export class Tilemap extends Node2D {
21
- readonly cols: number
22
- readonly rows: number
23
-
24
- constructor(options: TilemapOptions) {
25
- const data = options.data instanceof Int32Array ? options.data : Int32Array.from(options.data)
26
- const tileW = typeof options.tile === "number" ? options.tile : options.tile[0]
27
- const tileH = typeof options.tile === "number" ? options.tile : options.tile[1]
28
- const [ atlasCols, atlasRows ] = options.atlas
29
- const id = _creator2d.createTilemap(
30
- options.texture.id, options.cols, options.rows, tileW, tileH, atlasCols, atlasRows, data,
31
- )
32
- super(id) // wrap the native tilemap entity
33
- this.cols = options.cols
34
- this.rows = options.rows
35
- }
36
-
37
- setTile(x: number, y: number, index: number): this {
38
- _creator2d.setTile(this.id, x, y, index)
39
- return this
40
- }
41
- }
@@ -1,71 +0,0 @@
1
- // Tilesets as data: one `.tiles.ts` file per atlas, `export default defineTileset({...})` — the
2
- // material vocabulary (autotile rules) for maps painted by material id. The pure model + deriver
3
- // live in ./autotile.ts; this file is the runtime handle plus the `Autotile2D` aspect that binds a
4
- // tilemap node to its tileset:
5
- //
6
- // // world.tiles.ts
7
- // export default defineTileset({
8
- // image: asset('./TileSet.png'),
9
- // tile: 32,
10
- // materials: {
11
- // grass: { id: 1, kind: 'patch', color: '#4a7c3a', fill: [261, [262, 0.1]],
12
- // over: { '*': { edges: [197, 262, 325, 260], outer: [198, 326, 324, 196],
13
- // inner: [199, 327, 391, 263] } } },
14
- // road: { id: 2, kind: 'path', color: '#8a8578', straights: [520, 521], corners: [522, 523, 524, 525] },
15
- // },
16
- // })
17
- //
18
- // // meadow.scene2d.ts
19
- // import world from './world.tiles'
20
- // ground: { tilemap: { texture: asset('./TileSet.png'), tile: 32, atlas: [64, 64],
21
- // cells: cells('…') }, // cells hold MATERIAL ids here
22
- // aspects: [use(Autotile2D, { tileset: world, seed: 3 })] }
23
- //
24
- // The aspect flips the meaning of the same `cells('…')` payload from raw atlas indices to material
25
- // ids; the scene2d loader runs the deriver BEFORE the Tilemap is constructed (aspects are data on
26
- // the node def), so no post-construction data path exists and derived indices are never persisted.
27
-
28
- import { Aspect } from "../core/Aspect"
29
- import type { Node2D } from "./Node2D"
30
- import { deriveCells, type TilesetDef, type TileMaterial } from "./autotile"
31
-
32
- export class Tileset {
33
- private _def: TilesetDef
34
-
35
- constructor(def: TilesetDef) { this._def = def }
36
-
37
- /** The tileset definition (read-only by convention — the editor owns the file). */
38
- get def(): TilesetDef { return this._def }
39
-
40
- /** Names of the declared materials, in file order. */
41
- get materialNames(): string[] { return Object.keys(this._def.materials ?? {}) }
42
-
43
- /** A material by name. */
44
- material(name: string): TileMaterial | undefined { return this._def.materials?.[name] }
45
-
46
- /** The cell value maps store for a named material (what you paint / pass in `data`). */
47
- id(name: string): number | undefined { return this._def.materials?.[name]?.id }
48
-
49
- /** Derive display atlas indices from a material-id grid (what Autotile2D does at load). */
50
- derive(cols: number, rows: number, data: ArrayLike<number>, seed = 0): Int32Array {
51
- return deriveCells(this._def, cols, rows, data, seed)
52
- }
53
- }
54
-
55
- /** Declare a tileset (the default export of a `.tiles.ts` file). */
56
- export const defineTileset = (def: TilesetDef): Tileset => new Tileset(def)
57
-
58
- /**
59
- * Marks a tilemap node's `cells` as MATERIAL ids of a tileset instead of raw atlas indices:
60
- * `aspects: [use(Autotile2D, { tileset: world })]`. The scene2d loader derives the display
61
- * indices (neighbor-mask autotile + seeded scatter, deterministic) before building the tilemap;
62
- * the aspect itself holds no behavior. Change `seed` to reshuffle scatter variants.
63
- */
64
- export class Autotile2D extends Aspect<"autotile", Node2D> {
65
- static readonly aspect = "autotile"
66
-
67
- /** The imported `.tiles.ts` handle. */
68
- tileset: Tileset | null = null
69
- /** Scatter seed — same seed, same map, same result on every platform. */
70
- seed = 0
71
- }
@@ -1,77 +0,0 @@
1
- // A trigger zone, as an aspect on a Node2D. Requires a Shape2D (its geometry); creates a SENSOR body
2
- // from it, so a physics body overlapping the zone fires the node's 'enter' / 'exit' events instead of
3
- // colliding. A trigger does not block movement.
4
- //
5
- // const goal = new Node2D()
6
- // .aspect(Shape2D, { box: [32, 64] })
7
- // .aspect(Trigger2D)
8
- // goal.addEventListener('enter', other => win(other))
9
- // goal.position = [x, y] // the zone follows — it is kinematic, not static
10
- // goal.trigger.enabled = false // switch it off instead of parking it off-screen
11
- //
12
- // (A trigger is still pointer-pickable — clicks hit sensor shapes too.)
13
- //
14
- // Keep triggers on ROOT nodes: a sensor parented to a moving node does not follow it (see
15
- // docs/2d-physics-plan.md §6).
16
-
17
- import { Aspect } from "../core/Aspect"
18
- import { ensurePhysicsEvents } from "./loop"
19
- import { Shape2D } from "./Shape2D"
20
- import { PhysicsGroup2D, _watchGroupChanges, _unwatchGroupChanges, categoryOf, sensorMask } from "./groups2d"
21
- import type { Node2D } from "./Node2D"
22
-
23
- export class Trigger2D extends Aspect<"trigger", Node2D> {
24
- static readonly aspect = "trigger"
25
-
26
- private _h = 0
27
- private _enabled = true
28
- private _group: PhysicsGroup2D | undefined
29
- private _repush = (): void => {
30
- if (this._h) _creator2d.physicsSetFilter(this._h, categoryOf(this._group), sensorMask(this._group))
31
- }
32
-
33
- /** Which collision group this zone belongs to. Live. */
34
- get group(): PhysicsGroup2D | undefined { return this._group }
35
- set group(g: PhysicsGroup2D | undefined) {
36
- this._group = g
37
- this.node.get(Shape2D)?._setFilter(categoryOf(g), sensorMask(g))
38
- this._repush()
39
- }
40
-
41
- /** Native physics body id (0 if no physics support). Mirrors 3D `Trigger.id`. */
42
- get id(): number { return this._h }
43
-
44
- onAttach(): void {
45
- if (!_creator2d.physicsHasSupport || !_creator2d.physicsHasSupport()) return
46
- const shape = this.node.get(Shape2D)
47
- if (!shape) {
48
- throw new Error("Trigger2D requires a Shape2D aspect — add it first: node.aspect(Shape2D, {…}).aspect(Trigger2D)")
49
- }
50
- // KINEMATIC, not static: a zone has to be able to ride an elevator, a patrolling enemy or a
51
- // fighter's fist. It used to be static, which is why games parked spent triggers at [-9999,-9999].
52
- this._h = _creator2d.physicsCreateBody(this.node.id, 1 /* kinematic */)
53
- if (!this._h) return
54
- // sensorMask always keeps the character bit: a kinematic mover is not a Box2D body, so its shadow
55
- // body is what triggers actually see, and no game should have to know that.
56
- shape._addTo(this._h, { sensor: true, friction: 0, bounce: 0, category: categoryOf(this.group), mask: sensorMask(this.group) })
57
- if (this._group) _watchGroupChanges(this._repush)
58
- this.node._xf = this._h // node.position moves the zone
59
- this.node._xfKind = 2
60
- if (!this.enabled) _creator2d.physicsSetEnabled(this._h, false) // via the accessor on purpose — see Physics2D.onAttach
61
- ensurePhysicsEvents() // routes contact/sensor events → the node's 'enter' / 'exit'
62
- }
63
-
64
- onDetach(): void {
65
- _unwatchGroupChanges(this._repush)
66
- if (this._h) { _creator2d.physicsRemoveBody(this._h); this._h = 0 }
67
- this.node._xf = 0
68
- this.node._xfKind = 0
69
- }
70
-
71
- /** Switch the zone off and on — a spent pickup, a hitbox that is only live during a swing. */
72
- get enabled(): boolean { return this._enabled }
73
- set enabled(v: boolean) {
74
- this._enabled = v
75
- if (this._h) _creator2d.physicsSetEnabled(this._h, v)
76
- }
77
- }