Beginner-Friendly Tutorials Jul 28, 2026

How to Try Defold Morph Targets - First Indie Blend Shape Spike 2026

How to try Defold morph targets in 2026 - glTF blend shapes, play_anim vs set_blend_weights, morph shaders, HTML5 honesty, and a keep/hold receipt for indie teams.

By GamineAI Team

How to Try Defold Morph Targets - First Indie Blend Shape Spike 2026

popular pixel art thumbnail for Defold morph targets first indie blend shape spike

If you are searching defold morph targets, you do not need another “Defold now does 3D” pitch. You need a Monday path: pin Defold ≥ 1.13.0, import one glTF with blend shapes, prove model.play_anim can drive morph weights or drive them from Lua with model.set_blend_weights, confirm the material actually samples morph data, then decide keep / hold / rewrite before anyone promises facial dialogue on a Steam week.

On June 22, 2026, the Defold Foundation shipped 1.13.0 with native morph target (blend shape) support for model components (release post, forum notes). The model animation manual documents import, play_anim, get_blend_weights / set_blend_weights, and the shader path (morph_targets sampler + morph_targets_weights). The engine work landed through PR #12192; stable tag v1.13.0 followed on GitHub.

This evening is not Defold 1.13.1 lights (editor Light components / LightBuffer — still a beta story). It is not the Defold Steam collection and save audit (packaging). It is not Roblox Animation Graphs (different platform). It is defold morph targets on a spike branch — one face or prop, receipt, honest animation limits.

If you are… Start here Done when
Beginner Glossary → import one morph glTF → Play one morph clip You can see a shape change on screen
Working Lua / TA Gates M1–M6 → set_blend_weights + shader Receipt JSON + screenshot + HTML5 note
Studio lead Keep/hold table + diligence Written promote condition + dual owners

Time: about 90–120 minutes for a fresh spike project. Longer if your DCC export is broken or your custom vertex shader needs a morph pass.

Why this matters now

Three clocks make defold morph targets worth an evening this month:

  1. Stable morphs finally shipped. The 1.13.0 release calls morph targets one of the most important 3D additions — facial animation, dialogue mouth shapes, damage morphs, stylized deformation without mesh swaps. Discord will ask “did you try morphs?” — you need a receipt, not vibes.
  2. Script control is first-class. Official docs expose model.get_blend_weights() and model.set_blend_weights() so gameplay can drive expressions without baking every combination into clips (model animation manual).
  3. Honest limits still surprise teams. A model component plays one model.play_anim lane at a time — you cannot dual-play a skeletal clip and a separate morph clip. You can play skeletal animation and override morph weights from script. Shader materials must opt in; editor morph preview is not there yet. HTML5 / GLES2 paths need an honest note.

Also in the 1.13.x wave (do not confuse with tonight’s keyword): 1.13.1-beta Light components, morph-target instancing follow-ups, build and editor tooling. Tonight’s primary keyword is defold morph targets on 1.13.0+ stable.

Glossary - plain words

Term What it means
Morph target / blend shape Alternate vertex positions (plus normal/tangent deltas) for the same mesh; a weight blends how much of that shape applies.
Weight 0 → 1 0 = no effect; 1 = full target shape. Values outside that range can exaggerate if the asset/shader allow it.
glTF morph data Morph targets and initial weights imported from .gltf / .glb into the Model.
Morph animation clip A glTF animation that keys morph weights — playable with model.play_anim() like skeletal clips.
model.set_blend_weights Lua override applied after animation each frame until cleared.
model.get_blend_weights Reads current weights for the first morphed mesh in the model.
morph_targets texture Engine-generated sampler2DArray holding position/normal/tangent deltas per target.
morph_targets_weights Vertex uniform (vec4 packs of four weights) the shader reads.
One play_anim lane One model animation at a time — skeletal or morph clip via play_anim, not both clips at once.
Keep / hold / rewrite Keep = adopt morph path for ship; hold = lab only until shader/HTML5 proven; rewrite = wrong feature for this vertical slice.

What Defold 1.13.0 morph support actually ships (true summary)

