Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

SebastianPet 🌙

星露谷物语 · 塞巴斯蒂安 macOS 桌面宠物

A macOS desktop pet of Sebastian from Stardew Valley — he wanders across your windows, sits on top of them, reacts to keywords, reminds you to drink water, and runs a Pomodoro timer. Built with Python + PyObjC, no Xcode or Swift required.

个人自用项目,使用了星露谷物语的原版像素素材,仅供学习交流,不作商用。 Fan-made project using original Stardew Valley pixel art. For personal & educational use only, not for commercial distribution.

macOS Python 3.9+ License


Features

Desktop Physics — Sebastian walks along the top edges of your windows, climbs up their sides, and falls with gravity when a window disappears. Drag him and drop him onto any window edge — he'll grab on.

Keyword Easter Eggs — Click the 🌙 menu bar icon → "说点什么…" to type a keyword. He responds in character:

Keyword Reaction
下雨 (rain) "雨天会让我觉得安心。"
咖啡 (coffee) "咖啡……行,那个我需要。"
晚安 (goodnight) curls up to sleep
玛鲁 (Maru) "……" (silent annoyance)
游戏 (games) "要一起玩吗。……算了,你大概没空。"

Full list in config/dialogue.json — add your own keywords there.

Timed Reminders — Four built-in reminders, all spoken in Sebastian's voice:

  • 💧 Drink water — every 40 min
  • 🚶 Stand up & stretch — every 50 min
  • 👀 Look away from screen — every 25 min
  • 🌙 Go to sleep — between 1–5 AM, every 30 min

Each can be toggled individually. Intervals have ±3 min jitter so they don't all fire at once.

Pomodoro Timer — 25 min focus + 5 min break (15 min long break after 4 rounds). Live countdown in the menu bar (🍅24:31 / ☕️04:12). During focus, he sits at a keyboard; during break, he gets up and walks around.

Idle Detection — If you're AFK for 5+ minutes, he curls up and sleeps. All reminders go silent (no point talking to an empty chair). When you return, he greets you based on how long you were gone.

Stardew Valley UI — Dialogue bubbles, emotes, and portraits all use the original game's pixel art, rendered with proper nine-patch scaling.

Quick Start

Prerequisites

  • macOS (tested on macOS 14 Sonoma, Apple Silicon & Intel)
  • Python 3.9+ (system Python or Homebrew)

Install & Run

# Install dependencies
python3 -m pip install --user pyobjc-framework-Cocoa pyobjc-framework-Quartz numpy

# Clone and run
git clone https://github.com/SimoneScoop/SebastianPet.git
cd SebastianPet
python3 run.py

The app appears as a 🌙 icon in your menu bar — no Dock icon. Right-click Sebastian or click the menu bar icon for all controls. Quit from the menu.

Build as .app (optional)

./build_app.sh
open build/SebastianPet.app

No Xcode or codesign required. First launch may need: Finder → right-click the app → Open → confirm.

Interactions

Action Effect
Drag Pick him up; drop onto a window edge to perch, or let him fall
Double-click Rest / wake up
Right-click Context menu (same as menu bar)
Menu bar 🌙 Talk / Rest / Pomodoro / Reminders / Opacity / Quit

Opacity has four levels (100% / 85% / 65% / 40%). Preferences persist in ~/Library/Application Support/SebastianPet/prefs.json.

Project Structure

SebastianPet/
├── run.py                          # Entry point
├── src/
│   ├── app.py                      # Main loop, menu bar, event wiring
│   ├── pet_window.py               # Transparent floating window + mouse passthrough
│   ├── physics.py                  # Gravity, edge walking, window tracking
│   ├── animation.py                # State machine with priority interrupts
│   ├── sprites.py                  # Sprite loading, caching, placeholders
│   ├── chroma_key.py               # Green screen removal
│   ├── bubble.py                   # Stardew-style dialogue box (nine-patch)
│   ├── emotes.py                   # Overhead emote bubbles
│   ├── trigger.py                  # Keyword input panel
│   ├── dialogue.py                 # Keyword matching engine
│   ├── reminders.py                # Timed reminder scheduler
│   ├── pomodoro.py                 # Pomodoro timer + hourly chime
│   ├── idle.py                     # AFK detection (no accessibility permission needed)
│   ├── windows.py                  # Window enumeration via CGWindowList
│   ├── ui_assets.py                # Game UI texture loading & slicing
│   └── prefs.py                    # User preferences persistence
├── assets/
│   ├── sprites/<state>/frame_*.png # Animation frames (green screen PNG)
│   └── ui/                         # Game UI textures (dialog box, emotes, portraits)
├── config/
│   ├── dialogue.json               # Keyword → response mappings
│   ├── animation.json              # Frame rates, priorities, state config
│   ├── reminders.json              # Reminder intervals & dialogue lines
│   └── pomodoro.json               # Timer durations & hourly chime lines
├── tools/                          # Sprite import & processing scripts
├── tests/                          # Unit tests
└── build_app.sh                    # Package as macOS .app

How It Works

Mouse Passthrough — The window is transparent and ignores mouse events by default. A 60 Hz timer samples the alpha value under the cursor; interaction is only enabled when hovering over an opaque pixel. No accessibility permissions needed.

Window Physics — CGWindowListCopyWindowInfo enumerates visible windows as obstacles. Sebastian walks along their edges: horizontal edges play idle_wander, vertical edges play climb. Coordinate systems are converted from CGWindowList (top-left origin) to AppKit (bottom-left origin) once, then used consistently.

Animation State Machine — States have priorities (idle < trigger < drag < fall). Higher-priority actions interrupt lower ones. Each state can specify a post_state to transition to when done. Config-driven via animation.json.

Sprite Pipeline — Sprites are green-screen PNGs (#00FF00). Chroma key removal runs at load time with configurable tolerance and edge cleanup. Missing sprites get a purple placeholder with the state name — so you can develop logic before art is ready.

Customization

Add keywords: Edit config/dialogue.json. Each entry maps a keyword to a sprite animation, dialogue text, duration, and optional emote.

Adjust reminders: Edit config/reminders.json. Change intervals, add new reminders, or write new dialogue lines.

Swap sprites: Drop new green-screen PNGs into assets/sprites/<state>/. Name frames frame_001.png, frame_002.png, etc. The display scale auto-adjusts based on sprite height.

Tests

for t in tests/test_*.py; do python3 "$t"; done

Credits

  • Stardew Valley by ConcernedApe — character design, pixel art sprites, UI textures, and portraits. All game assets belong to ConcernedApe.
  • Built with PyObjC for native macOS integration without Xcode.

License

This is a personal fan project. Game assets are the property of ConcernedApe / Stardew Valley. This project is shared for educational purposes only — please do not redistribute commercially.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors