@maccesar/titools 4.15.0 → 4.16.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.
- package/README.md +7 -1
- package/package.json +1 -1
- package/skills/ti-game/SKILL.md +88 -197
- package/skills/ti-game/references/api.md +45 -13
- package/skills/ti-game/references/debugging-performance.md +103 -0
- package/skills/ti-game/references/examples.md +54 -0
- package/skills/ti-game/references/patterns.md +699 -0
- package/skills/ti-game/references/project-setup.md +15 -6
- package/skills/ti-game/references/recipes-action.md +633 -0
- package/skills/ti-game/references/recipes-adventure-effects.md +340 -0
- package/skills/ti-game/references/roadmap.md +44 -65
- package/skills/ti-game/references/tilemaps.md +125 -0
- package/skills/ti-game/references/recipes.md +0 -1679
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Setting up a ti.game project
|
|
2
2
|
|
|
3
|
-
Installing the module, wiring it into Classic and Alloy projects, organizing art and sound, and the lifecycle work the engine does not do for you.
|
|
3
|
+
Installing the module, wiring it into Classic and Alloy projects, organizing art and sound, and the lifecycle work the engine does not do for you. Verified against `ti.game@d587081` (2026-08-28).
|
|
4
4
|
|
|
5
5
|
<!-- TOC-START -->
|
|
6
6
|
## Contents
|
|
@@ -56,8 +56,10 @@ Pinning `version` is worth the extra attribute: with two module versions install
|
|
|
56
56
|
| `0.4.0` built before 2026-08-26 | additionally `sprite.attachTo()` / `detach()` / `attachedTo`, and `gameView.follow()` still aborts the app on Android if it is handed anything that is not a sprite |
|
|
57
57
|
| `0.4.0` built on 2026-08-26 but before `83b7863` | additionally the opacity an attachment inherits from its target, the `anchor` property, and percentage strings on every ratio — a build in this window has `attachTo` but treats `'55%'` as a number it cannot read |
|
|
58
58
|
| `0.4.0` at its last commit (`b780051`) | additionally everything the `0.5.0` bump carries: `hitboxShape: 'rotatedRect'`, circular solids resolved as circles, `solidMode`, `gravityX`, `linearDamping`, and `restitution` read off both sides of a contact. It also still pulls a swept sprite back to where its frame started when it begins the frame already touching a solid, so a `swept: true` body parked on a slope creeps and then breaks loose as if launched |
|
|
59
|
+
| `0.5.0` built before `d042060` | the performance HUD object form (`debug: { hud, hitbox, hudFont }`) and the `performance` event |
|
|
60
|
+
| `0.5.0` built before `10a046e` | additionally `Game.createTileLayer()`, native visible-cell tile rendering, tile collision/live edits, and TileLayer participation in `findPath` |
|
|
59
61
|
|
|
60
|
-
The
|
|
62
|
+
The newest local release tag is still `0.4.0` (2026-08-20), so tagged artifacts lag one manifest bump plus the HUD and TileLayer work that landed after `0.5.0` was introduced. If a documented call is `undefined`, check the manifest and build commit before hunting for a typo, and rebuild from upstream `main`. More reliable than either is feature detection: read a property **before** writing it (`typeof sprite.hitboxScaleX === 'undefined'`) or probe a method/factory (`typeof Game.createTileLayer === 'function'`). Write-then-read is not proof because Kroll can retain an unknown property on the proxy.
|
|
61
63
|
|
|
62
64
|
Building the module from source:
|
|
63
65
|
|
|
@@ -69,7 +71,7 @@ ti build -p ios --build-only # macOS only → ios/dist/ti.game-iphone-<ve
|
|
|
69
71
|
|
|
70
72
|
## Classic projects
|
|
71
73
|
|
|
72
|
-
`require('ti.game')` anywhere and add the GameView to a window. The
|
|
74
|
+
`require('ti.game')` anywhere and add the GameView to a window. The 33 demos in the module's `example/` folder are Classic, each one a CommonJS module exporting a start function (`app.js` is the launcher, not a demo):
|
|
73
75
|
|
|
74
76
|
```javascript
|
|
75
77
|
// Resources/flappy.js
|
|
@@ -270,6 +272,8 @@ The engine handles what it owns: the render loop pauses and resumes with the act
|
|
|
270
272
|
A leaked `setInterval` keeps running after the window closes, keeps reading sprite properties from a dead scene and keeps the whole closure alive. A looping `createSound` keeps playing over the next screen.
|
|
271
273
|
|
|
272
274
|
```javascript
|
|
275
|
+
const levelObjects = []; // keep emitters, ropes, and TileLayers here
|
|
276
|
+
|
|
273
277
|
function cleanup() {
|
|
274
278
|
clearInterval(aiTimer);
|
|
275
279
|
clearTimeout(spawnTimer);
|
|
@@ -280,7 +284,10 @@ function cleanup() {
|
|
|
280
284
|
target.removeEventListener(eventName, handler);
|
|
281
285
|
});
|
|
282
286
|
gameView.pause();
|
|
283
|
-
gameView.removeAllSprites();
|
|
287
|
+
gameView.removeAllSprites(); // Sprite/Text only
|
|
288
|
+
levelObjects.forEach((object) => { // emitters, ropes, tile layers
|
|
289
|
+
gameView.remove(object);
|
|
290
|
+
});
|
|
284
291
|
}
|
|
285
292
|
|
|
286
293
|
// Classic
|
|
@@ -301,7 +308,7 @@ function listen(target, eventName, handler) {
|
|
|
301
308
|
}
|
|
302
309
|
```
|
|
303
310
|
|
|
304
|
-
|
|
311
|
+
`removeAllSprites()` is named literally: it clears Sprite/Text objects and their attachment state, but leaves emitters, ropes, and tile layers in the scene. Track non-sprite scene objects in `levelObjects` and remove them explicitly. For restart-without-teardown, pooling and repositioning is cheaper than rebuilding: reset positions, zero velocities, `clearTweens()`, and re-`play()` animations.
|
|
305
312
|
|
|
306
313
|
### GPU textures: `unload()`
|
|
307
314
|
|
|
@@ -328,7 +335,7 @@ Since 2026-08-23 the module retires the previous generation itself: stale render
|
|
|
328
335
|
|
|
329
336
|
## Debugging and tuning
|
|
330
337
|
|
|
331
|
-
- **`debug: true` on the GameView** draws collision shapes for the whole scene;
|
|
338
|
+
- **`debug: true` on the GameView** draws collision shapes for the whole scene; object form separates hitboxes from the performance HUD: `debug: { hitbox: true, hud: 'topRight' }`. On a sprite or TileLayer, `debug` remains a boolean. See [debugging-performance.md](debugging-performance.md) for colors, telemetry payloads, platform-only keys, and a tuning workflow.
|
|
332
339
|
- **Physics that feels wrong is usually a units problem.** Speeds are px/s and accelerations px/s², both in surface pixels — which is why the demos express them as fractions of `W` and `H`. A gravity of `20` is imperceptible; `H * 2.2` is a snappy platformer.
|
|
333
340
|
- **Sprite is invisible?** Check in order: was it added to the GameView, does it have a sheet, is `width`/`height` non-zero, is it inside the surface bounds, and is its `zIndex` below a background sprite.
|
|
334
341
|
- **Collision never fires?** `collisionGroup` goes on the *target*, `collidesWith` on the *mover*. Both need to be set, and `visible: false` disables collision entirely.
|
|
@@ -344,4 +351,6 @@ The JS API is identical on Android and iOS. What differs is around it:
|
|
|
344
351
|
- **`logicalDensityFactor` lies in the iOS Simulator** — it reports the device scale while the surface renders at 1x. Derive dp→scene units from the surface instead: `H / Ti.Platform.displayCaps.platformHeight`.
|
|
345
352
|
- **Android's `touchFeedback` ripple** cannot animate over the GL canvas and logs `RippleDrawable` errors; give on-screen buttons manual `backgroundColor` feedback on `touchstart`/`touchend`.
|
|
346
353
|
- **Sound formats**: WAV, MP3 and OGG on Android; WAV, MP3 and M4A on iOS. WAV for effects, MP3 for music covers both.
|
|
354
|
+
- **TileLayer grid configuration**: assign `legend`, `firstGid`, `cols`, and `rows` in `createTileLayer()`. iOS accepts later writes; Android treats them as creation-time inputs.
|
|
355
|
+
- **Performance telemetry**: `averagePresentMs` and `presentFailures` exist only on iOS and are omitted on Android.
|
|
347
356
|
- **`theme: 'Theme.Titanium.DayNight.NoTitleBar'`** on the window is the Android idiom for a fullscreen game surface; on iOS use `navBarHidden`/`statusBarHidden` (or the Alloy XML equivalents).
|