- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
your-pet
A Linux-native desktop pet in the spirit of the Steam game your pet: a cute character that lives on top of your KDE Plasma desktop, follows your cursor, and can be dragged around.
Built for KDE Plasma 6 on Wayland using zwlr_layer_shell_v1 + wgpu.
Status
The character is alive on the desktop:
- Fullscreen layer-shell overlay (
Layer::Overlay, no decorations, no taskbar entry, never takes keyboard focus). - Transparent premultiplied-alpha swapchain on Vulkan.
- Continuous vsync-paced render loop driven by Wayland frame callbacks.
- The pet is a real object (position + scale) with a per-output input region tracking its bounds, so everything outside the character stays click-through.
- Left-button drag to move, mouse wheel to zoom (0.4x–3.0x); while carried the body bends through the spine and the arms and legs dangle and swing with inertia, then settle with a small spring wobble.
- Global cursor tracking: a small KWin script loaded over D-Bus mirrors
workspace.cursorPosto us, so the gaze follows the pointer anywhere on screen even though Wayland has no global cursor protocol. - VRM loading: GLB +
VRMC_vrmparsing, sRGB textures, opaque/cutout/blended materials, and a depth buffer. - Skinning: skins, joints and inverse bind matrices; vertices are transformed by joint matrices in the shader.
- Morph targets: VRM expressions drive per-vertex deltas; the
blinkexpression plays on a natural timer. - Humanoid look-at: head, neck and eyes turn toward the cursor, computed in each bone's own rest frame and clamped to the VRM angle limits.
- Idle behavior: arms rest at the sides instead of the T-pose, with breathing, a slow weight shift and a subtle bob.
- Spring bones:
VRMC_springBonechains (9 chains / 19 joints on the sample model) swing hair and accessories as the body moves. - Right-click menu drawn inside the overlay: reset position, toggle autostart, quit. Text and hover highlighting are rasterized with fontdue.
- Persistence: position, scale and output are written to
~/.config/your-pet/config.tomland restored on launch. - Autostart:
--autostart on|offor the menu toggles an XDG autostart entry.
Current visual: a VRM character standing on the desktop that follows your cursor, blinks, breathes, reacts to dragging, and offers a native-feeling right-click menu. Without a model file it falls back to the pulsing pink placeholder circle.
Running
Requires a running KDE Plasma Wayland session and a Vulkan-capable GPU.
cargo run
- Drag the character with the left mouse button.
- Scroll while the cursor is over it to zoom.
- Right-click it to open the menu (reset position, autostart, quit).
- Everything outside the character passes clicks through to your desktop.
Models are picked up automatically from assets/ (including one level of
subdirectories, so assets/miku/model.pmx next to its textures works) or
~/.local/share/your-pet/models/, or passed explicitly:
cargo run -- --model /path/to/model.vrm
cargo run -- --model /path/to/model.pmx
Supported formats: .vrm (VRM 1.0 and 0.x), .pmx (PMX 2.0/2.1) and .pmd.
MMD models reuse the full pet behavior (idle, gaze tracking, blink, drag
physics); dynamic rigid bodies drive spring chains for hair and clothing.
Not yet supported for MMD: IK solving, Bullet physics, sphere/toon maps,
edge outlines and VMD motion playback.
(assets/ is gitignored; the samples used during development are the VRM
Consortium's Seed-san and the blender_mmd_tools Hatsune Miku PMX sample.)
Position and scale are saved to ~/.config/your-pet/config.toml. The
autostart entry (also toggled from the menu) can be managed from a script:
your-pet --autostart on
your-pet --autostart off
Development aids: YOUR_PET_DEBUG_BLINK=1 holds the blink closed to inspect
the expression pipeline, YOUR_PET_DEBUG_MENU=1 opens the menu on startup,
and YOUR_PET_DEBUG_CARRIED=1 holds the carried pose.
Smoke test (render one frame and exit):
cargo run -- --once
Useful logging:
RUST_LOG=your_pet=debug,wgpu=warn,naga=warn cargo run
Architecture
| File | Responsibility |
|---|---|
src/main.rs |
Tracing setup and entry point. |
src/app.rs |
Wayland connection, layer-shell overlays (one per output), input regions, pointer interaction, frame-callback render loop. |
src/cursor.rs |
KWin cursor bridge: the D-Bus service and the KWin script that feeds it workspace.cursorPos. |
src/vrm.rs |
VRM/GLB parsing: scene graph, skins, morph targets, expressions and look-at posing. |
src/renderer.rs |
GPU upload and drawing: skinning and morphs in the shader, depth, camera fit. |
src/ui.rs |
Right-click menu rasterization (fontdue) and the textured-quad overlay pass. |
src/config.rs |
TOML settings and the XDG autostart entry. |
src/gpu.rs |
wgpu instance/device/queue and the placeholder shader pipeline. |
Why a fullscreen overlay
On Wayland a client cannot see the global cursor position, so "eyes follow
the mouse" comes from a tiny KWin script exposing workspace.cursorPos over
D-Bus (see src/cursor.rs). Everything else uses ordinary pointer events.
The overlay covers the whole output and the character is moved inside it; the
surface input region is narrowed to the character's bounds so clicks pass
through everywhere else.
Ideas
- VRM 0.x spring bones and spring colliders.
- More expressions and a dialogue system on top of the menu renderer.
- Dragging the pet between outputs.