Log inGet started
World

Ironspine

Branchmain
Branchesmain
Commit9a7cce6233

README.md

climber

The salvager in the heavy exosuit — the thing the camera is on for the whole of IRONSPINE — and the inverse kinematics that make it a body instead of a puppet.

How the suit gets onto the player

The player's body already carries a rigged humanoid whose bones exist as real entities. This module reads that rig live, works out each bone's own frame (+Y along the bone toward its child joint, +Z the way the suit faces), and parents a piece of armour to every bone with its local offset baked from that frame. The armour then follows the skeleton for free, in any pose, at no per-frame cost — and the scene file is never touched, because the whole suit is assembled at load time out of assets/climber/.

The figure underneath becomes a black undersuit, so the joints the plate cannot cover read as fabric rather than as holes.

What moves every frame

  • IKRig — hands to Game.state.hands.<side>.target, feet onto the real surface the boot is against (a ray into the tower), head and chest down Game.state.aim.
  • The head turns to the arm carrying the weight once the measured load passes 260 N, so a glance at the pose says which hand is dying before the HUD does.
  • The loaded shoulder shrugs and the free one drops; the forearm hydraulic ram compresses in proportion to the newtons the grip is solving.
  • The mag-clamp rings ramp through Game.gripColor as stamina burns. An open hand is dark and its jaws stand apart.
  • The chest lamp is a real spot light, so the suit lights the iron it is climbing.

Interface

CLIMB calls these; the signatures are fixed by the design spec.

CallMeaning
Climber.attach(body)hand the physical body over; dresses it and returns true
Climber.setHandTarget(side, pos, weight)where a hand is solving to, and how hard
Climber.setHandOpen(side, open)open/closed gauntlet — drives the jaws and the glow
Climber.setLimp(bool)true during a fall: the solver lets go
Climber.ready()has the suit arrived yet
Climber.report()everything the suit is doing right now, for verification

weight is a request, not a command: a hand that has a target always solves at least half way, because a suit whose arms sit in the animation's rest pose while its hands are on a rung is exactly the puppet look this module exists to kill.

Looking at the asset without the game running

local C = require("game.climber")
C.preview({ 0, 3, 0 })          -- put a mannequin down
C.dressPreview("hang")           -- dress it and pose it: "hang" | "reach" | "stand"
C.strainPreview(2300, 90, 20, 96) -- loadL, loadR, staminaL, staminaR
C.clearPreview()                 -- take it away again

The mannequin goes through the same dress() path the live player does, so what an author inspects is the object the game ships.

Where the parts live

  • assets/climber/suitgeom.module — the hard-surface mesh builder: chamfered plate, tapered tube, torus rib, hex bolt, swept cable, and the value noise the wear shading is painted with.
  • assets/climber/suitparts.module — the suit itself, part by part, plus the palette and the one wear function every surface is shaded through.
  • assets/climber/*.material — one material per surface kind. Every base colour is white on purpose: the palette rides in vertex colour, which the builtin pbr shader multiplies into the base, so one material carries rust, verdigris, salt bloom and edge polish across a whole mesh.