Skip to content

Latest commit

 

History

73 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Decktation Logo

Decktation - Push-to-Talk Dictation for Steam Deck

Voice dictation plugin for Steam Deck using faster-whisper with context-aware transcription.

Features

  • Push-to-Talk: Hold button combo (default: L1+R1) to record
  • Configurable buttons: Choose 1-5 button combinations from any Steam Deck controller buttons
  • Game presets: Switch between game profiles with different chat systems (WoW, Guild Wars 2, Generic)
  • Channel-aware: Speak channel prefixes like "party pull boss" and it routes to the right chat channel
  • Test Recording: Built-in 3-second test with automatic transcription display
  • Context-aware: Optional WoW addon integration for better accuracy with zone, boss, and party context
  • Fast transcription: Uses faster-whisper for efficient CPU-based speech recognition
  • Auto-type: Automatically types transcribed text into active window via ydotool
  • Toast notifications: Optional notifications when recording starts/stops

Installation

Important

Use a direct ZIP URL that points to the packaged plugin artifact. Recommended stable URL: https://silverfoxy.github.io/decktation/releases/latest/decktation.zip Branch build URL pattern: https://silverfoxy.github.io/decktation/branches/<url-encoded-branch-name>/decktation.zip GitHub release assets also work: https://github.com/silverfoxy/decktation/releases/latest/download/decktation.zip

Do not use GitHub's Source code (zip) or Source code (tar.gz) archives. Those do not contain Decktation's bundled Python dependencies.

  1. Open Decky Settings, enable developer options if necessary, and select Install Plugin from URL or Install Plugin from ZIP.

  2. Paste the direct ZIP URL above, or download decktation.zip first and then choose the file locally. Decky imports the archive and reloads the plugin automatically.

For example, branch feature/chat polish becomes feature%2Fchat%20polish in the URL path.

All dependencies and the private keyboard helper are pre-bundled in the release. No system packages or one-time sudo setup are required.

Usage

  1. Open Quick Access Menu (... button on Steam Deck)
  2. Navigate to Decktation plugin
  3. Select your game from the Game dropdown
  4. Enable the plugin (waits for Whisper model to load)
  5. (Optional) Change the button combination in the plugin UI
  6. In any app/game: hold [button1]+[button2] together to record, release to transcribe and type

Game Presets

Decktation ships with three presets configured in defaults/game_presets.json:

Preset Behavior
World of Warcraft Presses Enter to open chat, types channel prefix + message, presses Enter to send
Guild Wars 2 Presses Enter to focus chat, types the Guild Wars 2 channel command + message, presses Enter to send
Generic Types text directly into whatever window is focused — no Enter presses

WoW Channel Prefixes

In WoW mode, start your message with a channel name to route it to the right channel:

"party let's go"          →  /p let's go
"raid: focus adds first"  →  /raid focus adds first
"say, hello everyone"     →  /s hello everyone
"guild heads up"          →  /g heads up
"type search term"        →  types directly without opening chat

Separators supported: space, colon, comma, or period after the channel name. Case-insensitive.

Available WoW channels: say, party, raid, guild, officer, yell, instance, whisper, type

Guild Wars 2 Channel Prefixes

Guild Wars 2 mode uses the same voice-first flow. For example:

"map meta starts in five"       →  /m meta starts in five
"party stack on me"             →  /p stack on me
"squad: ready check"            →  /d ready check
"team push mid"                 →  /t push mid
"guild one hello everyone"      →  /g1 hello everyone
"whisper Player Name hello"     →  /w Player Name hello

Available Guild Wars 2 channels: say, map, party, squad, raid (an alias for squad), team, guild, guild one through guild six, whisper, type.

Adding Custom Channels

You can add channels beyond the built-in ones (e.g. WoW's numbered channels /1, /2) by editing two config files.

Step 1 — add the channel command to defaults/game_presets.json under the preset's channels map:

"channels": {
  "say": "/s ",
  "party": "/p ",
  "one": "/1 ",
  "two": "/2 "
}

Step 2 — add the spoken trigger words to defaults/channel_languages.json under each language's channels map:

"en": {
  "channels": {
    "one": ["one", "channel one"],
    "two": ["two", "channel two"]
  }
}

After saving both files, saying "one hello" or "channel one hello" will send /1 hello.

You can add as many trigger words per channel as you like (e.g., aliases in multiple languages). The key in defaults/channel_languages.json must match the key in defaults/game_presets.json.

Adding More Presets

Edit defaults/game_presets.json to add new games — no code changes needed. Each preset specifies:

  • chat_open_key — key to open the chat box ("enter" or null)
  • chat_send_key — key to send the message ("enter" or null)
  • default_channel — channel to use when no prefix is spoken
  • channels — map of spoken words to slash-command prefixes
  • whisper_prompt — vocabulary hint for the Whisper model

Button Configuration

The plugin uses a configurable button combo for push-to-talk. You can set 1–5 buttons from the plugin UI.

Available buttons:

  • L1, R1 (bumpers) — Default combo
  • L2, R2 (triggers)
  • L4, R4, L5, R5 (Steam Deck back grips, detected through raw HID)
  • A, B, X, Y (face buttons)

Use Cases

Gaming

  • WoW chat: Dictate messages with correct channel routing (party, raid, guild, etc.)
  • Generic text input: Type player names, search terms, chat in any game without a keyboard

General

  • Web browsing: Fill forms, search, comment
  • Discord/messaging: Send messages hands-free
  • Any text input: Works in any active window using the Generic preset

WoW Context Support (Optional)

For improved accuracy with WoW-specific vocabulary, install the included WoW addon and run convert_wow_context.py --watch. It reads your current zone, target, party members, and class/spec from the game and feeds them to Whisper as context.

See doc/TESTING_GUIDE.md for setup instructions.

Troubleshooting

Plugin not showing up

  • Check Decky Loader logs: /tmp/decky-*.log
  • Ensure all Python dependencies are installed
  • Restart Decky Loader

Recording not working

  • Ensure the plugin is enabled
  • Check that Steam Deck mic is working (test in another app)
  • Check /tmp/decktation.log for ydotoold ready
  • Check logs: /tmp/decktation.log

Button combo not detected

  • Try a different button combination in the plugin UI
  • Rear grip buttons are supported on Steam Deck hardware through raw HID
  • Check /tmp/decktation.log for controller listener errors
  • Verify controller listener is running: pgrep -f controller_listener

Performance on Steam Deck

  • Default base model is recommended (good balance)
  • For faster: use tiny model (edit wow_voice_chat.py line 28)
  • For accuracy: use small model (slower, needs more resources)

Technical Details

  • Speech recognition: faster-whisper (CTranslate2 backend)
  • Model: base (150MB, ~2-4s transcription time)
  • Input: Steam Deck microphone or connected headset
  • Controller input: Steam Deck raw HID reports (independent of per-game Steam Input layouts)
  • Output: Keyboard simulation via ydotool (bundled)
  • Game presets: defaults/game_presets.json — data-driven, no code changes needed to add games
  • Dependencies: Pre-bundled Python 3.11 libraries in lib/ folder
  • Architecture: TypeScript frontend + Python backend + separate controller listener process

Development

npm install           # Install Node dependencies (package-lock.json is ignored)
npm run build         # Compile TypeScript to dist/index.js
npm run watch         # Watch mode for development

# Unit tests (no hardware required)
python3 -m venv .venv && .venv/bin/pip install pytest
.venv/bin/pytest tests/ -v

CI runs unit tests and the TypeScript build on every push via GitHub Actions.

Privacy

  • Voice data stays local. Recording, transcription, chat parsing, and simulated keyboard input run on your Steam Deck. Decktation does not upload audio recordings, transcribed text, or WoW context data.
  • Model downloads. The first use of each selected Whisper model downloads its model files from Hugging Face. This requires an internet connection; subsequent use is local while the model remains cached on the device.
  • Optional diagnostics. The Diagnostics → Share setting is off by default. When enabled, Decktation sends scrubbed error and performance data to Sentry to help diagnose failures. It excludes audio, transcription text, WoW context, credentials, device/host identifiers, IP addresses, and paths containing the local user name. Diagnostics include the plugin release, error category/type, selected game preset, controller type, and whether a dictation operation succeeded.
  • You can disable diagnostics at any time from the plugin’s Diagnostics section; no diagnostics connection is initialized while the setting is off.

Permissions

Decktation declares Decky’s _root permission solely for the Steam Deck devices required by push-to-talk and text input:

  • It reads Valve raw controller reports from /dev/hidraw* so the configured physical button combination works independently of a game’s Steam Input layout.
  • It runs its bundled ydotoold helper against /dev/uinput to simulate the keystrokes that enter the transcription in the active window. The helper uses a private, owner-only socket in /tmp and is stopped when the plugin unloads.
  • Dictated text is passed as data to ydotool; it is never evaluated as a shell command. Decktation does not modify the system filesystem, install system packages, or create system services.

Credits

Built with:

License

MIT

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages