npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

a-character-ctrlr

v0.1.0

Published

A React Three Fiber third-person controller library with a primitive player, follow camera, and ragdoll debugging sandbox.

Readme

CharacterCtrlr

CharacterCtrlr is a hybrid library + demo project for a React Three Fiber third-person controller stack. It ships a reusable primitive player, a follow camera with camera-occlusion handling, scoped controller state, a humanoid ragdoll dummy, and an in-world ragdoll debug lab.

Production active-ragdoll direction

The repo is now explicitly being pushed toward a production-capable active ragdoll for mobile and PC.

Important boundaries:

  • src/lib is the shipping codepath
  • src/components is demo-only support code
  • the demo is used to inspect and reproduce behavior, not to host one-off controller logic
  • visual debugging is treated as part of the runtime engineering surface, not as optional polish

The chosen controller family is:

  • deterministic SIMBICON-style gait control
  • capture-point stepping heuristics for balance recovery
  • later directional locomotion expansion informed by Generalized Biped Walking Control

See:

Production baseline

The library is now in a solid packageable baseline for:

  • third-person movement with idle, walk, run, crouch, jump, and fall
  • external or keyboard-driven input
  • follow-camera control with pointer lock and scene-occlusion avoidance
  • state snapshots and movement lifecycle callbacks
  • a separate humanoid ragdoll test dummy with in-world debug visualization

What is not finished yet:

  • step-up and slope-specialized controller handling
  • tuned production active-ragdoll walking, running, and recovery behavior
  • authored interaction systems for doors, vehicles, weapons, and golf
  • skinned-character animation or motion-matching backends

Install

npm install a-character-ctrlr react react-dom three @react-three/fiber @react-three/rapier @react-three/drei

Quick start

import { Canvas } from "@react-three/fiber";
import { Physics } from "@react-three/rapier";
import { CharacterCtrlrCameraRig, CharacterCtrlrPlayer, CharacterCtrlrProvider } from "a-character-ctrlr";

export function Scene() {
  return (
    <CharacterCtrlrProvider initialState={{ playerPosition: [0, 2.5, 6] }}>
      <Canvas shadows camera={{ fov: 42, near: 0.1, far: 250, position: [0, 3.5, 8] }}>
        <Physics gravity={[0, -9.81, 0]}>
          <CharacterCtrlrPlayer controls="keyboard" position={[0, 2.5, 6]} />
        </Physics>
        <CharacterCtrlrCameraRig />
      </Canvas>
    </CharacterCtrlrProvider>
  );
}

Controlled input example

Use controls="none" when you want to drive the player from your own touch, gamepad, AI, or network state.

import { useEffect } from "react";
import { Canvas } from "@react-three/fiber";
import { Physics } from "@react-three/rapier";
import {
  CharacterCtrlrCameraRig,
  CharacterCtrlrPlayer,
  CharacterCtrlrProvider,
  useCharacterCtrlrInputController,
} from "a-character-ctrlr";

function BotDriver() {
  const controller = useCharacterCtrlrInputController();

  useEffect(() => {
    controller.replaceInput({ forward: true, run: true });
    return () => controller.resetInput();
  }, [controller]);

  return (
    <>
      <CharacterCtrlrPlayer
        controls="none"
        inputRef={controller.inputRef}
        onGroundedChange={(grounded) => {
          if (!grounded) {
            controller.pressInput("jump", false);
          }
        }}
      />
      <CharacterCtrlrCameraRig />
    </>
  );
}

export function Scene() {
  return (
    <CharacterCtrlrProvider>
      <Canvas>
        <Physics>
          <BotDriver />
        </Physics>
      </Canvas>
    </CharacterCtrlrProvider>
  );
}

Exported API

  • CharacterCtrlrProvider
  • createCharacterCtrlrStore
  • useCharacterCtrlrStore
  • useCharacterCtrlrStoreApi
  • useCharacterCtrlrKeyboardInput
  • useCharacterCtrlrInputController
  • CharacterCtrlrActiveRagdollPlayer experimental
  • CharacterCtrlrPlayer
  • CharacterCtrlrCameraRig
  • CharacterCtrlrRagdollDummy
  • DEFAULT_CHARACTER_CTRLR_INPUT
  • mergeCharacterCtrlrInput

