Pet that sits on your desktop
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-12 15:00:01 +05:30
src lalala 2026-09-12 15:00:01 +05:30
.gitignore feat: M3 VRM loading and rest-pose rendering 2026-09-11 17:24:41 +05:30
Cargo.lock lalala 2026-09-12 15:00:01 +05:30
Cargo.toml lalala 2026-09-12 15:00:01 +05:30
README.md lalala 2026-09-12 15:00:01 +05:30

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.cursorPos to us, so the gaze follows the pointer anywhere on screen even though Wayland has no global cursor protocol.
  • VRM loading: GLB + VRMC_vrm parsing, 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 blink expression 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_springBone chains (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.toml and restored on launch.
  • Autostart: --autostart on|off or 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.