Skip to content

Character models and animation

Updated 2026-09-14.

The 14 goblin, orc and village NPC variants use Blender-authored meshes with rigid joints. Source: art/blender/vyrgarde_characters_v2.blend. The previous vyrgarde_characters.blend is preserved. Runtime models live in client/public/models/characters.

Rebuild and inspect

/Applications/Blender.app/Contents/MacOS/Blender --background --factory-startup --python-exit-code 1 --python tools/blender/create_character_models.py
/Applications/Blender.app/Contents/MacOS/Blender --background art/blender/vyrgarde_characters_v2.blend --python tools/blender/render_character_preview.py
npm run validate:characters
npm run test:characters
npm run typecheck
npm run build

With the Vite client running, open http://127.0.0.1:5173/characters.html. The local workshop supports all 16 variants, individual animation states, an animation reel, lineup/crowd scenes and close/distant geometry inspection. It uses the game's actual loader, animator and entity view. It is a development page, not a production build entry. Normal gameplay remains at /.

Visuals and movement

The upgrade adds shaped axe blades, layered belts and bracers, buckles, outfit accents, war paint, improved faces and curved capes. The head and torso own their visible geometry, so hair, helmets and clothing move with their joints. Elbows and knees articulate independently; held items follow the right wrist.

client/src/render/characterAnimation.ts blends locomotion, breathing, body sway, NPC gestures, glances, windups, attacks, casting, blocking and hit/stagger reactions. Poses are computed on the client from server animation states; they are not baked glTF animation clips. Animation affects the visual hierarchy only. Server position, heading, damage, attack timing, hit capsules and interaction ranges retain their existing authority.

Keep all named pivots when editing: root, torso, head, armL, armR, forearmL, forearmR, legL, legR, shinL, shinR, heldItem, cloth. Blender faces -Y; the glTF export faces +Z, with the runtime visual wrapper converting it to the game's -Z forward. Preserve that conversion when adding poses.

Rendering cost

Each joint has one material batch using a shared colour atlas, packed metallic/roughness atlas and emission atlas. Textures are embedded. Clones share geometry and textures while keeping one private material per character for damage flashes and corpse fading. Static mesh-local matrices are cached; joint matrices remain animated.

Every rendered part has paired character_lod: near/far meshes. The runtime switches to distant geometry beyond 34 metres and back below 29 metres, avoiding flicker at the boundary. Close animation updates every frame, then drops to 20 Hz beyond 35 metres and 10 Hz beyond 85 metres. Offscreen joint updates run at 5 Hz; animation state changes still update immediately. Existing 48-metre character shadow culling remains. Nameplates and health bars have distance limits.

Measured from the complete 14-character library:

Metric Previous Updated
Close triangles 156,286 63,270 (-59.5%)
Close mesh batches 267 153 (-42.7%)
Distant triangles 156,286 20,002 (-87.2%)
Library bytes 6,533,520 3,887,704 (-40.5%)
Materials 27 1
Embedded images 24 3

These are character asset costs, not a claimed percentage increase in whole-game FPS. Close and distant geometry have the same number of batches; distant geometry reduces triangle processing. Recorded manifests are in art/blender/previews/performance-before.json and performance-after.json.

Verification

  • All 14 individual GLBs and the combined library pass attachment, texture, version, LOD pairing and geometry-budget checks.
  • Four animation regression tests cover movement authority, pose continuity, interrupted attacks, active NPC idles and optional-joint fallbacks.
  • Browser checks confirm moving heads, knees and elbows, windup-to-attack transitions, visible damage flashes and restoration of the authored emission map.
  • A 56-character browser scene loaded all 14 variants with 56 independent materials. Rendered triangles fell from 253,092 to 80,020 when selecting distant detail. Switching back to a single character continued rendering correctly.
  • The actual browser game loaded the 3,887,704-byte combined library without errors. Walking to Captain Rusk and opening his dialogue worked.
  • TypeScript checks and the production client build pass. The build retains its existing large shared Three.js/world chunk advisory.
  • The multiplayer smoke test saw both clients, movement and snapshots. The existing 45-second combat bot left the safe zone, killed four mobs, dealt 192 damage, received 101 damage, gained skills and looted a bag on an isolated local server.

These checks do not establish performance on other machines or a public deployment. The procedural fallback remains available if a model cannot load. Blender source and preview images remain editable/reproducible from the authoring scripts.

Runtime batching

The environment polish pass adds rigBatching.ts: each Blender character now renders as one GPU skin per LOD while retaining its named rigid joints and shared atlas. Near/far triangle counts are unchanged; runtime character mesh draw calls are reduced from 11–13 articulated batches to one. Skeletons and flash materials remain private per instance. See Environment models for verification and regeneration commands.