Useful exported types:

  • CharacterCtrlrControllerState
  • CharacterCtrlrStoreApi
  • CharacterCtrlrStoreInit
  • CharacterCtrlrInputState
  • CharacterCtrlrMovementMode
  • CharacterCtrlrPlayerSnapshot
  • CharacterCtrlrSupportState
  • CharacterCtrlrVec3

Key component props

CharacterCtrlrPlayer supports:

  • controls="keyboard" | "none"
  • input and inputRef for additive external input
  • tunables for walkSpeed, runSpeed, crouchSpeed, jumpVelocity, acceleration, deceleration, and airControl
  • onSnapshotChange, onMovementModeChange, onGroundedChange, onJump, and onLand
  • debug for the in-world player debug overlay
  • emitted snapshots currently report supportState as a simple "double" or "none" fallback for the capsule baseline

CharacterCtrlrActiveRagdollPlayer supports:

  • the same input and lifecycle callback shape as CharacterCtrlrPlayer
  • optional mixamoSource loading for hidden animation-target retargeting into the active ragdoll joint motors
  • experimental tunables for jumpImpulse, uprightTorque, turnTorque, and balanceDamping
  • experimental camera-target tuning with cameraFocusSmoothing, cameraFocusHeight, and cameraFocusLead
  • debug to view the articulated rig through the ragdoll debug overlay
  • emitted snapshots report articulated foot support as "none", "left", "right", or "double"

Production note:

  • active-ragdoll work is still marked experimental, but the implementation now has the intended long-term control architecture in place:
    • explicit gait FSM
    • phase-based pose targets
    • COM and capture-point feedback
    • step length, width, and clearance targets
    • locomotion family configs
    • recovery and deterministic gait re-entry
  • grounded-state recovery now uses:
    • contact hysteresis for grounded/airborne transitions
    • delayed jump-contact clearing
    • downward Rapier ground probes under the feet as a fallback when foot contact callbacks are unreliable
  • standing is now handled as a dedicated support problem rather than just an idle gait:
    • pelvis support is solved relative to the foot sole plane
    • idle and low-speed double-support use a stand-assist path
    • feet are planted and leveled while standing so the rig can hold posture before stepping
  • new locomotion, balance, and recovery work should land in the library runtime first and only then be exposed through the demo

CharacterCtrlrCameraRig supports:

  • followOffset, focusHeight, and smoothing
  • pointerLock, yawSensitivity, and pitchSensitivity
  • collisionEnabled, collisionPadding, and minCollisionDistance

CharacterCtrlrRagdollDummy supports:

  • position
  • debug
  • paused/manual-step demo debugging props for the in-repo sandbox

Repo layout

  • src/lib: publishable library source
  • src/components: demo-only scene pieces
  • dist: library build output
  • demo-dist: demo build output
  • RESEARCH.md: academic basis for the active-ragdoll architecture
  • ROADMAP.md: production implementation plan and phase breakdown

Scripts

  • npm run dev: run the demo locally
  • npm run dev:lan: run the demo on your LAN
  • npm run test: run the library smoke tests
  • npm run build:lib: build the package into dist
  • npm run build:demo: build the demo into demo-dist
  • npm run build: typecheck, test, and build both library and demo
  • npm run preview:lan: preview the demo build on your LAN

Demo tip:

  • the demo now defaults to the active ragdoll player
  • add ?player=capsule to the dev URL to load the capsule baseline instead
  • add ?motion=mixamo to enable the optional Mixamo target path in the ragdoll demo once the FBX files are placed in public/mixamo
  • the current ragdoll debugging/tuning path is http://localhost:5173/?player=ragdoll&motion=mixamo

Mixamo tip:

  • see docs/MIXAMO.md for the expected FBX downloads, file layout, and mixamoSource usage

Design direction

The current shipping strategy is deliberate: keep control, camera, state, and interaction logic deterministic first, then add more sophisticated animation systems later. For the active ragdoll specifically, that now means a production-focused finite-state controller with explicit support, foot planting, COM, capture-point, and balance diagnostics before any learned or mocap-heavy runtime is considered.

See also: