Skip to content

Commit e14fb3a

Browse files
committed
Document provider and random actions
1 parent c04111c commit e14fb3a

9 files changed

Lines changed: 184 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.3.0
4+
5+
- Added framework-neutral pet registries and controllers in `codex-pet-web`.
6+
- Added React `CodexPetProvider`, `useCodexPet`, and `useCodexPetRandomActions`.
7+
- Added `hide`, `show`, and `remove` controller commands.
8+
- Added idle-only weighted random action runners with configurable average intervals.
9+
- Updated the demo to start slightly smaller and merge bundled examples with local pets.
10+
- Removed the old Vertical fixture from the repository.
11+
312
## 0.2.0
413

514
- Added bundled example pet assets for Sapling, Carrot, and Bandit.

README.md

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,47 @@ npm install codex-pet-web
3030
## Quick Start: React
3131

3232
```tsx
33-
import { CodexPet } from "codex-pet-web-react";
33+
import {
34+
CodexPet,
35+
CodexPetProvider,
36+
useCodexPet,
37+
useCodexPetRandomActions
38+
} from "codex-pet-web-react";
39+
40+
function PetControls() {
41+
const pet = useCodexPet("assistant");
42+
useCodexPetRandomActions("assistant", {
43+
averageIntervalSeconds: 120,
44+
minIntervalSeconds: 45,
45+
maxIntervalSeconds: 300,
46+
actions: [
47+
{ state: "waving", weight: 3 },
48+
{ state: "jumping", weight: 2 },
49+
{ state: "waiting", weight: 1 },
50+
{ state: "review", weight: 1 }
51+
]
52+
});
53+
54+
return <button onClick={() => pet.play("waving")}>Wave</button>;
55+
}
3456

3557
export function AssistantPet() {
3658
return (
37-
<CodexPet
38-
aria-label="Assistant pet"
39-
draggable
40-
floating={{ x: 24, y: 24, zIndex: 1000 }}
41-
fps={8}
42-
scale={0.5}
43-
spritesheetUrl="/codex-pets/sapling/spritesheet.webp"
44-
stateFps={{ idle: 2, waiting: 3 }}
45-
/>
59+
<CodexPetProvider
60+
pets={{
61+
assistant: {
62+
draggable: true,
63+
floating: { x: 24, y: 24, zIndex: 1000 },
64+
fps: 8,
65+
scale: 0.45,
66+
spritesheetUrl: "/codex-pets/sapling/spritesheet.webp",
67+
stateFps: { idle: 2, waiting: 3 }
68+
}
69+
}}
70+
>
71+
<PetControls />
72+
<CodexPet id="assistant" aria-label="Assistant pet" />
73+
</CodexPetProvider>
4674
);
4775
}
4876
```
@@ -112,6 +140,14 @@ During drag, horizontal movement switches to `running-left` or `running-right`;
112140
on release, the pet plays one `jumping` loop and returns to its previous base
113141
state.
114142

143+
For app-wide control, register pets in `CodexPetProvider` and call
144+
`useCodexPet(id)` from anywhere inside the provider. Controllers expose
145+
`play`, `setState`, `setPosition`, `hide`, `show`, and `remove`.
146+
147+
For ambient behavior, `useCodexPetRandomActions` attempts a weighted random
148+
action on a randomized schedule. It only plays an action when the pet is idle,
149+
visible, mounted, and not paused.
150+
115151
## Sprite Contract
116152

117153
Codex pets are regular folders:
@@ -163,8 +199,10 @@ npm run copy:pets
163199
npm run dev
164200
```
165201

166-
`copy:pets` copies local pets from `~/.codex/pets` into the demo. Production
167-
demo builds copy the bundled example pets from `packages/core/example-pets`.
202+
`copy:pets` copies bundled examples plus local pets from `~/.codex/pets` into
203+
the demo. If a local pet uses the same id as a bundled example, the local pet
204+
wins. Production demo builds copy the bundled example pets from
205+
`packages/core/example-pets`.
168206

169207
Before publishing:
170208

@@ -175,4 +213,4 @@ npm run build
175213
npm run pack:dry
176214
```
177215

178-
The latest release line is `0.2.x`.
216+
The latest release line is `0.3.x`.

apps/demo/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"typecheck": "tsc -p tsconfig.json --noEmit"
1111
},
1212
"dependencies": {
13-
"codex-pet-web": "^0.2.0",
14-
"codex-pet-web-react": "^0.2.0",
13+
"codex-pet-web": "^0.3.0",
14+
"codex-pet-web-react": "^0.3.0",
1515
"react": "^19.0.0",
1616
"react-dom": "^19.0.0"
1717
},

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codex-pets-web",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"private": true,
55
"description": "Framework-neutral and React renderers for Codex pet spritesheets.",
66
"license": "MIT",