M1 wolves

art/blender/vyrgarde_wolves_v1.blend adds a hunting wolf and scarred pack leader. Rebuild using Blender's background mode and tools/blender/create_wolf_models.py. The wolf atlas has its own texture directory, so rebuilding it does not overwrite the humanoid atlas. npm run validate:characters now checks all 16 variants and both combined libraries.

Wolf library metric Value
Combined GLB 827,904 bytes
Near triangles, wolf / leader 5,856 / 6,300
Far triangles, wolf / leader 1,564 / 1,682
Atlas material / embedded images 1 / 3
Runtime draws per visible wolf 1 for the selected LOD

The quadruped rig uses armL/R for front legs, legL/R for hind legs, cloth for the tail and heldItem for the jaw. All four legs attach to the root; the head attaches to the torso. Its rig metadata is version 3 with quadruped: true. Do not apply the humanoid consolidation step to these pivots.

wolfAnimation.ts blends distance-driven diagonal strides with a lowered-head windup, committed lunge, recovery and howl. The client renders these poses from authoritative combat state. Two added tests sample pose continuity at 30/60/200 Hz and verify diagonal leg, tail and jaw motion. npm run test:starter includes them alongside eight content/combat tests.

PVP mob polish · 14 September 2026

PVP uses a separate eight-mob library under client/public/models/characters/pvp/, authored in art/blender/vyrgarde_mobs_pvp.blend. The original PVE GLBs and Blender source are preserved byte-for-byte. Generate the PVP version with:

/Applications/Blender.app/Contents/MacOS/Blender --background --factory-startup --python-exit-code 1 --python tools/blender/create_character_models.py -- --pvp
npm run validate:characters

The PVP models add stitched repairs, boot lacing, grip bindings, shield rims/bosses, layered arm plates, riveted armour edges, a hunter's fur mantle and harness, and a hexer's embroidered stole and staff details. Shoulder plates and spikes follow their upper-arm joints through attacks. All detail joins the existing atlas and GPU skin; it adds no separate material passes or collision shapes.

PVP animation adds distinct equipment carry, weighted shoulder motion, progressive windups, a circling sling, spear preparation, caster poses, fast releases and settling hit reactions. Wolves close their jaws and gather their paws after a lunge. These are client presentation changes; attack events, damage, collision, movement, respawns and bot decisions are unchanged. Player weapons, tower archers and village NPCs retain their existing poses.

Use /characters.html?mode=pvp in the Vite development client for the actual entity renderer, or choose PVE · Original characters to compare. Player-height view sets a 1.65 m camera with a 65-degree field of view. This workshop remains outside the production build.

Verification for this pass:

  • Generated the PVP Blender source, eight individual exports and combined library; all original and PVP GLBs pass rig, atlas, attachment and LOD validation.
  • PVP combined library: 2,776,692 bytes, 38,784 close triangles and 12,154 distant triangles across eight mobs. Largest close model: 5,248 triangles, below the existing 6,500 limit. Each visible character remains one GPU skin draw, excluding health bars and shadow passes.
  • 25 tests pass across character/wolf animation, attachment, rigid batching and death animation. New checks cover progressive windups, recoil recovery, wolf landing, unchanged player/NPC poses and bounded mob joints at 12/30/60/120 Hz.
  • Browser inspection covered player-height heavy/caster/hunter poses and the real entity renderer's 56-character running crowd. The crowd reported 92 draw calls and 135,156 triangles with automatic distance detail. This is a local workshop observation, not a whole-game performance certification or a multiplayer combat playtest.
  • A fresh browser load of the PVP entity workshop reported no warnings or errors. PVE comparison loaded the original raider geometry.
  • TypeScript checks and the same-origin production build pass; the existing large-chunk advisory remains. Local client assets are updated for playtesting; no public deployment is part of this pass.

Goblin rebuild · 14 September 2026

The four PVP goblins now use a rebuilt jaw/cranium, cheekbones, heavy brows, slit pupils, hooked nose, long ears, teeth and tusks. Their equipment distinguishes roles: a chipped cleaver and planked shield, a two-cord sling with stone pouches, an open cowl and charm staff, or riveted champion armour with a war maul. Cloth, shoulder plates, hands and carried weapons retain their animated joints. The PVE exports and original Blender source remain unchanged.

The PVP library is 3,037,884 bytes. Every close model stays below 6,500 triangles, uses the existing atlas and renders through one selected-LOD skin draw. Validation checks the new goblin_art_version: 3 metadata. Browser review covered all four models in the actual entity renderer, including player-height views, running, champion windup, slinger release and hexer casting. No warning/error entries were captured. These checks verify presentation and attachment integrity, not Steam-quality certification or whole-game frame-rate guarantees.