-
-
Notifications
You must be signed in to change notification settings - Fork 10
Interaction Core
The interaction core is the minimum set of behaviors that makes Mochi feel like a responsive creature rather than a collection of disconnected animations.
For the public alpha, the interaction core matters more than progression systems or feature breadth.
IDLE
├── single click → SQUISH → IDLE
├── double click → HEART → IDLE
├── ambient idle → TYPING → IDLE
├── context menu → WALK / SLEEP / EMOTE / COMPUTER
└── PICKUP → HELD / DRAG → PUT_DOWN → IDLE
The guiding requirement is:
Mochi must always recover and remain interactable.
A feature is not complete if its animation plays correctly but leaves Mochi unable to accept later input.
Idle is the safe/default behavior state.
Expected behavior:
- gentle breathing/idle loop
- occasional low-frequency ambient actions
- accepts clicks, double-clicks, drag, and context-menu input
- serves as the return state for most one-shot reactions
Ambient behavior must never compete with direct input.
A normal click should trigger a tactile reaction such as squish/bounce, then return to idle.
Requirements:
- one-shot playback
- no duplicate reaction timers
- clean return to
IDLE - no interference with a pending double-click
Because single- and double-clicks compete for the same initial input, single-click dispatch may need a short delay so the double-click path can cancel it.
Double-click should play the heart reaction without also firing the single-click reaction.
Required arbitration:
first click
→ pending single-click reaction
→ second click arrives inside double-click window
→ cancel pending single-click
→ play HEART once
→ IDLE
The heart animation must be transparent and return through the normal animation-completion path.
The typing/computer animation has two entry paths:
- ambient low-frequency idle behavior
- explicit Computer action from the context menu
Ambient rules:
- only begin from genuine idle
- use one owned, cancellable timer
- randomized delay should not accumulate duplicate sources
- direct interaction preempts the ambient reaction
- one-shot playback returns to idle
The explicit context-menu action should use the same animation/state path rather than introducing a special duplicate implementation.
This is the most important continuous physical interaction.
Desired flow:
IDLE
→ PICKUP
→ HELD / DRAG
→ PUT_DOWN
→ IDLE
Pickup is a non-looping transition from the exact idle pose to the exact held pose.
Requirements:
- begins at the current/canonical idle endpoint
- ends at the held/drag endpoint
- no visual pop at the boundary
- interruption by a quick release must have a safe recovery path
While held:
- drag animation may play once and hold a final frame, or use a clean loop depending on the authored asset
- dragging remains responsive
- subtle visual inertia may trail the cursor
- actual window/drop coordinates remain accurate
- eye highlights, transparency, and canonical silhouette remain consistent
Put-down is a non-looping transition from held pose back to idle.
Requirements:
- starts exactly from the held endpoint
- ends exactly at the idle endpoint
- release triggers it once
- re-grabbing during or immediately after the transition must not leave Mochi stuck
Test all of these:
idle → pickup → immediate release
idle → pickup → long drag → release
idle → pickup → fast drag → release
put_down → immediate re-grab
heart → idle → drag
computer → idle → drag
context menu → close → drag
Every path must resolve to a valid state.
The right-click menu is called the context menu.
Current/expected actions may include:
- Walk
- Sleep / Wake
- Emote
- Computer
- size/position reset or other utility actions
- Quit
Important lifecycle rule:
The menu must finish closing and release GTK input/focus grabs before behavior that moves the window begins.
Safe sequence:
action selected
→ context state cleared
→ popdown requested
→ wait for GTK closed signal
→ defer one main-loop turn
→ dispatch behavior
This prevents invisible popovers from intercepting later clicks, right-clicks, or drags.
Walking should visually match physical movement.
Requirements:
- animation or bounce only while moving
- movement and animation remain synchronized
- stop safely before returning to idle
- context-menu initiated walk must not retain a popover grab
- later drag/right-click input still works
Sleep is a transition, not an endlessly looping fall-asleep sequence.
Expected behavior:
IDLE
→ sleep transition
→ sleeping hold/loop
→ WAKE
→ IDLE
Requirements:
- sleep transition plays once
- sleeping state persists intentionally
- wake plays once
- wake returns to idle
- input can wake Mochi through a defined path
- sleep/wake cannot permanently block click/right-click/drag
The context-menu Emote action should select from existing compatible reaction animations.
Rules:
- start only when allowed by state priority
- do not interrupt non-interruptible transitions
- play once
- return cleanly
- reuse existing assets and state machinery
General priority from highest to lowest:
- direct user interaction
- pickup/drop and wake/sleep transitions
- deliberate movement
- explicit one-shot emotes
- ambient idle behavior
- idle
The exact implementation can evolve, but timers must never independently fight for control of the animation state.
A new interaction is only considered complete when:
- expected animation plays
- visual state and behavioral state agree
- interruption paths are defined
- no input surface remains mapped invisibly
- no duplicate timer is left running
- next click/right-click/drag works
- relevant unit/regression tests exist
- full suite passes
- live GTK/XWayland interaction is verified
That final recovery requirement is part of the feature, not optional polish.
- Home
- Getting Started
- Current Development Status
- Architecture and Tech Stack
- Interaction Core
- Animation and Art Pipeline
- Development and Testing
- Troubleshooting and Regressions
- Contributing and Issues
- Roadmap and Public Alpha
- Project Philosophy
Repository: https://github.com/miflow13/mochi-desktop
Issues: https://github.com/miflow13/mochi-desktop/issues