Develop an atmosphere mod for parental time limitation

  • Thread starter Thread starter dams31
  • Start date Start date
  • Views Views 1,699
  • Replies Replies 18

dams31

Member
Newcomer
Joined
Sep 3, 2025
Messages
7
Reaction score
0
Trophies
0
Age
42
XP
34
Country
France
Hi everyone,

I’m not a developer myself, but I’ve been experimenting with a small project together with ChatGPT, and I’d like to ask for some support from the community.

The idea is to create a Time Limiter overlay for the Nintendo Switch.
It’s somewhat inspired by NX Activity Log (which reads playtime data), but instead of focusing on logs and statistics, this project would allow:

  • ⏱️ Read and display session time for the current title (like NX Activity Log does).
  • ⬆️⬇️ Adjust allowed playtime using button combinations (+10 min / -10 min).
  • 🔒 Optional PIN protection so kids can’t just change the limit.
  • 📊 Per-game JSON storage with cumulative playtime.
  • 🎮 Tesla overlay integration to make it accessible in-game.





  • Installed Tesla Menu following this GitHub guide. = working
  • Followed the official devkitPro setup guide.
  • Installed libnx and tested with simple examples. => Not working





I cannot get the project to compile properly.

My minimal program is
main.cpp
#include <switch.h>
#include <string>

int main(int argc, char* argv[]) {
consoleInit(NULL);

// Hardcoded config (test version)
int limit = 60; // minutes
std::string pin = "1234"; // PIN code

u64 title_id = 0;
appletGetProgramId(&title_id);

// Main loop
while (appletMainLoop()) {
hidScanInput();
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);

if (kDown & KEY_PLUS) break; // exit with PLUS

consoleClear();
printf("Time Limiter Prototype (Test)\n");
printf("Title ID: %016lX\n", title_id);
printf("Limit: %d minutes\n", limit);
printf("PIN: %s\n", pin.c_str());
printf("\nPress + to quit.\n");

consoleUpdate(NULL);
}

consoleExit(NULL);
return 0;
}

Typical errors I get are like:

$ aarch64-none-elf-g++ -I/c/devkitPro/libnx/include -Iinclude -O2 -std=c++17 -L/c/devkitPro/libnx/lib source/main.cpp -specs /c/devkitPro/libnx/switch.specs -o build/time_limiter.nro
source/main.cpp: In function 'int main(int, char**)':
source/main.cpp:12:5: error: 'appletGetProgramId' was not declared in this scope; did you mean 'pmdmntGetProgramId'?
12 | appletGetProgramId(&title_id);
| ^~~~~~~~
| pmdmntGetProgramId
source/main.cpp:16:9: error: 'hidScanInput' was not declared in this scope
16 | hidScanInput();
| ^~~~~~
source/main.cpp:17:33: error: 'CONTROLLER_P1_AUTO' was not declared in this scope
17 | u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
| ^~~~~~~~
source/main.cpp:17:21: error: 'hidKeysDown' was not declared in this scope
17 | u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
| ^~~~~
source/main.cpp:19:21: error: 'KEY_PLUS' was not declared in this scope
19 | if (kDown & KEY_PLUS) break; // exit with PLUS

It looks like my setup with libnx is incomplete, or I’m not compiling in the proper way







Could someone point me in the right direction for:
  • the proper compilation workflow for my minimal example,
  • I can share the complete code prototype if any developer is interested to help me to go on a real development on github for example
Any help would be much appreciated!


Thanks a lot 🙌
 
Last edited by dams31,
That's because you use shitty AI that was trained on libnx from 2020-2021 + mix of delusions.

And nobody will help your AI slop to work as it shows you didn't even bother to look at libnx headers and switch-examples (using functions that don't exist + functions that are deprecated for years). Switch homebrew is not a great way to learn vibe coding as most stuff is not documented in easy to digest way.

Start writing manually code and write posts without using AI, then maybe you will get help. Your compilation environment is correct, your code is garbage.
 
Last edited by masagrator,
That's because you use shitty AI that was trained on libnx from 2020-2021 + mix of delusions.

And nobody will help your AI slop to work as it shows you didn't even bother to look at libnx headers and switch-examples (using functions that don't exist + functions that are deprecated for years). Switch homebrew is not a great way to learn vibe coding as most stuff is not documented in easy to digest way.

Start writing manually code and write posts without using AI, then maybe you will get help. Your compilation environment is correct, your code is garbage.
OK... As I said in my first message I'm not a developer and I'm trying to explain with clarity what I would like to do.
I can understand that from the point of view of experienced people seeing code from AI is not qualitative.

As a beginner I discovered that compiling a module for atmosphere could be an elegant solution to control the time spent by the kids on the switch. I spent some time to try to understand how to do that and I simplified a first code to pass the compilation step. After a couples of hours to make test trials errors I come back to the community to explain my difficulties and ask help.

