@maccesar/titools 5.1.1 → 5.2.1
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/CONTRIBUTING.md +69 -0
- package/README.md +112 -72
- package/agents/ti-pro.md +5 -1
- package/commands/ti-audit.md +5 -1
- package/docs/examples.md +91 -0
- package/docs/knowledge-index.md +57 -0
- package/lib/config.js +2 -0
- package/lib/downloader.js +1 -1
- package/package.json +4 -2
- package/skills/purgetss/references/multi-density-images.md +1 -1
- package/skills/ti-admob-unified/SKILL.md +58 -0
- package/skills/ti-admob-unified/agents/openai.yaml +4 -0
- package/skills/ti-admob-unified/assets/example/app.js +1207 -0
- package/skills/ti-admob-unified/assets/example/lib/ads.js +646 -0
- package/skills/ti-admob-unified/assets/example/library-usage.js +136 -0
- package/skills/ti-admob-unified/references/api-reference.md +615 -0
- package/skills/ti-admob-unified/references/banners.md +435 -0
- package/skills/ti-admob-unified/references/contributing.md +233 -0
- package/skills/ti-admob-unified/references/dependencies.md +91 -0
- package/skills/ti-admob-unified/references/fullscreen.md +238 -0
- package/skills/ti-admob-unified/references/game-monetization.md +148 -0
- package/skills/ti-admob-unified/references/getting-started.md +319 -0
- package/skills/ti-admob-unified/references/index.md +33 -0
- package/skills/ti-admob-unified/references/integration.md +87 -0
- package/skills/ti-admob-unified/references/library.md +220 -0
- package/skills/ti-admob-unified/references/mediation-parity.md +17 -0
- package/skills/ti-admob-unified/references/mediation.md +145 -0
- package/skills/ti-admob-unified/references/migration.md +259 -0
- package/skills/ti-admob-unified/references/module-changelog.md +84 -0
- package/skills/ti-admob-unified/references/module-license.txt +21 -0
- package/skills/ti-admob-unified/references/privacy.md +281 -0
- package/skills/ti-admob-unified/references/production.md +67 -0
- package/skills/ti-admob-unified/references/rewarded-interstitial.md +101 -0
- package/skills/ti-admob-unified/references/roadmap.md +143 -0
- package/skills/ti-admob-unified/references/source-notes.md +80 -0
- package/skills/ti-admob-unified/references/source-snapshot.json +644 -0
- package/skills/ti-admob-unified/references/third-party-notices.md +22 -0
- package/skills/ti-game/SKILL.md +31 -5
- package/skills/ti-game/references/api.md +36 -24
- package/skills/ti-game/references/debugging-performance.md +22 -7
- package/skills/ti-game/references/examples.md +113 -20
- package/skills/ti-game/references/input.md +101 -0
- package/skills/ti-game/references/patterns.md +56 -10
- package/skills/ti-game/references/physics.md +530 -0
- package/skills/ti-game/references/project-setup.md +131 -47
- package/skills/ti-game/references/recipes-action.md +149 -18
- package/skills/ti-game/references/recipes-adventure-effects.md +47 -4
- package/skills/ti-game/references/roadmap.md +11 -4
- package/skills/ti-game/references/source-notes.md +81 -0
- package/skills/ti-game/references/tilemaps.md +13 -4
- package/skills/ti-game-assets/SKILL.md +53 -0
- package/skills/ti-game-assets/agents/openai.yaml +4 -0
- package/skills/ti-game-assets/references/alpha.md +26 -0
- package/skills/ti-game-assets/references/art-direction.md +37 -0
- package/skills/ti-game-assets/references/integration.md +49 -0
- package/skills/ti-game-assets/references/manifest.example.json +429 -0
- package/skills/ti-game-assets/references/manifest.md +39 -0
- package/skills/ti-game-assets/references/offline-audio.md +33 -0
- package/skills/ti-game-assets/references/prompts.md +33 -0
- package/skills/ti-game-assets/references/repeating-textures.md +17 -0
- package/skills/ti-game-assets/references/responsible-ads.md +31 -0
- package/skills/ti-game-assets/references/sound-assets.md +42 -0
- package/skills/ti-game-assets/references/vector-sources.md +21 -0
- package/skills/ti-game-assets/scripts/alpha_tools.py +160 -0
- package/skills/ti-game-assets/scripts/requirements.txt +1 -0
- package/skills/ti-game-assets/scripts/validate_manifest.py +267 -0
- package/skills/ti-synthengine/SKILL.md +77 -67
- package/skills/ti-synthengine/assets/example/README.md +84 -0
- package/skills/ti-synthengine/assets/example/app.js +1178 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +83 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceScore.js +25 -0
- package/skills/ti-synthengine/references/advanced-examples.md +174 -0
- package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
- package/skills/ti-synthengine/references/android-sim80-correction.json +162 -0
- package/skills/ti-synthengine/references/api.md +573 -153
- package/skills/ti-synthengine/references/audio-engine.md +272 -124
- package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
- package/skills/ti-synthengine/references/examples.md +355 -106
- package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-physical-validation.json +1918 -0
- package/skills/ti-synthengine/references/guide.md +426 -75
- package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
- package/skills/ti-synthengine/references/performance-review.json +1146 -0
- package/skills/ti-synthengine/references/physical-validation.json +1457 -0
- package/skills/ti-synthengine/references/recipes-interaction.md +549 -0
- package/skills/ti-synthengine/references/recipes.md +434 -420
- package/skills/ti-synthengine/references/recommendations.md +72 -85
- package/skills/ti-synthengine/references/sound-design.md +375 -155
- package/skills/ti-synthengine/references/source-notes.md +109 -0
- package/skills/ti-synthengine/references/source-snapshot.json +452 -0
- package/skills/ti-synthengine/references/stats-performance.json +2992 -0
- package/skills/ti-synthengine/references/stats-performance.md +82 -0
- package/skills/ti-synthengine/references/studio-validation.json +6202 -0
- package/skills/ti-synthengine/references/troubleshooting.md +123 -78
- package/skills/ti-synthengine/references/unified-bypass-performance.json +22425 -0
- package/skills/ti-synthengine/references/unified-validation.json +314 -0
- package/AGENTS-VERCEL-RESEARCH.md +0 -175
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Keyboard, mouse and action maps
|
|
2
|
+
|
|
3
|
+
Reviewed 2026-10-23 against `m1ga/ti.game@88e181cb85526d8146d0be6e09b2b90c2551baad` native input resolvers and canvas adapters, with README clarification from `macCesar/ti.game@2bf5f828a3bb8028eed20d6ba27b97dd3aa9a753`. Requires an artifact containing those APIs; a shared version number is insufficient evidence. Existing controller events and analog input remain documented in [api.md](api.md#gamepads).
|
|
4
|
+
|
|
5
|
+
## Map and event contract
|
|
6
|
+
|
|
7
|
+
`GameView.inputMap` is optional, live, readable/writable and defaults to `{}`. It maps contexts to named actions, each with an array of digital bindings. `inputContext` accepts only a string or `null` (other types throw) and defaults to `'gameplay'`; `null` disables actions. Replace the whole map to rebind; the module supplies no settings UI or persistence.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const gameView = Game.createGameView({
|
|
11
|
+
inputMap: {
|
|
12
|
+
gameplay: {
|
|
13
|
+
thrust: [
|
|
14
|
+
{ device: 'keyboard', code: 'KeyW' },
|
|
15
|
+
{ device: 'keyboard', code: 'ArrowUp' }
|
|
16
|
+
],
|
|
17
|
+
fire: [
|
|
18
|
+
{ device: 'keyboard', code: 'Space' },
|
|
19
|
+
{ device: 'mouse', button: 'left' },
|
|
20
|
+
{ device: 'gamepad', button: 'a' }
|
|
21
|
+
],
|
|
22
|
+
pause: [{ device: 'keyboard', code: 'Escape' }]
|
|
23
|
+
},
|
|
24
|
+
paused: { pause: [{ device: 'keyboard', code: 'Escape' }] }
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
gameView.addEventListener('actiondown', ({ action, context }) => {
|
|
28
|
+
// Dispatch discrete actions or write native motion properties here.
|
|
29
|
+
// A pause handler can change inputContext to 'paused' and timeScale to 0.
|
|
30
|
+
});
|
|
31
|
+
gameView.addEventListener('actionup', ({ action, context }) => {
|
|
32
|
+
// Clear held controls, including releases caused by lost focus/cancellation.
|
|
33
|
+
});
|
|
34
|
+
// Add the view, open the window, then call this (also after native text entry):
|
|
35
|
+
gameView.focusInput();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The snippet is a map/transition template; scene setup and window lifecycle are in [project-setup.md](project-setup.md). No per-frame JavaScript polling is needed: action resolution runs natively on input transitions.
|
|
39
|
+
|
|
40
|
+
| Input | Contract |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `actiondown` / `actionup` | Payload `{ action, context }`. An action goes down on its first active binding and up after its last source releases, across different bindings and controllers |
|
|
43
|
+
| Map replacement | A valid map releases previous active actions and requires a fresh press; held keys cannot activate the replacement map until released and pressed again |
|
|
44
|
+
| Context change | Releases active actions from the old context, requires a fresh press; assigning the same context leaves state unchanged |
|
|
45
|
+
| Invalid map | Throws without replacing the map or active state |
|
|
46
|
+
| Cancellation | Focus loss, suspension, device disconnection and view shutdown release held actions. An action release need not have a physical/raw `keyup`; drive gameplay from action transitions |
|
|
47
|
+
| Auto-repeat | Ignored as a new press; holding a key does not repeat `actiondown` |
|
|
48
|
+
|
|
49
|
+
Context and action names must be nonempty strings. Empty contexts and empty action arrays are allowed. Each binding has **exactly two keys**: `device` plus `code` for keyboard, or `device` plus `button` for mouse/gamepad. Analog axes are not action bindings.
|
|
50
|
+
|
|
51
|
+
| Device | Accepted binding values |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `keyboard` (`code`) | `KeyA`…`KeyZ`, `Digit0`…`Digit9`, `ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Space`, `Escape`, `Enter`, `Tab`, `Backspace`, `Delete`, `Home`, `End`, `PageUp`, `PageDown`, `F1`…`F12`, `ShiftLeft`/`ShiftRight`, `ControlLeft`/`ControlRight`, `AltLeft`/`AltRight`, `MetaLeft`/`MetaRight` |
|
|
54
|
+
| `mouse` (`button`) | `left`, `middle`, `right` |
|
|
55
|
+
| `gamepad` (`button`) | `a`, `b`, `x`, `y`, `l1`, `r1`, `l2`, `r2`, `l3`, `r3`, `start`, `select`, `home`, `up`, `down`, `left`, `right` |
|
|
56
|
+
|
|
57
|
+
Existing gamepad properties, individual button events, sticks and triggers are unchanged. Use mapped actions **or** individual button handlers for each gameplay action to avoid dispatching twice. An app keeping its own gamepad adapter can omit gamepad bindings from the map.
|
|
58
|
+
|
|
59
|
+
## Keyboard focus and pointer ownership
|
|
60
|
+
|
|
61
|
+
Raw `keydown` / `keyup` events carry `{ code, character, modifiers: { shift, control, alt, meta } }`. `code` identifies the physical key independently of its text character; `character` can be empty for non-text keys.
|
|
62
|
+
|
|
63
|
+
Only the focused GameView receives keyboard events. `focusInput()` requests canvas focus on the UI thread; it neither opens a software keyboard nor captures keys globally. Native text fields retain their focus. Call it after opening the game window and after returning from a native text field.
|
|
64
|
+
|
|
65
|
+
When the active context has mouse bindings, pointer gestures delivered to the canvas feed mapped actions and are consumed rather than also becoming sprite tap/drag interactions. Empty maps, keyboard-only contexts and disabled actions preserve existing sprite pointer interaction. Overlay Titanium controls retain their clicks and focus; the module does not capture their mouse events. Android retains the engine touch listener.
|
|
66
|
+
|
|
67
|
+
For iOS/iPadOS 13.4–16 pointer identification, set the consuming application's `tiapp.xml` opt-in (iOS 17+ defaults it to true):
|
|
68
|
+
|
|
69
|
+
```xml
|
|
70
|
+
<ios>
|
|
71
|
+
<plist>
|
|
72
|
+
<dict>
|
|
73
|
+
<key>UIApplicationSupportsIndirectInputEvents</key>
|
|
74
|
+
<true/>
|
|
75
|
+
</dict>
|
|
76
|
+
</plist>
|
|
77
|
+
</ios>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This application-level setting distinguishes indirect pointers from direct touch; the module does not change global input settings at runtime. The current Apple package targets iOS/iPadOS **15+** and Mac Catalyst with Metal. Its keyboard/pointer guards dating from iOS 13.4 and disconnection notification guards dating from iOS 14 do not lower that package minimum.
|
|
81
|
+
|
|
82
|
+
## Runnable example and acceptance limits
|
|
83
|
+
|
|
84
|
+
`example/inputmap.js` is the current action-map demo. The launcher exposes it on Mac only; mobile builds retain touch-ready demos. The source remains usable for external-peripheral testing on mobile.
|
|
85
|
+
|
|
86
|
+
- A/D, J/L, arrows or gamepad move the character. The last pressed direction wins; releasing it resumes the other held direction.
|
|
87
|
+
- Space or gamepad A jumps. W/I/Up aims upward, including diagonal combinations; S/K/Down crouches.
|
|
88
|
+
- Left canvas click or gamepad X fires. Right/middle mouse bindings are accepted for testing but currently do not trigger actions on Mac; left click is verified by the source's acceptance notes.
|
|
89
|
+
- Escape switches pause/resume action contexts. A separate monitor shows raw key codes/modifiers and existing gamepad buttons, sticks and triggers.
|
|
90
|
+
- Instructions and action feedback occupy separate areas. An overlaid text field and focus button demonstrate native ownership; clicking the canvas after text entry restores game focus, and the first click does not fire. The shared back control returns to the launcher.
|
|
91
|
+
|
|
92
|
+
Upstream verification commands, run from the module checkout:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
python3 tests/input-map/run.py
|
|
96
|
+
python3 tests/input-map/uikit.py
|
|
97
|
+
python3 tests/gamepad-fixture/check.py
|
|
98
|
+
node --test tests/example-input/controls.test.js
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Resolver regressions test native binding validation, aggregation and transitions. UIKit fixtures exercise production responder methods with renderer/event sinks for focus, raw-key repetition/cancellation and pointer/overlay ownership. GameController fixtures cover receiver fanout, disconnect and action delivery without individual listeners. JavaScript example tests check demo control behavior. Compilation and these fixtures do not establish physical keyboard, mouse, controller or overlay behavior on every supported device; record that acceptance separately.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Cross-cutting ti.game patterns
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reviewed against upstream native `88e181c` and the documentation/examples in
|
|
4
|
+
`macCesar/ti.game@2bf5f82` on 2026-10-23. These are production-oriented extractions of the API combinations demonstrated upstream; they intentionally omit demo-launcher and back-navigation plumbing.
|
|
4
5
|
|
|
5
6
|
See [examples.md](examples.md) to choose the source demo, [api.md](api.md) for exact members, and the genre recipe files for complete game loops.
|
|
6
7
|
|
|
@@ -76,7 +77,14 @@ module.exports = function () {
|
|
|
76
77
|
};
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
Use the actual canvas for sizing. Current demos cap foreground art and text by
|
|
81
|
+
height as well as width so short desktop windows do not clip their controls.
|
|
82
|
+
For example, text can use `Math.max(1, Math.round(Math.min(W / 240, H / 360)))`.
|
|
83
|
+
Measure surface pixels per view point from `W / gameView.rect.width` when
|
|
84
|
+
converting native control margins; use a positive finite density fallback.
|
|
85
|
+
Keep a guarded first `resize` for world creation and relayout the HUD on later
|
|
86
|
+
resizes when the app supports changing windows. See
|
|
87
|
+
[project-setup.md](project-setup.md) for complete integration.
|
|
80
88
|
|
|
81
89
|
## Cross-cutting patterns
|
|
82
90
|
|
|
@@ -146,7 +154,7 @@ Recycling a sprite with `visible = false` fires `collisionend` on anything it wa
|
|
|
146
154
|
|
|
147
155
|
### Freeing a level's textures
|
|
148
156
|
|
|
149
|
-
Pooling recycles sprites; it does not free the **texture** behind them. A game that streams worlds accumulates every atlas it has ever loaded until
|
|
157
|
+
Pooling recycles sprites; it does not free the **texture** behind them. A game that streams worlds accumulates every atlas it has ever loaded until scene resources are released. `unload()` releases one on the next rendered frame.
|
|
150
158
|
|
|
151
159
|
```javascript
|
|
152
160
|
function unloadLevel(level) {
|
|
@@ -206,7 +214,17 @@ Slower layers read as further away. Three layers (clouds at 0.15×, hills at 0.4
|
|
|
206
214
|
|
|
207
215
|
### Multitouch on-screen controls
|
|
208
216
|
|
|
209
|
-
|
|
217
|
+
Use separate sibling input targets for held directions and actions. Their
|
|
218
|
+
native control type also matters for simultaneous touch; the factory below
|
|
219
|
+
uses Label rather than UIButton-backed controls.
|
|
220
|
+
|
|
221
|
+
The factory below deliberately uses Label. In Titanium SDK13.4.1.GA on iOS,
|
|
222
|
+
TiUIButton sets its internal UIButton's `exclusiveTouch=YES`; changing the
|
|
223
|
+
outer view's multitouch flag does not remove that exclusivity. Keep held
|
|
224
|
+
flight controls as sibling Label/View targets or native game sprites and
|
|
225
|
+
verify simultaneous input on-device. See `iphone/Classes/TiUIButton.m`,
|
|
226
|
+
method `button`, in that SDK; this is a Titanium UI boundary, not a ti.game
|
|
227
|
+
physics discrepancy.
|
|
210
228
|
|
|
211
229
|
```javascript
|
|
212
230
|
function makeButton(title, position, fontSize) {
|
|
@@ -252,7 +270,14 @@ bindHold(leftButton, () => {
|
|
|
252
270
|
});
|
|
253
271
|
```
|
|
254
272
|
|
|
255
|
-
The guard
|
|
273
|
+
The guard avoids releasing one control cancelling a newer opposite command.
|
|
274
|
+
It does not restore a still-held older direction. For mixed touch, keyboard and
|
|
275
|
+
controller input, track each source's held state and derive direction from the
|
|
276
|
+
active set, as current `platformer.js`/`volley.js` do. They cancel opposing
|
|
277
|
+
directions and resume the remaining one on release. `inputmap.js` deliberately
|
|
278
|
+
uses a different last-pressed-wins rule. Choose the policy explicitly; do not
|
|
279
|
+
confuse either with the native action aggregator, which combines bindings for
|
|
280
|
+
one named action. See [input.md](input.md) for native input maps and focus rules.
|
|
256
281
|
|
|
257
282
|
### HUD — `text.js`, `flappy.js`
|
|
258
283
|
|
|
@@ -306,7 +331,11 @@ dialog.addEventListener('tap', () => {
|
|
|
306
331
|
|
|
307
332
|
`maxWidth` is measured before `scale`, which is the only trap here — pass screen pixels straight in and the block comes out `scale` times too wide. `align` positions the lines against each other (the block's own width), not inside the wrap column, so anchor the sprite where the text should sit. A word longer than `maxWidth` overflows instead of breaking mid-word.
|
|
308
333
|
|
|
309
|
-
|
|
334
|
+
The built-in font now includes the accented characters listed in
|
|
335
|
+
[api.md](api.md#font); do not assume all accents need an overlay. Ship a custom
|
|
336
|
+
bitmap font for other supported glyph sets. Overlaid `Ti.UI.Label` views remain
|
|
337
|
+
appropriate for system fonts, right-to-left interfaces and native UI such as
|
|
338
|
+
menus, dialogs and text inputs.
|
|
310
339
|
|
|
311
340
|
### Labels, bars and turrets pinned to a sprite — `attachTo`, `text.js`
|
|
312
341
|
|
|
@@ -485,7 +514,15 @@ const ball = Game.createSprite({
|
|
|
485
514
|
|
|
486
515
|
Two things bite here. The sweep **ignores** anything that is not `solidMode: 'block'`, so `swept: true` will not stop a fast enough ball crossing the boundary between frames — keep the speeds inside a container sane. And a `'contain'` solid only holds *circles*: a rect mover runs a resolver that never reads `solidMode` and gets pushed **out** of the boundary instead of held in.
|
|
487
516
|
|
|
488
|
-
**`linearDamping`
|
|
517
|
+
**`linearDamping` attenuates velocity everywhere.** Car `drag` works inside
|
|
518
|
+
`carMode`; linear damping also works for ordinary sprites and can bring a pool
|
|
519
|
+
table to rest. The attenuation is not contact-only friction: it bleeds speed
|
|
520
|
+
on both axes, in the air as much as on felt, and along a slope as much as
|
|
521
|
+
across it. Below a combined 4 px/s the engine settles coasting or blocked motion, but
|
|
522
|
+
allows effective acceleration to build from rest; the decision is completed
|
|
523
|
+
after contact response. A deliberate unpowered 3 px/s drift with damping still
|
|
524
|
+
stops. See [thrust and damping](physics.md#thrust-inertia-and-linear-damping)
|
|
525
|
+
for the current rest policy and the older powered-launch bug.
|
|
489
526
|
|
|
490
527
|
**A bouncy surface is now a property of the surface.** `restitution` is read off both sides and mixed as `max`, so a springy floor rebounds riders that are not themselves bouncy:
|
|
491
528
|
|
|
@@ -557,7 +594,7 @@ ship.followPath(diamond, {
|
|
|
557
594
|
|
|
558
595
|
A non-looping run fires `pathcomplete` and clears itself; `followPath(null)` stops in place. Two points is the minimum — one point is ignored with a warning, not treated as "go there".
|
|
559
596
|
|
|
560
|
-
The path writes `x`/`y` outright, after velocity and gravity have been integrated, so **a sprite on a path ignores its own physics for placement**. It still feeds the frame delta, though, which means a platform on a looping circuit carries whatever is standing on it — a moving platform is now a path, not a tween ping-pong.
|
|
597
|
+
The path writes `x`/`y` outright, after velocity and gravity have been integrated, so **a sprite on a path ignores its own physics for placement**. In a periodic world the engine aligns the cursor before advancing so crossing the seam retains the intended frame delta; this does not make pathfinding periodic. It still feeds the frame delta, though, which means a platform on a looping circuit carries whatever is standing on it — a moving platform is now a path, not a tween ping-pong.
|
|
561
598
|
|
|
562
599
|
Animation chains are native in the same spirit:
|
|
563
600
|
|
|
@@ -597,7 +634,7 @@ Run these from a coarse timer or a tap handler — the demo probes at 150 ms —
|
|
|
597
634
|
|
|
598
635
|
### Pathfinding around obstacles — `maze.js`, `pointclick.js`
|
|
599
636
|
|
|
600
|
-
`gameView.findPath(from, to, options)` is grid A\* over the same sprites `raycast` sees: visible, tagged with a `collisionGroup
|
|
637
|
+
`gameView.findPath(from, to, options)` is grid A\* over the same sprites `raycast` sees: visible, non-`screenFixed`, tagged with a `collisionGroup`. It also includes fully solid cells from matching TileLayers; one-way cells remain walkable. It returns `{ x, y }` waypoints — or `null` — and those waypoints go straight into `followPath`, so the walk itself runs natively.
|
|
601
638
|
|
|
602
639
|
```javascript
|
|
603
640
|
gameView.addEventListener('tap', (e) => {
|
|
@@ -673,7 +710,16 @@ What still belongs in `setTimeout`: anything that must keep running while the ga
|
|
|
673
710
|
|
|
674
711
|
### Hit-stop on impact
|
|
675
712
|
|
|
676
|
-
|
|
713
|
+
Giving the scene zero dt for a few frames makes an impact read before the
|
|
714
|
+
explosion starts, while it keeps drawing and accepting touches. This avoids
|
|
715
|
+
restarting the render loop. (Pattern from Titanium Lander: 140 ms on a crash,
|
|
716
|
+
90 ms when a shield absorbs a hit.)
|
|
717
|
+
|
|
718
|
+
This sets scene dt to zero while touch and explicit property writes remain
|
|
719
|
+
active. Current Rope integration, history, constraints and tether response
|
|
720
|
+
freeze as well; newly created geometry can still initialize. The older
|
|
721
|
+
`3bea2f4` rope exception is fixed. See
|
|
722
|
+
[physics.md](physics.md#verlet-ropes-and-tethers).
|
|
677
723
|
|
|
678
724
|
```javascript
|
|
679
725
|
let hitStopTimer = null;
|