Characters

Usage guide of the character kits: choosing third-person, first-person, top-down or platformer, roster and forms, settings and defaults, character.control and camera services, events, hooks (character.jump, character.respawn, character.action), engines.

Source: module-kits:kits/character_third_person/usage/en.mdView Markdown source

Also read offline — CLI: grip-forge docs characterMCP tool: gripforge_docs { "topic": "character" }

The player character (character.* kits) #

The body the player controls: walking, running, jumping, the camera that follows it, and the contract other kits use to borrow it (vehicles, climbing, attacks, dashes). Readable offline: gripforge docs character, or the MCP tool gripforge_docs (topic character).

What it is for #

A game installs ONE controlled-character kit for its view, and optionally the add-ons. Every controlled-character kit owns the entity tagged player and provides character.control, so interaction, vehicles, scenes, saves and combat work whichever one is installed.

KitWhat it adds
character.third_persona kinematic capsule that walks, runs and jumps from input actions, a spring-arm chase camera, optional free look, shoulder aim for shooters, double jump
character.first_personthe same capsule seen through its eyes: pointer and right stick turn the head, the body faces where the eyes look
character.top_downthe view from above: isometric follow camera, world-relative movement, aim from the pointer, click to move, and a motor other kits use to lock, push or turn the body
character.platformercamera-relative platforming: accelerated movement, variable jump height, coyote time, jump buffering, checkpoint respawn
character.rostergame-defined characters and roles, team selection and locking, ability slots and bounded resources (reuses combat.abilities)
character.formstransformations (small, large, robot...) with a capability profile, collision size, duration and a bounded stack of previous forms; a Rust core

Install what the game needs; gripforge kit api <id> lists every setting of a kit.

Turn it on #

gripforge_gamekit_install   { project_id: "gkp_…", id: "character.third_person" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "character.third_person",
                              config: { "walkSpeed": 4, "runSpeed": 7, "airJumps": 1, "cameraDistance": 6 } }

The controlled-character kits require input.actions, world.ground (the platformer: world.platforms), the host physics (physics.character, physics.port) and game.engine. Controls come from the input kits (see the Controls guide): the actions are move_x / move_y, sprint, jump, and look_x / look_y when free look is on.

Settings and defaults #

character.third_person #

KeyDefaultMeaning
walkSpeed / runSpeed4 / 7m/s
jumpImpulse5take-off speed
airJumps / airJumpImpulse0 / 5extra jumps before landing (1: double jump); also usable after walking off an edge
cameraDistance / cameraHeight5 / 2metres
turnSmoothing0.150 snaps, 1 turns very slowly
freeLookfalsethe pointer and the right stick turn the camera; it no longer recentres behind the heading
shoulder0camera offset to the right of the character, metres (0 to 1.5)
aimDistance0with freeLook: camera distance while aim is held (0: cameraDistance)
combatDistance / combatSeconds0 / 4camera distance while the player fights (0: off), and how long after the last blow it holds
lookSensitivity / stickLookSpeed / pitchLimit0.0024 / 2.4 / 85free look comfort (radians per pixel, radians per second, degrees)
lockStrafe / lockCameraSpeedtrue / 6movement and camera blend while a combat.ranged target is locked
actionLayers{}animation layers by action family (attack, shoot, reload, block, hit...): mask, weight, fade and how much the movement slows

A shooter turns the shoulder aim on together: { "freeLook": true, "shoulder": 0.6, "aimDistance": 3 }, with combat.ranged aimFromView: true.

<!-- test: kits/character_third_person/tests/character_third_person.rs::the_combat_camera_pulls_back_while_the_player_fights_then_returns --> A melee game pulls the camera back while the player fights, so wind-ups and threats on the sides stay in view: { "cameraDistance": 4.5, "combatDistance": 6.5, "combatSeconds": 4 }. The player fights while a blow it dealt, took or swung is less than combatSeconds old, or while a lock-on of combat.lockon holds; camera.distance follows, and aimDistance still wins while aim is held. Without combatDistance nothing changes.

character.first_person #

walkSpeed 4, runSpeed 7, jumpImpulse 5, eyeHeight 1.62 m, fov 72 degrees, lookSensitivity, stickLookSpeed, pitchLimit 85. The player's own model is not drawn through its eyes; it comes back in a vehicle.

character.top_down #