packages/core/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,58 @@ Dragging temporarily switches the pet to `running-left` or `running-right`
7474
based on horizontal movement. On release it restores the previous base state and
7575
plays one `jumping` loop before returning to that state.
7676

77+
## Registry And Controllers
78+
79+
Use a registry when a product needs app-wide control or multiple pets:
80+
81+
```ts
82+
import { createCodexPetRegistry } from "codex-pet-web";
83+
84+
const registry = createCodexPetRegistry({
85+
pets: {
86+
assistant: {
87+
spritesheetUrl: "/codex-pets/sapling/spritesheet.webp",
88+
scale: 0.45,
89+
floating: { x: 24, y: 24 },
90+
draggable: true
91+
}
92+
}
93+
});
94+
95+
const pet = registry.get("assistant");
96+
pet.bind(document.querySelector("#pet")!);
97+
pet.play("waving", { loops: 1 });
98+
pet.hide();
99+
pet.show();
100+
```
101+
102+
`hide` keeps the pet registered and preserves state. `show` makes it visible
103+
again. `remove` unregisters the pet and destroys its visual binding.
104+
105+
## Random Idle Actions
106+
107+
```ts
108+
import { createCodexPetRandomActionRunner } from "codex-pet-web";
109+
110+
const runner = createCodexPetRandomActionRunner(pet, {
111+
averageIntervalSeconds: 120,
112+
minIntervalSeconds: 45,
113+
maxIntervalSeconds: 300,
114+
actions: [
115+
{ state: "waving", weight: 3 },
116+
{ state: "jumping", weight: 2 },
117+
{ state: "waiting", weight: 1 },
118+
{ state: "review", weight: 1 }
119+
]
120+
});
121+
122+
runner.start();
123+
```
124+
125+
The runner uses randomized one-shot timers. It only plays an action when the
126+
target pet is idle, visible, mounted, and not paused. Weights only affect which
127+
action is chosen; they do not affect how often attempts happen.
128+
77129
## Pure Frame Math
78130

79131
```ts

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codex-pet-web",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "Dependency-free TypeScript engine for Codex pet spritesheets.",
55
"license": "MIT",
66
"author": "FroeMic",

packages/react/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,65 @@ During drag, horizontal movement automatically switches the pet to
7070
`running-left` or `running-right`. When the pointer is released, it restores the
7171
previous base state and plays one `jumping` loop before returning to that state.
7272

73+
## Provider And Hooks
74+
75+
Use `CodexPetProvider` when pet state should survive route or component changes,
76+
or when one app controls multiple pets:
77+
78+
```tsx
79+
import {
80+
CodexPet,
81+
CodexPetProvider,
82+
useCodexPet,
83+
useCodexPetRandomActions
84+
} from "codex-pet-web-react";
85+
86+
function AssistantControls() {
87+
const pet = useCodexPet("assistant");
88+
89+
useCodexPetRandomActions("assistant", {
90+
averageIntervalSeconds: 120,
91+
minIntervalSeconds: 45,
92+
maxIntervalSeconds: 300,
93+
actions: [
94+
{ state: "waving", weight: 3 },
95+
{ state: "jumping", weight: 2 },
96+
{ state: "waiting", weight: 1 },
97+
{ state: "review", weight: 1 }
98+
]
99+
});
100+
101+
return (
102+
<>
103+
<button onClick={() => pet.play("waving")}>Wave</button>
104+
<button onClick={() => pet.hide()}>Hide</button>
105+
<button onClick={() => pet.show()}>Show</button>
106+
</>
107+
);
108+
}
109+
110+
export function AppPet() {
111+
return (
112+
<CodexPetProvider
113+
pets={{
114+
assistant: {
115+
spritesheetUrl: "/codex-pets/sapling/spritesheet.webp",
116+
scale: 0.45,
117+
floating: { x: 24, y: 24 },
118+
draggable: true
119+
}
120+
}}
121+
>
122+
<AssistantControls />
123+
<CodexPet id="assistant" aria-label="Assistant pet" />
124+
</CodexPetProvider>
125+
);
126+
}
127+
```
128+
129+
The provider is a thin React adapter over the core registry. The core controller
130+
owns behavior; React only binds a DOM node to it.
131+
73132
## Controlled State
74133

75134
```tsx

packages/react/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codex-pet-web-react",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "React wrapper for Codex pet spritesheets.",
55
"license": "MIT",
66
"author": "FroeMic",
@@ -34,7 +34,7 @@
3434
"test": "vitest run --config vitest.config.ts"
3535
},
3636
"dependencies": {
37-
"codex-pet-web": "^0.2.0"
37+
"codex-pet-web": "^0.3.0"
3838
},
3939
"peerDependencies": {
4040
"react": "^18.3.0 || ^19.0.0"

0 commit comments

Comments
 (0)