|
16151
|
My very own WebOS by @Ammar_6ft2 | Stardance
|
Ammar_6ft2
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @Ammar_6ft2 | Stardanc Title: My very own WebOS by @Ammar_6ft2 | Stardance...
|
1793436975.5017958
|
1794041775.5017958
|
|
16152
|
My awesome macropad! by @tinyanoob | Stardance
|
tinyanoob
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @tinyanoob | Starda Title: My awesome macropad! by @tinyanoob | Stardance...
|
1793245887.1530576
|
1793850687.1530576
|
|
16153
|
test by @azure | Stardance
|
azure
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: test by @azure | Stardance
|
1792914580.3031015
|
1793778580.3031015
|
|
16154
|
My awesome macropad! by @Mako | Stardance
|
Mako
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @Mako | Stardance
|
1793465320.1031086
|
1794070120.1031086
|
|
16155
|
Celestial Stix by @prymmperez | Stardance
|
prymmperez
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Celestial Stix by @prymmperez | Stardance
|
1793238471.1810906
|
1793843271.1810906
|
|
16156
|
Project Mirabyte by @xoxo_glitterbomb | Stardance
|
xoxo_glitterbomb
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Project Mirabyte by @xoxo_glitterbomb | Sta Title: Project Mirabyte by @xoxo_glitterbomb | Stardance...
|
1793231769.023172
|
1793836569.023172
|
|
16157
|
Frictionless by @K1117ms | Stardance
|
K1117ms
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Frictionless by @K1117ms | Stardance
|
1793282217.9127698
|
1793887017.9127698
|
|
16158
|
My first slack bot! by @Thimid | Stardance
|
Thimid
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @Thimid | Stardance
|
1793490784.731402
|
1794095584.731402
|
|
16159
|
captcha slover by @azure | Stardance
|
azure
|
1
|
2.0
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-12T06:05:08Z", "hours": 2.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "i made a captcha solver using yolo and pyautogui. one of the biggest challenges was compute, i don’t own a GPU so trying to run the model locally wasn’t possible but google collab was giving me issues even when tunnels worked sometimes it wouldn’t bind to port. I’m proud of how it turned out in the end not the most accurate project but a fun make. you’ll need to clone the project and put notebook into google collab or modify it for local use when the notebook works just copy the 1st link you see and paste it into the URL in the autocaptcha.py", "repo": "https://github.com/BraedynL0530/autocaptcha", "demo": "https://github.com/BraedynL0530/autocaptcha/tree/master"}]...
|
[{"post_id": 7254, "ts": "2026 [{"post_id": 7254, "ts": "2026-06-12T03:07:18Z", "hours": 1.1364, "text": "devlog 2 fixxing ocr and double click cordinates. I realized that it wasnt a traing issue most of the time rather the ocr just sucks so i cropped the header to help. and i also had client side cordinates for the header so ocr was bugging i fixxed it by adjusting for its pov. same with click cordinates. also for some reason it clicks the same square twice to i decied to filter out over lapping classes to fix it using iou. it has improved the accuracy but still not as accurate as id like"}, {"post_id": 6624, "ts": "2026-06-11T03:30:24Z", "hours": 1.1469, "text": "devlog 1 adding on fixxing the tunnel not connecting to port 8000/ 502 gateway error i needed a time .sleep after debugging with curl, also. ocr struggles with all the text so i cropped it for purely ocr, with a test script to find each corner and the width/height of it. need to fine tune model for more items as of now it doesnt know what to click and is only good at items in dataset and the full item not pieces of it."}]...
|
Title: captcha slover by @azure | Stardance
Devlo Title: captcha slover by @azure | Stardance
Devlogs:
devlog 1 adding on fixxing the tunnel not connecting to port 8000/ 502 gateway error i needed a time .sleep after debugging with curl, also. ocr struggles with all the text so i cropped it for purely ocr, with a test script to find each corner and the width/height of it. need to fine tune model for more items as of now it doesnt know what to click and is only good at items in dataset and the full item not pieces of it.
devlog 2 fixxing ocr and double click cordinates. I realized that it wasnt a traing issue most of the time rather the ocr just sucks so i cropped the header to help. and i also had client side cordinates for the header so ocr was bugging i fixxed it by adjusting for its pov. same with click cordinates. also for some reason it clicks the same square twice to i decied to filter out over lapping classes to fix it using iou. it has improved the accuracy but still not as accurate as id like
Ships:
i made a captcha solver using yolo and pyautogui. one of the biggest challenges was compute, i don’t own a GPU so trying to run the model locally wasn’t possible but google collab was giving me issues even when tunnels worked sometimes it wouldn’t bind to port. I’m proud of how it turned out in the end not the most accurate project but a fun make. you’ll need to clone the project and put notebook into google collab or modify it for local use when the notebook works just copy the 1st link you see and paste it into the URL in the autocaptcha.py...
|
1793775035.6437886
|
1794639035.6437886
|
|
16160
|
Untitled by @Carlson | Stardance
|
Carlson
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @Carlson | Stardance
|
1793170182.2219524
|
1793774982.2219524
|
|
16161
|
The OASIS Of SECRETSS! by @Taneesh | Stardance
|
Taneesh
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: The OASIS Of SECRETSS! by @Taneesh | Starda Title: The OASIS Of SECRETSS! by @Taneesh | Stardance...
|
1793198889.0165775
|
1793803689.0165775
|
|
16162
|
My first slack bot! by @Jtylerneering | Stardance
|
Jtylerneering
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @Jtylerneering | Sta Title: My first slack bot! by @Jtylerneering | Stardance...
|
1793422101.799317
|
1794026901.799317
|
|
16163
|
My first slack bot! by @Kasel | Stardance
|
Kasel
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @Kasel | Stardance
|
1793271210.0952816
|
1793876010.0952816
|
|
16164
|
My awesome macropad! by @Katie_c | Stardance
|
Katie_c
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @Katie_c | Stardanc Title: My awesome macropad! by @Katie_c | Stardance...
|
1793458075.7441776
|
1794062875.7441776
|
|
16165
|
My first slack bot! by @Justin76 | Stardance
|
Justin76
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @Justin76 | Stardanc Title: My first slack bot! by @Justin76 | Stardance...
|
1793195560.1221135
|
1793800360.1221135
|
|
16166
|
My first slack bot! by @Coreyh | Stardance
|
Coreyh
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @Coreyh | Stardance
|
1793199091.5610895
|
1793803891.5610895
|
|
16167
|
My awesome macropad! by @aeisha974 | Stardance
|
aeisha974
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @aeisha974 | Starda Title: My awesome macropad! by @aeisha974 | Stardance...
|
1793202772.855705
|
1793807572.855705
|
|
16168
|
ChickenBot Slack Bot by @Adammm | Stardance
|
Adammm
|
1
|
2.27
|
4
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-12T23:44:39Z", "hours": 2.0, "multiplier": 2.15, "payout": 4, "blessing": "neutral", "text": "I made a slack bot The most complecated part was making it run 24/7. The best part of making this bot was intergrating AI gemini api into the bot so it is possible to talk with AI via the bot. Pls dm if any problems", "repo": "https://github.com/Halcyon28/ChcknBot", "demo": "https://hackclub.enterprise.slack.com/archives/C0BA54WCAGK"}]...
|
[{"post_id": 16125, "ts": "202 [{"post_id": 16125, "ts": "2026-06-26T06:52:57Z", "hours": 0.2667, "text": "Bug fixes"}, {"post_id": 7739, "ts": "2026-06-12T22:25:47Z", "hours": 0.8375, "text": "Adding gemini AI to the bot"}, {"post_id": 7046, "ts": "2026-06-11T20:16:03Z", "hours": 0.7906, "text": "test log"}]...
|
Title: ChickenBot Slack Bot by @Adammm | Stardance Title: ChickenBot Slack Bot by @Adammm | Stardance
Devlogs:
test log
Adding gemini AI to the bot
Bug fixes
Ships:
I made a slack bot The most complecated part was making it run 24/7. The best part of making this bot was intergrating AI gemini api into the bot so it is possible to talk with AI via the bot. Pls dm if any problems...
|
1793688880.555938
|
1793775280.555938
|
|
16169
|
My awesome macropad! by @marcusbauer77 | Stardance
|
marcusbauer77
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @marcusbauer77 | St Title: My awesome macropad! by @marcusbauer77 | Stardance...
|
1793216875.855342
|
1793821675.855342
|
|
16170
|
My very own WebOS by @andrew_behring26 | Stardance
|
andrew_behring26
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @andrew_behring26 | St Title: My very own WebOS by @andrew_behring26 | Stardance...
|
1793512504.4265218
|
1794117304.4265218
|
|
16171
|
My awesome macropad! by @ahmadsafi332011 | Stardan My awesome macropad! by @ahmadsafi332011 | Stardance...
|
ahmadsafi332011
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @ahmadsafi332011 | Title: My awesome macropad! by @ahmadsafi332011 | Stardance...
|
1793360974.6431417
|
1793965774.6431417
|
|
16172
|
My very own 'Pokedex' by @Sashish | Starda My very own 'Pokedex' by @Sashish | Stardance...
|
Sashish
|
1
|
3.0
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-19T21:28:49Z", "hours": 3.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Its as simple at it gets, a real life Pokedex. It works just as you would think, animal in frame, click scan and you have your identification. I learned a lot while making this, I am happy with how it turned out, I will continue to add more features. Please let me know if something does not work or is bugged.", "repo": "https://github.com/Cosmis-SS/stardance-webos", "demo": "https://stardance-webos-brown.vercel.app/"}]...
|
[{"post_id": 12154, "ts": "202 [{"post_id": 12154, "ts": "2026-06-19T21:06:44Z", "hours": 2.5864, "text": "The very very basics are now down, at least it will scan and identify the animal, next steps will mostly be to add a log animals the user has scanned!"}, {"post_id": 10398, "ts": "2026-06-17T02:42:06Z", "hours": 0.2928, "text": "Right now its a very basic and quick mock up for the UI of a IRL ‘Pokedex’ right now its for North American animals, later it will push into recognizing stars in the sky and etc."}]...
|
Title: My very own 'Pokedex' by @Sashish | Title: My very own 'Pokedex' by @Sashish | Stardance
Devlogs:
Right now its a very basic and quick mock up for the UI of a IRL ‘Pokedex’ right now its for North American animals, later it will push into recognizing stars in the sky and etc.
The very very basics are now down, at least it will scan and identify the animal, next steps will mostly be to add a log animals the user has scanned!
Ships:
Its as simple at it gets, a real life Pokedex. It works just as you would think, animal in frame, click scan and you have your identification. I learned a lot while making this, I am happy with how it turned out, I will continue to add more features. Please let me know if something does not work or is bugged....
|
1793721381.1556756
|
1793807781.1556756
|
|
16173
|
Inklyze by @phattar4phan | Stardance
|
phattar4phan
|
0
|
2.0
|
0
|
[]
|
[{"post_id": 9242, "ts": "2026 [{"post_id": 9242, "ts": "2026-06-15T14:58:17Z", "hours": 0.0, "text": "Configurations Have done many configurations and preparations on this project Also use Gemini to implement landing page, since I’m not native in tsx. and most frontend works Will have the labeling going on tomorrow but I’ve to learn the foundations for OCR first"}, {"post_id": 10015, "ts": "2026-06-16T15:39:21Z", "hours": 1.0, "text": "Modified project for more Add more dependencies and also resolved some (uv.lock, pyproject.toml) Modify .gitignore to filtered more unnecessary files and directories Add kaggle downloader to automatically download and handle dataset downloading and cleaning (utils/kaggledl.py) Add version validator, just check if it’s correct version and usable (scripts/validation.py)"}, {"post_id": 10697, "ts": "2026-06-17T15:46:23Z", "hours": 0.0, "text": "Modify README.md: documentation That’s all for today, I will be doing more specific in fine-tuning OCR recognition model, I will use PPOCRv5_server_rec (server has more accuracy than mobile as cited on paddleocr.ai)"}, {"post_id": 11653, "ts": "2026-06-19T00:07:36Z", "hours": 0.0, "text": "Not doing much to day just modify some configurations and also rename a directory. Also config cloudflare deployment and merge to production"}, {"post_id": 12687, "ts": "2026-06-20T18:43:13Z", "hours": 1.0, "text": "More progress on fine tuning- done some configurations and also kaggle datasets handler and downloader and also images labeling"}]...
|
Title: Inklyze by @phattar4phan | Stardance
Devlo Title: Inklyze by @phattar4phan | Stardance
Devlogs:
More progress on fine tuning- done some configurations and also kaggle datasets handler and downloader and also images labeling
Not doing much to day just modify some configurations and also rename a directory. Also config cloudflare deployment and merge to production
Modify README.md: documentation That’s all for today, I will be doing more specific in fine-tuning OCR recognition model, I will use PPOCRv5_server_rec (server has more accuracy than mobile as cited on paddleocr.ai)
Modified project for more Add more dependencies and also resolved some (uv.lock, pyproject.toml) Modify .gitignore to filtered more unnecessary files and directories Add kaggle downloader to automatically download and handle dataset downloading and cleaning (utils/kaggledl.py) Add version validator, just check if it’s correct version and usable (scripts/validation.py)
Configurations Have done many configurations and preparations on this project Also use Gemini to implement landing page, since I’m not native in tsx. and most frontend works Will have the labeling going on tomorrow but I’ve to learn the foundations for OCR first...
|
1792932850.330388
|
1793796850.330388
|
|
16174
|
Untitled project by @quantum056 | Stardance
|
quantum056
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @quantum056 | Stardance
|
1793437008.5958478
|
1794041808.5958478
|
|
16175
|
My very own WebOS by @Lashika | Stardance
|
Lashika
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @Lashika | Stardance
|
1793195279.7745383
|
1793800079.7745383
|
|
16176
|
Cursor Convertor by @flummoxed | Stardance
|
flummoxed
|
0
|
1.72
|
0
|
[]
|
[{"post_id": 6974, "ts": "2026 [{"post_id": 6974, "ts": "2026-06-11T18:17:50Z", "hours": 1.2183, "text": "Devlog #2: Successfully got .ani hotspot value To read the .ani file, I had to go through a lot of trouble. .ani files are binary files, which means a a weird amount of struggle regarding reading them. And it’s not as simple as reading a .cur file, since .ani files are dynamic in their number of bytes. After fighting the internet for an ani-file parser, and a LOT of struggle with that ani-file library… being outdated… I went in and edited the issues with the ani-file library, still struggled to get it working… and gave up eventually. I resorted to Gemini to help me debug the issue. Got it working finally! A little note: did have to fight the AI as well to get it to work… but here it is! Now I have hotspot values for both .cur and .ani cursors… and the hard part is done I believe. (I hope I didn’t jinx myself…)"}, {"post_id": 6615, "ts": "2026-06-11T03:04:15Z", "hours": 0.4975, "text": "Devlog #1: Began writing a program to convert Windows cursors into usable Mac cursors Here we go. I’ve been quite irritated at the inability to find cursors that run with Mousecape, a program built to change your cursor for mac. Most are built for Windows, which is easier to put in custom cursors with. I believe this has been done by some other people; however they didn’t work… perhaps due to my human error, so I thought it would be a good idea just… to build it myself. End goal is to make a website or app of some sorts to make it really easy. A lot of research was required to start this one off. I had to do some research into .inf files (these help download .cur & .ani files into Windows systems) and .cape files (which are how Mousecape cursors are stored). Now, the difference between .cur files and normal .png files is that .cur files store an additional value (a hotspot value, which tells at what exact point the cursor can click? That’s the best explanation I have right now). And to get this value, you need to parse through the binary file of a .cur file to specific bytes. Through those specific bytes (stored as these funny little things called little-endian numbers (?)) we get our x and y value of the hotspot. With this predetermined value set by the author of the cursorpack, I can now place that directly into the .cape value. Less hassle for the user! With all of that out of the way, let me succinctly write what I have accomplished here: Wrote a Python script to get the values of the cursor hotspot from a .cur value, by taking the byte data and converting them into integers. Now, there was some struggle in getting .ani cursors (animated cursors!) to do the same thing (as you can see), and I haven’t exactly figured out what byte data things I need to do with that. (More research… I suppose :/) My next step tomorrow is to figure that out. Point is, that I got the .cur file to give me what I need. (I am quite aware of the rambling here, it is late and I will edit this log tomorrow.)"}]...
|
Title: Cursor Convertor by @flummoxed | Stardance
Title: Cursor Convertor by @flummoxed | Stardance
Devlogs:
Devlog #1: Began writing a program to convert Windows cursors into usable Mac cursors Here we go. I’ve been quite irritated at the inability to find cursors that run with Mousecape, a program built to change your cursor for mac. Most are built for Windows, which is easier to put in custom cursors with. I believe this has been done by some other people; however they didn’t work… perhaps due to my human error, so I thought it would be a good idea just… to build it myself. End goal is to make a website or app of some sorts to make it really easy. A lot of research was required to start this one off. I had to do some research into .inf files (these help download .cur & .ani files into Windows systems) and .cape files (which are how Mousecape cursors are stored). Now, the difference between .cur files and normal .png files is that .cur files store an additional value (a hotspot value, which tells at what exact point the cursor can click? That’s the best explanation I have right now). And to get this value, you need to parse through the binary file of a .cur file to specific bytes. Through those specific bytes (stored as these funny little things called little-endian numbers (?)) we get our x and y value of the hotspot. With this predetermined value set by the author of the cursorpack, I can now place that directly into the .cape value. Less hassle for the user! With all of that out of the way, let me succinctly write what I have accomplished here: Wrote a Python script to get the values of the cursor hotspot from a .cur value, by taking the byte data and converting them into integers. Now, there was some struggle in getting .ani cursors (animated cursors!) to do the same thing (as you can see), and I haven’t exactly figured out what byte data things I need to do with that. (More research… I suppose :/) My next step tomorrow is to figure that out. Point is, that I got the .cur file to give me what I need. (I am quite aware of the rambling here, it is late and I will edit this log tomorrow.)
Devlog #2: Successfully got .ani hotspot value To read the .ani file, I had to go through a lot of trouble. .ani files are binary files, which means a a weird amount of struggle regarding reading them. And it’s not as simple as reading a .cur file, since .ani files are dynamic in their number of bytes. After fighting the internet for an ani-file parser, and a LOT of struggle with that ani-file library… being outdated… I went in and edited the issues with the ani-file library, still struggled to get it working… and gave up eventually. I resorted to Gemini to help me debug the issue. Got it working finally! A little note: did have to fight the AI as well to get it to work… but here it is! Now I have hotspot values for both .cur and .ani cursors… and the hard part is done I believe. (I hope I didn’t jinx myself…)...
|
1793505237.236414
|
1794110037.236414
|
|
16177
|
My awesome macropad! by @tienminh21109 | Stardance
|
tienminh21109
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @tienminh21109 | St Title: My awesome macropad! by @tienminh21109 | Stardance...
|
1793523385.1344304
|
1794128185.1344304
|
|
16178
|
Untitled by @bl | Stardance
|
bl
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled by @bl | Stardance
|
1793173860.0207853
|
1793778660.0207853
|
|
16179
|
Robotics RoboLens by @mira_j_maroni | Stardance
|
mira_j_maroni
|
2
|
140.27
|
26
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-07T22:22:22Z", "hours": 124.0, "multiplier": 16.83, "payout": 0, "blessing": "neutral", "text": "What did I make? Since Ship #1, RoboLens grew from one AI scanner into four connected tools. I added a rules checker that reads the actual FRC game manual (2024–2026) alongside your robot photo so it’s grounded in real rules instead of guessing. I built out a full shared battery tracker. I added a guided camera that walks you through lighting/tilt/framing and auto-captures once the angle looks right. And the biggest addition: a Team Stats & Match Center with four tabs (My Team, Stats, Events, Sim) pulling live data from The Blue Alliance and the FRC Events API, including a season-wide “World Rating,” a matchup simulator with win probabilities, and bookmarking teams to get real push notifications before their matches. I also spent a lot of time on stuff that doesn’t show up as a “feature” but makes the app actually usable: a queue + exponential backoff + retry system so the shared free-tier Gemini key doesn’t randomly fail scans under load, a report button that feeds recurring AI mistakes back into future scans, offline detection so scans fail fast instead of hanging, and a new instant-loading splash screen. What was challenging for me? The AI usage limits were the most persistent problem. Everyone shares one free-tier Gemini key, so scans would fail with no clear pattern whenever enough people hit it at once. I fixed it in stages: first a queue limiting in-flight requests, then automatic retries with backoff (and respecting the retry-after header when Gemini gave one), then finally surfacing that retry status to the user (“High demand. Retrying (2/3)…”) instead of just showing a dead spinner. The guided camera and push notifications both turned into whole rabbit holes of browser-specific pain (iOS Safari blocking camera/notification permissions unless triggered by a direct tap, no live frame streaming on web so I had to build a custom JS-interop layer from scratch, and push not working on iOS at all unless the site’s added to the home screen firs)t. My favorite bug story: the Match Center’s Events tab would spin forever with zero errors. I burned time adding timeouts and retries that did nothing before realizing the real issue. The spinner wasn’t stuck waiting on the network, it was stuck because nothing ever tried. What am I the most proud of? Going from a single-purpose AI scanner to four genuinely useful, connected tools without the codebase turning into spaghetti. I’m also proud that scans now degrade gracefully under load instead of just failing, and that notifications work reliably even though I had zero experience with service workers or VAPID keys before this. And honestly, just sticking with it. 21 devlogs and three months of real iteration based on actual user feedback instead of giving up. What should people know so they can test your project? Live app: https://mirage54321.github.io/RoboLens/ You can log in as a guest for team 4388 to browse batteries without needing an account. Push notifications currently work reliably on desktop browsers and Android (iOS Safari requires the site to be added to your home screen as a bookmark). You can test this by logging into -4388 (Yes, a negative. I needed a number that wouldn’t have a real team). The AI scan/rules tools need a robot photo to test against; if you don’t have one handy, any well-lit photo of mechanical/electrical components will still show you how the flow works.", "repo": "https://github.com/mirage54321/RoboLens", "demo": "https://mirage54321.github.io/RoboLens/"}, {"ship_num": 2, "ts": "2026-06-22T18:39:59Z", "hours": 5.0, "multiplier": 5.73, "payout": 26, "blessing": "neutral", "text": "I made an app for specifically robotics teams (although this could be used for other things too). This is still a work in progress because there is so much more I want to add. I did this project so that I could make something with an AI model and I’m really proud of myself because Flutter was really hard to work with!", "repo": "https://github.com/mirage54321/RoboLens", "demo": "https://mirage54321.github.io/RoboLens/"}]...
|
[{"post_id": 65393, "ts": "202 [{"post_id": 65393, "ts": "2026-09-10T14:37:50Z", "hours": 6.5575, "text": "Devlog #23 -> Fixed the camera disconnect crash from the feedback. Turns out the camera plugin doesn’t actually throw an error when the hardware gets yanked mid-session, it just quietly flips an internal hasError flag and keeps going. Which is why the app was crashing somewhere random instead of failing cleanly. Nothing in my code was listening for that flag, so it just kept trying to read frames and capture photos off a dead controller. Fixed it by adding a listener that actually watches for that error state, cleans everything up, and drops the user onto a proper “Camera disconnected, try again” screen instead of freezing or throwing. Also fixed the retry logic after a failed capture so it doesn’t try to restart a stream on a controller that’s already dead. Next up: the cursor. Someone pointed that out, because every button on web just shows the default arrow. Live app: https://mirage54321.github.io/RoboLens/a"}, {"post_id": 64602, "ts": "2026-09-09T03:43:12Z", "hours": 4.7133, "text": "Devlog #22 -> I was looking at the comments people left me from my ship and the first thing I noticed that I should work on is the load-in page. It is definitely kind of plain. To be honest, I used Claude to help a lot with this one. Making the spinning circle was pretty easy but I had some complex ideas I wanted to put to work and I just didn’t know how to do it. It has a huge radar that has the colors pop up and says “scounting __ teams”. Overall, I am so happy about this new design! Let me know what you guys think! I also added a folder for the photos so it looks more organized! The next thing I plan to work on “loop crashes if the camera disconnects” comment. Live app: https://mirage54321.github.io/RoboLens/"}, {"post_id": 63881, "ts": "2026-09-07T21:41:15Z", "hours": 2.065, "text": "Updates!!! Basically, I’ve been checking to see how many users and views I have. I have google analytics on my project to keep an eye on it. Right now I have 52 users and 163 views. Which honestly, I am pretty dang happy about. (1) I haven’t really been advertising (2) I literally thought it was gonna be like 20 views Woop woop! Okay, now on these past few days I have been working on getting as many hours as possible. I don’t have a personal computer so I am really aiming for literally any of the laptops. Now, programatically I have been working on removing the 3 burst messages for iPhone (it wouldn’t compact itself on the Apple homescreen). FYI: 90% of the time for this was spent removing the 3 burst messages for iPhone and writing Ship #2… so you better be ready for Ship 2! View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 63811, "ts": "2026-09-07T19:35:43Z", "hours": 0.7911, "text": "Notifications are working again! Basically, the rebuilding of Render helped fix the issue which is kind of ragebait. I’m getting a little nervous though because I wonder what happens if someone doesn’t reopen the bookmark (because that is how it resets). Would they still get the messages? Will it update automatically? Overall, it works great. I just worry there may be an error that arises (that is a risk with any project honestly). View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 63771, "ts": "2026-09-07T18:47:23Z", "hours": 5.1583, "text": "Devlog #19 -> I know I just committed a bunch the last few days. I guess I realized there is only a few days left and I found how to be way more efficent in getting hours. If I just keep this open and something else on another computer and work with them kinda being different windows then I get a lot more time because the switching of windows in the same computer made me keep forgetting to come back and work on the project (and I’m guessing was cutting the time too). Anywho! The most recent changes I have made is removing the ? mark button. I think I was going for a like “about me” thing but I think it was a little redundant and kind of unneccessary to say the least. I added a report button instead (it’s just in the home page). I got this idea from lovable which was something I worked with during my internship. I highkey have been working so much on this project (you can see by all my hours) that I didn’t want to connect it to the backend. It is just a popout that takes you to an gmail link and you can click send. Maybe if I run out of ideas I can add it as a backend. Now, if I am going to be so honest. I have worked a lot on this project and I want to ship but I also want to just crank out some more hours. I’m extremely proud of this project and I need to get it out to the world so that I can get some users! My issues to work on are: Low MongoDB storage for free account Professionalizing (now just looking back over and seeing if there is anything I wanna fix before putting on chief delphi) View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 63405, "ts": "2026-09-07T07:05:48Z", "hours": 8.2653, "text": "Devlog #18 -> Okay, super short devlog just to explain what I am doing. Basically all my hours are spent on fixing the notifications. It is super annoying right now because I am trying to finalize my project and the notifications randomly stop working. I tried clearing out mongoDB and checking on my cron-job and those seem to be working just fine. I’m not sure what to do. I pushed the hours up (for the practice day so I can check it earlier) and redeployed with Render. I shall see tomorrow if it works. View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 62347, "ts": "2026-09-05T17:45:39Z", "hours": 8.4539, "text": "Devlog #17 -> Part 3, wrapping this one up Last piece was making the retrying actually visible instead of just quietly happening in the background. Before, if a scan was retrying you’d just stare at a spinner with no idea what was going on. Now the loading screen updates to say something like “High demand. Retrying (2/3)…” so people know the app hasn’t frozen, it’s just waiting its turn. Between the queueing, the backoff retries on both ends, and this messaging, this should turn a lot of what used to be “scan failed, try again” moments into just a few extra seconds of waiting instead. Doesn’t make the free tier limit go away entirely, but it’s a big improvement over what I had. Current problems / what’s next: Low MongoDB storage for free account Professionalizing (before putting on Chief Delphi)"}, {"post_id": 61646, "ts": "2026-09-04T17:29:48Z", "hours": 9.4403, "text": "Devlog #16 -> Part 2, continuing from #15 Got retries working on top of the queue from last time. If Gemini comes back with a 429 (rate limited) or 503 (overloaded) instead of an actual answer, the backend now waits and tries again automatically, using exponential backoff (2s, then 4s, then 8s) instead of hammering it again right away, up to a few attempts before it actually gives up and reports failure. It also checks for a retry-after header first and uses that instead of the backoff timer if Gemini actually tells us how long to wait. Then I mirrored the same idea on the Flutter side, so if the backend’s retries still aren’t enough, the app itself will retry the whole request a couple more times before showing the user an error."}, {"post_id": 60875, "ts": "2026-09-03T14:59:25Z", "hours": 12.3994, "text": "Devlog #15 -> Part 1 (still working on this one!) Finally started actually tackling the AI usage limit problem from devlog #2. Since everyone using the app shares the same free-tier Gemini key, scans would just randomly fail with no real pattern whenever enough people were hitting it at once. Started on the backend side first: instead of letting every incoming scan hit Gemini immediately, I added a little queue that only lets 2 requests be in-flight to Gemini at a time, and everything else waits its turn. Next step is getting it to actually retry instead of just failing after the wait, but that’s for the next devlog."}, {"post_id": 60344, "ts": "2026-09-02T16:57:27Z", "hours": 7.4197, "text": "Devlog #14 -> Part 5 of 5 Finally! This final devlog is about the small tweaks I made in the app. I made it have a new photo Small one, just swapped out one of the app’s images for something more current since the old one was from way back in devlog #1 and didn’t really represent what the app looks like anymore. Nothing technical here, just housekeeping. It kinda works offline I say “kinda” because this isn’t a real offline mode where you can browse cached data with no internet, it’s more like the app now knows when it’s offline and fails fast instead of just hanging. Basically, I added a ConnectivityCheck helper that on web reads navigator.onLine (a free, instant, synchronous browser check for whether the device has a network interface up) so if you’re in airplane mode or your wifi is off, the AI scan screens can immediately say “can’t use this when offline” instead of sitting there for a full request timeout before failing. On native platforms there’s no real equivalent without pulling in a whole new plugin like connectivity_plus, so I just made the stub always report “online” there — an actually-offline phone still gets caught by the AI request’s own timeout/retry handling, just without the instant fail I get on web. One thing worth noting: this only checks if the device thinks it has a network connection, not whether that network actually has working internet behind it. So a wifi network that’s connected but dead will still say “online” here. That case still gets caught eventually, just the slower way through the request timeout instead of instantly. Good enough for now though, this was mostly about killing the most common case of someone trying to scan with their phone in airplane mode and just watching the app hang. I changed the load in screen Went back and reworked the loading screen from devlog #5. It’s now a plain CSS screen sitting directly in index.html instead of living inside the Flutter app itself, which means it can actually paint the instant the page loads, before Flutter has even finished downloading and booting up. That was the whole point: the old version technically only appeared once Flutter itself was far enough along to render it, so there was still a blank/white flash before it. Now there’s a little animated wordmark and spinner (the spinner’s colored arc cycles through the same colors as the logo letters) that fades out and removes itself once Flutter fires its first real frame. While I was in there I also fixed something unrelated but annoying: Flutter’s web service worker by default waits to activate a new version until every open instance of the app is fully closed, which for something people add to their home screen basically never happens naturally. So people could keep opening an old cached version of the app for a long time after I’d pushed updates. Added a bit of JS to force any newly installed service worker to skip that wait and take over immediately (reloading the page once it does), so the next time someone opens the app after I ship something, they actually get it. And that’s it, I’m all caught up! Five devlogs in one sitting was a lot, but future updates should go back to being posted as I actually build them instead of in one giant backlog dump. Current problems / what’s next: Low MongoDB storage for free account Releasing the app (onto chief delphi to get feedback)!! Making it ready to release (working on the ? and report button) Future ideas: team tracker, public chat for teams, judging/interview prep tool, callout tool, round robin generator View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 59335, "ts": "2026-09-01T02:11:53Z", "hours": 9.7772, "text": "Devlog #13 -> Part 4 of 5 Continuing from #12: more on the match center, mostly the stuff that actually broke on me. Biggest bug of the bunch: on the Events tab, tapping into an event was supposed to show “scheduled to attend” info and the competing teams list, but both of those sections would just spin forever, no error, nothing. I assumed it was a network timing issue at first and went down a whole rabbit hole adding timeouts and retry logic that did absolutely nothing. Turns out the actual problem was way dumber: when I pushed the EventDetailScreen with Navigator.push, that screen gets placed in the Overlay as a sibling of the tab tree, not a child of it, meaning it’s NOT under my MatchScope anymore. So the second that screen tried to call MatchScope.of(context), it threw an assertion error immediately, before initState even got the chance to call setState and load anything. The spinner wasn’t stuck because of a slow network, it was stuck because the load call never even ran. Fixed it by just re-wrapping the pushed route in its own MatchScope using the same controller instance. Felt very silly once I found it, but also weirdly satisfying to finally understand. Next was the matchup simulator and win probabilities. On the schedule screen I show a rough “Red 45% / Blue 55%” prediction for each match. My first instinct was to use each event’s own OPR for this, but that falls apart for upcoming events since OPR doesn’t exist until a team has actually played a match there. So instead I based predictions on the season-wide World Rating from the Stats tab (average points across every event a team’s played all season), which actually gives predictions even for a event that hasn’t started yet. Also went back and hooked the push notification bell (from devlog #11) directly into the match center’s top bar now that there’s finally a “your team” + “your event” to actually attach a subscription to. There’s a little pulsing glow animation on the bell the first time you land on a screen where you could enable alerts, just so people notice it’s there instead of it blending into the top bar. Took way too many attempts to get the glow animation timing feeling smooth and not epileptic-seizure-inducing, but I think I landed on something decent. Genuinely didn’t expect the 4th app to take this many devlogs but here we are. One more to wrap up some small stuff and then I think I’m caught up! View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 58655, "ts": "2026-08-31T04:34:12Z", "hours": 9.4486, "text": "Devlog #12 -> Part 3 of 5 Okay, actual 4th app time: Team Stats & Match Center (internally I’ve just been calling it “match” in the code, so if you dig around the file names that’s why). I started by mocking everything out before touching any real API, just so I could get the UI feeling right first. Made an intro screen (basically pitching the three features: match alerts, team stats, matchup simulator) and a fake mockTeams list with made-up EPA numbers just so I had something to look at while building. Once the layout felt right, I started swapping the fake data for real stuff from The Blue Alliance’s API, proxied through my backend the same way I already had set up for the FRC Events API (so I’m not spamming TBA directly from a bunch of client apps and to keep my API key private). Architecture-wise, I did something different from my other three apps: instead of passing state down through a million constructor params, I made a MatchDataController (basically one class holding all the team/event/match data + loading state) and wrapped the whole feature in a MatchScope, which is just an InheritedNotifier. So anywhere in the match center I can just call MatchScope.of(context) and get the controller without threading it through every single widget. Probably overkill for how big this feature ended up being, but once I had 4 tabs and a handful of sub-screens all needing the same data, I was really glad I did it this way instead of my usual pass-everything-into-the-constructor approach. Speaking of tabs, I split it into 4: My Team -> your team’s own info/next match Stats -> a season-wide “World Rating” I calculate from aggregating TBA’s OPR data across events (this was its own whole thing, might do a separate devlog on it someday) Events -> browse every FRC event, filter by time or location, see who’s live right now Sim -> the matchup simulator I keep promising Getting match data to actually parse right from TBA’s JSON took a minute (comp levels like qm/qf/sf/f needed their own label logic, predicted_time vs actual_time needed fallback logic since actual_time barely ever gets posted until after the match is already over, that kind of thing) but nothing too crazy, just tedious model-writing. Devlog #13 is basically a straight continuation of this one, mostly bug stories and the simulator, so be ready for that. View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 55760, "ts": "2026-08-27T19:05:53Z", "hours": 4.8611, "text": "Devlog #11 -> Part 2 of 5 Now for the second devlog, I am going to talk about how I got notifications to work. This is the one that ate my week. So the goal: when a match is coming up for a team you bookmarked, get a push notification even if the app/tab isn’t open. That last part is the whole problem, because it means I can’t just pop a normal in-app alert, I actually need real browser push notifications, which meant learning a whole new stack: service workers, VAPID keys, and the Push API. Here’s roughly how it works now ->Subscribe -> user picks a team number + event key, the app asks the browser for notification permission, and if granted it registers a push subscription through the service worker using my VAPID public key. Send to backend -> that subscription (plus team number/event key) gets sent to my Express backend and stored in MongoDB. Actually sending them -> the backend uses the web-push npm package to send the push whenever it detects a match coming up for that team. Getting the Flutter side to talk to any of this was its own adventure, since none of this exists as a nice Dart package, so I had to write a JS interop layer (basically a matchPush object in plain JS that Dart calls into) and wire it up through the same conditional-export trick I used for the guided camera: one file for web, one stub file that just says “unsupported” for native, so the app doesn’t explode on phone builds while I haven’t built native push yet. Problems I ran into (there were many) ->iOS Safari straight up does not support web push at all unless the site has been added to the home screen first. So right now notifications basically only work reliably on desktop browsers and Android, and I have to eventually explain that to iOS users somehow. Permission requests have the same “must be triggered by a direct tap” rule I fought with on the guided camera, so subscribing has to happen from an actual button press, no auto-subscribing on load. Debugging this was rough because half the errors happen silently in the service worker, not in the normal Flutter console, so I was stuck adding console.logs into push.js and checking devtools like a caveman for a while.It works now though! Bookmark a team, subscribe, and you’ll get pinged. Native (phone-installed) push notifications are still a “later” problem since that needs a totally different setup (probably Firebase Cloud Messaging), so for now the stub just returns unsupported on native and I’m keeping my scope to web. Two devlogs about the 4th app itself coming up next, promise. View it here: https://mirage54321.github.io/RoboLens/ P.S. For right now there are 3 notifications that send for iOS I plan to change that though!"}, {"post_id": 54198, "ts": "2026-08-25T02:42:40Z", "hours": 8.6025, "text": "Devlog #10 -> Part 1 of 5 Please don’t hurt me, but I have to post multiple devlogs because I worked on so many things in all this time. It’s a lot of stuff to talk about and I don’t want to write it all into one because it will be super unorganized and hard for me to find in the future. In this first devlog, I am going to talk about how I got bookmarks to work. The idea came from thinking ahead to the match notifier. If someone wants alerts for a match, they need a way to say “these are the teams I care about” without having to retype a team number every single time. So I added a bookmark system using shared_preferences (just storing a list of team numbers locally on the device/browser). You can now star a team from a few places in the app and it’ll save to your bookmarks list, which I’m planning to hook the notifier into so it can just loop through your saved teams instead of asking you every time. This one was honestly pretty painless compared to my usual chaos. The only annoying part was making sure the bookmarked list actually persisted correctly on web (learned my lesson from the MongoDB flutter-web thing, so I tested this one on both platforms before moving on lol). Turns out shared_preferences just works with local storage under the hood on web, so no weird surprises this time. Short devlog, I know, but wait till you see what devlog #11 turned into. View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 49268, "ts": "2026-08-17T23:33:09Z", "hours": 6.1139, "text": "Devlog #9 -> Okay, so getting the report button to work was a little finicky. I wasn’t sure what approach to take: I could make it easy by just sending me the reported things and I could look at them and just change the prompt, or I could make it difficult by just feeding every single reported issue back into the AI model so that the AI tries to not make the same mistake (which might be a problem because someone could report something that was actually right), or make it VERY difficult make it feed back into the AI if a similar issues were coming up again and again. Guess which one I chose? Yup, the third. Basically, I decided to store the reports in MongoDB and look for recurring mistakes instead of letting a single report change the AI. That way, if one person reports something incorrectly, it doesn’t immediately affect everyone else’s scans. If the same type of mistake keeps getting reported, I can investigate it and use those reports to improve the AI.This seems really complex, and it was. It took me 4 hours (it says 6 on the devlog but 2 of them was working on the 4th app). Alright, ready for my fourth widget idea………. a match notifier!! Now don’t get too excited. I have more to tell. So, every FRC kid knows that there’s a website called Nexus that sends messages for when your game is going to start so you can get in queue, and it works really well. There’s also this thing I came across called statbotics, and it calculates many things like EPA, and more (I didn’t really stay on that website for too long). So, what I plan to do is combine them. Hopefully, I’m not getting myself into too much of a challenge. This will most definitely be the hardest thing I have ever done on this app. Wish me luck! P.S. I started making the fourth widget before the report button then switched to finish the report button halfway so if you see my commits in a confusing order that’s why. View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 43541, "ts": "2026-08-08T21:26:06Z", "hours": 0.3608, "text": "Devlog #8 -> Part 2/2 (part 2 of this devlog) I also posted my app onto reddit (r/FRC) and got some feedback. From the feedback, I got the message that an AI scanner can’t be all that reliable/useful without a user-end customization. I totally agree with this. The problem is that I’m not sure if it is worth it to spend time on adding in customization tools for the AI as there is not a lot of return from it. Therefore, I think that right now the AI’s are at the best product they can be as of now (besides adding functionality to the report button). So, my time would be better spent adding in more apps into the app. On the bright side, there were lots of positive reviews about the battery section! I am now going to work on the report button for the UI because I think it will take less time to add than adding a fourth app. In my next post, I will have a confirmed idea for the fourth app! Things to work on: Low MongoDB storage for free account Report button on the UI needs to feed into the AI ⭐ (Going to do this first because it is easier) Find solution for Render (takes a long time to power on and first time you try to do anything it always fails) Adding fourth ‘app’ ⭐⭐ View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 43529, "ts": "2026-08-08T21:02:52Z", "hours": 6.3211, "text": "Devlog #7 -> Part 2/2 (but part 1 of this devlog) Okay. This was very annoying to work on because every single time I would edit the code, I would have to recommit in order to see it on the github pages (because the permissions wouldn’t work on the flutter web-server). So, getting the guided camera working on web brought a whole lot of browser-specific issues that don’t show up on native mobile. First, the app would hang on a black loading screen because permission_handler and frame streaming aren’t supported in browsers. I then fixed that by branching on kIsWeb to skip those native-only calls and let the browser’s own getUserMedia prompt handle camera access instead.Next, iOS Safari blocked the camera request outright because it requires permission calls to fire directly from a user tap with no delay -> solved by gating the whole flow behind an explicit “Enable Camera” button instead of auto-starting on page load. Since camera_web doesn’t support live frame streaming and sensors_plus doesn’t handle iOS’s motion permission prompt, live guidance (tilt, brightness, sharpness) had to be rebuilt from scratch for web: a custom JS-interop layer (WebProbe) draws each video frame onto a hidden canvas to sample brightness/sharpness, and separately requests iOS’s DeviceMotionEvent permission to read tilt.That introduced two more subtle bugs (a Dart generics issue causing a null-cast crash in the interop code, and a timing issue where the element wasn’t in the DOM yet when we went looking for it) both fixed with explicit type arguments and a retry loop. With all of that sorted, the guided camera now works consistently across native and web, with live tilt/lighting/sharpness feedback and autocapture. View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 37868, "ts": "2026-07-30T20:50:16Z", "hours": 4.4522, "text": "Devlog #6 -> Part 1/2 Hey! I know it has been awhile since I worked on my project (adding the guided camera has been taking a lot of will power), but I have a new update. I have added the guided camera to the scan screen (which I will add to the rules screen too after it is finished). The process that the guided camera uses is: Startup -> requests camera permission immediately for phone usage (permission_handler) or waits for a tap on “Enable Camera” first for browser usage. Camera setup -> fetches available cameras (from Flutter’s camera plugin), picks the back-facing one (falls back to the first available camera on the device if no back camera is found), sets resolution to high on phone or medium on browser (since browsers often reject high-res requests), then calls initialize() to start the live preview. Manual fallback for taking photos -> the shutter button is always available to captures the photo; this is the primary method right now. Capture -> stops the frame stream (phone only), takes the picture, reads the bytes, then returns them to the previous screen via Navigator.pop(context, bytes). An issue I ran into was camera permissions on iPhone Safari. It worked fine on my laptop but wouldn’t work on my phone. I eventually figured out that iPhones are notorious for always requiring explicit permission prompts, so I solved it by requiring the camera request to be triggered by a direct user tap. Basically, I added an “Enable Camera” button on web that only calls the camera setup when tapped, since iOS Safari silently blocks getUserMedia (instead of showing an error) if there’s any delay between the tap and the request. Now I am working on the flutter comments (“too dark”, “focus”, etc.) because right now those aren’t working. Once I get the live guidance to work, then I will be able to implement an auto-capture (that way the photo is taken when at a good angle). View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 29717, "ts": "2026-07-16T20:11:47Z", "hours": 4.3139, "text": "Devlog #5 -> My app now has a load in screen! Yay! I figured it was necessary just to make my whole app look more professional. It was pretty easy (took lots of time though) to add and I didn’t fall into any huge difficulties. Only a mini one because I tried to make the animation in the home screen class and it got chaotic. Once it was its own file it was quite easy because then I just needed to fix up the UI. Look here if you want to learn more about how to do animations in your own project (if using Flutter): https://docs.flutter.dev/ui/animations I also added a very tiny change to the error message for logging in. Instead of saying “Team already registered”, it tells you to contact my email if you cannot access your team. I guess I got really nervous that someone would try to access their team, and if they couldn’t, they would go and put another team’s number and so on indefinitely. Right now, I think this is a good way to fix the issue, but I’ll add a way to report it in the app; that way, the issue can be solved quicker, and you won’t have to send an email to someone. I did have the idea to make it so there is identification of some sort for each team; however, that would just make the app complex, and my whole goal was to have a simple solution to problems. So, if this app actually does really well in the FRC world, I will add some sort of verification; that way lost accounts can be found, and it would just give all-around easier access. Next, I am going to focus on my long put off task: photo to video. I am not sure how I am going to do this, if I am going to be so honest. My idea for it came fom the Smile Doctors invisalign app where it opens up your camera and tells you things like “go to better lighting” or “move to the left”. However, I think that will be super complex and difficult to implement so I might have to start a lot smaller. Best of luck to myself, I guess! List of current tasks: Low MongoDB storage for free account Report button on the UI needs to feed into the AI ⭐ Find solution for Render (takes a long time to power on and first time you try to do anything it always fails) Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) ⭐⭐ View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 28023, "ts": "2026-07-14T00:50:11Z", "hours": 4.6822, "text": "Devlog #4 -> Hey! I have been working on the issues I talked about in my last devlog. So far I have successfully solved one: How I solved “Connenction to MongoDB working for flutter web but not github?” -> The issue was that GitHub Pages is a static hosting service and couldn’t connect directly to MongoDB. Therefore I had to update the application so the GitHub Pages frontend communicates with the Express backend on Render. Basically, I just modified some of the backend configuration like changing (in very very simple terms): fetch(‘/battery’) to something like fetch(‘ https://ridgeboticsapp.onrender.com/battery ’). I also added a ? mark button so that if clicked on it can tell you a little more about the app. Right now, it is just saying some basic things but I plan to show this app to my friends and see what they think I should add to that text in order to help people figure out what is going on if they just found my app. Finally, I fixed an error I wasn’t even aware of: the name finder for each teams batteries. I made it so when you sign up your team, it will try to search up the team name with that FRC number. However, there would be times where I would sign in as my team and it would show up with some random name like “Robo-Knights” or something weird. I think this was related to the Gemini model because I had used it while testing, soincorrect team names could have been stored and reused instead of being verified. To fix this, I connected my backend to the official FRC Events API. Now, the app sends the team’s FRC number to FIRST to retrieve the official team information to then save the verified team name. This prevents teams from accidentally being assigned another team’s name and makes sure the battery data is connected to the correct FRC team. It was never too big of an issue because I could always just edit the names in MongoDB but having it so it says the name right 100% of the time is just much easier for me. Now my new top things to work on are: If team is signed up but you don’t have access to your team Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) Report button working better to fix the AI’s findings View it here: https://mirage54321.github.io/RoboLens/ P.S. If you are trying things out you can sign in as a guest for 4388 and see my teams batteries"}, {"post_id": 24928, "ts": "2026-07-08T20:05:31Z", "hours": 1.5633, "text": "Devlog #3 -> In the past few days I have been working on adding a battery tracker because I believe that it has the potential to be very helpful to FRC teams. Tracking batteries is always a pain for my team, and other teams I’ve connected with can probably agree with that statement. Batteries can randomly fail by not charging or just full-on dying in two minutes. Although one might assume that keeping track of all this is easy, it truly is not. Having a system to hold records and data, I believe, can be very helpful to teams! I’ve added the third tool to the app: a shared battery tracker where a team can log in with a team number and passcode, add batteries, and mark each one as charging, in use, or available. It also lets you flag a battery as weak or unreliable with a note, so if a battery dies mid-match, the whole team can see that history the next time they’re deciding which one to grab. I even added an option for the AI to recommend which battery to use next based on how long it’s been charged and whether it’s been flagged before. My new challenge for this tool has been working with MongoDB. It stores the data fine, but it wasn’t letting me log in (it kept throwing an error). What confused me more is that when I ran it in Flutter web, it worked just fine. This is what I plan to work on for the next few days. To fix my last problem, which was with the AI saying it had spikes in usage, I changed the message to ask the user to try again because it usually works on the try right after. Right now, this is just a temporary solution until I can find a new AI model. List of things to work on: Low MongoDB storage for free account Report button on the UI needs to feed into the AI Find permanant solution for the AI usage Connenction to MongoDB working for flutter web but not github? Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) View it here: https://mirage54321.github.io/RoboLens/ Log in as guest for team 4388 if you just want to view it. P.S. My logged time is glitching out a bunch and I would love if someone could help me in the #stardance-help on slack."}, {"post_id": 23707, "ts": "2026-07-06T20:19:01Z", "hours": 9.0781, "text": "Devlog #2-> Now that I’ve finished the foundation of my project, I can keep adding tools! On my last ship, I realized I should keep more documentation. So be ready for more devlogs going forward! To get a little more comfortable with what I’m doing, I decided to add another AI scanning tool that I have been thinking about: a rules checker. The general scanner already looked for physical problems like wiring and cracks, but I wanted something that could actually check a robot against the official FRC rulebook. So I added the actual PDFs of past FRC game manuals (2024, 2025, and 2026) and let the user pick which season’s rules to check against. That PDF gets fed into the AI alongside the photo, so instead of relying on whatever general FRC knowledge the model already has (which could be outdated or made up), it’s reading the exact rulebook for that year while it looks at the image. Getting the PDF into the AI request in the first place took some figuring out. I had to load it from the app’s assets, converting it into a format the API would actually accept, and making sure it got sent alongside the image without breaking anything. Once it worked though, the difference was noticeable (the AI’s answers started actually referencing real rules instead of guesses). The bigger challenge was AI usage limits. Not “too many messages” though. Instead, it was more that other people using the same free model at the same time meant my requests were competing with everyone else’s. Half the time a scan would go through fine, and the other half it just wouldn’t, with no real pattern I could find. To fix this I… haven’t yet, honestly. Still an open problem :(. Hoping to hear from you guys for some ideas! I’m a little nervous because AI kind of has a negative connotation in FRC. To address that issue, I’m planning to make the whole app not centered around AI so I’ll be adding more tools. Excited to keep going though, because I just started programming my new idea: adding a battery tracker! View it here: https://mirage54321.github.io/RoboLens/"}, {"post_id": 13860, "ts": "2026-06-22T18:21:53Z", "hours": 4.63, "text": "Devlog #1-> I’ve finished the foundation of my project! The app currently has a simple UI and one AI tool that takes in a photo and tells you what’s wrong with it — whether it’s frayed wiring, loose screws, cracked/bent frames, or corrosion. Goal of my project: cut down the time it takes to find an issue so an FRC team has more time to actually fix the problem, and flag problems a human might miss during a rushed pit-stop check. Working with Flutter to program the UI wasn’t too bad. I’ve always been used to Java and JavaScript, so although Dart isn’t exactly the same, I picked it up pretty fast. I had the most difficulty implementing the AI. I started with an Ollama model, but it was way too slow — it would time out before it ever finished telling me what it noticed in the photo. I then found out Google lets you use a free Gemini model, so I got an API key for that and added it in. The new problem: every time I published my app as a GitHub Page, the API key would get disabled because it wasn’t safe sitting in client-side code. I finally learned the key needs to live on a backend to actually be secure, so I set one up using Render. I’m so proud of how my project is looking so far! Next up, I plan to add more tools, like a rules scanner."}]...
|
Title: Robotics RoboLens by @mira_j_maroni | Stard Title: Robotics RoboLens by @mira_j_maroni | Stardance
Devlogs:
Devlog #1-> I’ve finished the foundation of my project! The app currently has a simple UI and one AI tool that takes in a photo and tells you what’s wrong with it — whether it’s frayed wiring, loose screws, cracked/bent frames, or corrosion. Goal of my project: cut down the time it takes to find an issue so an FRC team has more time to actually fix the problem, and flag problems a human might miss during a rushed pit-stop check. Working with Flutter to program the UI wasn’t too bad. I’ve always been used to Java and JavaScript, so although Dart isn’t exactly the same, I picked it up pretty fast. I had the most difficulty implementing the AI. I started with an Ollama model, but it was way too slow — it would time out before it ever finished telling me what it noticed in the photo. I then found out Google lets you use a free Gemini model, so I got an API key for that and added it in. The new problem: every time I published my app as a GitHub Page, the API key would get disabled because it wasn’t safe sitting in client-side code. I finally learned the key needs to live on a backend to actually be secure, so I set one up using Render. I’m so proud of how my project is looking so far! Next up, I plan to add more tools, like a rules scanner.
Devlog #2-> Now that I’ve finished the foundation of my project, I can keep adding tools! On my last ship, I realized I should keep more documentation. So be ready for more devlogs going forward! To get a little more comfortable with what I’m doing, I decided to add another AI scanning tool that I have been thinking about: a rules checker. The general scanner already looked for physical problems like wiring and cracks, but I wanted something that could actually check a robot against the official FRC rulebook. So I added the actual PDFs of past FRC game manuals (2024, 2025, and 2026) and let the user pick which season’s rules to check against. That PDF gets fed into the AI alongside the photo, so instead of relying on whatever general FRC knowledge the model already has (which could be outdated or made up), it’s reading the exact rulebook for that year while it looks at the image. Getting the PDF into the AI request in the first place took some figuring out. I had to load it from the app’s assets, converting it into a format the API would actually accept, and making sure it got sent alongside the image without breaking anything. Once it worked though, the difference was noticeable (the AI’s answers started actually referencing real rules instead of guesses). The bigger challenge was AI usage limits. Not “too many messages” though. Instead, it was more that other people using the same free model at the same time meant my requests were competing with everyone else’s. Half the time a scan would go through fine, and the other half it just wouldn’t, with no real pattern I could find. To fix this I… haven’t yet, honestly. Still an open problem :(. Hoping to hear from you guys for some ideas! I’m a little nervous because AI kind of has a negative connotation in FRC. To address that issue, I’m planning to make the whole app not centered around AI so I’ll be adding more tools. Excited to keep going though, because I just started programming my new idea: adding a battery tracker! View it here: https://mirage54321.github.io/RoboLens/
Devlog #3 -> In the past few days I have been working on adding a battery tracker because I believe that it has the potential to be very helpful to FRC teams. Tracking batteries is always a pain for my team, and other teams I’ve connected with can probably agree with that statement. Batteries can randomly fail by not charging or just full-on dying in two minutes. Although one might assume that keeping track of all this is easy, it truly is not. Having a system to hold records and data, I believe, can be very helpful to teams! I’ve added the third tool to the app: a shared battery tracker where a team can log in with a team number and passcode, add batteries, and mark each one as charging, in use, or available. It also lets you flag a battery as weak or unreliable with a note, so if a battery dies mid-match, the whole team can see that history the next time they’re deciding which one to grab. I even added an option for the AI to recommend which battery to use next based on how long it’s been charged and whether it’s been flagged before. My new challenge for this tool has been working with MongoDB. It stores the data fine, but it wasn’t letting me log in (it kept throwing an error). What confused me more is that when I ran it in Flutter web, it worked just fine. This is what I plan to work on for the next few days. To fix my last problem, which was with the AI saying it had spikes in usage, I changed the message to ask the user to try again because it usually works on the try right after. Right now, this is just a temporary solution until I can find a new AI model. List of things to work on: Low MongoDB storage for free account Report button on the UI needs to feed into the AI Find permanant solution for the AI usage Connenction to MongoDB working for flutter web but not github? Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) View it here: https://mirage54321.github.io/RoboLens/ Log in as guest for team 4388 if you just want to view it. P.S. My logged time is glitching out a bunch and I would love if someone could help me in the #stardance-help on slack.
Devlog #4 -> Hey! I have been working on the issues I talked about in my last devlog. So far I have successfully solved one: How I solved “Connenction to MongoDB working for flutter web but not github?” -> The issue was that GitHub Pages is a static hosting service and couldn’t connect directly to MongoDB. Therefore I had to update the application so the GitHub Pages frontend communicates with the Express backend on Render. Basically, I just modified some of the backend configuration like changing (in very very simple terms): fetch(‘/battery’) to something like fetch(‘ https://ridgeboticsapp.onrender.com/battery ’). I also added a ? mark button so that if clicked on it can tell you a little more about the app. Right now, it is just saying some basic things but I plan to show this app to my friends and see what they think I should add to that text in order to help people figure out what is going on if they just found my app. Finally, I fixed an error I wasn’t even aware of: the name finder for each teams batteries. I made it so when you sign up your team, it will try to search up the team name with that FRC number. However, there would be times where I would sign in as my team and it would show up with some random name like “Robo-Knights” or something weird. I think this was related to the Gemini model because I had used it while testing, soincorrect team names could have been stored and reused instead of being verified. To fix this, I connected my backend to the official FRC Events API. Now, the app sends the team’s FRC number to FIRST to retrieve the official team information to then save the verified team name. This prevents teams from accidentally being assigned another team’s name and makes sure the battery data is connected to the correct FRC team. It was never too big of an issue because I could always just edit the names in MongoDB but having it so it says the name right 100% of the time is just much easier for me. Now my new top things to work on are: If team is signed up but you don’t have access to your team Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) Report button working better to fix the AI’s findings View it here: https://mirage54321.github.io/RoboLens/ P.S. If you are trying things out you can sign in as a guest for 4388 and see my teams batteries
Devlog #5 -> My app now has a load in screen! Yay! I figured it was necessary just to make my whole app look more professional. It was pretty easy (took lots of time though) to add and I didn’t fall into any huge difficulties. Only a mini one because I tried to make the animation in the home screen class and it got chaotic. Once it was its own file it was quite easy because then I just needed to fix up the UI. Look here if you want to learn more about how to do animations in your own project (if using Flutter): https://docs.flutter.dev/ui/animations I also added a very tiny change to the error message for logging in. Instead of saying “Team already registered”, it tells you to contact my email if you cannot access your team. I guess I got really nervous that someone would try to access their team, and if they couldn’t, they would go and put another team’s number and so on indefinitely. Right now, I think this is a good way to fix the issue, but I’ll add a way to report it in the app; that way, the issue can be solved quicker, and you won’t have to send an email to someone. I did have the idea to make it so there is identification of some sort for each team; however, that would just make the app complex, and my whole goal was to have a simple solution to problems. So, if this app actually does really well in the FRC world, I will add some sort of verification; that way lost accounts can be found, and it would just give all-around easier access. Next, I am going to focus on my long put off task: photo to video. I am not sure how I am going to do this, if I am going to be so honest. My idea for it came fom the Smile Doctors invisalign app where it opens up your camera and tells you things like “go to better lighting” or “move to the left”. However, I think that will be super complex and difficult to implement so I might have to start a lot smaller. Best of luck to myself, I guess! List of current tasks: Low MongoDB storage for free account Report button on the UI needs to feed into the AI ⭐ Find solution for Render (takes a long time to power on and first time you try to do anything it always fails) Photo to video (that way it can help you find the right orientation for the AI to scan with the best feedback possible) ⭐⭐ View it here: https://mirage54321.github.io/RoboLens/
Devlog #6 -> Part 1/2 Hey! I know it has been awhile since I worked on my project (adding the guided camera has been taking a lot of will power), but I have a new update. I have added the guided camera to the scan screen (which I will add to the rules screen too after it is finished). The process that the guided camera uses is: Startup -> requests camera permission immediately for phone usage (permission_handler) or waits for a tap on “Enable Camera” first for browser usage. Camera setup -> fetches available cameras (from Flutter’s camera plugin), picks the back-facing one (falls back to the first available camera on the device if no back camera is found), sets resolution to high on phone or medium on browser (since browsers often reject high-res requests), then calls initialize() to start the live preview. Manual fallback for taking photos -> the shutter button is always available to captures the photo; this is the primary method right now. Capture -> stops the frame stream (phone only), takes the picture, reads the bytes, then returns them to the previous screen via Navigator.pop(context, bytes). An issue I ran into was camera permissions on iPhone Safari. It worked fine on my laptop but wouldn’t work on my phone. I eventually figured out that iPhones are notorious for always requiring explicit permission prompts, so I solved it by requiring the camera request to be triggered by a direct user tap. Basically, I added an “Enable Camera” button on web that only calls the camera setup when tapped, since iOS Safari silently blocks getUserMedia (instead of showing an error) if there’s any delay between the tap and the request. Now I am working on the flutter comments (“too dark”, “focus”, etc.) because right now those aren’t working. Once I get the live guidance to work, then I will be able to implement an auto-capture (that way the photo is taken when at a good angle). View it here: https://mirage54321.github.io/RoboLens/
Devlog #7 -> Part 2/2 (but part 1 of this devlog) Okay. This was very annoying to work on because every single time I would edit the code, I would have to recommit in order to see it on the github pages (because the permissions wouldn’t work on the flutter web-server). So, getting the guided camera working on web brought a whole lot of browser-specific issues that don’t show up on native mobile. First, the app would hang on a black loading screen because permission_handler and frame streaming aren’t supported in browsers. I then fixed that by branching on kIsWeb to skip those native-only calls and let the browser’s own getUserMedia prompt handle camera access instead.Next, iOS Safari blocked the camera request outright because it requires permission calls to fire directly from a user tap with no delay -> solved by gating the whole flow behind an explicit “Enable Camera” button instead of auto-starting on page load. Since camera_web doesn’t support live frame streaming and sensors_plus doesn’t handle iOS’s motion permission prompt, live guidance (tilt, brightness, sharpness) had to be rebuilt from scratch for web: a custom JS-interop layer (WebProbe) draws each video frame onto a hidden canvas to sample brightness/sharpness, and separately requests iOS’s DeviceMotionEvent permission to read tilt.That introduced two more subtle bugs (a Dart generics issue causing a null-cast crash in the interop code, and a timing issue where the element wasn’t in the DOM yet when we went looking for it) both fixed with explicit type arguments and a retry loop. With all of that sorted, the guided camera now works consistently across native and web, with live tilt/lighting/sharpness feedback and autocapture. View it here: https://mirage54321.github.io/RoboLens/
Devlog #8 -> Part 2/2 (part 2 of this devlog) I also posted my app onto reddit (r/FRC) and got some feedback. From the feedback, I got the message that an AI scanner can’t be all that reliable/useful without a user-end customization. I totally agree with this. The problem is that I’m not sure if it is worth it to spend time on adding in customization tools for the AI as there is not a lot of return from it. Therefore, I think that right now the AI’s are at the best product they can be as of now (besides adding functionality to the report button). So, my time would be better spent adding in more apps into the app. On the bright side, there were lots of positive reviews about the battery section! I am now going to work on the report button for the UI because I think it will take less time to add than adding a fourth app. In my next post, I will have a confirmed idea for the fourth app! Things to work on: Low MongoDB storage for free account Report button on the UI needs to feed into the AI ⭐ (Going to do this first because it is easier) Find solution for Render (takes a long time to power on and first time you try to do anything it always fails) Adding fourth ‘app’ ⭐⭐ View it here: https://mirage54321.github.io/RoboLens/
Devlog #9 -> Okay, so getting the report button to work was a little finicky. I wasn’t sure what approach to take: I could make it easy by just sending me the reported things and I could look at them and just change the prompt, or I could make it difficult by just feeding every single reported issue back into the AI model so that the AI tries to not make the same mistake (which might be a problem because someone could report something that was actually right), or make it VERY difficult make it feed back into the AI if a similar issues were coming up again and again. Guess which one I chose? Yup, the third. Basically, I decided to store the reports in MongoDB and look for recurring mistakes instead of letting a single report change the AI. That way, if one person reports something incorrectly, it doesn’t immediately affect everyone else’s scans. If the same type of mistake keeps getting reported, I can investigate it and use those reports to improve the AI.This seems really complex, and it was. It took me 4 hours (it says 6 on the devlog but 2 of them was working on the 4th app). Alright, ready for my fourth widget idea………. a match notifier!! Now don’t get too excited. I have more to tell. So, every FRC kid knows that there’s a website called Nexus that sends messages for when your game is going to start so you can get in queue, and it works really well. There’s also this thing I came across called statbotics, and it calculates many things like EPA, and more (I didn’t really stay on that website for too long). So, what I plan to do is combine them. Hopefully, I’m not getting myself into too much of a challenge. This will most definitely be the hardest thing I have ever done on this app. Wish me luck! P.S. I started making the fourth widget before the report button then switched to finish the report button halfway so if you see my commits in a confusing order that’s why. View it here: https://mirage54321.github.io/RoboLens/
Devlog #10 -> Part 1 of 5 Please don’t hurt me, but I have to post multiple devlogs because I worked on so many things in all this time. It’s a lot of stuff to talk about and I don’t want to write it all into one because it will be super unorganized and hard for me to find in the future. In this first devlog, I am going to talk about how I got bookmarks to work. The idea came from thinking ahead to the match notifier. If someone wants alerts for a match, they need a way to say “these are the teams I care about” without having to retype a team number every single time. So I added a bookmark system using shared_preferences (just storing a list of team numbers locally on the device/browser). You can now star a team from a few places in the app and it’ll save to your bookmarks list, which I’m planning to hook the notifier into so it can just loop through your saved teams instead of asking you every time. This one was honestly pretty painless compared to my usual chaos. The only annoying part was making sure the bookmarked list actually persisted correctly on web (learned my lesson from the MongoDB flutter-web thing, so I tested this one on both platforms before moving on lol). Turns out shared_preferences just works with local storage under the hood on web, so no weird surprises this time. Short devlog, I know, but wait till you see what devlog #11 turned into. View it here: https://mirage54321.github.io/RoboLens/
Devlog #11 -> Part 2 of 5 Now for the second devlog, I am going to talk about how I got notifications to work. This is the one that ate my week. So the goal: when a match is coming up for a team you bookmarked, get a push notification even if the app/tab isn’t open. That last part is the whole problem, because it means I can’t just pop a normal in-app alert, I actually need real browser push notifications, which meant learning a whole new stack: service workers, VAPID keys, and the Push API. Here’s roughly how it works now ->Subscribe -> user picks a team number + event key, the app asks the browser for notification permission, and if granted it registers a push subscription through the service worker using my VAPID public key. Send to backend -> that subscription (plus team number/event key) gets sent to my Express backend and stored in MongoDB. Actually sending them -> the backend uses the web-push npm package to send the push whenever it detects a match coming up for that team. Getting the Flutter side to talk to any of this was its own adventure, since none of this exists as a nice Dart package, so I had to write a JS interop layer (basically a matchPush object in plain JS that Dart calls into) and wire it up through the same conditional-export trick I used for the guided camera: one file for web, one stub file that just says “unsupported” for native, so the app doesn’t explode on phone builds while I haven’t built native push yet. Problems I ran into (there were many) ->iOS Safari straight up does not support web push at all unless the site has been added to the home screen first. So right now notifications basically only work reliably on desktop browsers and Android, and I have to eventually explain that to iOS users somehow. Permission requests have the same “must be triggered by a direct tap” rule I fought with on the guided camera, so subscribing has to happen from an actual button press, no auto-subscribing on load. Debugging this was rough because half the errors happen silently in the service worker, not in the normal Flutter console, so I was stuck adding console.logs into push.js and checking devtools like a caveman for a while.It works now though! Bookmark a team, subscribe, and you’ll get pinged. Native (phone-installed) push notifications are still a “later” problem since that needs a totally different setup (probably Firebase Cloud Messaging), so for now the stub just returns unsupported on native and I’m keeping my scope to web. Two devlogs about the 4th app itself coming up next, promise. View it here: https://mirage54321.github.io/RoboLens/ P.S. For right now there are 3 notifications that send for iOS I plan to change that though!
Devlog #12 -> Part 3 of 5 Okay, actual 4th app time: Team Stats & Match Center (internally I’ve just been calling it “match” in the code, so if you dig around the file names that’s why). I started by mocking everything out before touching any real API, just so I could get the UI feeling right first. Made an intro screen (basically pitching the three features: match alerts, team stats, matchup simulator) and a fake mockTeams list with made-up EPA numbers just so I had something to look at while building. Once the layout felt right, I started swapping the fake data for real stuff from The Blue Alliance’s API, proxied through my backend the same way I already had set up for the FRC Events API (so I’m not spamming TBA directly from a bunch of client apps and to keep my API key private). Architecture-wise, I did something different from my other three apps: instead of passing state down through a million constructor params, I made a MatchDataController (basically one class holding all the team/event/match data + loading state) and wrapped the whole feature in a MatchScope, which is just an InheritedNotifier. So anywhere in the match center I can just call MatchScope.of(context) and get the controller without threading it through every single widget. Probably overkill for how big this feature ended up being, but once I had 4 tabs and a handful of sub-screens all needing the same data, I was really glad I did it this way instead of my usual pass-everything-into-the-constructor approach. Speaking of tabs, I split it into 4: My Team -> your team’s own info/next match Stats -> a season-wide “World Rating” I calculate from aggregating TBA’s OPR data across events (this was its own whole thing, might do a separate devlog on it someday) Events -> browse every FRC event, filter by time or location, see who’s live right now Sim -> the matchup simulator I keep promising Getting match data to actually parse right from TBA’s JSON took a minute (comp levels like qm/qf/sf/f needed their own label logic, predicted_time vs actual_time needed fallback logic since actual_time barely ever gets posted until after the match is already over, that kind of thing) but nothing too crazy, just tedious model-writing. Devlog #13 is basically a straight continuation of this one, mostly bug stories and the simulator, so be ready for that. View it here: https://mirage54321.github.io/RoboLens/
Devlog #13 -> Part 4 of 5 Continuing from #12: more on the match center, mostly the stuff that actually broke on me. Biggest bug of the bunch: on the Events tab, tapping into an event was supposed to show “scheduled to attend” info and the competing teams list, but both of those sections would just spin forever, no error, nothing. I assumed it was a network timing issue at first and went down a whole rabbit hole adding timeouts and retry logic that did absolutely nothing. Turns out the actual problem was way dumber: when I pushed the EventDetailScreen with Navigator.push, that screen gets placed in the Overlay as a sibling of the tab tree, not a child of it, meaning it’s NOT under my MatchScope anymore. So the second that screen tried to call MatchScope.of(context), it threw an assertion error immediately, before initState even got the chance to call setState and load anything. The spinner wasn’t stuck because of a slow network, it was stuck because the load call never even ran. Fixed it by just re-wrapping the pushed route in its own MatchScope using the same controller instance. Felt very silly once I found it, but also weirdly satisfying to finally understand. Next was the matchup simulator and win probabilities. On the schedule screen I show a rough “Red 45% / Blue 55%” prediction for each match. My first instinct was to use each event’s own OPR for this, but that falls apart for upcoming events since OPR doesn’t exist until a team has actually played a match there. So instead I based predictions on the season-wide World Rating from the Stats tab (average points across every event a team’s played all season), which actually gives predictions even for a event that hasn’t started yet. Also went back and hooked the push notification bell (from devlog #11) directly into the match center’s top bar now that there’s finally a “your team” + “your event” to actually attach a subscription to. There’s a little pulsing glow animation on the bell the first time you land on a screen where you could enable alerts, just so people notice it’s there instead of it blending into the top bar. Took way too many attempts to get the glow animation timing feeling smooth and not epileptic-seizure-inducing, but I think I landed on something decent. Genuinely didn’t expect the 4th app to take this many devlogs but here we are. One more to wrap up some small stuff and then I think I’m caught up! View it here: https://mirage54321.github.io/RoboLens/
Devlog #14 -> Part 5 of 5 Finally! This final devlog is about the small tweaks I made in the app. I made it have a new photo Small one, just swapped out one of the app’s images for something more current since the old one was from way back in devlog #1 and didn’t really represent what the app looks like anymore. Nothing technical here, just housekeeping. It kinda works offline I say “kinda” because this isn’t a real offline mode where you can browse cached data with no internet, it’s more like the app now knows when it’s offline and fails fast instead of just hanging. Basically, I added a ConnectivityCheck helper that on web reads navigator.onLine (a free, instant, synchronous browser check for whether the device has a network interface up) so if you’re in airplane mode or your wifi is off, the AI scan screens can immediately say “can’t use this when offline” instead of sitting there for a full request timeout before failing. On native platforms there’s no real equivalent without pulling in a whole new plugin like connectivity_plus, so I just made the stub always report “online” there — an actually-offline phone still gets caught by the AI request’s own timeout/retry handling, just without the instant fail I get on web. One thing worth noting: this only checks if the device thinks it has a network connection, not whether that network actually has working internet behind it. So a wifi network that’s connected but dead will still say “online” here. That case still gets caught eventually, just the slower way through the request timeout instead of instantly. Good enough for now though, this was mostly about killing the most common case of someone trying to scan with their phone in airplane mode and just watching the app hang. I changed the load in screen Went back and reworked the loading screen from devlog #5. It’s now a plain CSS screen sitting directly in index.html instead of living inside the Flutter app itself, which means it can actually paint the instant the page loads, before Flutter has even finished downloading and booting up. That was the whole point: the old version technically only appeared once Flutter itself was far enough along to render it, so there was still a blank/white flash before it. Now there’s a little animated wordmark and spinner (the spinner’s colored arc cycles through the same colors as the logo letters) that fades out and removes itself once Flutter fires its first real frame. While I was in there I also fixed something unrelated but annoying: Flutter’s web service worker by default waits to activate a new version until every open instance of the app is fully closed, which for something people add to their home screen basically never happens naturally. So people could keep opening an old cached version of the app for a long time after I’d pushed updates. Added a bit of JS to force any newly installed service worker to skip that wait and take over immediately (reloading the page once it does), so the next time someone opens the app after I ship something, they actually get it. And that’s it, I’m all caught up! Five devlogs in one sitting was a lot, but future updates should go back to being posted as I actually build them instead of in one giant backlog dump. Current problems / what’s next: Low MongoDB storage for free account Releasing the app (onto chief delphi to get feedback)!! Making it ready to release (working on the ? and report button) Future ideas: team tracker, public chat for teams, judging/interview prep tool, callout tool, round robin generator View it here: https://mirage54321.github.io/RoboLens/
Devlog #15 -> Part 1 (still working on this one!) Finally started actually tackling the AI usage limit problem from devlog #2. Since everyone using the app shares the same free-tier Gemini key, scans would just randomly fail with no real pattern whenever enough people were hitting it at once. Started on the backend side first: instead of letting every incoming scan hit Gemini immediately, I added a little queue that only lets 2 requests be in-flight to Gemini at a time, and everything else waits its turn. Next step is getting it to actually retry instead of just failing after the wait, but that’s for the next devlog.
Devlog #16 -> Part 2, continuing from #15 Got retries working on top of the queue from last time. If Gemini comes back with a 429 (rate limited) or 503 (overloaded) instead of an actual answer, the backend now waits and tries again automatically, using exponential backoff (2s, then 4s, then 8s) instead of hammering it again right away, up to a few attempts before it actually gives up and reports failure. It also checks for a retry-after header first and uses that instead of the backoff timer if Gemini actually tells us how long to wait. Then I mirrored the same idea on the Flutter side, so if the backend’s retries still aren’t enough, the app itself will retry the whole request a couple more times before showing the user an error.
Devlog #17 -> Part 3, wrapping this one up Last piece was making the retrying actually visible instead of just quietly happening in the background. Before, if a scan was retrying you’d just stare at a spinner with no idea what was going on. Now the loading screen updates to say something like “High demand. Retrying (2/3)…” so people know the app hasn’t frozen, it’s just waiting its turn. Between the queueing, the backoff retries on both ends, and this messaging, this should turn a lot of what used to be “scan failed, try again” moments into just a few extra seconds of waiting instead. Doesn’t make the free tier limit go away entirely, but it’s a big improvement over what I had. Current problems / what’s next: Low MongoDB storage for free account Professionalizing (before putting on Chief Delphi)
Devlog #18 -> Okay, super short devlog just to explain what I am doing. Basically all my hours are spent on fixing the notifications. It is super annoying right now because I am trying to finalize my project and the notifications randomly stop working. I tried clearing out mongoDB and checking on my cron-job and those seem to be working just fine. I’m not sure what to do. I pushed the hours up (for the practice day so I can check it earlier) and redeployed with Render. I shall see tomorrow if it works. View it here: https://mirage54321.github.io/RoboLens/
Devlog #19 -> I know I just committed a bunch the last few days. I guess I realized there is only a few days left and I found how to be way more efficent in getting hours. If I just keep this open and something else on another computer and work with them kinda being different windows then I get a lot more time because the switching of windows in the same computer made me keep forgetting to come back and work on the project (and I’m guessing was cutting the time too). Anywho! The most recent changes I have made is removing the ? mark button. I think I was going for a like “about me” thing but I think it was a little redundant and kind of unneccessary to say the least. I added a report button instead (it’s just in the home page). I got this idea from lovable which was something I worked with during my internship. I highkey have been working so much on this project (you can see by all my hours) that I didn’t want to connect it to the backend. It is just a popout that takes you to an gmail link and you can click send. Maybe if I run out of ideas I can add it as a backend. Now, if I am going to be so honest. I have worked a lot on this project and I want to ship but I also want to just crank out some more hours. I’m extremely proud of this project and I need to get it out to the world so that I can get some users! My issues to work on are: Low MongoDB storage for free account Professionalizing (now just looking back over and seeing if there is anything I wanna fix before putting on chief delphi) View it here: https://mirage54321.github.io/RoboLens/
Notifications are working again! Basically, the rebuilding of Render helped fix the issue which is kind of ragebait. I’m getting a little nervous though because I wonder what happens if someone doesn’t reopen the bookmark (because that is how it resets). Would they still get the messages? Will it update automatically? Overall, it works great. I just worry there may be an error that arises (that is a risk with any project honestly). View it here: https://mirage54321.github.io/RoboLens/
Updates!!! Basically, I’ve been checking to see how many users and views I have. I have google analytics on my project to keep an eye on it. Right now I have 52 users and 163 views. Which honestly, I am pretty dang happy about. (1) I haven’t really been advertising (2) I literally thought it was gonna be like 20 views Woop woop! Okay, now on these past few days I have been working on getting as many hours as possible. I don’t have a personal computer so I am really aiming for literally any of the laptops. Now, programatically I have been working on removing the 3 burst messages for iPhone (it wouldn’t compact itself on the Apple homescreen). FYI: 90% of the time for this was spent removing the 3 burst messages for iPhone and writing Ship #2… so you better be ready for Ship 2! View it here: https://mirage54321.github.io/RoboLens/
Devlog #22 -> I was looking at the comments people left me from my ship and the first thing I noticed that I should work on is the load-in page. It is definitely kind of plain. To be honest, I used Claude to help a lot with this one. Making the spinning circle was pretty easy but I had some complex ideas I wanted to put to work and I just didn’t know how to do it. It has a huge radar that has the colors pop up and says “scounting __ teams”. Overall, I am so happy about this new design! Let me know what you guys think! I also added a folder for the photos so it looks more organized! The next thing I plan to work on “loop crashes if the camera disconnects” comment. Live app: https://mirage54321.github.io/RoboLens/
Devlog #23 -> Fixed the camera disconnect crash from the feedback. Turns out the camera plugin doesn’t actually throw an error when the hardware gets yanked mid-session, it just quietly flips an internal hasError flag and keeps going. Which is why the app was crashing somewhere random instead of failing cleanly. Nothing in my code was listening for that flag, so it just kept trying to read frames and capture photos off a dead controller. Fixed it by adding a listener that actually watches for that error state, cleans everything up, and drops the user onto a proper “Camera disconnected, try again” screen instead of freezing or throwing. Also fixed the retry logic after a failed capture so it doesn’t try to restart a stream on a controller that’s already dead. Next up: the cursor. Someone pointed that out, because every button on web just shows the default arrow. Live app: https://mirage54321.github.io/RoboLens/a
Ships:
I made an app for specifically robotics teams (although this could be used for other things too). This is still a work in progress because there is so much more I want to add. I did this project so that I could make something with an AI model and I’m really proud of myself because Flutter was really hard to work with!
What did I make? Since Ship #1, RoboLens grew from one AI scanner into four connected tools. I added a rules checker that reads the actual FRC game manual (2024–2026) alongside your robot photo so it’s grounded in real rules instead of guessing. I built out a full shared battery tracker. I added a guided camera that walks you through lighting/tilt/framing and auto-captures once the angle looks right. And the biggest addition: a Team Stats & Match Center with four tabs (My Team, Stats, Events, Sim) pulling live data from The Blue Alliance and the FRC Events API, including a season-wide “World Rating,” a matchup simulator with win probabilities, and bookmarking teams to get real push notifications before their matches. I also spent a lot of time on stuff that doesn’t show up as a “feature” but makes the app actually usable: a queue + exponential backoff + retry system so the shared free-tier Gemini key doesn’t randomly fail scans under load, a report button that feeds recurring AI mistakes back into future scans, offline detection so scans fail fast instead of hanging, and a new instant-loading splash screen. What was challenging for me? The AI usage limits were the most persistent problem. Everyone shares one free-tier Gemini key, so scans would fail with no clear pattern whenever enough people hit it at once. I fixed it in stages: first a queue limiting in-flight requests, then automatic retries with backoff (and respecting the retry-after header when Gemini gave one), then finally surfacing that retry status to the user (“High demand. Retrying (2/3)…”) instead of just showing a dead spinner. The guided camera and push notifications both turned into whole rabbit holes of browser-specific pain (iOS Safari blocking camera/notification permissions unless triggered by a direct tap, no live frame streaming on web so I had to build a custom JS-interop layer from scratch, and push not working on iOS at all unless the site’s added to the home screen firs)t. My favorite bug story: the Match Center’s Events tab would spin forever with zero errors. I burned time adding timeouts and retries that did nothing before realizing the real issue. The spinner wasn’t stuck waiting on the network, it was stuck because nothing ever tried. What am I the most proud of? Going from a single-purpose AI scanner to four genuinely useful, connected tools without the codebase turning into spaghetti. I’m also proud that scans now degrade gracefully under load instead of just failing, and that notifications work reliably even though I had zero experience with service workers or VAPID keys before this. And honestly, just sticking with it. 21 devlogs and three months of real iteration based on actual user feedback instead of giving up. What should people know so they can test your project? Live app: https://mirage54321.github.io/RoboLens/ You can log in as a guest for team 4388 to browse batteries without needing an account. Push notifications currently work reliably on desktop browsers and Android (iOS Safari requires the site to be added to your home screen as a bookmark). You can test this by logging into -4388 (Yes, a negative. I needed a number that wouldn’t have a real team). The AI scan/rules tools need a robot photo to test against; if you don’t have one handy, any well-lit photo of mechanical/electrical components will still show you how the flow works....
|
1793768130.857615
|
1794632130.857615
|
|
16180
|
Ra's bass of denial by @dhruvra | Stardance
|
dhruvra
|
0
|
2.58
|
0
|
[]
|
[{"post_id": 15125, "ts": "202 [{"post_id": 15125, "ts": "2026-06-24T16:06:42Z", "hours": 0.6736, "text": "Devlog #4 I have a bass now! I’ve assembled everything together and added a hole for the screen I’m going to use, which is just a small capacitive touch screen I found with a built in speaker. Now, I just need to focus on software. My current idea is to find an open-source guitar tuner and use it to recognize certain combinations of notes. Yamada Ryo would be proud, I hope."}, {"post_id": 14926, "ts": "2026-06-24T07:38:16Z", "hours": 0.7658, "text": "Devlog #3 I finally worked on parts of the guitar that aren’t the body! I have a draft of the pickguard done that just needs some smoothing out, as well as the beginnings of a neck. Thanks to the fact that I haven’t CADed in a while, I’m running into a couple issues, the main one being the fillet tool, since I need it to radius the neck. I’ve also decided on a screen to mount, and will add a hole for it on the guitar in my final design. Next up: software! This may be a hardware project, but stairway ain’t gonna be denied unless I make the bass actually recognize it. So I get to do both! Yay!"}, {"post_id": 14886, "ts": "2026-06-24T05:24:23Z", "hours": 0.87, "text": "Devlog #2 I’m actually getting somewhere now! Thanks to Onshape’s image tool, I was able to underlay the plan I found, and the bass actually looks pretty decent. All that’s left is to just figure out how big the screen will be, and then I can worry about the neck! CADing is something I haven’t done in a while but it’s been really fun making this, probably because it’s a personal project instead of random brainrot for a club or a team. For anyone that happens to come across my bass of denial wondering if they should give CAD a try, go for it!"}, {"post_id": 14248, "ts": "2026-06-23T08:26:16Z", "hours": 0.2742, "text": "Here we go! So for my hardware project, I’m building a bass similar to a Fender Precision. The original goal of the project was to just make a bass that looks the same as Ryo Yamada’s from Bocchi the Rock!, but then I thought, “that seems kinda boring.” So I added more! Now, the bass is also planned to have a screen and microphone, so when infamous guitar songs like Stairway To Heaven are played, the bass can react to it by telling their guitarist to stop (thank you, Wayne’s World). This CAD design is a complete prototype, lacking any clear measurements or incredible precision. The holes on the right are for the pickups and the volume/tone knobs, while the one on the left is for the screen."}]...
|
Title: Ra's bass of denial by @dhruvra | Stard Title: Ra's bass of denial by @dhruvra | Stardance
Devlogs:
Here we go! So for my hardware project, I’m building a bass similar to a Fender Precision. The original goal of the project was to just make a bass that looks the same as Ryo Yamada’s from Bocchi the Rock!, but then I thought, “that seems kinda boring.” So I added more! Now, the bass is also planned to have a screen and microphone, so when infamous guitar songs like Stairway To Heaven are played, the bass can react to it by telling their guitarist to stop (thank you, Wayne’s World). This CAD design is a complete prototype, lacking any clear measurements or incredible precision. The holes on the right are for the pickups and the volume/tone knobs, while the one on the left is for the screen.
Devlog #2 I’m actually getting somewhere now! Thanks to Onshape’s image tool, I was able to underlay the plan I found, and the bass actually looks pretty decent. All that’s left is to just figure out how big the screen will be, and then I can worry about the neck! CADing is something I haven’t done in a while but it’s been really fun making this, probably because it’s a personal project instead of random brainrot for a club or a team. For anyone that happens to come across my bass of denial wondering if they should give CAD a try, go for it!
Devlog #3 I finally worked on parts of the guitar that aren’t the body! I have a draft of the pickguard done that just needs some smoothing out, as well as the beginnings of a neck. Thanks to the fact that I haven’t CADed in a while, I’m running into a couple issues, the main one being the fillet tool, since I need it to radius the neck. I’ve also decided on a screen to mount, and will add a hole for it on the guitar in my final design. Next up: software! This may be a hardware project, but stairway ain’t gonna be denied unless I make the bass actually recognize it. So I get to do both! Yay!
Devlog #4 I have a bass now! I’ve assembled everything together and added a hole for the screen I’m going to use, which is just a small capacitive touch screen I found with a built in speaker. Now, I just need to focus on software. My current idea is to find an open-source guitar tuner and use it to recognize certain combinations of notes. Yamada Ryo would be proud, I hope....
|
1793396909.6494436
|
1794001709.6494436
|
|
16181
|
Drone Game by @OpenAir_Company | Stardance
|
OpenAir_Company
|
0
|
2.3
|
0
|
[]
|
[{"post_id": 6598, "ts": "2026 [{"post_id": 6598, "ts": "2026-06-11T02:26:54Z", "hours": 2.3014, "text": "The RED CLOVER"}]...
|
Title: Drone Game by @OpenAir_Company | Stardance
Title: Drone Game by @OpenAir_Company | Stardance
Devlogs:
The RED CLOVER...
|
1793534154.7893407
|
1794138954.7893407
|
|
16182
|
My awesome macropad! by @Bhavesh | Stardance
|
Bhavesh
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My awesome macropad! by @Bhavesh | Stardanc Title: My awesome macropad! by @Bhavesh | Stardance...
|
1793569860.6293426
|
1794174660.6293426
|
|
16183
|
Slackword Bot by @ketchupismm | Stardance
|
ketchupismm
|
2
|
8.0
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-10T12:56:18Z", "hours": 0.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a dictionary slack app that has 3 functions. Definitions using command, examples are using definitions command, and help command to show all commands. Something that was extremely challenging was adding in the dictionary API and then the GROQ after and had to use ai at the end to help me set up the yes button, polishing my work to be readable, and just small debugging issues like mistypes. I’m really proud of how everything went from learning commands and learning APIs, it’s pretty much my first passion project. The setup is pretty annoying and I’ve tried to explain it as simple as I could in Github when I published it.", "repo": "https://github.com/ketchupismm-cell/Slackword-Bot", "demo": "https://app.slack.com/client/E09V59WQY1E/C0P5NE354?skip_today=1"}, {"ship_num": 2, "ts": "2026-07-02T01:55:13Z", "hours": 8.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a dictionary slack app that has 3 functions. Definitions using command, examples are using definitions command, and help command to show all commands. Something that was extremely challenging was adding in the dictionary API and then the GROQ after and had to use ai at the end to help me set up the yes button, polishing my work to be readable, and just small debugging issues like mistypes. I’m really proud of how everything went from learning commands and learning APIs, it’s pretty much my first passion project. The setup is pretty annoying and I’ve tried to explain it as simple as I could in Github when I published it.", "repo": "https://github.com/ketchupismm-cell/Slackword-Bot", "demo": "https://app.slack.com/client/E09V59WQY1E/C0P5NE354?skip_today=1"}]...
|
[{"post_id": 25926, "ts": "202 [{"post_id": 25926, "ts": "2026-07-10T12:55:41Z", "hours": 0.4089, "text": "For my bot, I have two commands and one feature on my slackword app. /slackword-define, /slackword-help the one feature is the examples when you click the yes button when you use the define command"}, {"post_id": 20455, "ts": "2026-07-02T01:37:45Z", "hours": 1.4642, "text": "I published my work into Github, run it on Nest and as a systemd service"}, {"post_id": 19768, "ts": "2026-07-01T04:47:37Z", "hours": 2.0594, "text": "Finally finished up with adding in exemplar button after definition command is used and took a while to polish everything Planning to add on other commands such as daily word tomorrow"}, {"post_id": 19546, "ts": "2026-06-30T21:24:32Z", "hours": 2.3167, "text": "I added GROQ as a LLM for special-nouns"}, {"post_id": 18822, "ts": "2026-06-30T00:54:20Z", "hours": 1.9583, "text": "Working on cleaning code and adding additional features to definitions"}]...
|
Title: Slackword Bot by @ketchupismm | Stardance
Title: Slackword Bot by @ketchupismm | Stardance
Devlogs:
Working on cleaning code and adding additional features to definitions
I added GROQ as a LLM for special-nouns
Finally finished up with adding in exemplar button after definition command is used and took a while to polish everything Planning to add on other commands such as daily word tomorrow
I published my work into Github, run it on Nest and as a systemd service
For my bot, I have two commands and one feature on my slackword app. /slackword-define, /slackword-help the one feature is the examples when you click the yes button when you use the define command
Ships:
I made a dictionary slack app that has 3 functions. Definitions using command, examples are using definitions command, and help command to show all commands. Something that was extremely challenging was adding in the dictionary API and then the GROQ after and had to use ai at the end to help me set up the yes button, polishing my work to be readable, and just small debugging issues like mistypes. I’m really proud of how everything went from learning commands and learning APIs, it’s pretty much my first passion project. The setup is pretty annoying and I’ve tried to explain it as simple as I could in Github when I published it.
I made a dictionary slack app that has 3 functions. Definitions using command, examples are using definitions command, and help command to show all commands. Something that was extremely challenging was adding in the dictionary API and then the GROQ after and had to use ai at the end to help me set up the yes button, polishing my work to be readable, and just small debugging issues like mistypes. I’m really proud of how everything went from learning commands and learning APIs, it’s pretty much my first passion project. The setup is pretty annoying and I’ve tried to explain it as simple as I could in Github when I published it....
|
1793703024.3483472
|
1793789424.3483472
|
|
16184
|
Frictionless by @devangbhole | Stardance
|
devangbhole
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Frictionless by @devangbhole | Stardance
|
1793375397.7666962
|
1793980197.7666962
|
|
16185
|
My very own WebOS by @marcusbauer77 | Stardance
|
marcusbauer77
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @marcusbauer77 | Stard Title: My very own WebOS by @marcusbauer77 | Stardance...
|
1793519412.5752056
|
1794124212.5752056
|
|
16186
|
Space Trajectory Predictor by @Aleeyou | Stardance
|
Aleeyou
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Space Trajectory Predictor by @Aleeyou | St Title: Space Trajectory Predictor by @Aleeyou | Stardance...
|
1793192048.5332117
|
1793796848.5332117
|
|
16187
|
My very own WebOS by @fishstyx | Stardance
|
fishstyx
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @fishstyx | Stardance
|
1793382469.1021163
|
1793987269.1021163
|
|
16188
|
Clothy Folder by @SrikaraP | Stardance
|
SrikaraP
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Clothy Folder by @SrikaraP | Stardance
|
1793289308.3636692
|
1793894108.3636692
|
|
16189
|
Untitled project by @AidenB | Stardance
|
AidenB
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Untitled project by @AidenB | Stardance
|
1793267245.2629144
|
1793872045.2629144
|
|
16190
|
Apollo mission simulator by @prajithvishnur | Star Apollo mission simulator by @prajithvishnur | Stardance...
|
prajithvishnur
|
1
|
1.0
|
15
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-16T02:48:52Z", "hours": 1.0, "multiplier": 15.2, "payout": 15, "blessing": "neutral", "text": "I think I have finished version one of the game. I am now going to ship. I hope you all enjoy it, and I can’t wait for the feedback!!!", "repo": "https://github.com/prajith-vishnu/apollo13-mission-critical", "demo": "https://prajith-vishnu.github.io/apollo13-mission-critical/"}]...
|
[{"post_id": 8891, "ts": "2026 [{"post_id": 8891, "ts": "2026-06-14T20:06:57Z", "hours": 0.5925, "text": "Got a lot of scenarios for the game built. It’s going pretty well, also hosting it on git."}, {"post_id": 6893, "ts": "2026-06-11T15:40:09Z", "hours": 0.3906, "text": "created a start screen that i think looks rlly cool. hope to turn this into an awesome space game."}]...
|
Title: Apollo mission simulator by @prajithvishnur Title: Apollo mission simulator by @prajithvishnur | Stardance
Devlogs:
created a start screen that i think looks rlly cool. hope to turn this into an awesome space game.
Got a lot of scenarios for the game built. It’s going pretty well, also hosting it on git.
Ships:
I think I have finished version one of the game. I am now going to ship. I hope you all enjoy it, and I can’t wait for the feedback!!!...
|
1793713856.4208887
|
1793800256.4208887
|
|
16191
|
Macondo Esoteric Compiler by @vitamin | Stardance
|
vitamin
|
1
|
5.64
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-18T21:57:07Z", "hours": 3.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a compiler that transforms esoteric code into clean and optimized C. It was pretty difficult for me to create an algorithm to parse and coalesce tokens instead of using a slightly worse string swapping type. I’m really proud that the emitted C code is optimized specifically so GCC can easily fold constants and having a well-optimized compiler overall. (sorry if this is your second time seeing this) Note: Was previously shipped to Macondo but got permanently rejected (no re-ship) by FraudSquad with no note/notice or any reasoning, tried to reach out but got no responses or answers. All hours and working time (much more than the 3 hours that appear here) are logged via Hackatime, Github repo timestamps, and Macondo journals.", "repo": "https://github.com/vktryyy/macondo-compiler", "demo": "https://macondo-compiler-v3.streamlit.app/"}]...
|
[{"post_id": 28642, "ts": "202 [{"post_id": 28642, "ts": "2026-07-15T00:43:59Z", "hours": 2.3806, "text": "If the demo displays “😴-Zzzz: This app has gone to sleep due to inactivity. Would you like to wake it back up?”, click the blue button below that says “Yes, get this app back up!” until it redirects you to this screen (attached image) with changing emoji’s and wait until the demo is ready to view and use. This happens because I’m using the free community tier of streamlit.app, so it automatically puts the app to sleep to save recourses and bandwidth for other community users who are also deploying websites/apps on the free tier."}, {"post_id": 13309, "ts": "2026-06-21T19:48:05Z", "hours": 0.2572, "text": "THIS PROJECT IS JUST A RE-SHIP FOR MY ORIGINAL PROJECT ON MACONDO, READ THE SHIP LOG. A reason why there’s only a handful of DevLogs is because this project was already finished and journaled on Macondo, so I didn’t have much to put here. All hours and working time (much more than the 3 hours that appear here) are logged via Hackatime, Github repo timestamps, and Macondo journals."}, {"post_id": 11587, "ts": "2026-06-18T21:27:03Z", "hours": 0.2897, "text": "print(“DevLog #2:”) the updates: token coalescing: instead of spamming the CPU, consecutive instructions like NEXT NEXT NEXT get compressed into a clean ptr += 3; . compiler integration: connected the frontend to local GCC/Clang compilers via subprocess , wrapped it in an automated -O3 pipeline, and added a 4-second timeout to kill infinite loops. to-do: teach the IR to recognize loop-clearing patterns (turning [-] into an immediate *ptr = 0; )."}, {"post_id": 10417, "ts": "2026-06-17T03:41:16Z", "hours": 2.8561, "text": "print(“DevLog #1:”) 65,000-Byte typo. Macondo (the language I created) sets up a standard 65KB memory array for the Brainf*** runtime, or at least it was supposed to. While hardcoding the C template, my finger slipped somehow (probably while I was drinking tea) and wrote this instead: char mem[65Z536] = {0} Calling ‘gg’ on itself. While debugging the subprocess execution that fires off GCC, SOMEONE must have accidentally hit some vim shortcuts or typed out their frustration into the source code. Right before checking the GCC return code, there was a standalone ‘gg’ sitting in the script. cmd = [“gcc”, “-O3”, tmp_name, “-o”, outfile] res = subprocess.run(cmd) gg # <— been here the whole time, unaware. if res.returncode == 0:"}]...
|
Title: Macondo Esoteric Compiler by @vitamin | Sta Title: Macondo Esoteric Compiler by @vitamin | Stardance
Devlogs:
print(“DevLog #1:”) 65,000-Byte typo. Macondo (the language I created) sets up a standard 65KB memory array for the Brainf*** runtime, or at least it was supposed to. While hardcoding the C template, my finger slipped somehow (probably while I was drinking tea) and wrote this instead: char mem[65Z536] = {0} Calling ‘gg’ on itself. While debugging the subprocess execution that fires off GCC, SOMEONE must have accidentally hit some vim shortcuts or typed out their frustration into the source code. Right before checking the GCC return code, there was a standalone ‘gg’ sitting in the script. cmd = [“gcc”, “-O3”, tmp_name, “-o”, outfile] res = subprocess.run(cmd) gg # <— been here the whole time, unaware. if res.returncode == 0:
print(“DevLog #2:”) the updates: token coalescing: instead of spamming the CPU, consecutive instructions like NEXT NEXT NEXT get compressed into a clean ptr += 3; . compiler integration: connected the frontend to local GCC/Clang compilers via subprocess , wrapped it in an automated -O3 pipeline, and added a 4-second timeout to kill infinite loops. to-do: teach the IR to recognize loop-clearing patterns (turning [-] into an immediate *ptr = 0; ).
THIS PROJECT IS JUST A RE-SHIP FOR MY ORIGINAL PROJECT ON MACONDO, READ THE SHIP LOG. A reason why there’s only a handful of DevLogs is because this project was already finished and journaled on Macondo, so I didn’t have much to put here. All hours and working time (much more than the 3 hours that appear here) are logged via Hackatime, Github repo timestamps, and Macondo journals.
If the demo displays “😴-Zzzz: This app has gone to sleep due to inactivity. Would you like to wake it back up?”, click the blue button below that says “Yes, get this app back up!” until it redirects you to this screen (attached image) with changing emoji’s and wait until the demo is ready to view and use. This happens because I’m using the free community tier of streamlit.app, so it automatically puts the app to sleep to save recourses and bandwidth for other community users who are also deploying websites/apps on the free tier.
Ships:
I made a compiler that transforms esoteric code into clean and optimized C. It was pretty difficult for me to create an algorithm to parse and coalesce tokens instead of using a slightly worse string swapping type. I’m really proud that the emitted C code is optimized specifically so GCC can easily fold constants and having a well-optimized compiler overall. (sorry if this is your second time seeing this) Note: Was previously shipped to Macondo but got permanently rejected (no re-ship) by FraudSquad with no note/notice or any reasoning, tried to reach out but got no responses or answers. All hours and working time (much more than the 3 hours that appear here) are logged via Hackatime, Github repo timestamps, and Macondo journals....
|
1793689278.0239406
|
1793775678.0239406
|
|
16192
|
My very own WebOS by @VAL496 | Stardance
|
VAL496
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @VAL496 | Stardance
|
1793260495.6895485
|
1793865295.6895485
|
|
16193
|
prism by @olaiwonismail | Stardance
|
olaiwonismail
|
1
|
11.38
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-13T17:46:48Z", "hours": 9.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Built Prism, a virtual mic that cleans your audio in real time and feeds it to Discord/Zoom/OBS(basically various apps) as a microphone. CPU-only AI noise removal (RNNoise, GTCRN, DeepFilterNet3), switchable live with a strength slider and noise meter. Hardest part was keeping it real-time: matching block sizes, resampling, and STFT timing so the denoisers stay phase-aligned under ~40ms latency else its give a very choppy audio. Proud that it all runs on my potato pc’s CPU with low idle usage. To test: install VB-Audio Virtual Cable, run the app, then pick “CABLE Output” as your mic in any app. Disclaimer -GTCRN isn’t in the latest exe release yet but you can use the other models", "repo": "https://github.com/Olaiwonismail/prism", "demo": "https://olaiwonismail.github.io/prism/"}]...
|
[{"post_id": 10654, "ts": "202 [{"post_id": 10654, "ts": "2026-06-17T14:48:22Z", "hours": 2.3792, "text": "-progress is slow just came back from the hospital Was able to add a way for you to demo it in your browser -added a fastapi endpoint that runs the denoiser on the uploaded audio -wired the apps webpage to the api so people can try it without having to install the app the app is only availbale to use on windows btw (linux and mac support coming soon)"}, {"post_id": 8207, "ts": "2026-06-13T17:31:39Z", "hours": 0.2792, "text": "added this to the site so users can understand how it works"}, {"post_id": 8143, "ts": "2026-06-13T16:12:36Z", "hours": 1.2011, "text": "i added ultra‑light GTCRN model support i updated the website to show v0.1.0 available for download"}, {"post_id": 7760, "ts": "2026-06-12T23:26:44Z", "hours": 1.5822, "text": "created a website for prism where people can download this project and read more about it(see the roadmap, read release notes) added MIT license created an executable(.exe) for prism dropped v0.1.0 ,it’s on the GitHub releases pages"}, {"post_id": 7311, "ts": "2026-06-12T05:47:09Z", "hours": 1.5156, "text": "Added DeepFilterNet (ONNX) as an optional denoiser, swappable via config alongside RNNoise Added adjustable noise removal slider (0-100%) with separate on/off toggle Added noise meter: shows how much noise is being removed + estimated room noise floor phase 2 done I guess 🎉 will improve the ui plan to use tauri later on but for now tkinter will do"}, {"post_id": 6946, "ts": "2026-06-11T17:27:39Z", "hours": 0.7703, "text": "Built Phase 2 (features i added) RNNoise AI noise removal Fixed the WO Mic crash Fixed your voice getting clipped at the start of words"}, {"post_id": 6909, "ts": "2026-06-11T16:10:52Z", "hours": 0.94, "text": "built a minimal Tkinter UI for Prism: a small window with an on/off toggle for filtering, a dropdown to switch between microphones, a live level meter with gate status, and a status line. To support it, the audio code was refactored from a blocking loop into a controllable AudioEngine that can start, stop, and switch mics at runtime — a stopgap until the Tauri UI, but the engine part is permanent. currently i’m in my hostel and there is a lot of noise in the background the images show a before and after the filtering of noise"}, {"post_id": 6843, "ts": "2026-06-11T14:23:58Z", "hours": 1.1961, "text": "Added safe mic auto-detection. Prism now validates the input device instead of blindly using the Windows default — it rejects VB-Cable and Sound Mapper pseudo-devices (which cause a feedback loop where Prism listens to its own output), falls back to the first real microphone, and exits with a clear help message if no mic exists. no ui yet 🤧"}, {"post_id": 6668, "ts": "2026-06-11T05:36:56Z", "hours": 1.2961, "text": "One afternoon I was giving a presentation in my rooom, and the room came with me , a ceiling fan , my roomate watching tiktoks in the background, the low hum a room always has. All of it rode my mic straight into the call. I couldn’t mute (I was the one talking), and I couldn’t fix the room. So the idea for Prism was simple and a little stubborn: your voice should be the only thing that leaves your microphone progress so far: -work on the project structure, -Capture physical mic input -Route processed audio to virtual cable output (VB-Audio) -High-pass filter (the processing layer for now)"}]...
|
Title: prism by @olaiwonismail | Stardance
Devlog Title: prism by @olaiwonismail | Stardance
Devlogs:
One afternoon I was giving a presentation in my rooom, and the room came with me , a ceiling fan , my roomate watching tiktoks in the background, the low hum a room always has. All of it rode my mic straight into the call. I couldn’t mute (I was the one talking), and I couldn’t fix the room. So the idea for Prism was simple and a little stubborn: your voice should be the only thing that leaves your microphone progress so far: -work on the project structure, -Capture physical mic input -Route processed audio to virtual cable output (VB-Audio) -High-pass filter (the processing layer for now)
Added safe mic auto-detection. Prism now validates the input device instead of blindly using the Windows default — it rejects VB-Cable and Sound Mapper pseudo-devices (which cause a feedback loop where Prism listens to its own output), falls back to the first real microphone, and exits with a clear help message if no mic exists. no ui yet 🤧
built a minimal Tkinter UI for Prism: a small window with an on/off toggle for filtering, a dropdown to switch between microphones, a live level meter with gate status, and a status line. To support it, the audio code was refactored from a blocking loop into a controllable AudioEngine that can start, stop, and switch mics at runtime — a stopgap until the Tauri UI, but the engine part is permanent. currently i’m in my hostel and there is a lot of noise in the background the images show a before and after the filtering of noise
Built Phase 2 (features i added) RNNoise AI noise removal Fixed the WO Mic crash Fixed your voice getting clipped at the start of words
Added DeepFilterNet (ONNX) as an optional denoiser, swappable via config alongside RNNoise Added adjustable noise removal slider (0-100%) with separate on/off toggle Added noise meter: shows how much noise is being removed + estimated room noise floor phase 2 done I guess 🎉 will improve the ui plan to use tauri later on but for now tkinter will do
created a website for prism where people can download this project and read more about it(see the roadmap, read release notes) added MIT license created an executable(.exe) for prism dropped v0.1.0 ,it’s on the GitHub releases pages
i added ultra‑light GTCRN model support i updated the website to show v0.1.0 available for download
added this to the site so users can understand how it works
-progress is slow just came back from the hospital Was able to add a way for you to demo it in your browser -added a fastapi endpoint that runs the denoiser on the uploaded audio -wired the apps webpage to the api so people can try it without having to install the app the app is only availbale to use on windows btw (linux and mac support coming soon)
Ships:
Built Prism, a virtual mic that cleans your audio in real time and feeds it to Discord/Zoom/OBS(basically various apps) as a microphone. CPU-only AI noise removal (RNNoise, GTCRN, DeepFilterNet3), switchable live with a strength slider and noise meter. Hardest part was keeping it real-time: matching block sizes, resampling, and STFT timing so the denoisers stay phase-aligned under ~40ms latency else its give a very choppy audio. Proud that it all runs on my potato pc’s CPU with low idle usage. To test: install VB-Audio Virtual Cable, run the app, then pick “CABLE Output” as your mic in any app. Disclaimer -GTCRN isn’t in the latest exe release yet but you can use the other models...
|
1793692601.3175917
|
1793779001.3175917
|
|
16194
|
My first slack bot! by @kaycee | Stardance
|
kaycee
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My first slack bot! by @kaycee | Stardance
|
1793303309.3200731
|
1793908109.3200731
|
|
16195
|
My very own WebOS by @shalaka | Stardance
|
shalaka
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @shalaka | Stardance
|
1793386202.2428684
|
1793991002.2428684
|
|
16196
|
The Color Carousel by @bluerook4 | Stardance
|
bluerook4
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: The Color Carousel by @bluerook4 | Stardanc Title: The Color Carousel by @bluerook4 | Stardance...
|
1793404139.4543078
|
1794008939.4543078
|
|
16197
|
Frictionless by @slower232 | Stardance
|
slower232
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Frictionless by @slower232 | Stardance
|
1793494436.8003364
|
1794099236.8003364
|
|
16198
|
My very own WebOS by @takshkothari09 | Stardance
|
takshkothari09
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: My very own WebOS by @takshkothari09 | Star Title: My very own WebOS by @takshkothari09 | Stardance...
|
1793404480.7840924
|
1794009280.7840924
|
|
16199
|
ESP32 Walkie Talkie by @aditya_verma | Stardance
|
aditya_verma
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: ESP32 Walkie Talkie by @aditya_verma | Star Title: ESP32 Walkie Talkie by @aditya_verma | Stardance...
|
1793296359.0830524
|
1793901159.0830524
|
|
16200
|
Frictionless by @laura_puu | Stardance
|
laura_puu
|
0
|
0.0
|
0
|
[]
|
[]
|
Title: Frictionless by @laura_puu | Stardance
|
1793461971.880634
|
1794066771.880634
|