From the 1.13.0 release, forum notes, model animation manual, model component manual, and PR #12192:

  • glTF morph / blend target import on model components (mesh morphs come in with the mesh).
  • Morph weight animations playable with model.play_anim() when the animation set includes them.
  • Runtime Lua control via model.get_blend_weights() and model.set_blend_weights() (one-based Lua indices; clear override with nil / empty call).
  • Shader constructsmorph_targets_weights uniform and sampler2DArray morph_targets (three array layers per target: position, normal, tangent deltas).
  • Official examples referenced from the release post (Morph Target Animation playback; Morph Target Weights for script-driven blends).
  • Honest limits (from PR / docs): instancing needs more work; cannot mix skeletal + morph as two simultaneous play_anim calls; cannot play multiple morph clips at once the same way; editor morph preview not available yet (#ifndef EDITOR wrappers in shader examples); some shader helpers (textureSize) are not GLES2-friendly.

This is stable channel capability (1.13.0+), unlike editor Light components which remain a 1.13.1-beta keep/hold. Still use a spike branch — morph-aware materials and animation policy are ship risks even when the editor version is stable.

Keep / hold / rewrite - Monday decisions

Situation Keep Hold Rewrite
Dialogue face on desktop with morph glTF ready Spike morphs on 1.13.0+ branch Merging untested morph shader into fest depot tonight Claiming “faces done” after import alone
Need run + smile at once via two play_anim calls Redesign to skeletal + set_blend_weights Expecting dual play_anim morph+skel
HTML5 demo on WebGL1 / ES2 Morph shaders until GLES3/WebGL2 path proven Shipping morph VS that requires textureSize on ES2
Pure 2D pixel game Optional prop morph only Forcing facial pipeline into a sprite ship
Custom skinned materials without morph sample Port morph pass after spike Dual materials forever Deleting working skinning mid-milestone
Partner diligence zip Receipt + screenshot + limit notes “It twitched in Play once” Shipping without owners or promote condition

Default indie posture: keep the spike workflow and receipt on 1.13.0+; hold ship merge until M1–M6 are green and animation policy is written (one play_anim lane + script morph overrides).

Prerequisites

  • Git (or zip backups) — morph material mistakes are easier to revert than to debug mid-week.
  • Defold editor 1.13.0 or newer (stable). Confirm version in Help → About / project settings before you start.
  • A tiny 3D collection: one Model with a morph-capable glTF (or Defold’s morph examples), Camera, floor, light or unlit proof color so you can see deformation.
  • Optional: existing HTML5 export if you must answer the web gate tonight.
  • 90–120 minutes uninterrupted.

If you have never audited a Defold Steam desktop bundle, keep Steam collection save audit for another evening. If you still need editor lights, that is a separate beta night — 1.13.1 lights.

For Lua message patterns around models, skim Game Development with Lua Scripting — tonight’s depth is morph weights and shaders, not general Lua architecture.

Beginner path - first morph on screen (no jargon first)

Goal: one model whose shape clearly changes when you press Play.

  1. Install or confirm Defold ≥ 1.13.0 (v1.13.0 release or newer). Do not mix this spike with a 1.12.x ship install without a second editor.
  2. Create a new project or clone onto a branch named spike/defold-1130-morph.
  3. Import a glTF that includes morph targets (start from Defold’s morph examples linked from the 1.13.0 post if your art pipeline is not ready).
  4. Add a Model component; assign the mesh, skeleton if present, animation set, and a material that supports morphs (builtins path or the manual’s morph vertex shader pattern).
  5. In a script init, either:
    • model.play_anim("#model", "smile", go.PLAYBACK_LOOP_FORWARD) if you have a morph weight clip named smile, or
    • read weights, set weights[1] = 1, call model.set_blend_weights("#model", weights).
  6. Press Play. Confirm the mesh deforms. Raise and lower the weight or stop the animation to see the base shape return.
  7. Screenshot Play mode. Fill the receipt at the end of this article. Do not treat “imported without crash” as ship-ready faces.

That is the beginner win. Everything below is the working-dev gate set.

Working-dev gates M1–M6

Gate What you prove Artifact
M1 Version pin Editor reports ≥1.13.0; ship install untouched if separate about_version.txt or screenshot
M2 Morph import Model Outline shows morph-capable mesh; no import error gltf_import_note.md
M3 Morph play_anim One morph weight clip plays visibly play_anim_morph.gif or screenshot
M4 Script override set_blend_weights changes shape; clear restores anim/base weights_override_log.txt
M5 Material morph path Vertex shader samples morph_targets / weights (or proven builtin) Material path + compile clean
M6 HTML5 + owners Web note filed; receipt signed; keep/hold written defold_1130_morph_receipt_v1.json

M1 - Pin Defold ≥ 1.13.0 without wrecking ship

Morph APIs do not exist on older stables the same way. Print version. If your Steam branch is still on 1.12.x, keep two installs or upgrade the spike project only. Record both spike_version and ship_version in the receipt.

M2 - Import one morph glTF cleanly

Per the model manual, morph targets import with the mesh from glTF. If the file has multiple meshes, Defold reads the first — author for that rule. Skeleton + morph data can coexist; animation policy still matters later.

Fail: import succeeds but no morphs exist in the asset (DCC export forgot blend shapes). Fix in Blender/Maya/etc., re-export, re-import — do not invent Lua weights for missing targets.

M3 - Play a morph animation clip

function init(self)
    model.play_anim("#model", "smile", go.PLAYBACK_LOOP_FORWARD)
end

If the clip is skeletal-only, you will not see blend-shape motion. Confirm the animation set actually keys morph weights (manual).

Honest limit: you cannot also play_anim a separate skeletal clip on the same model at the same time. Plan one clip lane.

M4 - Drive weights from Lua

function init(self)
    local weights = model.get_blend_weights("#model")
    weights[1] = 0.75
    weights[2] = 0.25
    model.set_blend_weights("#model", weights)
end

-- later, clear override:
-- model.set_blend_weights("#model")
-- model.set_blend_weights("#model", nil)

Docs: override applies after animation every frame until cleared; indices are one-based; extras ignored; missing values treated as zero for meshes with more targets.

Recommended production pattern for locomotion + face: play skeletal locomotion with play_anim, drive mouth/brows with set_blend_weights from dialogue state — not two competing play_anim calls.

M5 - Morph-aware material (the silent fail)

If the vertex shader never samples morph_targets and applies weighted deltas, weights do nothing visible. The model animation manual shows the morph_targets_weights array packing (four weights per vec4) and apply_morph_target pattern. Editor preview of morph textures is limited — trust runtime Play, not editor scrub alone.

Fail: “weights print in Lua but mesh frozen” → material path, not Lua.

M6 - HTML5 honesty + receipt + owners

Document whether tonight’s shader uses features that break on OpenGL ES 2.0 / WebGL1 (manual notes textureSize-style samples are not ES2-safe). Desktop GREEN does not equal HTML5 GREEN. Name ship_owner and spike_owner. Decision must be keep, hold, or rewrite with a promote condition.

Proof table - what “GREEN” looks like

Check GREEN RED
Version ≥1.13.0 on spike Guessing from Discord
Import Morph targets present on mesh Empty morph list
play_anim morph Visible deformation Clip plays but shape static
set_blend_weights Shape tracks script values Values change, mesh ignores
Clear override Returns to anim/base Stuck in last override
Material Morph sample in VS Unmorphed skinned/unlit only
Dual play_anim attempt Documented as unsupported “Bug report” filed against intended limit
HTML5 Explicit pass/hold/n/a Assumed same as desktop
Receipt JSON on disk with owners Slack memory only

Discord-ready brief (creator share hook)

Paste this after the evening:

Defold 1.13.0+ morph targets (blend shapes) are real. We spiked branch spike/defold-1130-morph: one morph glTF, play_anim or set_blend_weights, morph-aware material, receipt filed. We do not dual-play_anim skeleton + morph clips. HTML5 marked hold/n/a until WebGL path proven. Ship merge waits on M1–M6.

Creators: that message is the shareable outcome. Developers: the receipt below is the bookmark.

Evening timeline (90–120 minutes)

Block Minutes Focus
0–15 Confirm ≥1.13.0; branch project M1
15–40 Import morph glTF; Model wired M2
40–65 play_anim morph clip smoke M3
65–85 set_blend_weights + clear M4
85–100 Material morph path verify M5
100–120 HTML5 note + receipt + Discord brief M6

If you run long, cut HTML5 build and mark hold with reason — still file M6.

Common mistakes (and fast fixes)

Mistake Symptom Fix
Dual play_anim skel + morph Second clip “wins” or looks broken Skeletal play_anim + set_blend_weights for face
Unmorph material Weights change, mesh frozen Add morph sample path from manual
Zero-based weight indices Wrong target moves Use one-based Lua indices
Forgot to clear override Anim clips never recover set_blend_weights("#model") / nil
Editor-only judgment “Works in Outline” Trust runtime Play; editor morph preview limited
Mixing lights beta tonight Context switch chaos Morphs on stable 1.13.0; lights another night
Mixing Steam save audit Depot thrash Morphs tonight; save audit later
glTF multi-mesh surprise Wrong mesh imported Author first mesh or split files
ES2 HTML5 morph VS Black / compile fail on web Hold morph on web or simplify shader
Shipping without promote rule Mid-fest morph merge Receipt promote_after filled

If packaged Steam saves already misbehave, fix that on the ship channel with the save-root help article — do not debug saves while learning morph weights.

Animation policy - write this before art scales

Pin a one-page policy in the spike folder:

  1. Locomotion / body — skeletal clips via model.play_anim.
  2. Face / damage / stylized mesh — morph weights via set_blend_weights (and/or a single morph clip when idle).
  3. Never schedule two competing play_anim calls expecting blend.
  4. Material — every morphed hero uses a reviewed morph-capable material ID.
  5. Platform — desktop first; HTML5 morph is a separate gate.

That policy is what companies want in a diligence zip more than a pretty GIF.

Company / diligence paragraph

For a publisher or contractor zip:

  1. Spike channel is Defold ≥1.13.0 on an isolated branch with defold_1130_morph_receipt_v1.json.
  2. Morph adoption requires M1–M6 green and written animation policy (one play_anim lane + script morph overrides).
  3. HTML5 products document WebGL / ES version requirements or a non-morph fallback.
  4. Art pipeline exports morphs into the first mesh Defold reads, or splits assets intentionally.
  5. No production player traffic on experimental morph shaders until promote condition clears.

Cost/ROI: one evening now vs a week of “faces broken on build machine” and mid-fest dual-animation fights. Governance: two named owners (ship vs spike).

Templates for Defold save-path audits live under 12 free Defold / GDevelop / Ren'Py save-path resources — different format ladder, same evidence habit. Pair morph receipts with BUILD_RECEIPT culture when you promote builds.

Receipt template - defold_1130_morph_receipt_v1.json

{
  "receipt": "defold_1130_morph_receipt_v1",
  "project": "YOUR_GAME",
  "collected_at": "2026-07-28",
  "spike_version": "1.13.0_or_newer",
  "ship_version": "VERSION_YOU_SHIP",
  "release_url": "https://defold.com/2026/06/22/Defold-1-13-0/",
  "branch": "spike/defold-1130-morph",
  "gates": {
    "M1_version_pin": true,
    "M2_morph_import": true,
    "M3_play_anim_morph": true,
    "M4_set_blend_weights": true,
    "M5_morph_material": true,
    "M6_html5_owners": true
  },
  "asset": "path/to/morph.glb",
  "morph_clip": "smile_or_none",
  "script_override_tested": true,
  "material": "morph_aware_material_id",
  "play_mode_screenshot": "artifacts/play_mode_screenshot.png",
  "html5_morph": "n/a",
  "html5_note": "desktop-only spike; WebGL morph deferred",
  "animation_policy": "skel_play_anim_plus_script_morph_weights",
  "decision": "hold_pending_html5_or_keep_desktop",
  "ship_owner": "NAME",
  "spike_owner": "NAME",
  "promote_after": "M1-M6 green on ship candidate; animation policy reviewed",
  "notes": "One play_anim lane; set_blend_weights for face; see manuals model-animation + PR #12192"
}

Store next to your other evidence folders. Re-run M3–M5 after every material or glTF export change.

Comparison - where this sits vs other keep/holds

Topic Engine Question
This article Defold 1.13.0+ Can we smoke morph / blend shapes with honest animation policy?
Defold 1.13.1 lights Defold beta Can we light a collection with editor Light components?
Roblox Animation Graphs Roblox Can we ship locomotion blends without Luau state-machine theater?
Phaser Spine Mesh2D Phaser Can we smoke slot objects without batch-break theater?
MonoGame 3.8.5 MonoGame DesktopVK / Content Builder without breaking DesktopGL?

Same keep/hold discipline; different primary keywords. Do not cannibalize Defold lights vs morph targets.

Secondary 1.13.x features (park for later)

Do not expand tonight’s receipt to cover everything in the 1.13 wave:

  • Editor Light components (1.13.1-beta) — use the lights evening
  • Morph-target instancing for crowds (called out as future work in PR notes)
  • Mixing multiple simultaneous morph clips as first-class (also future)
  • Metal / warm-build / archive size work from adjacent releases

Each deserves its own evening. Tonight is morph targets.

Stretch goals (only after M1–M6 green)

  • Wire dialogue lines to a small weight table (viseme-ish) without claiming full lip sync.
  • Compare CPU cost: morph on vs off on mid laptop (one paragraph in receipt notes).
  • Export a second morph prop (crate damage) to prove pipeline repeatability.
  • Attempt HTML5 build with a GLES3/WebGL2-safe morph shader and update html5_morph.

Stop at one stretch if the clock hits 120 minutes — file the receipt first.

Key takeaways

  1. defold morph targets shipped in Defold 1.13.0 (June 22, 2026) as stable glTF blend-shape support for models.
  2. Control morphs with model.play_anim (weight clips) and/or model.set_blend_weights (script override).
  3. A model has one play_anim lane — do not expect skeletal + morph dual clips.
  4. Recommended pattern: skeletal locomotion via play_anim + face via set_blend_weights.
  5. Materials must opt in to sample morph_targets / morph_targets_weights or weights are invisible.
  6. Lua weight indices are one-based; clear overrides deliberately.
  7. Editor morph preview is limited — prove deformation in Play.
  8. HTML5 / ES2 may reject morph shader helpers — file an honest hold.
  9. Keep morphs off the same night as lights beta or Steam save audits.
  10. File defold_1130_morph_receipt_v1.json with dual owners and a promote condition.
  11. Write animation policy before art scales facial targets.
  12. Discord brief + receipt beats “the mouth twitched once” when partners ask.

FAQ

What are Defold morph targets?

Alternate mesh shapes (blend shapes) imported from glTF and blended by weights. Defold 1.13.0+ supports them on model components with animation and Lua weight APIs — see the model animation manual and 1.13.0 release.

How do I set morph weights from Lua?

Call model.get_blend_weights("#model"), edit the table (one-based indices), then model.set_blend_weights("#model", weights). Clear with model.set_blend_weights("#model") or nil.

Can I play a walk animation and a smile animation at the same time?

Not as two model.play_anim calls. Play the skeletal walk, drive smile weights with set_blend_weights, or redesign clips. Official docs state one model animation at a time via play_anim.

Why do my blend weights do nothing?

Usually the material vertex shader does not apply morph deltas. Second: no morph targets on the imported mesh. Third: override cleared incorrectly or wrong component URL.

Is morph support still beta?

Morph targets landed in 1.13.0 stable. Editor Light components are the separate 1.13.1-beta story — do not conflate them.

Will morph targets work on HTML5?

Only if your morph shader and graphics context support the required features. Manual examples that use textureSize are not OpenGL ES 2.0 friendly. Prove desktop first; mark HTML5 hold until tested.

Is this the same as the Defold lights article?

No. Lights = LightBuffer / ambient-directional-point-spot on 1.13.1-beta. This URL = morph / blend shapes on 1.13.0+. Link them; do not merge keywords.

Where should studios put diligence evidence?

defold_1130_morph_receipt_v1.json, Play screenshot, animation policy paragraph, HTML5 note, ship vs spike owners, promote condition.

Do morph targets replace skeletal animation?

No. They complement it for surface deformation (faces, damage, stylized squash). Skeletal animation still owns bone-driven motion.

How does this relate to Lua scripting generally?

Morph weight tables are a Lua API concern; message architecture and update loops still follow normal Defold script patterns — see Lua scripting overview.

Related reading

Bottom line

defold morph targets in 1.13.0+ are the first evening worth running if you care about facial dialogue, damage morphs, or stylized deformation in Defold — and the first evening worth not merging if you still dual-play_anim by habit or ship an unmorph material. Pin the version, import one morph glTF, prove play_anim or set_blend_weights, verify the shader path, record HTML5 truth, file the receipt, keep animation policy boring. When ship promotes, M1–M6 are already rehearsed.