@shigureni/minion 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,20 @@ export const ACTIONS: { durationMs: [number, number]; weight: number }[] = [
21
21
  { weight: 2, durationMs: [2000, 3000] }, // 12 食べる2
22
22
  ]
23
23
 
24
+ // 稼働していないセッション用の「静かな」行動だけの部分集合(clipIndexはACTIONS/Swiftの
25
+ // 並びを指す)。移動・ジャンプ・食事は含めず、待機と座り姿勢をゆっくり切り替える。
26
+ export const SLEEPING_ACTIONS: {
27
+ clipIndex: number
28
+ durationMs: [number, number]
29
+ weight: number
30
+ }[] = [
31
+ { clipIndex: 0, weight: 40, durationMs: [6000, 12000] }, // 待機
32
+ { clipIndex: 7, weight: 15, durationMs: [6000, 12000] }, // 座る1
33
+ { clipIndex: 8, weight: 15, durationMs: [6000, 12000] }, // 座る2
34
+ { clipIndex: 9, weight: 15, durationMs: [6000, 12000] }, // 座る3
35
+ { clipIndex: 10, weight: 15, durationMs: [6000, 12000] }, // 座る4
36
+ ]
37
+
24
38
  export type PetAction = { clipIndex: number; durationMs: number }
25
39
 
26
40
  export function pickAction(random: MinionRandomSource): PetAction {
@@ -43,6 +57,26 @@ export function pickAction(random: MinionRandomSource): PetAction {
43
57
  return { clipIndex: chosen, durationMs: min + random.next() * (max - min) }
44
58
  }
45
59
 
60
+ export function pickSleepingAction(random: MinionRandomSource): PetAction {
61
+ const roll = random.next() * 100
62
+ let cumulative = 0
63
+ let chosen = SLEEPING_ACTIONS[0]
64
+
65
+ for (const action of SLEEPING_ACTIONS) {
66
+ cumulative += action.weight
67
+ if (roll < cumulative) {
68
+ chosen = action
69
+ break
70
+ }
71
+ }
72
+
73
+ const [min, max] = chosen?.durationMs ?? [0, 0]
74
+ return {
75
+ clipIndex: chosen?.clipIndex ?? IDLE_CLIP,
76
+ durationMs: min + random.next() * (max - min),
77
+ }
78
+ }
79
+
46
80
  export type PetBehavior = {
47
81
  running: boolean
48
82
  name: string
@@ -85,9 +119,7 @@ export class PetBehaviorEngine {
85
119
  const existing = this.behaviors.get(id)
86
120
 
87
121
  if (!existing) {
88
- const action = info.running
89
- ? pickAction(this.random)
90
- : { clipIndex: IDLE_CLIP, durationMs: 0 }
122
+ const action = info.running ? pickAction(this.random) : pickSleepingAction(this.random)
91
123
  this.behaviors.set(id, {
92
124
  running: info.running,
93
125
  name: info.name,
@@ -105,20 +137,16 @@ export class PetBehaviorEngine {
105
137
 
106
138
  if (existing.running !== info.running) {
107
139
  existing.running = info.running
108
- if (info.running) {
109
- const action = pickAction(this.random)
110
- existing.clipIndex = action.clipIndex
111
- existing.actionEndsAt = now + action.durationMs
112
- } else {
113
- // 稼働が止まったら、直前のアクションの途中コマで固まらないよう待機姿勢に戻す。
114
- existing.clipIndex = IDLE_CLIP
115
- }
116
- dirty = true
117
- } else if (info.running && now >= existing.actionEndsAt) {
118
- const action = pickAction(this.random)
140
+ // 稼働が止まったときも静かな姿勢を選び直す(走りの途中コマで固まらないように)
141
+ const action = info.running ? pickAction(this.random) : pickSleepingAction(this.random)
119
142
  existing.clipIndex = action.clipIndex
120
143
  existing.actionEndsAt = now + action.durationMs
121
144
  dirty = true
145
+ } else if (now >= existing.actionEndsAt) {
146
+ const action = info.running ? pickAction(this.random) : pickSleepingAction(this.random)
147
+ if (action.clipIndex !== existing.clipIndex) dirty = true
148
+ existing.clipIndex = action.clipIndex
149
+ existing.actionEndsAt = now + action.durationMs
122
150
  }
123
151
  }
124
152
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shigureni/minion",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Desktop pet that reacts to your Claude Code session activity",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -280,6 +280,9 @@ final class Pet {
280
280
  window.setFrameOrigin(NSPoint(x: x, y: y))
281
281
  }
282
282
 
283
+ // スポーン時の向きはランダム。移動する行動を取るまでこの向きを保つ。
284
+ facingLeft = Bool.random()
285
+
283
286
  window.orderFrontRegardless()
284
287
  }
285
288