# Character transformations (character.forms) ## What it is for Temporary or permanent transformations for characters, creatures or robots (small, large, robot...). Each form is a complete profile: capsule size, speed and damage multipliers, and a list of capability ids the game defines. A bounded stack keeps the previous forms and suspends their remaining durations while another form is active. The kit only decides; the engine checks that the destination fits, swaps the collider, the controller and the model, then confirms. See also the [character guide](guide:character). ## Turn it on ```text gripforge_gamekit_install { project_id: "gkp_…", id: "character.forms" } gripforge_gamekit_configure { project_id: "gkp_…", id: "character.forms", config: { "changeCooldown": 1, "maxDepth": 2, "forms": [ { "id": "base" }, { "id": "small", "radius": 0.2, "height": 0.6, "duration": 3, "capabilities": ["vent"] } ] } } ``` ## First example A `change` command does not commit anything: it answers an action `{ token, effect }` for the engine, with `effect = { kind: "form", reason: "requested", from: "base", to: "small", profile }`. The form is current only after the engine confirms with `resolve` (success true); declining keeps the form and the history. ```json { "op": "change", "form": "small", "alive": true, "allowed": true } { "op": "resolve", "token": "", "success": true } ``` ## Settings and defaults | Setting | Default | Meaning | |---|---|---| | `baseForm` | `base` | permanent form that anchors the history (must have duration 0) | | `changeCooldown` | 0.5 | seconds between entering new forms; expiry and explicit return ignore it | | `maxDepth` | 4 | suspended previous forms kept in the stack (1 to 8) | | `forms` | `base` and a 10 s `small` | 1 to 16 profiles: `id` (required), `duration` (0: permanent), `radius` 0.4, `height` 1.8, `speedScale` 1, `damageScale` 1, `capabilities` (up to 32 ids) | Scales are relative to the unchanged base character, not cumulative. Capabilities are the complete set this kit manages. ## Services, events, variables - `character.forms` (service): `create(id, config)`, `request(id, command)`, `remove(id)`, `ids()`. - Commands: `change` (needs `alive` and `allowed` true, a different known form, no cooldown, room in the stack), `revert` (previous form, ignores the cooldown, refused on an empty stack), `reset` (back to the base form, clears the stack), `step` (`dt` up to 0.1 s: advances the cooldown and the timer of the active form; an expiry proposes a return), `resolve`, `preview`, `status`, `config`, `save`, `load`. - State: `{ current: { id, remaining }, stack: [{ id, remaining }], cooldown }`; the first stack entry is always the base form. - Events under the `character.forms` prefix: created, removed, changed (with the command and its result) and refused (with the refusing mod and the reason). ## Hooks and modding | Hook | Asked | |---|---| | `character.forms.create` | before an instance is created | | `character.forms.request` | before a command that changes state is applied; a tap may refuse it | Moddable: the settings above. A pending action blocks the next command until it is resolved. ## Limits The kit never moves or teleports the character to make room: if the engine rejects a growth or a return (blocked), the old form stays and the next `step` retries an expired return. Health and inventory are not scaled or reset. A capability such as `fly` is only an id: the game supplies the animation or controller. Runs on the web and in the native player; the engines load it through the shared kit library. ## Versions Kit 1.1.0 and service `character.forms` 1.1.0 (hooks, presets and outcome events); first release 1.0.0.