KeyDefaultMeaning
moveSpeed / acceleration / turnSpeed7 / 60 / 18m/s, m/s squared, rad/s
aimautothe pointer when the host publishes aim.point, else the nearest enemy in front, else the heading
aimAssistRange / aimAssistCone7 / 100metres / degrees
cameraYaw / cameraPitch / cameraDistance45 / 55 / 22degrees, degrees, metres
cameraProjectionperspectiveor orthographic (then cameraViewHeight is the visible world height)
cameraFov, cameraTargetOffset, cameraSmoothing0, [0,0,0], 0.125lens, framed point, follow softness (seconds)
clickArrive / clickReach0.3 / 1.6click to move: stop distance, and reach before attacking or using the clicked entity
clickPath / clickBlocked / clickRepathnavigation / straight / 0.5route with ai.navigation when the game has it, what to do when the point is unreachable, replan delay

character.platformer #

moveSpeed 6.8, acceleration 42, jumpImpulse 9.5, gravity 23, coyoteTime 0.12 s, jumpBuffer 0.14 s, airControl 0.68, jumpCut 0.48 (upward speed kept when the jump key is released early), fallGravity 1.25, cameraDistance 9, cameraHeight 5, capsule radius 0.35 and height 1.8. With world.platforms the kit also keeps the course records and settings of the campaign.

character.roster and character.forms #

character.roster: unique (a character is taken once per game), autoPlayer, maxMembers, title, and the collection roster_characters ({ id, name, slots: [{ id, ability, label, action }] }, up to 12 slots). character.forms: baseForm (default base), changeCooldown 0.5 s, maxDepth 4 (1 to 8) and 1 to 16 forms, each { id, duration, radius, height, speedScale, damageScale, capabilities[] } (duration 0 is permanent; the default set is a base form and a ten-second small form).

Services other kits use #

  • character.control: player(), position(), yaw(), lookYaw() / pitch() (where the camera looks: the aim of a shooter), speed(), detach / attach, teleport, hold(owner). In the Rust player also claim(owner, priority), release(owner, velocity), beginMove(owner), setVelocity(owner, velocity), velocity() so grapples, grinds and boosts can borrow the capsule by priority.
  • camera.third_person, camera.first_person, camera.top_down (the pose the renderer reads) and camera.look (free look: add(dx, dy), yaw(), pitch()).
  • character.motor (top down): lock, push or turn the body for attacks, dashes and staggers.
  • character.platformer: grounded(), velocity(), launch(vy) (a spring), push(dx, dz) (a conveyor).

Events: player.moved (10 Hz while moving: { id, x, y, z, yaw, speed }), player.jumped (aerial is true for an extra jump), player.action (an action started and how it slows the movement), player.pushed. Variables: player.speed, camera.yaw, camera.pitch, camera.shoulder. The character listens to vehicle.entered / vehicle.exited: the capsule is detached while driving and returns beside the door.

Hooks and modding #

The names and payloads are the same in every character kit, so one tap works whichever character a game plays.

HookPayloadWhat a tap may do
character.jump{ entity, speed, aerial }change speed (0 to 30), cancel the jump
character.respawn{ entity, x, y, z, reason }change the position, cancel; asked at a scene entry (scene) or on the scene's player instance (instance), not on a load or while driving
character.action{ entity, anim, movement, moveScale }change how an action slows the movement (free, slow, lock, root)
character.pushtop downaccept or change a push
roster.select, roster.lock, roster.close, roster.use, roster.grantrosterpick another character, refuse a lock, cancel the end of selection, swap the ability of a slot, change a granted amount
{ "id": "no_jump_indoors", "hook": "character.jump", "if": [{ "in_zone": "z_house" }], "cancel": true, "reason": "low_ceiling" }

Moddable keys: the speeds, jump values, camera keys and actionLayers. The comfort of the person playing (lookSensitivity, stickLookSpeed) is not moddable. In game.engine content a scene entry places the player (position and heading), and an instance of kind player is the player.

Engines #

The movement rules are the same Rust implementation on the web and in the native player. character.third_person, character.top_down and character.platformer are also delivered to Godot and Unity as files (a character body with a seed scene and a generated options file) and to Unreal through the shared kit library; character.first_person, character.roster and character.forms run on the web and in the native player. On the engines that do not run the hooks yet, the behaviour is the one without any tap.

When it does not do what you expect #

SymptomCause and fix
The player does not moveno input.actions, or the action is not mapped to the device: check the Controls guide
No double jumpairJumps is 0 (the default); set it to 1
The camera keeps recentring behind the characterfreeLook is off; turn it on for pointer-driven views
A second shooter-style setting does nothingaimDistance only works with freeLook; shoulder works without
A form change is refusedthe cooldown is running, the stack is full (maxDepth) or the engine reported the destination blocked