Tutorials & Beginner-First May 25, 2026

Your First Construct 3 itch.io Subdomain WASM Smoke Before Custom Domain - 2026

2026 Construct 3 beginner tutorial—itch.io subdomain wasm smoke test, curl MIME proof, DevTools CORS check, and cors_smoke_receipt_v1.json before custom domain hosting.

By GamineAI Team

Your First Construct 3 itch.io Subdomain WASM Smoke Before Custom Domain - 2026

Pixel-art hero for Construct 3 itch.io subdomain wasm smoke before custom domain beginner pipeline 2026

You enabled a custom domain on itch before the game loaded on yourstudio.itch.io/demo. Preview in Construct was fine. Press kit went out with play.brand.com. Facilitators sent blank canvas screenshots and CORS console lines—you spent the evening re-zipping exports that were never wrong.

July 2026 HTML5-first teams need one green URL on itch’s subdomain before DNS vanity. This Tutorials & Beginner-First evening pipeline proves wasm MIME, zero CORS errors, and a 60-second golden path on *.itch.io—then files cors_smoke_receipt_v1.json so custom domain work follows hosting strategy, not panic uploads.

Non-repetition note: The trend playbook owns subdomain vs custom policy. itch CDN MIME help owns post-upload octet-stream. This URL owns hands-on subdomain smoke steps for Construct. Planned help Construct CORS custom domain fix complements traceback fixes.

Why this matters now (July 2026)

  1. Custom domain rush — Marketing wants branded URLs before engineering proves wasm on subdomain.
  2. Triple-channel receiptsBUILD_RECEIPT needs facilitator_url_canonical on a host that actually runs Construct wasm.
  3. CORS vs MIME — Teams fix MIME locally; production fails on origin split when skipping subdomain.
  4. Construct fest velocityRoguelite seed ledger and NW.js freeze assume HTML5 itch lane is GREEN first.
  5. Facilitator Discord — Playtest links must be subdomain until cors_smoke_receipt passes.

Direct answer: Upload HTML5 zip to itch subdomain only tonightcurl -I wasm → DevTools CORS check → 60s play → cors_smoke_receipt_v1.jsonthen discuss custom domain with decision tree.

Who this is for

Audience Outcome
Beginner first itch HTML5 ship One known-good URL
Producer Pin facilitator link in Discord
Technical artist MIME + CORS proof table
Solo dev Stop re-uploading identical zips

Time: ~2–3 hours first pass; 20 minutes per weekly demo refresh.
Prerequisites: Construct 3 project, itch.io account, browser with DevTools, curl (or PowerShell Invoke-WebRequest).

Before you start

  • [ ] Read trend playbook split pattern—custom domain not required tonight
  • [ ] Disable itch custom domain temporarily if already on
  • [ ] Folder release-evidence/html5/cors-smoke/
  • [ ] build_label string for title screen (e.g. html5-smoke-2026-05-25-rc1)
  • [ ] Pair with Wednesday smoke after receipt GREEN

Evening overview (five blocks)

Block Minutes Output
1 — HTML5 export 30 demo-html5.zip
2 — Subdomain upload 25 Live studio.itch.io/... URL
3 — MIME curl proof 20 wasm_mime_proof.md
4 — DevTools CORS + play 40 Screenshots + golden path
5 — Receipt 15 cors_smoke_receipt_v1.json

Block 1 — Construct HTML5 export (Gate S1)

Setting Recommendation
Export Web (HTML5)
Minify On
Worker scripts Note filenames for receipt
Version bump Match build_label in project
Compression Default; do not hand-edit wasm after export
Scirra arcade Off for fest demos unless you intend Arcade lane

Export zip; unzip locally once—confirm layout:

demo-html5/
  index.html
  data.json (or data.bin)
  data.wasm          # name may vary—log exact name
  scripts/           # worker + engine JS
  media/             # if referenced relatively

Common S1 failures:

Mistake Symptom on itch
Exported NW.js instead of HTML5 Wrong runtime entirely
Missing index.html at zip root 404 shell
Nested folder export/export/ itch upload shows empty
Forgot version text object Cannot match facilitator bug reports

Add a Text object BuildLabel on loader layout showing html5-smoke-2026-05-25-rc1—facilitators screenshot proof.

S1 pass: Zip lists wasm + worker; build_label visible in preview.

