SwimmerAvatarKit
SwimmerAvatarKit is PieAI's shared procedural 3D avatar package. It turns a small, reproducible JSON recipe into a glossy chibi Three.js character and provides an optional React Three Fiber component.
The GLOSS art generator is vendored unchanged from Kindergrimm under the Unlicense. SwimmerAvatarKit owns the stable TypeScript API, recipe persistence, resource lifecycle, tests, and release process around it.
Install
pnpm add @pieai/swimmer-avatar-kit three
React Three Fiber consumers also install compatible React and R3F versions:
pnpm add react @react-three/fiber
React Three Fiber
import { Canvas } from "@react-three/fiber";
import { randomRecipe } from "@pieai/swimmer-avatar-kit";
import { Avatar } from "@pieai/swimmer-avatar-kit/react-three-fiber";
const recipe = randomRecipe("user-42");
export function ProfileAvatar() {
return (
<Canvas camera={{ position: [0, 1, 5] }}>
<ambientLight intensity={1.2} />
<Avatar recipe={recipe} gaze scale={0.8} position={[0, -1, 0]} />
</Canvas>
);
}
Avatar acquires a renderer-scoped material-library lease by default. Many
avatars on one canvas therefore share materials and one studio environment;
the last unmount releases them.
Framework-neutral Three.js
import {
buildAvatar,
randomRecipe,
} from "@pieai/swimmer-avatar-kit";
import {
createStudioMaterialLibrary,
dressScene,
} from "@pieai/swimmer-avatar-kit/materials";
// Optional. `buildAvatar` never touches the scene it is mounted into, so a
// host that already has lighting keeps it. Call this to get the lighting the
// reference lab uses: ACES, a key light, hemisphere fill, background, floor.
dressScene(scene, renderer);
const materials = createStudioMaterialLibrary(renderer);
const avatar = buildAvatar(randomRecipe("user-42"), {
materialFor: materials.materialFor,
});
scene.add(avatar.object);
function frame(deltaSeconds: number) {
avatar.update(deltaSeconds);
renderer.render(scene, camera);
}
// Avatar geometry and shared materials have separate owners.
avatar.dispose();
materials.dispose();
Never dispose mesh materials while another avatar can still share them.
avatar.dispose() intentionally disposes geometry only. The material library
owns and disposes its cache.
Reproducible and persistable recipes
import {
deserializeAvatarRecipe,
randomRecipe,
serializeAvatarRecipe,
} from "@pieai/swimmer-avatar-kit";
const recipe = randomRecipe("account:42");
const stored = serializeAvatarRecipe(recipe);
const restored = deserializeAvatarRecipe(stored);
The serialized form uses a versioned SwimmerAvatarKit envelope. Where that string is stored is a product decision: v0.1 supports local or product-owned storage and does not couple avatars to SwimmerBackend or declare a cross-product identity policy.
Entry points
| Entry point | Purpose | Runtime |
|---|---|---|
@pieai/swimmer-avatar-kit |
Recipes, metadata, build/update/dispose | Three.js |
@pieai/swimmer-avatar-kit/materials |
Gloss materials and studio environment | Browser/WebGL |
@pieai/swimmer-avatar-kit/react-three-fiber |
<Avatar /> adapter |
React + R3F |
Current boundary
v0.1 supports GLOSS avatars with autonomous blinking, gaze, expressions, and breathing. It does not yet promise walking/running poses. Kindergrimm's DRAWN poses target a different rig, while the GLOSS biped is currently a static set of meshes rather than an articulated locomotion skeleton. That work requires a separate rig/retargeting spike before OwnMySpace should depend on it.
DRAWN, VOXEL, and OBJECT are also outside this package version. In particular, procedural OBJECT plants may become another shared capability, but they should not be hidden inside the avatar API.
Upstream and release
- Provenance: NOTICE.md
- Update process: UPSTREAM.md
- Local gate:
pnpm verify - Network update check:
pnpm upstream:check
npm publication is intentionally absent from local scripts. Releases run only
through the manually triggered Trusted Publishing workflow on main.