Would you have some examples or some time to share to learn how to make it working ?

Best regards
 
OK I cloned the branch and tested the compilation of applet/app-playstats. I was able to compile it! I will try to restart from that example.
 
OK I cloned the branch and tested the compilation of applet/app-playstats. I was able to compile it! I will try to restart from that example.
Listen, I'm just gonna be honest with ya: That code the AI spit out, even if it were compilable(?), isn't even close to what you want to do here. It's basically setting some variables and printing them to the screen and waiting for you to press + to close it. AI is really good for that, especially with lower level languages. It doesn't have a clue and leaves out all of the important stuff. It also wrote an application, not a sysmodule.
 
  • Love
Reactions: impeeza
Listen, I'm just gonna be honest with ya: That code the AI spit out, even if it were compilable(?), isn't even close to what you want to do here. It's basically setting some variables and printing them to the screen and waiting for you to press + to close it. AI is really good for that, especially with lower level languages. It doesn't have a clue and leaves out all of the important stuff. It also wrote an application, not a sysmodule.
For sure the code I published first was a minimal test for the compilation.

Here this is the complete code generated with IA and a few iterations
#include <switch.h>
#include <nlohmann/json.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>

using json = nlohmann::json;

// Structure de configuration
struct Config {
int daily_limit;
int special_limit;
std::string password;
std::vector<std::string> special_title_ids;
};

// Lire la configuration depuis JSON
Config load_config() {
Config cfg;
std::ifstream f("/config/time_limiter.json");
if(!f.is_open()) {
printf("Impossible de lire /config/time_limiter.json\n");
cfg.daily_limit = 60;
cfg.special_limit = 30;
cfg.password = "1234";
return cfg;
}
json j;
f >> j;
cfg.daily_limit = j["daily_limit"];
cfg.special_limit = j["special_group"]["limit"];
cfg.password = j["password"];
for(auto &id : j["special_group"]["title_ids"])
cfg.special_title_ids.push_back(id.get<std::string>());
return cfg;
}

// Fonction simple pour demander PIN
bool ask_pin(const std::string &correct_pin) {
std::string entered;
consoleClear();
printf("Entrez le PIN pour modifier le temps: ");
std::cin >> entered;
return entered == correct_pin;
}

int main() {
consoleInit(NULL);
Config cfg = load_config();

int daily_time = 0; // en minutes
int special_time = 0; // en minutes
time_t last_tick = time(NULL);

consoleClear();
printf("Overlay Time Limiter actif\n");

while(appletMainLoop()) {
hidScanInput();
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
u64 kHeld = hidKeysHeld(CONTROLLER_P1_AUTO);

// Récupérer le TitleID actif
u64 title_id = 0;
appletGetProgramId(&title_id);
char title_str[17];
snprintf(title_str, sizeof(title_str), "%016lX", title_id);
std::string titleID(title_str);

// Vérifier si jeu spécial
bool is_special = std::find(cfg.special_title_ids.begin(),
cfg.special_title_ids.end(),
titleID) != cfg.special_title_ids.end();

// Incrémenter le temps toutes les 60 secondes réelles
time_t now = time(NULL);
if(now - last_tick >= 60) {
daily_time++;
if(is_special) special_time++;
last_tick = now;
}

// Boutons pour modifier le temps (+/- 10 min) avec PIN
if((kHeld & KEY_L) && (kDown & KEY_RIGHT)) {
if(ask_pin(cfg.password)) daily_time += 10;
}
if((kHeld & KEY_L) && (kDown & KEY_LEFT)) {
if(ask_pin(cfg.password)) daily_time = std::max(0, daily_time - 10);
}

// Vérification limites
if(daily_time >= cfg.daily_limit) printf("Temps quotidien atteint!\n");
if(special_time >= cfg.special_limit) printf("Temps FC24+FC25 atteint!\n");

// Affichage overlay
consoleClear();
printf("Temps quotidien: %d/%d min\n", daily_time, cfg.daily_limit);
printf("Temps FC24+FC25: %d/%d min\n", special_time, cfg.special_limit);
printf("Titre actif: %s\n", titleID.c_str());
printf("Appuyez L + droite/gauche pour +10/-10 min (PIN requis)\n");

consoleUpdate(NULL);
}

consoleExit(NULL);
return 0;
}
Post automatically merged:

From the git examples I have corrected the function names to call the different buttons and was able to compile it
// Include the most common headers from the C standard library
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// Include the main libnx system header, for Switch development
#include <switch.h>

int main(int argc, char* argv[]) {
consoleInit(NULL);

// Configure our supported input layout: a single player with standard controller styles
padConfigureInput(1, HidNpadStyleSet_NpadStandard);

// Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller)
PadState pad;
padInitializeDefault(&pad);

// Hardcoded config (test version)
int limit = 60; // minutes
//std::string pin = "1234"; // PIN code

u64 title_id = 0;
//appletGetProgramId(&title_id);

// Main loop
while (appletMainLoop()) {
//hidScanInput();
padUpdate(&pad);
//u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);

u64 kDown = padGetButtonsDown(&pad);

//if (kDown & KEY_PLUS) break; // exit with PLUS
if (kDown & HidNpadButton_Plus)
break; // break in order to return to hbmenu

consoleClear();
printf("Time Limiter Prototype (Test)\n");
printf("Title ID: %016lX\n", title_id);
printf("Limit: %d minutes\n", limit);
//printf("PIN: %s\n", pin.c_str());
printf("\nPress + to quit.\n");

consoleUpdate(NULL);
}

consoleExit(NULL);
return 0;
Post automatically merged:

For sure the code I published first was a minimal test for the compilation.

Here this is the complete code generated with IA and a few iterations

Post automatically merged:

From the git examples I have corrected the function names to call the different buttons and was able to compile it

What is missing to me :
- I did not found the function to get the ID of the current title
- I have some compilation issues when adding std libs (#include <fstream>,#include <iostream>,#include <string>,#include <vector>,#include <algorithm>,#include <ctime>) My C/C++ lessons are very old now and I don't remember how to add it
- #include <nlohmann/json.hpp> needs a include file that I got but also the standard lib algorithm
- I don't know how to make a sysmodule instead of an application
Post automatically merged:

I found some details of the libnx there : https://switchbrew.github.io/libnx/functions.html
 
Last edited by dams31,
I'm at a complete loss here. Do you plan to make the child in question use this like some kind of punch card? How is this going to stop them from playin all those damn vidya gaems and do their homework? If you can't even include the headers... I give up.
 
I'm at a complete loss here. Do you plan to make the child in question use this like some kind of punch card? How is this going to stop them from playin all those damn vidya gaems and do their homework? If you can't even include the headers... I give up.

I just want to make a time limitation exactly the same function as Google Family Link does.

I tried to add std headers from the sample file, maybe something is wrong in the makefile. During my first attemps it worked.

I give up.
As you want if my subject is not interesting for you
 
I just want to make a time limitation exactly the same function as Google Family Link does.

I tried to add std headers from the sample file, maybe something is wrong in the makefile. During my first attemps it worked.
If you have no programming experience and are doing it just for fun/learning , I would start with the simplest thing you can find like what @masagrator provided.

As you want if my subject is not interesting for you
It is an interesting topic, but it's the equivalent of me reading a couple of medical books, asking chatGPT if head transplants are possible, and then asking someone for help on how to re-attach a severed head while reconnecting the nerves to preserve mobility of the limbs.
There's a lot you would need to learn about the Switch's hardware and coding in general before you can realistically attempt a project like this.
 
Hello,
I made some progress!
IMG_6394.jpg


I was able to run the main functionnalities that I would like to include in my parental control with an nro prototype application (count time, add more time with a pin,...) -> this is the app2.zip hereafter.

The step after would be to build a sysmodule to launch the parental control at the startup and to control it with an overlay menu.

My very first step is to compile a module (time_limiter_sys2) which is only writing a log file in the /switch directory and doing a tick count. I tried to do a client with another nro to see the tick count but now the module seems not to be working because I have not the log file generated.
Could you help me with a very simple module example ? It would only write the logfile for example ? I'm not confident in the post compilation process that I did with a python tool (under tools/make_pfs0.py) to generate the module file.

Thanks !
 

Attachments

Hello I developed a sysmodule+overlay. It is available on github. https://github.com/TristanIsrael/NSParentalControl.
Maybe it is worth to have a look at it?
If you are more advanced, maybe we could collaborate?

The current features are:
Gamers

  • Check the played time
  • Check the remaining play time
  • When the time is out, the system is blocked
Administrator (protected by a PIN code)

  • Define a PIN to protect setup access
  • Enable or disable the parental control
I am working on a new GUI more friendly with the remaining time visible as a badge (but I have problems, I came to open a thread when I saw your post...).

Regards
 
  • Like
Reactions: Aonja and ber71
Of course there will be improvements in the future, for example the database file is not ciphered so it can be easily corrupted.
There is a roadmap for improvements.
 
Hello it is A A A A, I just published the 1.1.0 version and I added some information in the Readme.md file because I forgot to mention how to make the sysmodule boot at start.
 
Hello it is A A A A, I just published the 1.1.0 version and I added some information in the Readme.md file because I forgot to mention how to make the sysmodule boot at start.
Anyway you can realease the version 1.4 with all the features? Would like it not to restart, can see kids complaining that they didnt save or lost their progress. Maybe a special combo of button to bypass the restart and restart the timer? Thank you! This is a great app.
 
Last edited by Peeta01,

Site & Scene News

Popular threads in this forum