Outbound: Construct HTML5 export.

Block 2 — Upload to itch subdomain only (Gate S2)

  1. Create itch project → Kind: HTML
  2. Upload zip → wait upload complete
  3. Set visibility restricted for smoke if needed
  4. Copy URL: https://YOURNAME.itch.io/GAME_SLUGnot custom domain
  5. Do not enable custom domain until Block 5 receipt GREEN

S2 pass: Game page loads itch subdomain; no play.brand.com in address bar.

Block 3 — WASM MIME proof (Gate S3)

Open DevTools → Network → reload → click .wasm → copy Request URL.

curl -I "PASTE_WASM_URL_HERE"
Header Pass
Content-Type application/wasm (not application/octet-stream)
HTTP status 200

Log in wasm_mime_proof.md:

# wasm MIME — build html5-smoke-2026-05-25-rc1
- URL: https://...
- Content-Type: application/wasm
- pass: true

If octet-stream, follow itch CDN MIME help before continuing—MIME failure mimics “broken Construct.”

S3 pass: application/wasm on live CDN URL, not local server.

Block 4 — CORS + golden path (Gates S4–S5)

S4 — Console CORS (step-by-step)

  1. Open incognito window (reduces extension noise).
  2. Paste only https://yourname.itch.io/your-demo — confirm hostname.
  3. F12 → Console → clear log → hard refresh (Ctrl+Shift+R).
  4. Filter log level Errors only first pass.
  5. Expand any red line—note whether filename ends in .wasm or workermain.js.
  6. Open Network → sort by Status — failed wasm rows are 200 with wrong type OR blocked.
Result Action
Zero CORS errors S4 pass
CORS on wasm/worker Stop—do not enable custom domain; read trend playbook
MIME error Return to S3
404 on worker Re-export zip; check nested folder

Screenshot console with URL bar visible. Save HAR export if engineering needs async review.

Why incognito: Ad blockers and dev extensions sometimes mask real CORS/MIME errors—or inject false positives. Facilitators should use clean profiles too; document that in README snippet.

S5 — 60-second golden path

Step Pass
Loader reaches menu Yes
Start / first input Yes
One gameplay action Yes
No freeze 60s Yes

Archive short screen recording optional; screenshot of gameplay sufficient for receipt.

Block 5 — cors_smoke_receipt_v1.json (Gate S6)

{
  "schema": "cors_smoke_receipt_v1",
  "build_id": "html5-smoke-2026-05-25-rc1",
  "engine": "construct-3",
  "host_lane": "itch_subdomain",
  "page_url": "https://yourname.itch.io/your-demo",
  "wasm_url": "https://cdn.itch.io/.../data.wasm",
  "gates": {
    "S1_export": "pass",
    "S2_subdomain_upload": "pass",
    "S3_wasm_mime": "pass",
    "S4_no_cors_errors": "pass",
    "S5_golden_path_60s": "pass",
    "S6_receipt": "pass"
  },
  "wasm_content_type": "application/wasm",
  "custom_domain_tested": false,
  "facilitator_url_canonical": "https://yourname.itch.io/your-demo",
  "promotion_allowed": true
}

Commit under release-evidence/html5/cors-smoke/. Set Discord pin to facilitator_url_canonical.

S6 pass: JSON committed; producer confirms pin matches.

Gates S1–S6 summary

Gate Fail blocks
S1 Upload
S2 All remote tests
S3 Golden path (streaming)
S4 Custom domain experiment
S5 Fest facilitator link
S6 BUILD_RECEIPT html5_host row

PowerShell variant (Windows)

Invoke-WebRequest -Uri "WASM_URL" -Method Head | Select-Object -Expand Headers

Look for Content-Type key—same pass rules as curl.

Local preview trap

Test Proves
Construct preview Export not corrupt
python -m http.server Zip layout
itch subdomain What players get

Never file S6 pass from local server alone.

BUILD_RECEIPT row

{
  "build_id": "html5-smoke-2026-05-25-rc1",
  "channel": "itch_public",
  "html5_host": "itch_subdomain",
  "cors_smoke_receipt": "release-evidence/html5/cors-smoke/cors_smoke_receipt_v1.json",
  "wasm_mime_receipt": "release-evidence/html5/wasm_mime_proof.md"
}

Align build_label with triple-channel help if GX lane exists.

When custom domain is allowed next

Only after S6 GREEN:

  1. Read CORS vs subdomain playbook decision tree.
  2. Choose split pattern (marketing custom + play subdomain) unless header plan documented.
  3. Run separate custom-domain smoke—do not overwrite cors_smoke_receipt subdomain pass.
  4. File cors_hosting_decision_receipt_v1.json when custom experiment completes.

Troubleshooting

Symptom Fix lane
White screen, no console S3 MIME
CORS wasm blocked Stay subdomain; playbook
Works once, fails later CDN cache MIME help
Works desktop, fails mobile Re-run S5 on phone browser
Custom domain only broken Expected—finish this tutorial first

Facilitator README snippet

## Playtest link (Construct HTML5)
- Use: https://yourname.itch.io/your-demo (subdomain)
- Do not use custom domain until producer posts cors_smoke GREEN
- Bug reports: attach Console screenshot + build_label

Pair with NW.js later

7-day Construct NW.js freeze is Steam lane—HTML5 subdomain smoke still required for itch/GX parallel demos.

Weekly refresh (20 minutes)

  1. Bump build_label
  2. Re-export zip
  3. Re-upload itch
  4. Re-run curl on wasm URL
  5. Spot-check S4 console
  6. Update receipt build_id only—keep host_lane: itch_subdomain until hosting decision changes

FAQ

Can I skip subdomain if custom is already live?
Disable custom for smoke night, or you cannot prove S4/S5 on canonical itch host.

Is GX.games the same steps?
Similar wasm/MIME discipline—add separate receipt row per GX tools resource.

Does this fix Steam builds?
No—NW.js/Steam is different export. HTML5 receipt still required for browser fest lane.

One wasm file name only?
Log actual name in receipt wasm_url—Construct versions differ.

Key takeaways

  1. Subdomain proof first—custom domain is not step one.
  2. MIME then CORS—order matters for Construct wasm.
  3. cors_smoke_receipt_v1.json pins facilitator URL.
  4. 60s golden path catches hangs MIME curl misses.
  5. Pair with hosting playbook before branded URLs ship.

Evidence folder layout

release-evidence/html5/cors-smoke/
  cors_smoke_receipt_v1.json
  wasm_mime_proof.md
  devtools_console_subdomain.png
  golden_path_screenshot.png
  export_manifest.txt        # unzip -l output

Thursday row review should list cors_smoke path beside wasm_mime—prevents promoting GX-only proofs while itch lane RED.

Browser smoke matrix (minimum)

Browser S4 CORS S5 golden path
Chrome desktop Required Required
Firefox desktop Required Spot-check
Chrome Android Recommended Menu tap test
Safari iOS If iOS is fest target Loader + one input

One browser GREEN is not enough for October facilitators—log matrix in wasm_mime_proof.md footer.

itch.io upload UI checklist (producer-friendly)

  1. Dashboard → Create new project (or open existing).
  2. Kind of project: HTML (not downloadable if you need browser play—match your fest intent).
  3. Uploads → Upload new file → select zip (under itch size limits).
  4. Wait until This file has been processed (not only uploaded).
  5. Embed options: fullscreen recommended for demos.
  6. Visibility: Draft/Restricted while smoke; Public only after S6.
  7. Copy View game link from subdomain—verify hostname is *.itch.io.

Do not open Custom domain tab tonight.

MIME vs CORS decision table (beginners)

Console message Lane
Incorrect response MIME type S3 → MIME help
blocked by CORS policy S4 → stay subdomain; read playbook
WebAssembly.instantiate failed Often MIME; sometimes corrupt wasm
Failed to fetch network URL typo or adblock rare on itch

Teaching facilitators this table reduces duplicate GitHub issues.

Integration with playtest isolation

Playtest isolation playbook separates Steam surfaces—HTML5 itch is its own surface_id:

{
  "surface_id": "itch_html5_public",
  "facilitator_url_canonical": "https://yourname.itch.io/your-demo",
  "build_label": "html5-smoke-2026-05-25-rc1"
}

Do not paste Steam depot instructions into itch playtest threads.

Advanced: cors_origin_map stub (optional tonight)

If you already read the trend playbook, draft minimal map for later custom experiment:

