Skip to content

iwsen/deck-stats

Repository files navigation

Deck Stats

A Decky plugin for tracking per-game playtime on your Steam Deck. Records sessions automatically, shows activity heatmaps, streaks, milestones, and goals through a built-in interface.

Supports multiple games simultaneously - with session history, daily/weekly/monthly breakdowns, docked vs handheld split, and editable sessions for backfilling missing data.

📌 Features

  • Automatic session tracking - detects the running game every 10 seconds
  • Docked vs handheld time split per session (via /sys/class/drm)
  • Battery level recorded at session start and end
  • Activity heatmap - 7×24 grid by day-of-week and hour-of-day
  • Play streaks - current consecutive days and all-time best
  • Milestones - notifications at 10/25/50/100/250/500/1000 hours per game
  • Goals - daily/weekly/monthly targets per game or across all games
  • Session editor - modify start/end time, duration, notes, docked/handheld split
  • Manual session creation for backfilling past playtime
  • Export/import - full data backup as JSON
  • 10 languages: English, Russian, Chinese, Spanish, Portuguese-BR, German, French, Polish, Turkish, Japanese
  • Quick Access Menu widget with live elapsed timer and 7-day mini chart

📂 Project Structure

.
├── README.md
├── main.py                          # Python backend (Decky plugin host)
├── plugin.json                      # Plugin metadata (name, author, tags)
├── package.json                     # Node dependencies
├── rollup.config.js                 # Rollup bundler config (@decky/rollup)
├── tsconfig.json                    # TypeScript config
└── src/
    ├── index.tsx                    # Plugin entry point & QAM widget
    ├── api.ts                       # RPC client wrappers
    ├── types.ts                     # TypeScript interfaces
    ├── components/
    │   ├── FullPage.tsx             # Main stats page (4 tabs)
    │   ├── SectionHeader.tsx        # Reusable section label
    │   ├── EditGoalModal.tsx        # Goal creation/editing modal
    │   ├── EditSessionModal.tsx     # Session editing modal
    │   └── tabs/
    │       ├── OverviewTab.tsx      # Dashboard: totals, streaks, heatmap, top games
    │       ├── ByGameTab.tsx        # Per-game stats ranked by playtime
    │       ├── SessionsTab.tsx      # Paginated session list with edit/delete
    │       └── SettingsTab.tsx      # Goals, export/import, language, clear data
    ├── charts/
    │   ├── ActivityHeatmap.tsx      # 7×24 hour heatmap component
    │   └── BarChart.tsx             # Generic bar chart component
    ├── utils/
    │   ├── format.ts                # Duration, datetime, file size formatters
    │   ├── colors.ts                # Color palette & deterministic game colors
    │   └── ui.ts                    # Spacing, typography, card/row styles
    └── i18n/
        ├── index.ts                 # i18n system with auto language detection
        └── en.ts, ru.ts, zh.ts ...  # Language files (10 languages)

⚙️ How It Works

  • main.py runs an async 10-second polling loop - detects the active Steam game by scanning /proc/*/environ, records session start/end times, accumulates docked and handheld seconds, and fires Decky events to refresh the UI
  • OverviewTab.tsx shows all-time, today, week, month, and year totals with deltas; current/best streaks; top 10 games; 7-day bar chart; and the 7×24 activity heatmap
  • ByGameTab.tsx lists every game ranked by total playtime with per-game heatmaps, 30-day trends, milestone progress, and goal tracking
  • SessionsTab.tsx renders a paginated session list (25 per page) with inline edit and delete; supports creating sessions manually
  • SettingsTab.tsx manages goals, language preference, JSON export/import, and full data wipe
  • index.tsx provides the QAM widget: current game with live elapsed timer, 7-day mini bars, and a tracking toggle

🧮 Tabs

Tab What it shows
Overview Totals by period, streaks, top games, heatmap, session-length buckets
By Game Per-game playtime ranking with individual heatmaps, milestones, goals
Sessions Full session history - editable and deletable, manual creation
Settings Goals, language, export/import, data management

🗄️ Database Schema

SQLite database stored in the Decky plugin data directory.

CREATE TABLE sessions (
  id INTEGER PRIMARY KEY,
  app_id TEXT NOT NULL,
  app_name TEXT NOT NULL,
  start_time REAL NOT NULL,
  end_time REAL,
  duration REAL,
  notes TEXT DEFAULT '',
  docked_seconds REAL DEFAULT 0,
  handheld_seconds REAL DEFAULT 0,
  battery_start INTEGER,
  battery_end INTEGER,
  was_charging INTEGER DEFAULT 0
);

CREATE TABLE goals (
  id INTEGER PRIMARY KEY,
  app_id TEXT NOT NULL,
  target_hours REAL NOT NULL,
  period TEXT NOT NULL,       -- 'daily', 'weekly', 'monthly'
  created_at REAL NOT NULL,
  UNIQUE(app_id, period)
);

CREATE TABLE milestones (
  id INTEGER PRIMARY KEY,
  app_id TEXT NOT NULL,
  threshold_hours REAL NOT NULL,
  reached_at REAL NOT NULL,
  UNIQUE(app_id, threshold_hours)
);

CREATE TABLE settings (
  key TEXT PRIMARY KEY,
  value TEXT NOT NULL
);

🔌 RPC Methods

All Python methods are called from TypeScript via @decky/api.

Method Description
get_overview() Totals, streaks, top games, recent sessions, session buckets
get_by_game() All games ranked by playtime
get_game_detail(app_id) Full stats for one game including heatmap and milestones
get_weekly_summary() 7-day playtime per game
get_daily_series(days) Daily totals for the last N days
list_sessions(page, size, app_id) Paginated session list
list_goals() All active goals with current progress
get_milestones(app_id) Reached milestones for a game
update_session(id, fields) Edit session fields
delete_session(id) Remove a session
create_session(...) Add a session manually
set_goal(app_id, period, hours) Create or update a goal
delete_goal(id) Remove a goal
export_to_file(path) Save all data as JSON
import_from_file(path) Restore from JSON backup
clear_all_data() Wipe all sessions, goals, milestones
set_tracking_enabled(bool) Pause or resume tracking
getDbInfo() Session count, date range, DB file size
getLanguage() / set_language(lang) Language preference

⚙️ Installation

Install via the Decky Plugin Store - search for Deck Stats.

Manual installation

  1. Enable Developer Mode in Decky settings
  2. Download the latest release and extract it to ~/homebrew/plugins/deck-stats/
  3. Restart Decky

Building from source

# Install Node dependencies
npm install

# Build the frontend
npm run build

The bundled output goes to dist/index.js. Deploy the whole repo directory to ~/homebrew/plugins/deck-stats/ on the Steam Deck.

📱 Requirements

  • Steam Deck with Decky Loader installed
  • Plugin API version 1

About

Track playtime, streaks and milestones for every game on your Steam Deck!

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages