You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The first release of PlayGuard: the settings of Nintendo's Parental Controls phone app, on the console itself, offline. Custom firmware (Atmosphère) required.
⏱️ Play-time limit:
The same every day or one per day on a week chart, saved profiles, extra time today in one press, and a one-switch console lock.
📊 Activity:
Play time per game and per user account, day by day, a summary per period, and export to CSV, JSON, XLSX or PDF.
🔒 Restrictions and PIN:
Restriction level, age rating and its organisation, show or change the PIN, and an optional PIN to open PlayGuard.
🕒 Network clock:
Set from public NTP servers, so the play timer counts right on a console that never reaches Nintendo.
🛡️ Safe by design:
The play timer is never written while it counts down, every change is logged and can be undone, settings are backed up to the SD card.
🛟 A way back in:
A recovery sysmodule for a forgotten PIN, and unlinking the phone app on a second-hand console.
🔄 Updates and reports:
Update in place from PlayGuard, "What's new" after each update, diagnostic reports sent as a link and QR codes.
🌍 Languages and themes:
Every console language, light and dark themes.
Important
Coming from Pctl Manager: the app is now in sd:/switch/playguard/ and its files in sd:/config/playguard/.
📜 What changed
Every change in 1.0.0 (95 changes)
⚠ BREAKING CHANGES
new name and SD-card folder (sd:/switch/playguard/).
🚀 Features
a branded loading screen with a progress bar over the start-up steps (#101) (12716f8)
a summary per period and games to rediscover in Activity (#81) (3543af7)
About tab, What's new after updates, and ways to support PlayGuard (#34) (a7a4fb3)
Activity day by day, deleted games' totals and play time per account (#21) (33f2153)
activity: time on no account, and new user accounts flagged (#93) (49ce852)
an intro at start-up, the loading screen held 2 seconds (Preferences) (#110) (ee3aea7)
ask for the PIN before a change, or to open PlayGuard (#19) (bb91242)
back up and restore the parental-control settings (0a6a556)
bedtime alarm display and opt-in advanced actions (time's up alarm, pause / resume) (4a00686)
change the bedtime alarm, checked against what the console reports (#44) (dd86342)
clock: set the network clock to the console clock when no server answers (#94) (a8f1c8d)
console lock — one switch for a 0-minute limit every day (#28) (ec78f4f)
dev builds in tabs, reports to GitHub gists only (as .url links); fix update check and build install on the console (#114) (a874d16)
dev builds: the build list at once, kept and refreshed on demand; artifacts download through a GitHub App; network tasks no longer wait behind the play log (#48) (18144ca)
dev: clear the cache and the log files, with confirmations and result screens (#102) (ef3e91f)
developer tool to compare the play-timer block, exemption list in the diagnostic report (#22) (8e8841d)
development builds from the build artifacts, signed in to GitHub with a QR code; no more pre-releases (#40) (a2c6ce6)
dev: the builds on a screen of their own, by kind, the pull requests sortable (#112) (0ccf593)
diagnostic report in sd:/switch/playguard/logs/ (never contains the PIN) (4a00686)
diagnostics: the start-up times in the diagnostic report (#106) (ebe85c5)
export the Activity figures to the SD card as CSV, JSON, XLSX or PDF (0a6a556)
extra time today from the Play timer tab (0a6a556)
firmware 23.0.1 / Atmosphère 1.12.0 support with firmware and Atmosphère detection (4a00686)
French translation, language and theme preferences, readable error messages (4a00686)
install a development build in place from the developer tools (#39) (9af654e)
lock parental controls again right after a write (4a00686)
network clock from ~50 public NTP servers, measured against 3 servers (adapted from anbingxi's fork) (4a00686)
single build with runtime read-only, developer mode and firmware screen (#8) (111afeb)
tabbed interface (Overview with a play-time gauge, Play timer, Restrictions, Network clock, Companion app, PIN & security, Tools & about) (4a00686)
the Activity tab opens at once on its last figures, kept on the SD card, and refreshes them quietly (#42) (5f38ec0)
the console's live clock and time zone for "today", midnight while open, pending and automatic extra-time restore (#16) (32ee158)
the play-timer recording says what happened, in an event column (#66) (e535ca9)
the version at the right of every screen's header, a development build shown apart (#115) (fbe1c84)
UI/UX overhaul — editable week chart, first steps, change history with undo, per-account activity, Preferences tab (#24) (3c0b950)
UI/UX overhaul, play-timer profiles and extra time, console information and PlayGuard naming (#6) (97af3c8)
update: update in place as a method, a screen at start-up for a newer release (#117) (0364abf)
upload: a gist with a file per part, not one bundled text (#109) (6c8885b)
upload: send reports to bpa.st, or a secret gist when signed in to GitHub (#49) (a16524e)
upload: the latest crash reports sent with the report, the bug form's launch and system filled in (#113) (ebd1cef)
warn while the "time's up" alarm is off, and compare PlayGuard with replacement sysmodules (#30) (a0dd1da)
🐞 Bug Fixes
a failed read or save no longer loses extra time, the history or a block the timer still counts (#72) (360507f)
a hand-written rescue report, a damaged config or an unlocked exit no longer get past the PIN (#70) (5d2376c)
an uncaught exception crashes PlayGuard, not hbmenu after it (#68) (607ce67)
bpa.st's new Let's Encrypt root on the console, and long dialogs wrapped again (#103) (df74698)
build: ship the compiled deko3d shaders, uam does not give the same bytes twice (#105) (bb8ebd1)
every D-pad press moves one line, nothing hidden at the ends; "..." on the console font (#35) (33a57a4)
findings of a full review — two crashes, the play-timer gate, relock safety, console lock, rescue delete (#33) (edbf386)
harden the PIN: Show the PIN always asks, "open" locks again after time away (#83) (9807925)
hints for documented error codes, a "list cut" signal, relock after a manual unlock (#95) (570126f)
join background threads instead of detaching them (the console cannot) (#99) (b57ef58)
keep damaged settings and history, check the play-timer block, gate firmware 23.x (#84) (4ccbd20)
keep the play-timer fields PlayGuard does not decode, relock after an unverified unlock, resilient preferences (#10) (cde7aef)
label the week charts, mark over-limit and unsaved days, unchecked extra-time list, download progress (#76) (101f81f)
Latin font for every label on the console, no cross-fade between screens (#36) (2c45307)
open the pctl:a session per action and release it right away (Atmosphère crashes on 22.5) (4a00686)
play-timer write gate moved into the service layer, also covering "Remove the limit" (4a00686)
QR codes drawn as one texture, a long link crashed the app (#108) (d174d4f)
restore with nothing to change, warn while the phone app is linked, all-time totals of games deleted before PlayGuard (#90) (47a58c4)
security: localtime_r in the crash handler, files created 0644 (#107) (bac99e1)
sign in to GitHub with the recreated PlayGuard OAuth app (#63) (5cd6326)
the first steps' clock check no longer hangs on its spinner (#43) (81967c3)
the PIN lock screen says what the PIN screen answered (#55) (5352990)
the right PIN opens PlayGuard from the lock screen (#65) (83db34f)
UI feedback and consistency (unlocked title, B cancels, danger buttons, clock and update checks, plain app errors) (#11) (0251ce8)
upload: send the report as multipart and show dpaste's real error (#45) (d1889c7)
verify the temporary unlock before writing (4a00686)
warn about the recovery sysmodule, confirm loosened restrictions, say what to do after a system error, accept any script in profile names (#75) (7d4ae43)
✨ Polish
activity: small icons, bounded caches, kept "Show all", less UI-thread work (#91) (1926019)
game names and icons kept between runs, compressed titles read, quitting no longer waits for a play-data read (#85) (dc6f467)
one pctl session per Overview refresh, clocks read every 10 s, per-run caches (#13) (452e639)
rename the project to PlayGuard, JigSawFr as author (6aff9e1)
SD-card writes off the UI thread (config, history, developer log, exports) (#96) (2bd4996)
split ui.cpp by concern, one game sort, fsync before rename, strict config lists (#77) (08a9c61)
stop leaving PlayGuard's own time out of the Activity tab (#64) (135dbbe)
the Activity list updates in place, builds its first 50 rows, decodes each icon once; background tasks end before the app (#74) (7b63af0)
the UI's last console calls behind core/platform.h, simulated on the desktop (#23) (b2c362d)
🛠️ For contributors: build, tests, docs (27 changes)
🧰 Other
a code of conduct, a support page, translation and console-report forms, labels kept in a file, a social preview image (#82) (9ac96c0)
draw with deko3d on the Switch (.nro 9.4 MB -> 3.7 MB) (#12) (bd345c3)
PlayGuard's own warnings on (errors in CI), the last English strings translated, docs caught up (#71) (a444e5b)
release zip with the sphaira GitHub entry, raw .nro and .zip release assets (4a00686)
restore the Switch CPU flags, ccache and a pinned toolchain in CI, sanitized host tests (#9) (84ca61a)
🧪 Tests
CHECK() instead of assert() in the host suites, clang and coverage in CI, reproducible zips (#78) (c9cfcbb)
desktop smoke looks for the PlayGuard window (85accf9)
draw the footer clock at the console's time in the visual references, not a black box (#80) (f9862e6)
host tests for pt_flow, http and backup_flow logic; visual refs for library and devbuild (#89) (f835907)
host tests for the PIN lock, console lock and history undo decisions (#73) (b9c619b)
one console-free core for the console and the simulator, failure injection, play-timer decisions under test (#15) (c2b5c9e)
unit tests of the C service layer, desktop build with a simulated console, headless smoke test, resource checks (4a00686)
📚 Documentation
a limit written by PlayGuard is enforced on the console (#53) (c10c638)
a roadmap, and how PlayGuard compares with Nintendo's companion app (#50) (2482082)
a work-in-progress notice at the top of both READMEs until 1.0.0 is out (#98) (33d49af)
emuMMC/sysMMC note, a decode call while linked, honest compatibility FAQ, specific error hints, corrected texts (#88) (0fdacc0)
every key of config.json, its values and default (#67) (751c4f8)
explain conventional commits and squash merges for releases (4a00686)
README screenshots regenerated from the current UI (#116) (489f283)
refresh the README screenshots, list every file PlayGuard writes (#41) (7f71944)
remove the work-in-progress notice from both READMEs for 1.0.0 (#118) (aad42e5)
reorganise the README for readers, move build docs to CONTRIBUTING.md (#31) (d474430)
roadmap horizon mentions iPhone Live Activities fed by the MQTT bridge (#79) (de32116)
say how AI assistants were used to build PlayGuard (#52) (2c886b8)
tests, simulator, store texts, SD-card file lists and README screenshots caught up with the code (#97) (4469a60)
what to do when locked out (second-hand console, forgotten PIN) (#26) (ee19595)
why PlayGuard exists, and the horizon of a bridge to MQTT and Home Assistant (#51) (a3146a3)
📦 Install
New install: download playguard.zip (2.3 MB) and extract it to the root of the SD card.
The app lands in sd:/switch/playguard/, its files in sd:/config/playguard/.
Already installed? Update from PlayGuard itself (About › Update), sphaira or the Homebrew App Store. The app alone: playguard.nro (5.8 MB).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1.0.0 · 2026-10-12
⬇️ Download playguard.zip (2.3 MB) · the app alone (5.8 MB) · how to install
🌟 Highlights
The first release of PlayGuard: the settings of Nintendo's Parental Controls phone app, on the console itself, offline. Custom firmware (Atmosphère) required.
⏱️ Play-time limit:
The same every day or one per day on a week chart, saved profiles, extra time today in one press, and a one-switch console lock.
📊 Activity:
Play time per game and per user account, day by day, a summary per period, and export to CSV, JSON, XLSX or PDF.
🔒 Restrictions and PIN:
Restriction level, age rating and its organisation, show or change the PIN, and an optional PIN to open PlayGuard.
🕒 Network clock:
Set from public NTP servers, so the play timer counts right on a console that never reaches Nintendo.
🛡️ Safe by design:
The play timer is never written while it counts down, every change is logged and can be undone, settings are backed up to the SD card.
🛟 A way back in:
A recovery sysmodule for a forgotten PIN, and unlinking the phone app on a second-hand console.
🔄 Updates and reports:
Update in place from PlayGuard, "What's new" after each update, diagnostic reports sent as a link and QR codes.
🌍 Languages and themes:
Every console language, light and dark themes.
Important
Coming from Pctl Manager: the app is now in
sd:/switch/playguard/and its files insd:/config/playguard/.📜 What changed
Every change in 1.0.0 (95 changes)
⚠ BREAKING CHANGES
🚀 Features
🐞 Bug Fixes
✨ Polish
🛠️ For contributors: build, tests, docs (27 changes)
🧰 Other
🧪 Tests
📚 Documentation
📦 Install
New install: download
playguard.zip(2.3 MB) and extract it to the root of the SD card.The app lands in
sd:/switch/playguard/, its files insd:/config/playguard/.Already installed? Update from PlayGuard itself (About › Update), sphaira or the Homebrew App Store. The app alone:
playguard.nro(5.8 MB).Locked out?
playguard-rescue.zip(69 KB) is the optional recovery sysmodule, for a forgotten PIN.Note
Requires custom firmware (Atmosphère). Checked on firmware 21.0.0 → 22.5.0. Compatibility
🔍 Build
Build report (size, tests, coverage, screenshots, toolchain) ·
SHA256SUMS.txt· provenance:gh attestation verify playguard.nro -R JigSawFr/PlayGuardContributors: @claude, @JigSawFr, @tailiang2008
All reactions