Lesson 242: itch WASM Heap Cap Playtest Receipt on BUILD_RECEIPT (2026)
Direct answer: Before June itch HTML5 playtest scale, file wasm_heap_cap_receipt_v1.json proving a pinned max_used_heap_mb, 20-minute performance.memory snapshot on the real Play URL, tab refocus survival, and build_label + surface on Lesson 201—then promote BUILD_RECEIPT wasm_heap_cap_playtest. Distinct from long-session memory preflight (leak hygiene) and Construct analytics (GA4 funnel).

Why this matters now (June 2027 itch tab kills at minute 20)
June 2027 playtest cohorts leave itch tabs open through full roguelite runs. Reviews say “fine for 15 minutes, dead at 20” while five-minute Editor smoke stays green. Lesson 241 tracks funnel events; this lesson files wasm_heap_cap_receipt_v1 so memory policy is on BUILD_RECEIPT before July scale.
The Phaser WASM heap cap preflight is the ninety-second gate—242 is the course milestone. Pair tab-refocus playbook when alt-tab white-screens.
Beginner path (20-minute itch soak)
| Step | Action | Success check |
|---|---|---|
| 1 | Confirm long-session / leak hooks GREEN | H1 cousin pass |
| 2 | Commit playtest_heap_policy.json |
H2 cap documented |
| 3 | Open itch Play URL (not localhost) | Real embed |
| 4 | Log heap every 60s for 20 min | H3 soak complete |
| 5 | Alt-tab 30s mid-run, return | H5 refocus OK |
| 6 | File receipt + BUILD_RECEIPT | playtest_heap_ok: true |
Time: ~60 minutes first cap tune; ~15 minutes when policy JSON exists.
Developer path (gates H1–H6)
| Gate | Check | Fail when |
|---|---|---|
| H1 | Long-session memory cousin pass | Texture/audio shutdown missing |
| H2 | playtest_heap_policy.json on branch |
Hand-wavy “384 MB” in Discord |
| H3 | 20-minute wall-clock on itch Play | Editor-only proof |
| H4 | usedJSHeapSize at minute 20 ≤ cap |
Stair-step after minute 10 |
| H5 | Tab refocus mid-run | White canvas after return |
| H6 | Receipt + BUILD_RECEIPT | Promote before H4 GREEN |
H2 — playtest_heap_policy.json
{
"schema": "playtest_heap_policy_v1",
"build_label": "summer-playtest-2027-rc1",
"surface": "playtest_invite",
"max_used_heap_mb": 384,
"max_active_chunks": 9,
"tab_refocus_required": true,
"soak_minutes": 20
}
Align build_label with Lesson 201 VERSION spine.
H4 — Snapshot table (attach to receipt)
| Minute | used heap (MB) | Notes |
|---|---|---|
| 0 | Cold start | |
| 10 | Mid-run | |
| 20 | End soak | |
| 20 + refocus | After alt-tab |
Pass: minute-20 used ≤ max_used_heap_mb and Δ(20 − 10) < 15% of cap.
wasm_heap_cap_receipt_v1.json
{
"schema": "wasm_heap_cap_receipt_v1",
"build_label": "summer-playtest-2027-rc1",
"surface": "playtest_invite",
"play_url": "https://studio.itch.io/playtest-demo",
"heap_policy_path": "release-evidence/phaser/PLAYTEST_HEAP_POLICY.json",
"snapshot_path": "release-evidence/phaser/HEAP_SNAPSHOT_20MIN.txt",
"soak_minutes": 20,
"used_heap_mb_minute_20": 312,
"max_used_heap_mb": 384,
"tab_refocus_ok": true,
"paired_receipts": {
"long_session_memory": "release-evidence/phaser/LONG_SESSION_MEMORY_PREFLIGHT.json",
"channel_label": "release-evidence/html5/TRIPLE_CHANNEL_LABEL_RECEIPT.json"
},
"gates": {
"H1_long_session_cousin": "pass",
"H2_heap_policy": "pass",
"H3_twenty_minute_soak": "pass",
"H4_snapshot_delta": "pass",
"H5_tab_refocus": "pass",
"H6_build_receipt": "pass"
},
"playtest_heap_ok": true,
"promotion_allowed": true
}
Pin under release-evidence/phaser/WASM_HEAP_CAP_RECEIPT.json (engine-agnostic path on BUILD_RECEIPT even for non-Phaser HTML5).
BUILD_RECEIPT row (H6)
| Column | Pass when |
|---|---|
wasm_heap_cap_playtest |
playtest_heap_ok: true |
channel_label_match |
Lesson 201 GREEN |
construct_playtest_analytics |
Lesson 241 independent |
Relationship to guide vs long-session preflight
| Artifact | Role |
|---|---|
| Long-session memory preflight | ScaleManager + shutdown hooks |
| WASM heap cap preflight | H1–H6 checklist |
| Tilemap streaming | Chunk discipline cousin |
| This lesson | BUILD_RECEIPT wasm_heap_cap_playtest |
Construct-only teams still file this row when shipping itch WASM—receipt schema is surface-keyed, not engine-keyed.
Key takeaways
- Leak hygiene ≠ heap cap receipt—run long-session preflight then 242.
- Soak on itch Play, not localhost.
- Tab refocus is mandatory—players alt-tab to Discord.
- Lesson 239 tag
performance→ this row. - Q3 capstone 244 wires 236–243 including heap cap.
- 12-free itch MIME tools — shell loads before soak.
- Do not merge into
construct_playtest_analytics_receipt—separate columns.
Common mistakes
- Raising cap instead of fixing monotonic heap growth.
- Single heap sample at minute 5.
- Skipping H5 refocus.
- Wrong
build_labelon snapshot vs itch upload. - Testing Steam wrapper only—itch iframe differs.
Troubleshooting
| Symptom | Lane |
|---|---|
| Tab kill ~18 min | H4 cap + tilemap chunks |
| Refocus white screen | H5 + tab-refocus playbook |
| Heap climbs each floor | Tilemap streaming guide |
| Works local, fails itch | ScaleManager parent (long-session) |
| Analytics without memory row | Lesson 241 separate |
Mini exercise (60 minutes)
- Reproduce OOM before cap on loaner laptop.
- Pin
playtest_heap_policy.json. - Run 20-minute soak + refocus.
- File receipt; BUILD_RECEIPT GREEN.
- Link Lesson 201 row.
Continuity — Q3 2027 summer playtest wave (236–244)
| Lesson | Receipt focus |
|---|---|
| 236–241 | Art → analytics |
| 242 (this) | itch WASM heap cap |
| 243–244 | Clip consent → capstone |
Previous: Lesson 241 — Construct playtest analytics.
Next: Lesson 243 — OBS playtest clip consent.
FAQ
Same as Phaser heap cap guide?
Guide = checklist; 242 = BUILD_RECEIPT column.
Same as long-session preflight?
Long-session = leaks; 242 = cap + 20-minute proof.
Construct HTML5 only?
Receipt is itch WASM playtest keyed—Phaser is the reference implementation.
Need 241 first?
Independent columns; both required for Q3 capstone 244.
itch playtest tabs that die at minute 20 need a filed heap cap and snapshot—not another five-minute smoke—before July cohort scale on BUILD_RECEIPT.