{
  "schema": "cors_origin_map_v1",
  "lanes": [
    {
      "lane_id": "itch_subdomain",
      "page_origin": "https://yourname.itch.io",
      "same_origin": true,
      "status": "production"
    }
  ]
}

Custom lane stays out until subdomain S6 GREEN.

Producer calendar (fest week)

Day Action
Mon Blocks 1–3 (export, upload, MIME)
Tue Blocks 4–5 (CORS, receipt, Discord pin)
Wed Demo smoke on canonical URL
Thu Row review html5_host + cors_smoke
Fri Evaluate custom domain per playbook

Common Discord myths (correct gently)

Myth Truth
“Re-export fixes CORS” Hosting origin fix; zip may be identical
“itch is down” Often MIME or custom domain
“Works in editor” Irrelevant to S6
“Ad blockers only” Check MIME/CORS first on clean profile

Security note

Subdomain URLs are still public when visibility Public—smoke Restricted limits accidental traffic during MIME debug. Rotate build_label when promoting to fest so old bugs map to old builds.

Stretch goals (if time remains)

wasm_mime_receipt_v1.json (pair with cors smoke)

When MIME was ever in doubt, also file:

{
  "schema": "wasm_mime_receipt_v1",
  "build_id": "html5-smoke-2026-05-25-rc1",
  "wasm_url": "https://cdn.itch.io/.../data.wasm",
  "content_type_observed": "application/wasm",
  "post_upload_mime_ok": true,
  "curl_timestamp_utc": "2026-05-25T20:15:00Z"
}

cors_smoke_receipt can reference this path in paired_receipts[]—auditors see both gates.

Two evening scenarios (pick yours)

Scenario A — First HTML5 ship (never uploaded)

Follow blocks 1→5 in order. Expect 2.5 hours. Custom domain tab stays untouched. Success = Discord pin to subdomain URL only.

Scenario B — Custom domain already broke production

  1. Disable custom domain in itch settings (or stop sharing custom URL).
  2. Confirm subdomain loads—if still broken, MIME lane (Scenario A blocks 1–3).
  3. Only after S6, re-read playbook before re-enabling custom.
  4. Do not delete receipts—add new build_id for fixed pass.

Scenario B teams often discover subdomain was always fine—press kit caused 100% of facilitator pain.

Godot teams reading this (cross-engine)

Godot Web exports use different file names but same gate order: subdomain proof → MIME → CORS → receipt. See Godot wasm memory playbook for runtime limits after hosting is GREEN.

Validation script sketch (optional)

# check_cors_smoke_receipt.py — run from repo root
import json, sys
r = json.load(open("release-evidence/html5/cors-smoke/cors_smoke_receipt_v1.json"))
assert r["gates"]["S6_receipt"] == "pass"
assert r["custom_domain_tested"] is False
assert "itch.io" in r["facilitator_url_canonical"]
print("cors_smoke_receipt OK")

Fails CI if someone flips custom_domain_tested early.

What not to do tonight

  • Do not tune gameplay balance during smoke evening.
  • Do not enable Steam Cloud on HTML5 lane.
  • Do not compare to NW.js exe—different receipt family.
  • Do not post “fixed” in Discord without build_label screenshot.
  • Do not merge custom domain marketing PDF until producer signs S6.

Receipt reviewer checklist (producer)

  • [ ] facilitator_url_canonical hostname is *.itch.io
  • [ ] custom_domain_tested is false
  • [ ] All S1–S6 gates say pass
  • [ ] Screenshot files exist in evidence folder
  • [ ] wasm_content_type is application/wasm
  • [ ] Discord pin updated to match canonical URL

After S6 — custom domain experiment (separate evening)

Schedule second session for hosting playbook—new receipt cors_hosting_decision_receipt_v1.json, not a silent overwrite of tonight’s smoke pass. Marketing may publish brand landing same day only if split pattern links subdomain for Play button.

FAQ (extended)

itch says processing—can I test?
Wait for processed state; partial uploads fail S3 with confusing errors.

Multiple wasm files?
curl each; all must be application/wasm.

Embed on external site?
Out of scope—another origin; finish itch subdomain first.

Construct beta channel?
Log exact editor version in receipt notes field.

Whisper / OBS playtest same night?
Finish cors smoke first—facilitators need a stable HTML5 URL before VOD batch (OBS concat tutorial).

Related reading