Skip to content

PlayGuard 1.0.0

Choose a tag to compare

@playguard-release playguard-release released this 12 Oct 20:17
576f264

1.0.0 · 2026-10-12

⬇️ Download playguard.zip (2.3 MB) · the app alone (5.8 MB) · how to install

⚠️ 1 breaking change · 🚀 58 features · 🐞 27 fixes · ✨ 9 polish · every commit


🌟 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 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 tab with play time per game (0a6a556)
  • 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)
  • new PlayGuard logo and store art (f576890)
  • onboarding, applet warning, Activity totals, week view and i18n polish (#14) (17bc3f1)
  • per-day editor with no-limit days, Monday–Friday / weekend presets, copy a day and discard changes (4a00686)
  • play-time limit profiles saved on the SD card (4a00686)
  • PlayGuard in every console language (#25) (8ff5b0c)
  • preferences — start tab, extra-time amounts, remembered Activity choices, daily update check, start-up clock check, backups kept (#17) (cfb9d44)
  • profiles with any name, edited and renamed without applying; backups keep the alarm, the rating body and the raw play-timer block (#18) (392499d)
  • READ_ONLY build "PlayGuard Diagnostics" that cannot change anything (4a00686)
  • record the play timer every 30 s, explain the clock sync setting, document how the parental controls work (#46) (884f94f)
  • recovery sysmodule and screen for a forgotten PIN that blocks the console (#27) (39be7fc)
  • restrictions — what a preset restricts before choosing it, the rating organisation editable and restored from backups (#20) (10bfe9d)
  • restrictions tab (level, age rating, social-media posting, communication, VR mode) (4a00686)
  • say that PlayGuard's time over a game counts, and leave it out of the Activity tab (#37) (b401170)
  • say when the console is not counting play time, what it does at the limit, and what changed outside PlayGuard (#87) (2ec32af)
  • SD-card layout: sd:/config/playguard, a folder per system, logs in subfolders with limits (#111) (bc59c46)
  • send a diagnostic report online, with the debug files, as a link and QR codes (#38) (21f38d4)
  • show the PIN in the Security tab (0a6a556)
  • 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

  1. 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/.

  2. Already installed? Update from PlayGuard itself (About › Update), sphaira or the Homebrew App Store. The app alone: playguard.nro (5.8 MB).

  3. 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/PlayGuard

Contributors: @claude, @JigSawFr, @tailiang2008