|
64380
|
SELENE by @lakshay99_b | Stardance
|
lakshay99_b
|
2
|
36.0
|
98
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-24T08:01:16Z", "hours": 4.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Let me tell u this is my 2nd ship and might be a meaningful one. I want to make it clear that i was able to post develog after 24 hour of coding as all previous devlogs got deleted due some misunderstanding of team.", "repo": "https://github.com/lakshay-boora/selene", "demo": "https://selene-angvians.vercel.app"}, {"ship_num": 2, "ts": "2026-10-16T10:15:14Z", "hours": 32.0, "multiplier": 6.23, "payout": 98, "blessing": "neutral", "text": "Finally hosted Selene Bench on both platforms: Vercel: selene-bench.vercel.app EdgeOne: advisory-gray-xyuz9gon.edgeone.dev Live Earth–Moon physics lab — tweak gravity, watch eclipses, and try the cinematic collision mode.", "repo": "https://github.com/lakshay-boora/selene", "demo": "https://selene-angvians.vercel.app"}]...
|
[{"post_id": 81004, "ts": "202 [{"post_id": 81004, "ts": "2026-10-19T15:57:10Z", "hours": 0.4719, "text": "isnt it good? can any one tell me isnt a good readme or should i improve it?"}, {"post_id": 80599, "ts": "2026-10-18T08:21:50Z", "hours": 0.3261, "text": "isnt it crazy that u can make the following geometry with my demo by just setting gravity to max…."}, {"post_id": 80594, "ts": "2026-10-18T08:02:40Z", "hours": 0.4247, "text": "huff. finaly i changed a lot and try to code the badest i can or else reviewer would flag it as ai. i have edited the whole three.js all the styles of moon and earth , removed all camera angles and tried to make it as simple as possible, and now i am sending it for recheck. hope everything would go smooth."}, {"post_id": 80590, "ts": "2026-10-18T07:30:47Z", "hours": 1.4233, "text": "it is really a heart breaking movement when someone rejects your 3week’s efforts saying that it is ai😔. but its ok i respect the reviewers i would make some alteration and then try to resubmite it."}, {"post_id": 80425, "ts": "2026-10-17T16:30:01Z", "hours": 1.7658, "text": "should i change my readme? its being around a day from when i have submited my site and it is still pending, so i am doubting my readme is it a good one? can u check it and recommend me."}, {"post_id": 80131, "ts": "2026-10-16T10:13:18Z", "hours": 0.3211, "text": "Finally hosted Selene Bench on both platforms: Vercel: selene-bench.vercel.app EdgeOne: advisory-gray-xyuz9gon.edgeone.dev Live Earth–Moon physics lab — tweak gravity, watch eclipses, and try the cinematic collision mode."}, {"post_id": 80130, "ts": "2026-10-16T09:55:18Z", "hours": 2.3431, "text": "it’s almost done just fixing some left over render. i would host it through edgeone as vercel is not responding to 3.js i hope judges would not mark it as a flag as they did last time with me."}, {"post_id": 79837, "ts": "2026-10-15T16:16:26Z", "hours": 2.0581, "text": "it’s very interesting to work with the physics of the planets and setting the variables, although it need too much research but it was a fun task."}, {"post_id": 79784, "ts": "2026-10-15T12:18:20Z", "hours": 1.0386, "text": "i finally found the way to place the right configuration for the three.js. it’s the most difficult part i am facing in the full deveopment of ‘studania’. one more update, studania project have a bit change in it. nowonwards it would help u learn the relation between moon and earth through simulated 3d models of moon and earth , u can alter their physical constant and see what would happen! enjoy the space!!!!"}, {"post_id": 71650, "ts": "2026-09-21T07:33:20Z", "hours": 26.0361, "text": "THIS IS GOING TO BE MY NEW START FROM NOW"}]...
|
Title: SELENE by @lakshay99_b | Stardance
Devlogs Title: SELENE by @lakshay99_b | Stardance
Devlogs:
THIS IS GOING TO BE MY NEW START FROM NOW
i finally found the way to place the right configuration for the three.js. it’s the most difficult part i am facing in the full deveopment of ‘studania’. one more update, studania project have a bit change in it. nowonwards it would help u learn the relation between moon and earth through simulated 3d models of moon and earth , u can alter their physical constant and see what would happen! enjoy the space!!!!
it’s very interesting to work with the physics of the planets and setting the variables, although it need too much research but it was a fun task.
it’s almost done just fixing some left over render. i would host it through edgeone as vercel is not responding to 3.js i hope judges would not mark it as a flag as they did last time with me.
Finally hosted Selene Bench on both platforms: Vercel: selene-bench.vercel.app EdgeOne: advisory-gray-xyuz9gon.edgeone.dev Live Earth–Moon physics lab — tweak gravity, watch eclipses, and try the cinematic collision mode.
should i change my readme? its being around a day from when i have submited my site and it is still pending, so i am doubting my readme is it a good one? can u check it and recommend me.
it is really a heart breaking movement when someone rejects your 3week’s efforts saying that it is ai😔. but its ok i respect the reviewers i would make some alteration and then try to resubmite it.
huff. finaly i changed a lot and try to code the badest i can or else reviewer would flag it as ai. i have edited the whole three.js all the styles of moon and earth , removed all camera angles and tried to make it as simple as possible, and now i am sending it for recheck. hope everything would go smooth.
isnt it crazy that u can make the following geometry with my demo by just setting gravity to max….
isnt it good? can any one tell me isnt a good readme or should i improve it?
Ships:
Finally hosted Selene Bench on both platforms: Vercel: selene-bench.vercel.app EdgeOne: advisory-gray-xyuz9gon.edgeone.dev Live Earth–Moon physics lab — tweak gravity, watch eclipses, and try the cinematic collision mode.
Let me tell u this is my 2nd ship and might be a meaningful one. I want to make it clear that i was able to post develog after 24 hour of coding as all previous devlogs got deleted due some misunderstanding of team....
|
1792857130.9702277
|
1792943530.9702277
|
|
17333
|
Frictionless by @NITHIN | Stardance
|
NITHIN
|
1
|
8.0
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-12T20:20:11Z", "hours": 4.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "QuickBox What I made: QuickBox is a single-page web toolbox that bundles together several small everyday tools into one place. It includes a clipboard history manager, text formatting tools, a quick to-do list, a unit converter, a password generator, a snippet vault for saving reusable text, timestamp tools, and a QR code generator. What was challenging: Getting all the different tools to work smoothly together on one page without conflicts was tricky, especially making sure each tool saved its own data separately using local storage so nothing got mixed up. Building the unit converter to handle multiple categories like length, weight, time, data size, and temperature with correct formulas also took careful testing. What I am proud of: I am proud of how everything works together as one cohesive toolbox instead of separate scattered tools. The clipboard history and snippet vault in particular solve a real repetitive annoyance, since copying and reusing text normally takes several steps, and here it is reduced to a single click. How to test it: Open the quickbox.html file in any modern browser. No installation, login, or setup is required. All data is stored locally in the browser, so your clipboard history, to-do list, and snippets will be saved even after closing and reopening the page. Try saving some text to the clipboard history or snippet vault, then click on an item to copy it instantly. You can also try the text tools by pasting text and applying transformations, or generate a password and a QR code to see the results update immediately.", "repo": "https://github.com/Nithinfgs/frictionless", "demo": "https://astonishing-souffle-d55679.netlify.app/"}]...
|
[{"post_id": 8101, "ts": "2026 [{"post_id": 8101, "ts": "2026-06-13T14:58:37Z", "hours": 4.0, "text": "8:28 PMClaude responded: Reworked the UI with a bold neo-brutalist style (cream background, hard shadows, custom fonts) instead of the generic AI look.Reworked the UI with a bold neo-brutalist style (cream background, hard shadows, custom fonts) instead of the generic AI look. Added two new features: a Pomodoro-style Focus Timer and a Decision Picker tool."}, {"post_id": 7664, "ts": "2026-06-12T20:09:55Z", "hours": 2.0, "text": "Just finished"}, {"post_id": 7529, "ts": "2026-06-12T16:01:50Z", "hours": 0.0, "text": "Building the frontend foundation. Refactoring CSS, polishing the design system, and making the dashboard responsive across screen sizes."}]...
|
Title: Frictionless by @NITHIN | Stardance
Devlog Title: Frictionless by @NITHIN | Stardance
Devlogs:
Building the frontend foundation. Refactoring CSS, polishing the design system, and making the dashboard responsive across screen sizes.
Just finished
8:28 PMClaude responded: Reworked the UI with a bold neo-brutalist style (cream background, hard shadows, custom fonts) instead of the generic AI look.Reworked the UI with a bold neo-brutalist style (cream background, hard shadows, custom fonts) instead of the generic AI look. Added two new features: a Pomodoro-style Focus Timer and a Decision Picker tool.
Ships:
QuickBox What I made: QuickBox is a single-page web toolbox that bundles together several small everyday tools into one place. It includes a clipboard history manager, text formatting tools, a quick to-do list, a unit converter, a password generator, a snippet vault for saving reusable text, timestamp tools, and a QR code generator. What was challenging: Getting all the different tools to work smoothly together on one page without conflicts was tricky, especially making sure each tool saved its own data separately using local storage so nothing got mixed up. Building the unit converter to handle multiple categories like length, weight, time, data size, and temperature with correct formulas also took careful testing. What I am proud of: I am proud of how everything works together as one cohesive toolbox instead of separate scattered tools. The clipboard history and snippet vault in particular solve a real repetitive annoyance, since copying and reusing text normally takes several steps, and here it is reduced to a single click. How to test it: Open the quickbox.html file in any modern browser. No installation, login, or setup is required. All data is stored locally in the browser, so your clipboard history, to-do list, and snippets will be saved even after closing and reopening the page. Try saving some text to the clipboard history or snippet vault, then click on an item to copy it instantly. You can also try the text tools by pasting text and applying transformations, or generate a password and a QR code to see the results update immediately....
|
1792882140.0688329
|
1793746140.0688329
|
|
64430
|
Void Run by @rayyans4890 | Stardance
|
rayyans4890
|
1
|
24.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T17:33:38Z", "hours": 24.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Void Run is a 2D browser shooter I made for Stardance. You play as a ship in space and shoot aliens that keep coming at you. There are 3 enemy types: Drifter, Stinger and Brute. Stingers show up from wave 2 and Brutes from wave 4. A new wave starts every 25 seconds and the enemies spawn faster each time, so the game keeps getting harder. The hardest part was the JavaScript. The movement and shooting took a while to get working, and the title screen took a lot longer than I expected. I used AI to help with the sectioning of the title screen in a few places, but most of the code is my own. I’m proud that I finished it. I built the HUD, the menus, the three enemies and the wave system myself, and it works on a phone too. To test it, press Play or Enter to start. Move with WASD or the arrow keys, shoot with Space or the mouse, and press P to pause. Your best score is saved in your browser, so try to beat it.", "repo": "https://github.com/rayyans4890-png/Void-Run", "demo": "https://rayyans4890-png.github.io/Void-Run/"}]...
|
[{"post_id": 81015, "ts": "202 [{"post_id": 81015, "ts": "2026-10-19T16:18:36Z", "hours": 8.7747, "text": "Devlog 4: Final Version The game is finished. The JavaScript is fully complete and the final CSS file is done. I added 3 enemy types to the game, Drifter, Stinger and Brute, and I’m very satisfied with the result. The title screen was also updated with a new tagline and a bit more information, and the HUD now shows the best score and the current wave. The waves get faster as you play, so the game gets harder the longer you survive. Completed JavaScript Final CSS 3 enemies Final title screen and HUD Remaining Write the README Upload the project to GitHub Ship the project Next steps Only the README is left. I will write it, upload everything to GitHub and then ship the project. I really hope it gets a good rating, since my goal is the Aula F75 keyboard."}, {"post_id": 77833, "ts": "2026-10-08T13:27:17Z", "hours": 4.6917, "text": "Devlog 3: JavaScript I finally wrote the JavaScript. The main movement and shooting are now working, and enemies appear on the screen. The game is playable for the first time, even though it is still rough. The boss keeps giving me problems and I could not get it to work properly. I decided to leave it for later instead of wasting more time on it today. Another issue is that the ship can only move left and right along a horizontal line. I plan to change this so it moves freely in every direction while you control it. Completed Main JavaScript Shooting Movement (horizontal only for now) Enemies showing on screen Pause button Known issues The boss is not working properly The ship can only move along a horizontal line Remaining Fix the boss Add free movement in all directions Next steps Fixing the movement comes first, since it affects how the whole game feels. Then I will go back to the boss."}, {"post_id": 77202, "ts": "2026-10-06T02:31:58Z", "hours": 7.305, "text": "Devlog 2: Title Screen The title screen is finally finished. It took a lot longer than I expected, but I’m happy with how clean it looks. I used AI to help me with the sectioning of the title screen in a few places, but most of the code was written by me. The screen now has the Void Run logo, the tagline, and a Play button. You can also press Enter to start. The HUD shows the score, hull, best score and wave number. At the bottom there is a controls bar and a list of the enemy types, which are Drifter, Stinger and Brute. Completed Title screen with logo and tagline Play button and Enter shortcut HUD layout Controls bar and enemy list HTML and CSS Remaining JavaScript Next steps Only the JavaScript is left. That includes movement, shooting and the enemies. I will try to finish it tomorrow."}, {"post_id": 76178, "ts": "2026-10-02T16:26:20Z", "hours": 2.8008, "text": "Devlog 1: Project Start I started working on Void Run today. It is a 2D browser shooter set in space, where you play as a ship shooting aliens that are coming at you. The idea is simple on purpose, and I want to keep it that way so I can actually finish it. For now I focused on the base of the project. I set up the styles with a dark theme and built the basic HUD and the title screen. I wanted the layout in place first so the game logic has something to sit on later. Completed Project setup Basic HUD Title screen Base styles in style.css Remaining Player movement Shooting mechanics Main game design Next steps Later today I will start on movement, shooting and the main design of the game. After that I can begin adding the aliens."}]...
|
Title: Void Run by @rayyans4890 | Stardance
Devlo Title: Void Run by @rayyans4890 | Stardance
Devlogs:
Devlog 1: Project Start I started working on Void Run today. It is a 2D browser shooter set in space, where you play as a ship shooting aliens that are coming at you. The idea is simple on purpose, and I want to keep it that way so I can actually finish it. For now I focused on the base of the project. I set up the styles with a dark theme and built the basic HUD and the title screen. I wanted the layout in place first so the game logic has something to sit on later. Completed Project setup Basic HUD Title screen Base styles in style.css Remaining Player movement Shooting mechanics Main game design Next steps Later today I will start on movement, shooting and the main design of the game. After that I can begin adding the aliens.
Devlog 2: Title Screen The title screen is finally finished. It took a lot longer than I expected, but I’m happy with how clean it looks. I used AI to help me with the sectioning of the title screen in a few places, but most of the code was written by me. The screen now has the Void Run logo, the tagline, and a Play button. You can also press Enter to start. The HUD shows the score, hull, best score and wave number. At the bottom there is a controls bar and a list of the enemy types, which are Drifter, Stinger and Brute. Completed Title screen with logo and tagline Play button and Enter shortcut HUD layout Controls bar and enemy list HTML and CSS Remaining JavaScript Next steps Only the JavaScript is left. That includes movement, shooting and the enemies. I will try to finish it tomorrow.
Devlog 3: JavaScript I finally wrote the JavaScript. The main movement and shooting are now working, and enemies appear on the screen. The game is playable for the first time, even though it is still rough. The boss keeps giving me problems and I could not get it to work properly. I decided to leave it for later instead of wasting more time on it today. Another issue is that the ship can only move left and right along a horizontal line. I plan to change this so it moves freely in every direction while you control it. Completed Main JavaScript Shooting Movement (horizontal only for now) Enemies showing on screen Pause button Known issues The boss is not working properly The ship can only move along a horizontal line Remaining Fix the boss Add free movement in all directions Next steps Fixing the movement comes first, since it affects how the whole game feels. Then I will go back to the boss.
Devlog 4: Final Version The game is finished. The JavaScript is fully complete and the final CSS file is done. I added 3 enemy types to the game, Drifter, Stinger and Brute, and I’m very satisfied with the result. The title screen was also updated with a new tagline and a bit more information, and the HUD now shows the best score and the current wave. The waves get faster as you play, so the game gets harder the longer you survive. Completed JavaScript Final CSS 3 enemies Final title screen and HUD Remaining Write the README Upload the project to GitHub Ship the project Next steps Only the README is left. I will write it, upload everything to GitHub and then ship the project. I really hope it gets a good rating, since my goal is the Aula F75 keyboard.
Ships:
Void Run is a 2D browser shooter I made for Stardance. You play as a ship in space and shoot aliens that keep coming at you. There are 3 enemy types: Drifter, Stinger and Brute. Stingers show up from wave 2 and Brutes from wave 4. A new wave starts every 25 seconds and the enemies spawn faster each time, so the game keeps getting harder. The hardest part was the JavaScript. The movement and shooting took a while to get working, and the title screen took a lot longer than I expected. I used AI to help with the sectioning of the title screen in a few places, but most of the code is my own. I’m proud that I finished it. I built the HUD, the menus, the three enemies and the wave system myself, and it works on a phone too. To test it, press Play or Enter to start. Move with WASD or the arrow keys, shoot with Space or the mouse, and press P to pause. Your best score is saved in your browser, so try to beat it....
|
1792857132.190074
|
1793721132.190074
|
|
67845
|
BrainF#ckery Compiler by @mindstormpro3 | Stardanc BrainF#ckery Compiler by @mindstormpro3 | Stardance...
|
mindstormpro3
|
0
|
5.43
|
0
|
[]
|
[{"post_id": 81025, "ts": "202 [{"post_id": 81025, "ts": "2026-10-19T16:25:31Z", "hours": 2.5642, "text": "BrainF#ckery Devlog #3! What’s Changed? Well… I added command line arguments!!! Gone are the days of manually typing your BF code into the terminal, now you can specify and input and output file, as well as pass flags! I also published to PyPi!!! Find it Here! On top of all that, I also made a bunch of small changes and modifications to fix bugs and make my compiler work better. Command Line Args! Here’s the current full list: -h , or --Help -> Your basic help command, don’t need to say much here -v , or --Verbose -> Enables verbose (extra) logging -i or --Input -> Takes a file path as an input file (a .bf file) -o or --Output -> Takes a file path to be the outputted executable (a .exe file)| -r or --Run -> Runs the newly compiled executable right after it’s done being compiled. c or --Clean -> deletes the build files ( .obj and .asm product files) after compilation is complete ***And hopefully more to come! I already have some ideas! : b WE’RE ON PYPI!!!!!!!!!! Check it out HERE!!! And finally, the boring bugfixes… :( A couple things: I realized, after a very smart friend of mine pointed it out, that I was not popping the stack after pushing it to call a function… If I left this in, more complex programs would crash due to a stack overflow…. I added comment clearing! Originally, the compiler would only read BF code that happened to be one of the 8 valid characters, but what if you happened to put a valid BF char in a comment? Well now there’s a loop that runs before the rest of the compiler that strips all lines of their text after a ; character, meaning all comments get deleted! I also added more error handling, so in case of a file not found or something, instead of the code crashing it just prints an error to the logs and returns. Thanks for sticking around for my devlog! see ya next time! : b"}, {"post_id": 77560, "ts": "2026-10-07T14:07:07Z", "hours": 2.4694, "text": "BrainF#ckery Devlog #2! What’s Changed? A LOT! Since the last devlog, I’ve practically finished the BF -> Assembly compiler, and even used subprocess.run() to call NASM and GCC to build the script! It currently looks for a file called in.bf and then compiles it into an EXE that gets dumped straight into a build/ folder along with the out.asm and out.obj files! How does the Compiler actually work? Right now, all the compiler really does is go character by character in the input file, and if the character is one of the special 8, ( <>+-,.[] ) I just append some assembly into the out.asm file that corresponds with the instruction. For example, for + I just add inc byte [ebx] which increments the byte stored at the location the EBX register is pointing at. (EBX stores the tape pointer, and you manipulate it with < and > ). The cool thing about writing the compiler like this is that it literally just ignores everything else, so I don’t have to write code to “clean” the input file of newlines, tabs, spaces, comments, ect. Now for [ and ] , they’re a bit special. The way these guys work is I have a stack and counter. Whenever I add a [ to the assembly, I first increment the counter by 1 and then push the value to the stack. Then I use fstrings to modify the assembly I’m about to add by doing this: cmp byte [ebx], 0 jz loopEnd{bracketCounter} Now to break this down, cmp is comparing the current cell ( byte [ebx] ) with 0. Then, the next instruction, jz only jumps to the given location in code if the two values compared previously are equal to eachother. The fstrings come into play because they modify this jump location to be loopEnd(whatever the counter is) , and this location becomes the corrisponding ] when that instruction is read. What’s next? Well, firstly I need to make a bunch of QoL changes to the compiler, like allowing the user to pass custom input and output names/directories, specify whether or not to fully compile or leave it as a chunk of assembly, ect I also want to make a slightly higher level BF-esque language, where you can do stuff like + 2, 5 to increase cell 2 by 5, if statements, batch outputting, ect, but that’s not gonna be the easiest thing… See Ya Later! - Elio"}, {"post_id": 76632, "ts": "2026-10-04T06:57:23Z", "hours": 0.3983, "text": "BrainF#ckery Devlog #1! What is BrainF#ckery? BrainF#ckery, or BFery for short, is a compiler for Brainf#ck! It’s written fully in python and takes BF and converts it into working assembly that you can plug into NASM and gcc to turn BF into a working executable! But why? Shut Up. How will it work? BFery will essentially just read and translate any BF directly into assembly. It’s actually really simple, since most of BF converts into a single line of assembly, like > , which moves the tape pointer up one, translates to inc rbx . That’s it! the rest are as follows: < -> dec rbx (dec means to decrease) + -> inc byte [rbx] ( byte tells NASM to only write one byte of data, and the two brackets here are the equivalent of dereferencing a pointer in C.) - -> dec byte [rbx] the rest( [ ] , . ) I have yet to figure out… OK Thats really all for this devlog, thanks for stoppin’ by! Elio"}]...
|
Title: BrainF#ckery Compiler by @mindstormpro3 | S Title: BrainF#ckery Compiler by @mindstormpro3 | Stardance
Devlogs:
BrainF#ckery Devlog #1! What is BrainF#ckery? BrainF#ckery, or BFery for short, is a compiler for Brainf#ck! It’s written fully in python and takes BF and converts it into working assembly that you can plug into NASM and gcc to turn BF into a working executable! But why? Shut Up. How will it work? BFery will essentially just read and translate any BF directly into assembly. It’s actually really simple, since most of BF converts into a single line of assembly, like > , which moves the tape pointer up one, translates to inc rbx . That’s it! the rest are as follows: < -> dec rbx (dec means to decrease) + -> inc byte [rbx] ( byte tells NASM to only write one byte of data, and the two brackets here are the equivalent of dereferencing a pointer in C.) - -> dec byte [rbx] the rest( [ ] , . ) I have yet to figure out… OK Thats really all for this devlog, thanks for stoppin’ by! Elio
BrainF#ckery Devlog #2! What’s Changed? A LOT! Since the last devlog, I’ve practically finished the BF -> Assembly compiler, and even used subprocess.run() to call NASM and GCC to build the script! It currently looks for a file called in.bf and then compiles it into an EXE that gets dumped straight into a build/ folder along with the out.asm and out.obj files! How does the Compiler actually work? Right now, all the compiler really does is go character by character in the input file, and if the character is one of the special 8, ( <>+-,.[] ) I just append some assembly into the out.asm file that corresponds with the instruction. For example, for + I just add inc byte [ebx] which increments the byte stored at the location the EBX register is pointing at. (EBX stores the tape pointer, and you manipulate it with < and > ). The cool thing about writing the compiler like this is that it literally just ignores everything else, so I don’t have to write code to “clean” the input file of newlines, tabs, spaces, comments, ect. Now for [ and ] , they’re a bit special. The way these guys work is I have a stack and counter. Whenever I add a [ to the assembly, I first increment the counter by 1 and then push the value to the stack. Then I use fstrings to modify the assembly I’m about to add by doing this: cmp byte [ebx], 0 jz loopEnd{bracketCounter} Now to break this down, cmp is comparing the current cell ( byte [ebx] ) with 0. Then, the next instruction, jz only jumps to the given location in code if the two values compared previously are equal to eachother. The fstrings come into play because they modify this jump location to be loopEnd(whatever the counter is) , and this location becomes the corrisponding ] when that instruction is read. What’s next? Well, firstly I need to make a bunch of QoL changes to the compiler, like allowing the user to pass custom input and output names/directories, specify whether or not to fully compile or leave it as a chunk of assembly, ect I also want to make a slightly higher level BF-esque language, where you can do stuff like + 2, 5 to increase cell 2 by 5, if statements, batch outputting, ect, but that’s not gonna be the easiest thing… See Ya Later! - Elio
BrainF#ckery Devlog #3! What’s Changed? Well… I added command line arguments!!! Gone are the days of manually typing your BF code into the terminal, now you can specify and input and output file, as well as pass flags! I also published to PyPi!!! Find it Here! On top of all that, I also made a bunch of small changes and modifications to fix bugs and make my compiler work better. Command Line Args! Here’s the current full list: -h , or --Help -> Your basic help command, don’t need to say much here -v , or --Verbose -> Enables verbose (extra) logging -i or --Input -> Takes a file path as an input file (a .bf file) -o or --Output -> Takes a file path to be the outputted executable (a .exe file)| -r or --Run -> Runs the newly compiled executable right after it’s done being compiled. c or --Clean -> deletes the build files ( .obj and .asm product files) after compilation is complete ***And hopefully more to come! I already have some ideas! : b WE’RE ON PYPI!!!!!!!!!! Check it out HERE!!! And finally, the boring bugfixes… :( A couple things: I realized, after a very smart friend of mine pointed it out, that I was not popping the stack after pushing it to call a function… If I left this in, more complex programs would crash due to a stack overflow…. I added comment clearing! Originally, the compiler would only read BF code that happened to be one of the 8 valid characters, but what if you happened to put a valid BF char in a comment? Well now there’s a loop that runs before the rest of the compiler that strips all lines of their text after a ; character, meaning all comments get deleted! I also added more error handling, so in case of a file not found or something, instead of the code crashing it just prints an error to the logs and returns. Thanks for sticking around for my devlog! see ya next time! : b...
|
1792468320.23423
|
1793073120.23423
|
|
65921
|
Gamer's Baku by @PrakstheBruce | Stardance
|
PrakstheBruce
|
0
|
4.22
|
0
|
[]
|
[{"post_id": 81027, "ts": "202 [{"post_id": 81027, "ts": "2026-10-19T16:37:03Z", "hours": 4.2247, "text": "Gamer Baku — Game Development Devlog 1 Engine used - Godot “ WarioWare-style minigame collection” The Idea Gamer Baku is a fast-paced minigame project inspired by WarioWare. The idea is to create a fun collection of short challenges, starting with a Kung Fu Panda-inspired character jumping across platforms to catch dumplings. I began developing it using Godot and the Stardance WarioWare mission guide. Building the Game I started by creating the title screen and connecting the Start button to the main level. This took some debugging because of incorrect scene paths and button signals, but I eventually got the transition working. Next, I built the level interface with a timer, level display, and dumpling icons. I created a separate themed timer scene and worked on the countdown logic to make it reusable. Making the Gameplay Work I created the player using CharacterBody2D and implemented horizontal movement, jumping, and gravity. One of my biggest challenges was the player falling through platforms. After debugging the collision shapes, I discovered that two platforms shared the same RectangleShape2D resource. Separating them fixed the problem. Once movement and collisions worked, I added dumpling collectibles using Area2D . Collecting a dumpling increases the global counter, hides the dumpling, and makes it reappear after five seconds. I also added a UI counter that updates automatically. #Challenges and Learning Throughout development, I worked through issues involving scene transitions, collision detection, timers, signals, and global variables. Each bug helped me understand Godot’s scene system and how different gameplay components communicate. The project has taught me that game development isn’t just about writing code. It’s also about testing, debugging, and connecting individual systems into a working experience. What’s Next? My next goals are to: Connect the timer to proper win and failure conditions. Finish the lives system and minigame transitions. Build a second minigame with a different challenge. Create original Winner and Death screens. Polish the gameplay, write a README, and publish the finished game. -> Final Thoughts Gamer Baku is still a work in progress, but the foundation is taking shape. The title screen, player movement, platform collisions, and dumpling collection mechanics are working. What started as an idea inspired by WarioWare has become a hands-on learning experience in game development. Now, the goal is to turn these individual systems into a complete and enjoyable minigame collection. This is only the beginning of Gamer Baku."}]...
|
Title: Gamer's Baku by @PrakstheBruce | Starda Title: Gamer's Baku by @PrakstheBruce | Stardance
Devlogs:
Gamer Baku — Game Development Devlog 1 Engine used - Godot “ WarioWare-style minigame collection” The Idea Gamer Baku is a fast-paced minigame project inspired by WarioWare. The idea is to create a fun collection of short challenges, starting with a Kung Fu Panda-inspired character jumping across platforms to catch dumplings. I began developing it using Godot and the Stardance WarioWare mission guide. Building the Game I started by creating the title screen and connecting the Start button to the main level. This took some debugging because of incorrect scene paths and button signals, but I eventually got the transition working. Next, I built the level interface with a timer, level display, and dumpling icons. I created a separate themed timer scene and worked on the countdown logic to make it reusable. Making the Gameplay Work I created the player using CharacterBody2D and implemented horizontal movement, jumping, and gravity. One of my biggest challenges was the player falling through platforms. After debugging the collision shapes, I discovered that two platforms shared the same RectangleShape2D resource. Separating them fixed the problem. Once movement and collisions worked, I added dumpling collectibles using Area2D . Collecting a dumpling increases the global counter, hides the dumpling, and makes it reappear after five seconds. I also added a UI counter that updates automatically. #Challenges and Learning Throughout development, I worked through issues involving scene transitions, collision detection, timers, signals, and global variables. Each bug helped me understand Godot’s scene system and how different gameplay components communicate. The project has taught me that game development isn’t just about writing code. It’s also about testing, debugging, and connecting individual systems into a working experience. What’s Next? My next goals are to: Connect the timer to proper win and failure conditions. Finish the lives system and minigame transitions. Build a second minigame with a different challenge. Create original Winner and Death screens. Polish the gameplay, write a README, and publish the finished game. -> Final Thoughts Gamer Baku is still a work in progress, but the foundation is taking shape. The title screen, player movement, platform collisions, and dumpling collection mechanics are working. What started as an idea inspired by WarioWare has become a hands-on learning experience in game development. Now, the goal is to turn these individual systems into a complete and enjoyable minigame collection. This is only the beginning of Gamer Baku....
|
1792457472.380902
|
1793062272.380902
|
|
68159
|
willy's blog by @asherwandenreich | Stardance
|
asherwandenreich
|
0
|
5.52
|
0
|
[]
|
[{"post_id": 81035, "ts": "202 [{"post_id": 81035, "ts": "2026-10-19T17:01:55Z", "hours": 2.4525, "text": "Pushed “dark mode & about pg.” Deleted some unused files that came from installing next.js on the wrong layer/folder. Launched the website via npm run dev and used the VS Code Simple Browser feature. Took html notes in html.md, learned spacing, font size, and font color code. Found out I couldn’t use an apostrophe, and learned how to make next.js understand. Deleted all the default next.js features and started using Tailwind to make it look presentable. Finally made what I’m most proud of this devlog: the light/dark mode toggle switch. Switched dark mode from following the OS light/dark mode to following a class. Tested if it works by adding the class to layout.tsx. Made first client component (components/darkmode.tsx). Made my own button, troubleshooted an error caused by a missing return, and import/export."}, {"post_id": 79730, "ts": "2026-10-15T07:39:26Z", "hours": 0.7, "text": "Finished “Build Your Own Blog,” yay! In the repo there’s a little .md I created to take notes on the git commands and the flags I used. Spent a while pushing the code to GitHub through the terminal instead of using Claude, which I was used to doing because of a hackathon I did with my friends. Spent more time finnicking around with Vercel (time which wasn’t recorded for Stardance) and finally deploying the website. Super happy with the end result and I have ambitious plans for the next steps. I spent a few hours last night setting up Oracle Cloud and installing Headscape on that server. I want to use Cloudflare for DNS and buy my own domain, and host the Oracle Cloud / Headscape VPN on a subdomain."}, {"post_id": 79257, "ts": "2026-10-13T07:22:19Z", "hours": 2.3686, "text": "Following the tutorial, “Build your own Blog.” Currently on step 7/9, but somewhere along the line something went wrong. (screenshot attached below) Maybe because I wanted to type out the code instead of copy and pasting, but idk. Trying to finish the tutorial and deploy to Vercel, and then I want to start experimenting with 3D libraries and motion like you often see on Instagram reels."}]...
|
Title: willy's blog by @asherwandenreich | Sta Title: willy's blog by @asherwandenreich | Stardance
Devlogs:
Following the tutorial, “Build your own Blog.” Currently on step 7/9, but somewhere along the line something went wrong. (screenshot attached below) Maybe because I wanted to type out the code instead of copy and pasting, but idk. Trying to finish the tutorial and deploy to Vercel, and then I want to start experimenting with 3D libraries and motion like you often see on Instagram reels.
Finished “Build Your Own Blog,” yay! In the repo there’s a little .md I created to take notes on the git commands and the flags I used. Spent a while pushing the code to GitHub through the terminal instead of using Claude, which I was used to doing because of a hackathon I did with my friends. Spent more time finnicking around with Vercel (time which wasn’t recorded for Stardance) and finally deploying the website. Super happy with the end result and I have ambitious plans for the next steps. I spent a few hours last night setting up Oracle Cloud and installing Headscape on that server. I want to use Cloudflare for DNS and buy my own domain, and host the Oracle Cloud / Headscape VPN on a subdomain.
Pushed “dark mode & about pg.” Deleted some unused files that came from installing next.js on the wrong layer/folder. Launched the website via npm run dev and used the VS Code Simple Browser feature. Took html notes in html.md, learned spacing, font size, and font color code. Found out I couldn’t use an apostrophe, and learned how to make next.js understand. Deleted all the default next.js features and started using Tailwind to make it look presentable. Finally made what I’m most proud of this devlog: the light/dark mode toggle switch. Switched dark mode from following the OS light/dark mode to following a class. Tested if it works by adding the class to layout.tsx. Made first client component (components/darkmode.tsx). Made my own button, troubleshooted an error caused by a missing return, and import/export....
|
1792471681.7449305
|
1793076481.7449305
|
|
16497
|
HYDRA by @JoonHyuk | Stardance
|
JoonHyuk
|
0
|
1.37
|
0
|
[]
|
[{"post_id": 8104, "ts": "2026 [{"post_id": 8104, "ts": "2026-06-13T15:01:43Z", "hours": 0.2733, "text": "FINISHED ALL WIRING!"}, {"post_id": 7263, "ts": "2026-06-12T03:36:02Z", "hours": 1.0928, "text": "FINSIHED DAY 1"}]...
|
Title: HYDRA by @JoonHyuk | Stardance
Devlogs:
FI Title: HYDRA by @JoonHyuk | Stardance
Devlogs:
FINSIHED DAY 1
FINISHED ALL WIRING!...
|
1792763260.9811487
|
1793368060.9811487
|
|
69067
|
DCD (Digital Cassette Device) by @AoujHaider | Sta DCD (Digital Cassette Device) by @AoujHaider | Stardance...
|
AoujHaider
|
0
|
16.36
|
0
|
[]
|
[{"post_id": 81040, "ts": "202 [{"post_id": 81040, "ts": "2026-10-19T17:20:59Z", "hours": 0.8431, "text": "Very nice"}, {"post_id": 80503, "ts": "2026-10-17T21:49:22Z", "hours": 2.8322, "text": "still working on the pcb, just need to log in my hours"}, {"post_id": 80129, "ts": "2026-10-16T09:50:20Z", "hours": 4.1878, "text": "just logging in my hours, i forgot to use lapse when designing this ;("}, {"post_id": 79893, "ts": "2026-10-15T18:05:35Z", "hours": 1.9364, "text": "Finished designing the case and stuff for the DCD, the empty space is for the “cassette” I’m designing so i will update it when I’m done, If anyone has some design changes they would like to make feel free to comment"}, {"post_id": 79336, "ts": "2026-10-13T15:32:34Z", "hours": 4.6767, "text": "I have finally finished up my schematics for my project AFTER 2 DAYS."}, {"post_id": 78996, "ts": "2026-10-12T09:17:06Z", "hours": 1.8869, "text": "I’ve finished the brainstorm and design phase of my project. It’s basically a digital version of a cassette tape (ikik reinventing the wheel) but i wanted to give the cassette player (Inspired by the Sony TPS L2) a more modern touch, Modern being an oled screen, more minimally designed buttons (thinking about using haptics) small and slim form factor plus some cyberpunk-esk design elements (i haven’t added that to the design yet). On paper it doesn’t feel as exciting or brilliant but from the survey i did 60-70% of the people i surveyed would buy this if it’s resonably priced. Please let me know if you would make any changes or want anything added into it,"}]...
|
Title: DCD (Digital Cassette Device) by @AoujHaide Title: DCD (Digital Cassette Device) by @AoujHaider | Stardance
Devlogs:
I’ve finished the brainstorm and design phase of my project. It’s basically a digital version of a cassette tape (ikik reinventing the wheel) but i wanted to give the cassette player (Inspired by the Sony TPS L2) a more modern touch, Modern being an oled screen, more minimally designed buttons (thinking about using haptics) small and slim form factor plus some cyberpunk-esk design elements (i haven’t added that to the design yet). On paper it doesn’t feel as exciting or brilliant but from the survey i did 60-70% of the people i surveyed would buy this if it’s resonably priced. Please let me know if you would make any changes or want anything added into it,
I have finally finished up my schematics for my project AFTER 2 DAYS.
Finished designing the case and stuff for the DCD, the empty space is for the “cassette” I’m designing so i will update it when I’m done, If anyone has some design changes they would like to make feel free to comment
just logging in my hours, i forgot to use lapse when designing this ;(
still working on the pcb, just need to log in my hours
Very nice...
|
1792475606.939642
|
1793080406.939642
|
|
46067
|
My own site! by @nitikpsn | Stardance
|
nitikpsn
|
1
|
2.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T17:27:09Z", "hours": 2.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "shipping my site ;)", "repo": "https://github.com/Nitikpsn/nitik-personal-siite", "demo": "https://www.nitikpsn.xyz/"}]...
|
[{"post_id": 81041, "ts": "202 [{"post_id": 81041, "ts": "2026-10-19T17:21:50Z", "hours": 2.3806, "text": "My personal site is done ;)"}]...
|
Title: My own site! by @nitikpsn | Stardance
Devl Title: My own site! by @nitikpsn | Stardance
Devlogs:
My personal site is done ;)
Ships:
shipping my site ;)...
|
1792648478.892632
|
1792734878.892632
|
|
32613
|
ImageTranslation by @nbth | Stardance
|
nbth
|
0
|
23.33
|
0
|
[]
|
[{"post_id": 81042, "ts": "202 [{"post_id": 81042, "ts": "2026-10-19T17:24:25Z", "hours": 0.4008, "text": "First Release work good on https://cubari.moe/read/mangadex/7a82d0ef-034e-427b-bf5c-ed7d08ddbd6b/1/1/ check the release note please https://github.com/code-ga/image-translate-extension/releases/tag/v0.1.0"}, {"post_id": 80698, "ts": "2026-10-18T15:29:22Z", "hours": 3.6092, "text": "Devlog TL;DR Translation: Experimented with local NLLB and Google Translate, weighing privacy against performance. Architecture: Moved translation into an offscreen document with a dedicated Web Worker. Performance: Added caching, task scheduling, and bounded concurrency. OCR: Improved error handling, caching, and image processing reliability. Release: Brought the core features together for Image Translate v0.1.0. Privacy vs. performance My original goal was to keep everything local, so users wouldn’t have to send their text to an external service. However, NLLB-200 comes with a hefty model size of around 2.4 GB, which can put serious pressure on browser memory. I experimented with Google Translate as an alternative. It’s much lighter on the user’s device, but there’s a trade-off: text sent for translation leaves the device and is processed by a third-party service. That means giving up some privacy for convenience and lower resource usage. Neither approach is perfect. Local inference costs memory and performance; hosted translation introduces an external data dependency. I’m still figuring out the right balance for an extension whose original motivation was privacy. Moving heavy work out of the background Chrome’s Manifest V3 service worker isn’t ideal for heavy inference. I moved translation into an offscreen document and added a dedicated Web Worker for model inference. The background script now mainly routes messages. I also switched to runtime.connect ports for longer-running communication to reduce messaging failures when the service worker gets suspended. Caching and scheduling Repeated requests were wasting time, so I added an L1 memory cache and an L2 IndexedDB cache, using SHA-256 keys to identify repeated requests. A priority queue, bounded concurrency, and admission control help prevent pages containing lots of images from overwhelming the extension. Debugging wasn’t fun I ran into WebGPU/WASM initialization failures, an OCR crash caused by getContext is not a function , and InvalidCharacterError from malformed Base64 data. Turns out, running an ML model is only half the battle. Browser APIs, cross-origin restrictions, and memory limits can be just as frustrating. Making OCR more reliable I switched batch processing to Promise.allSettled , allowing individual images to fail without breaking the whole batch. OCR results are cached locally with a seven-day TTL, and the popup now tracks errors per item. I also added script detection, a tinyld fallback, text normalization, OCR region grouping, and token protection to support the translation pipeline. What’s next? Image Translate v0.1.0 brings together automatic image and canvas detection, PaddleOCR, translation, hover popups, caching, domain settings, and error tracking. The next challenge is finding a sensible balance between translation quality, memory usage, and privacy. Ideally, users should have a clear choice between local translation and hosted services rather than having that trade-off hidden from them."}, {"post_id": 59653, "ts": "2026-09-01T15:55:27Z", "hours": 4.4203, "text": "TL;DR Messaging: Fixed a silent settings synchronization bug by introducing typed, namespaced messages. Hover Translation: Added a hover-to-translate popup with language selection and race-condition-safe handling. Default Language: Users can now configure a default translation language that syncs across tabs. Error Feedback: OCR and translation failures now show toast notifications instead of silently failing. Domain Rules: Fixed empty domain lists incorrectly allowing translation everywhere. Auto-translate: Restored automatic translation behavior that was accidentally removed during the refactor. Unified messaging I discovered a pretty annoying bug in the settings synchronization system. The popup was sending: ts\"notify-settings-changed\" while the background script was listening for: ts\"settings/notify-changed\" Because of this mismatch, settings changes were not propagated correctly and failed silently. To avoid this kind of problem in the future, I introduced types/messages.ts with typed, namespaced message routing. Now the message names are centralized instead of being manually written across different parts of the extension. Settings changes can now propagate correctly and update active tabs in real time. Hover translation popup The overlay can now translate individual OCR regions directly through a hover popup. When hovering over an OCR box, the extension displays: The original detected text A target language selector The translated result The popup uses a small debounce before appearing and has a delayed close behavior when the mouse leaves. If the user moves back into the popup, the close action is cancelled. I also had to handle race conditions. Translation requests can finish in a different order than they were created, so late responses are ignored when they no longer belong to the currently active popup. The popup handles its own translation request and lifecycle, which makes it much more self-contained. Default translation language (model error) Users can now choose a default target language in Settings. The current default is Vietnamese ( vi ), with support for 17 languages. The setting is stored using browser.storage.sync and changes are broadcast to active tabs. The language selected inside a hover popup is temporary, while the configured default language remains the user’s persistent preference. In the future we will switch from machine translate or deep learning translate Error feedback instead of silent failures Previously, OCR and translation errors could fail without giving the user any useful feedback. I added utils/toast.ts to provide inline error notifications. Errors are debounced and deduplicated so the user does not get spammed with notifications when multiple failures happen at once. I also extracted shared popup styling into utils/popup-base.ts to reduce duplicated UI logic. Empty domains fix There was another logic issue with enabledDomains . An empty domain list should mean: Translate nothing. However, the previous implementation treated an empty list as if every domain was allowed. This has now been fixed in both background.ts and isDomainAllowed() . An empty list correctly disables translation entirely. Auto-translate restored During the refactor, some of the automatic translation logic was accidentally removed. This included: autoTranslateIfAllowed() URL polling The live DOM observer As a result, the extension would remain inactive until the user manually triggered it. These behaviors have now been restored, so automatic translation works again when the page loads and when new content appears dynamically."}, {"post_id": 49630, "ts": "2026-08-18T14:56:13Z", "hours": 5.2028, "text": "tl;dr WXT.js: Refactored the extension into smaller, more maintainable modules. Context Menu: Inject content scripts on pages to reliably detect clicked elements — a privacy/resource trade-off. Overlay: Reworked image overlays to be more independent from the website’s DOM and avoid rendering on invisible images. SPA Support: Added DOM-change detection for React-style navigation, at the cost of some extra resource usage. PaddleOCR: Still fighting text-box grouping 😭. Current grouping is imperfect, and we’re considering a better OCR model. WXT.js This is really easy. Almost everything is guided on their introduction page, so I need to follow it. Also, I need to refactor code from 1 huge file into many smaller files, which helps me maintain this more easily better context menu ( and first trade-off) Uh, due to the main problem that extensions don’t know which one was clicked. So I need to trade off user privacy with convenience. From now on, extensions will inject a content script into every page that you open, including enabling and disabling auto-translation better overlay box Over time, the extension displays an image by adding an extension element to a div, which is the image tag’s parent. But now we switch the approach to create a separate div that does not depend ( or depends less) on how the page works. Also, we need to check whether the current image displays are visible, or we will not render an overlay box for them. Add case for SPA web For frameworks like React.js, navigation is often handled as a Single-Page Application (SPA) update rather than a traditional page reload. When the user navigates to a different page, the application may update the DOM and the URL in the browser without triggering a full page refresh.Because of this, the extension cannot rely only on events such as page reloads or tab switches to detect when it needs to update its state. We therefore need to listen for DOM changes so the extension can detect when the application has rendered new content and reload or reinitialize its functionality accordingly. This will consume more resources, but we are unable to measure them Paddle-OCR and grouping text box (I hate this; why yolo ) This is the very unsolved problem that may annoy the user and me. The problem is paddle-ocr working like this, meaning it will separate the text bubble into smaller parts, which will make translation crazy. Currently, we are adding grouping to solve the issue of text on the same line, but the solution is not ready yet. Also, we are considering switching models for a better experience"}, {"post_id": 36271, "ts": "2026-07-28T08:22:41Z", "hours": 6.1336, "text": "tl;dr I am trying to make the extension more convenient for the user and boost the performance of AI tasks. And switch to a new framework for a better development cycle ( https://crxjs.dev is really bad; don’t use that currently) Why Because I recently found a manga page that has the manga that I want to read, I tried to make the extension more useful by adding a domain system (URL matching system ) which will automatically translate pages that match the URL. CORS problem This is not the main section, but I want to tell you about why this extension has some limitations with strictly page. Due to the original idea, focus on local first, but Chrome’s security design mainly blocks other processes from accessing image data of pages that have a config to block ( their CORS config ), so our extension will unable to run on that page, also i will work on a local backend to handle this problem (in a good situation) #Domain system design This design is quite weird because that firstly working on all page start will that domain. Then I used that, and all image include thumnail will be translated, and so i switched to a regex design, which will be more dynamic for users Extension page I am trying to make them easier to use, so I designed a simple ui ( tell AI to do that ). That will be more useful in the future ( currently, that just helps me in debug stage ) Background change Because of real-time (auto-translation mode ), we need to switch from using single mode to batch mode of the OCR library. If we continue to use the legacy solution that will make the user’s computer overloaded and cause a huge delay ( and error rate ). So we are switching to this solution. Also, is the batching solution for the background ( manager process, orchestrator) The background process will collect tasks from the content.js process in all tabs and then send them to the OCR and translate process ( batchingly, like 5 images per step, in about 80ms if no image is in the queue to keep offscreen work) build problem Vite builds to modular JavaScript code. But browsers don’t like that due to backward compatibility, so they reject it. next step I will migrating to mordern framework ( https://wxt.dev/ ), which will help me in the build process (I have a build problem with the module webpack of Vite, sadly )"}, {"post_id": 24788, "ts": "2026-07-08T16:12:20Z", "hours": 3.5633, "text": "After many efforts, I can OCR the image locally. (pic. 1 ) Tech choosing Firstly, I need to find a way to help me use the npm ecosystem. So I know that I can use Vite ( because Chrome just cares about how you define config in manifest, other files are not important ). but their don’t support live-reload, which makes me feel very bad in development. I hope I can use https://crxjs.dev/guide/installation/create-crxjs/ for this. UI and UX development Then I think that I want to build up some menu in the extension page, which will make my extension very modern. But I think about that, if I try to translate just one image, how can the user translate just one image? Because of that, I decided to build up a context menu that allows users to choose what they want to translate and just leave the extension page there with hello text. (pic. 2 and pic. 3 ) CORS problem Then I need to solve some problem with CORS in Chrome ( legendary web development problem ). They won’t allow me to just read the image tag, so I need to send the image URL to the background Context problem But background doesn’t have the context (like document.createElement or canvas, which will be able to boost my OCR speed ) which normal HTML page has, so I need to create an offscreen. Then the CORS problem comes back, and I need to build up some indexed storage solution to fix this. Thanks to Chrome. TL;DR And after their cors problem, isolation problem, chrome problem i here to present you the image that has the box showing you text that you see 😢😢"}]...
|
Title: ImageTranslation by @nbth | Stardance
Devl Title: ImageTranslation by @nbth | Stardance
Devlogs:
After many efforts, I can OCR the image locally. (pic. 1 ) Tech choosing Firstly, I need to find a way to help me use the npm ecosystem. So I know that I can use Vite ( because Chrome just cares about how you define config in manifest, other files are not important ). but their don’t support live-reload, which makes me feel very bad in development. I hope I can use https://crxjs.dev/guide/installation/create-crxjs/ for this. UI and UX development Then I think that I want to build up some menu in the extension page, which will make my extension very modern. But I think about that, if I try to translate just one image, how can the user translate just one image? Because of that, I decided to build up a context menu that allows users to choose what they want to translate and just leave the extension page there with hello text. (pic. 2 and pic. 3 ) CORS problem Then I need to solve some problem with CORS in Chrome ( legendary web development problem ). They won’t allow me to just read the image tag, so I need to send the image URL to the background Context problem But background doesn’t have the context (like document.createElement or canvas, which will be able to boost my OCR speed ) which normal HTML page has, so I need to create an offscreen. Then the CORS problem comes back, and I need to build up some indexed storage solution to fix this. Thanks to Chrome. TL;DR And after their cors problem, isolation problem, chrome problem i here to present you the image that has the box showing you text that you see 😢😢
tl;dr I am trying to make the extension more convenient for the user and boost the performance of AI tasks. And switch to a new framework for a better development cycle ( https://crxjs.dev is really bad; don’t use that currently) Why Because I recently found a manga page that has the manga that I want to read, I tried to make the extension more useful by adding a domain system (URL matching system ) which will automatically translate pages that match the URL. CORS problem This is not the main section, but I want to tell you about why this extension has some limitations with strictly page. Due to the original idea, focus on local first, but Chrome’s security design mainly blocks other processes from accessing image data of pages that have a config to block ( their CORS config ), so our extension will unable to run on that page, also i will work on a local backend to handle this problem (in a good situation) #Domain system design This design is quite weird because that firstly working on all page start will that domain. Then I used that, and all image include thumnail will be translated, and so i switched to a regex design, which will be more dynamic for users Extension page I am trying to make them easier to use, so I designed a simple ui ( tell AI to do that ). That will be more useful in the future ( currently, that just helps me in debug stage ) Background change Because of real-time (auto-translation mode ), we need to switch from using single mode to batch mode of the OCR library. If we continue to use the legacy solution that will make the user’s computer overloaded and cause a huge delay ( and error rate ). So we are switching to this solution. Also, is the batching solution for the background ( manager process, orchestrator) The background process will collect tasks from the content.js process in all tabs and then send them to the OCR and translate process ( batchingly, like 5 images per step, in about 80ms if no image is in the queue to keep offscreen work) build problem Vite builds to modular JavaScript code. But browsers don’t like that due to backward compatibility, so they reject it. next step I will migrating to mordern framework ( https://wxt.dev/ ), which will help me in the build process (I have a build problem with the module webpack of Vite, sadly )
tl;dr WXT.js: Refactored the extension into smaller, more maintainable modules. Context Menu: Inject content scripts on pages to reliably detect clicked elements — a privacy/resource trade-off. Overlay: Reworked image overlays to be more independent from the website’s DOM and avoid rendering on invisible images. SPA Support: Added DOM-change detection for React-style navigation, at the cost of some extra resource usage. PaddleOCR: Still fighting text-box grouping 😭. Current grouping is imperfect, and we’re considering a better OCR model. WXT.js This is really easy. Almost everything is guided on their introduction page, so I need to follow it. Also, I need to refactor code from 1 huge file into many smaller files, which helps me maintain this more easily better context menu ( and first trade-off) Uh, due to the main problem that extensions don’t know which one was clicked. So I need to trade off user privacy with convenience. From now on, extensions will inject a content script into every page that you open, including enabling and disabling auto-translation better overlay box Over time, the extension displays an image by adding an extension element to a div, which is the image tag’s parent. But now we switch the approach to create a separate div that does not depend ( or depends less) on how the page works. Also, we need to check whether the current image displays are visible, or we will not render an overlay box for them. Add case for SPA web For frameworks like React.js, navigation is often handled as a Single-Page Application (SPA) update rather than a traditional page reload. When the user navigates to a different page, the application may update the DOM and the URL in the browser without triggering a full page refresh.Because of this, the extension cannot rely only on events such as page reloads or tab switches to detect when it needs to update its state. We therefore need to listen for DOM changes so the extension can detect when the application has rendered new content and reload or reinitialize its functionality accordingly. This will consume more resources, but we are unable to measure them Paddle-OCR and grouping text box (I hate this; why yolo ) This is the very unsolved problem that may annoy the user and me. The problem is paddle-ocr working like this, meaning it will separate the text bubble into smaller parts, which will make translation crazy. Currently, we are adding grouping to solve the issue of text on the same line, but the solution is not ready yet. Also, we are considering switching models for a better experience
TL;DR Messaging: Fixed a silent settings synchronization bug by introducing typed, namespaced messages. Hover Translation: Added a hover-to-translate popup with language selection and race-condition-safe handling. Default Language: Users can now configure a default translation language that syncs across tabs. Error Feedback: OCR and translation failures now show toast notifications instead of silently failing. Domain Rules: Fixed empty domain lists incorrectly allowing translation everywhere. Auto-translate: Restored automatic translation behavior that was accidentally removed during the refactor. Unified messaging I discovered a pretty annoying bug in the settings synchronization system. The popup was sending: ts"notify-settings-changed" while the background script was listening for: ts"settings/notify-changed" Because of this mismatch, settings changes were not propagated correctly and failed silently. To avoid this kind of problem in the future, I introduced types/messages.ts with typed, namespaced message routing. Now the message names are centralized instead of being manually written across different parts of the extension. Settings changes can now propagate correctly and update active tabs in real time. Hover translation popup The overlay can now translate individual OCR regions directly through a hover popup. When hovering over an OCR box, the extension displays: The original detected text A target language selector The translated result The popup uses a small debounce before appearing and has a delayed close behavior when the mouse leaves. If the user moves back into the popup, the close action is cancelled. I also had to handle race conditions. Translation requests can finish in a different order than they were created, so late responses are ignored when they no longer belong to the currently active popup. The popup handles its own translation request and lifecycle, which makes it much more self-contained. Default translation language (model error) Users can now choose a default target language in Settings. The current default is Vietnamese ( vi ), with support for 17 languages. The setting is stored using browser.storage.sync and changes are broadcast to active tabs. The language selected inside a hover popup is temporary, while the configured default language remains the user’s persistent preference. In the future we will switch from machine translate or deep learning translate Error feedback instead of silent failures Previously, OCR and translation errors could fail without giving the user any useful feedback. I added utils/toast.ts to provide inline error notifications. Errors are debounced and deduplicated so the user does not get spammed with notifications when multiple failures happen at once. I also extracted shared popup styling into utils/popup-base.ts to reduce duplicated UI logic. Empty domains fix There was another logic issue with enabledDomains . An empty domain list should mean: Translate nothing. However, the previous implementation treated an empty list as if every domain was allowed. This has now been fixed in both background.ts and isDomainAllowed() . An empty list correctly disables translation entirely. Auto-translate restored During the refactor, some of the automatic translation logic was accidentally removed. This included: autoTranslateIfAllowed() URL polling The live DOM observer As a result, the extension would remain inactive until the user manually triggered it. These behaviors have now been restored, so automatic translation works again when the page loads and when new content appears dynamically.
Devlog TL;DR Translation: Experimented with local NLLB and Google Translate, weighing privacy against performance. Architecture: Moved translation into an offscreen document with a dedicated Web Worker. Performance: Added caching, task scheduling, and bounded concurrency. OCR: Improved error handling, caching, and image processing reliability. Release: Brought the core features together for Image Translate v0.1.0. Privacy vs. performance My original goal was to keep everything local, so users wouldn’t have to send their text to an external service. However, NLLB-200 comes with a hefty model size of around 2.4 GB, which can put serious pressure on browser memory. I experimented with Google Translate as an alternative. It’s much lighter on the user’s device, but there’s a trade-off: text sent for translation leaves the device and is processed by a third-party service. That means giving up some privacy for convenience and lower resource usage. Neither approach is perfect. Local inference costs memory and performance; hosted translation introduces an external data dependency. I’m still figuring out the right balance for an extension whose original motivation was privacy. Moving heavy work out of the background Chrome’s Manifest V3 service worker isn’t ideal for heavy inference. I moved translation into an offscreen document and added a dedicated Web Worker for model inference. The background script now mainly routes messages. I also switched to runtime.connect ports for longer-running communication to reduce messaging failures when the service worker gets suspended. Caching and scheduling Repeated requests were wasting time, so I added an L1 memory cache and an L2 IndexedDB cache, using SHA-256 keys to identify repeated requests. A priority queue, bounded concurrency, and admission control help prevent pages containing lots of images from overwhelming the extension. Debugging wasn’t fun I ran into WebGPU/WASM initialization failures, an OCR crash caused by getContext is not a function , and InvalidCharacterError from malformed Base64 data. Turns out, running an ML model is only half the battle. Browser APIs, cross-origin restrictions, and memory limits can be just as frustrating. Making OCR more reliable I switched batch processing to Promise.allSettled , allowing individual images to fail without breaking the whole batch. OCR results are cached locally with a seven-day TTL, and the popup now tracks errors per item. I also added script detection, a tinyld fallback, text normalization, OCR region grouping, and token protection to support the translation pipeline. What’s next? Image Translate v0.1.0 brings together automatic image and canvas detection, PaddleOCR, translation, hover popups, caching, domain settings, and error tracking. The next challenge is finding a sensible balance between translation quality, memory usage, and privacy. Ideally, users should have a clear choice between local translation and hosted services rather than having that trade-off hidden from them.
First Release work good on https://cubari.moe/read/mangadex/7a82d0ef-034e-427b-bf5c-ed7d08ddbd6b/1/1/ check the release note please https://github.com/code-ga/image-translate-extension/releases/tag/v0.1.0...
|
1792799364.855267
|
1793404164.855267
|
|
68101
|
BLARE by @mandeepswami | Stardance
|
mandeepswami
|
0
|
4.28
|
0
|
[]
|
[{"post_id": 81043, "ts": "202 [{"post_id": 81043, "ts": "2026-10-19T17:25:48Z", "hours": 1.4606, "text": "makingn he case"}, {"post_id": 78387, "ts": "2026-10-10T16:57:43Z", "hours": 0.7667, "text": "Working on the case"}, {"post_id": 77874, "ts": "2026-10-08T17:00:18Z", "hours": 1.24, "text": "The PCB is complete didnt take long and it feels easier than making hackapd"}, {"post_id": 77548, "ts": "2026-10-07T12:24:05Z", "hours": 0.8167, "text": "Schematic is almost complete .Thinking of adding more keys or a rotary encoder"}]...
|
Title: BLARE by @mandeepswami | Stardance
Devlogs Title: BLARE by @mandeepswami | Stardance
Devlogs:
Schematic is almost complete .Thinking of adding more keys or a rotary encoder
The PCB is complete didnt take long and it feels easier than making hackapd
Working on the case
makingn he case...
|
1792468513.054217
|
1793073313.054217
|
|
70535
|
FUGITIVE'S website by @FUGITIVE | Stardance
|
FUGITIVE
|
0
|
2.22
|
0
|
[]
|
[{"post_id": 81049, "ts": "202 [{"post_id": 81049, "ts": "2026-10-19T17:36:06Z", "hours": 2.2183, "text": "click if you want to see who am i- https://racer-x-blacklist.pages.dev/"}]...
|
Title: FUGITIVE'S website by @FUGITIVE | Stard Title: FUGITIVE'S website by @FUGITIVE | Stardance
Devlogs:
click if you want to see who am i- https://racer-x-blacklist.pages.dev/...
|
1792432032.1188877
|
1793036832.1188877
|
|
28432
|
RadiaX (Mechanics) by @Marco_da_mechanic | Stardan RadiaX (Mechanics) by @Marco_da_mechanic | Stardance...
|
Marco_da_mechanic
|
0
|
19.49
|
0
|
[]
|
[{"post_id": 81051, "ts": "202 [{"post_id": 81051, "ts": "2026-10-19T17:46:48Z", "hours": 1.4336, "text": "ALR. This thing is finished, BOM is ready and Github repo too. The assembly guide will follow soon, cause I think it’ll make more sence with the actual hardware as a ref picture"}, {"post_id": 71280, "ts": "2026-09-20T15:52:45Z", "hours": 4.2839, "text": "The Scanner is now finished, atleast the mechanical principles. The only things missing now are @Luka ’s electronics and the Lead."}, {"post_id": 69270, "ts": "2026-09-16T18:24:02Z", "hours": 3.3336, "text": "Back to the Cad. I added and adjusted some stuff in the Dual X-Ray tube design. And fit @Luka ‘s electronics in there. Also I’ve kinda finished the first scanner prototype. Some adjustments needed"}, {"post_id": 45779, "ts": "2026-08-12T14:13:00Z", "hours": 1.15, "text": "One of the last steps. A small step for y’all but a big one for me. The filter system is done, I designed them and added the mounting. Now I need to find some magnets with a 10mm diameter and a threaded rod attached. The last things are the ventilation and the cable routing. Btw if someone followed the last logs you can see a huge diffrence, I was on vacation and had my laptop with me, and I didn’t have internet. So I couldn’t upload lapses. Smt around 40h are missing but they are in the fusion time tracker (it’s a add-on if someone cares). So yeah that’s it."}, {"post_id": 22450, "ts": "2026-07-04T22:24:56Z", "hours": 6.5544, "text": "The dual tube design is nearly finished yayy. So I can’t really tell all the things I did, but this was mostly CAD, the Important structual Parts are calculated and integrated. But this design was really fun due to the challanges I’ve experienced with it. The percicion needed, the integration of the HV electronics, Cooling, how to keep it sealed and yeah. There are still a few things missing, Luka’s PCB, a mounting for the movement shaft and the exact dimensions of the slip ring. And really important side notice, if you’re doing a longer CAD session, please safe every major step. Fusion crashed and I got the biggest scare of my life cause I thought everything was gone, so yeah thats it."}, {"post_id": 20254, "ts": "2026-07-01T20:00:41Z", "hours": 1.5203, "text": "(I know the CAD looks bad but it’s just a Dummy) Today I started with the design of the dual X-Ray tube design and It’s so much worse than a single tube design, the HV is still a problem, the sword like thingie you can see in the middle is a copper cooling pipe, and copper likes to conduct electricity. Transformer Oil will be used in there, but the metal residue and just dust can have a hugeee impact on the isolation factor, than the kables which don’t like to be twisted, the weight bc I only have one mounting point, or i take a second mounting with a bearing to suport the weight and use the other mounting point just for the rotation. And yeah that’s basically it for today"}, {"post_id": 18676, "ts": "2026-06-29T21:19:17Z", "hours": 1.2142, "text": "Stuff I’ve done in maccondo, summary is AI written . I’ve added radial bearings to handle the radial loads and updated the CAD model accordingly. I calculated everything for the radial force distribution and integrated it into the design. I also fixed issues in the Fusion assembly and rebuilt parts of the mounting plate–flange connection because components kept moving in the wrong direction during assembly. I created an assembly setup on the flange and mounting plate, then exported it into an animation for later use. I updated the technical drawings with additional parameters and spent around 1h45 in CAD work. I worked through a lot of math for the scanner design, mainly the lead shielding requirements and the geometry between the X-ray tube and the screen. That took most of the time since I had to go back and forth with missing values and references, and it also changed the overall tube-to-detector geometry. The calculations are done now and fully integrated into the design. I redesigned the entire enclosure because the old one looked like a shoe box. The new one is more like a proper housing/oven design. I also added cable mountings and defined parts of the internal lead geometry, which will later depend on the electronics. I realized the plate could slip or put load on the stepper motor if the object isn’t perfectly centered, so I added a proper flange connection part to stabilize it. I also started planning manufacturing, but it’s still unclear who will machine the 10mm aluminum plates or how exactly the parts will be produced. On the electronics side, I integrated components into the assembly. I also revisited the peristaltic pump design, which I originally built, printed, and assembled with a stepper motor. It generated pressure at first, but when I tried pumping water, the stepper motor stalled. I tried troubleshooting possible causes like tube compression, friction, and PLA interference, but nothing fully solved it yet. I started a new improved pump design with better geometry, even though the first version made me question the design. That’s basically everything I worked on so far. Lapse somehow doesn’t like me, and there are a pretty many hours missing. 12.4h after July 1"}]...
|
Title: RadiaX (Mechanics) by @Marco_da_mechanic | Title: RadiaX (Mechanics) by @Marco_da_mechanic | Stardance
Devlogs:
Stuff I’ve done in maccondo, summary is AI written . I’ve added radial bearings to handle the radial loads and updated the CAD model accordingly. I calculated everything for the radial force distribution and integrated it into the design. I also fixed issues in the Fusion assembly and rebuilt parts of the mounting plate–flange connection because components kept moving in the wrong direction during assembly. I created an assembly setup on the flange and mounting plate, then exported it into an animation for later use. I updated the technical drawings with additional parameters and spent around 1h45 in CAD work. I worked through a lot of math for the scanner design, mainly the lead shielding requirements and the geometry between the X-ray tube and the screen. That took most of the time since I had to go back and forth with missing values and references, and it also changed the overall tube-to-detector geometry. The calculations are done now and fully integrated into the design. I redesigned the entire enclosure because the old one looked like a shoe box. The new one is more like a proper housing/oven design. I also added cable mountings and defined parts of the internal lead geometry, which will later depend on the electronics. I realized the plate could slip or put load on the stepper motor if the object isn’t perfectly centered, so I added a proper flange connection part to stabilize it. I also started planning manufacturing, but it’s still unclear who will machine the 10mm aluminum plates or how exactly the parts will be produced. On the electronics side, I integrated components into the assembly. I also revisited the peristaltic pump design, which I originally built, printed, and assembled with a stepper motor. It generated pressure at first, but when I tried pumping water, the stepper motor stalled. I tried troubleshooting possible causes like tube compression, friction, and PLA interference, but nothing fully solved it yet. I started a new improved pump design with better geometry, even though the first version made me question the design. That’s basically everything I worked on so far. Lapse somehow doesn’t like me, and there are a pretty many hours missing. 12.4h after July 1
(I know the CAD looks bad but it’s just a Dummy) Today I started with the design of the dual X-Ray tube design and It’s so much worse than a single tube design, the HV is still a problem, the sword like thingie you can see in the middle is a copper cooling pipe, and copper likes to conduct electricity. Transformer Oil will be used in there, but the metal residue and just dust can have a hugeee impact on the isolation factor, than the kables which don’t like to be twisted, the weight bc I only have one mounting point, or i take a second mounting with a bearing to suport the weight and use the other mounting point just for the rotation. And yeah that’s basically it for today
The dual tube design is nearly finished yayy. So I can’t really tell all the things I did, but this was mostly CAD, the Important structual Parts are calculated and integrated. But this design was really fun due to the challanges I’ve experienced with it. The percicion needed, the integration of the HV electronics, Cooling, how to keep it sealed and yeah. There are still a few things missing, Luka’s PCB, a mounting for the movement shaft and the exact dimensions of the slip ring. And really important side notice, if you’re doing a longer CAD session, please safe every major step. Fusion crashed and I got the biggest scare of my life cause I thought everything was gone, so yeah thats it.
One of the last steps. A small step for y’all but a big one for me. The filter system is done, I designed them and added the mounting. Now I need to find some magnets with a 10mm diameter and a threaded rod attached. The last things are the ventilation and the cable routing. Btw if someone followed the last logs you can see a huge diffrence, I was on vacation and had my laptop with me, and I didn’t have internet. So I couldn’t upload lapses. Smt around 40h are missing but they are in the fusion time tracker (it’s a add-on if someone cares). So yeah that’s it.
Back to the Cad. I added and adjusted some stuff in the Dual X-Ray tube design. And fit @Luka ‘s electronics in there. Also I’ve kinda finished the first scanner prototype. Some adjustments needed
The Scanner is now finished, atleast the mechanical principles. The only things missing now are @Luka ’s electronics and the Lead.
ALR. This thing is finished, BOM is ready and Github repo too. The assembly guide will follow soon, cause I think it’ll make more sence with the actual hardware as a ref picture...
|
1792518795.6364994
|
1793123595.6364994
|
|
22691
|
Scratcher by @BetterClient | Stardance
|
BetterClient
|
0
|
182.41
|
0
|
[]
|
[{"post_id": 81059, "ts": "202 [{"post_id": 81059, "ts": "2026-10-19T18:13:33Z", "hours": 5.56, "text": "CLI I did some small refactors and added a new CLI, built with Clikt It’s very simple to use: scratcher check file --options //check the file for any compilation errors without compiling scratcher compile file --options outFile //compile into a .sb3 file scratcher standard-library //print out the standard library Clikt also provides easy to use help menus I also added a sort function to the array and list libraries"}, {"post_id": 78430, "ts": "2026-10-10T19:47:24Z", "hours": 7.5478, "text": "PROPER ERRORS Errors are the one thing that I knew were terrible but I could never build up the courage to fix. So I just fixed them. Now all errors in the language are formatted nicely, show you exactly where the error happened and give you a nice description. Along with this, I made a new system for collecting errors, so now the compiler won’t stop at the first error and will continue going and give you all errors at once. This makes fixing code a lot easier. This also opens up the possibility of an LSP server later on (before and after in images)"}, {"post_id": 76716, "ts": "2026-10-04T12:20:48Z", "hours": 6.6447, "text": "More demos and QOL Try it out: https://scratch.mit.edu/projects/1387804691/ Demos Math lexer, parser and interpreter: New demo that lets you input math expressions (eg: 1 + 1 ) and get the result. 3d cube renderer: a spinning 3d cube and player controls QOL Smarter inlining cost calculation A math centered optimization for removing identities Get rid of PromoteToGlobals (temp) GC documentation Codegen fixes (receiver functions generate the same block, causing scratch to get confused) Stack size optimization (reuse stack slots of the same type) Fix crash when the garbage collector is disabled"}, {"post_id": 74467, "ts": "2026-09-27T13:15:50Z", "hours": 7.5128, "text": "Demo programs and general improvements I added demo programs to scratcher, these show the language actually being used Try one out! https://scratch.mit.edu/projects/1385339395/ General improvements Bug fixes Dummy sprite Make the type checker ignored in inlined functions Make topLevelInit smaller and remove unused functions from final compilation TurboWarp specific compilation mode with faster operations on strings/lists (not compatible with vanilla scratch if enabled)"}, {"post_id": 72783, "ts": "2026-09-23T18:48:59Z", "hours": 2.1378, "text": "Indexed repeat and general improvements Added a new indexed for and repeat statement which allows way easier index tracking: //Before: int index = 0; repeat(10) { ... index++; } //After: repeat(10) { index -> ... } I also made the PooledList get garbage collected with the refcount gc Did some really small refactors aswell"}, {"post_id": 71161, "ts": "2026-09-20T11:38:26Z", "hours": 2.5564, "text": "List pools Static lists are cool, but they are very limited expressiveness wise because they must be known at compile time Pools fix this by having a pool of static lists that the user code can allocate at any time PooledList a = allocate(); But because the pool is limited, the pooled list must be freed when not needed, the garbage collector will not handle it(yet) a.free(); Other than that, the PooledList behaves just like a List and can do almost anything a List does I also added proper documentation for Out of memory errors."}, {"post_id": 70752, "ts": "2026-09-19T18:17:22Z", "hours": 10.2792, "text": "QOL I added a shit ton of quality of life stuff: Tons of bug fixes Big array syntax: int[] myArray = [1, 2, 3, 4, 5, 6]; Safe casting for enums(previously a panic): Result.Success? a = res as? Result.Success; Out of memory detection: Scratch caps lists at 200k elements, after that it silently stops adding stuff to the list Compact int list: Store pretty much infinite integers without wasting heap space SHORT CIRCUITS: DONT EXECUTE RIGHT SIDE OF && or || if left side is false/true! If statements without braces: if(a) b++; CONTINUE AND BREAK: while(true) { if(a) break; if(b) continue; } STATIC LISTS: store data outside of the heap in scratch lists so that you dont run out of heap space: static str[] myList; This also allows for file reading: static str[] myList = \"hello.json\"; So you can properly store data(like ROMs) CASE SENSITIVE EQUALS: DID YOU KNOW THAT SCRATCH “=” BLOCK IS CASE INSENSITIVE??? And its pretty hard to make it case sensitive Now you can do “===” and its case sensitive: 'a' === 'A' RETURNS FALSE"}, {"post_id": 65445, "ts": "2026-09-10T16:08:38Z", "hours": 8.1706, "text": "DOCUMENTATION I do not want to touch any markdown ever again"}, {"post_id": 62828, "ts": "2026-09-06T11:04:43Z", "hours": 2.5681, "text": "Privates Added a “private” keyword, anything declared private cannot be accessed from outside the current file. This prevents the user from messing with internal states of libraries they are using For example, the list library from the standard library. Now you can’t directly mess with the list pointer triangles.ptr[5] = ...; This now results in an error because “ptr” is private! I also added some small optimizations for lambdas."}, {"post_id": 60869, "ts": "2026-09-03T14:48:30Z", "hours": 3.9831, "text": "Operator overloading Added operator overloading, now you can define overloads for specific operators so that code looks cleaner Just use the operator keyword with the correct signature and you’re done! You can overload the operators: +, -, /, *, %, [], []= For example: warp operator <T> void T[].set(int index, T item) { self::replace(this, item, index); } //use array[index] = item //compiler translates to set(array, index, item) I also realized that my previous refactor of arrays broke my nullability system: int[] a = Array(int, 5); say(a[3]); This would print null , which my type system missed I fixed this by moving arrays to a standard library module, the same array import works, but you have to change how you create the array: //before: int[] a = Array(int, 5); //doesn't need to be marked as null!!! int[] a = Array(int, 5); a[0] = ...; a[1] = ...; ... //after int?[] a = arrayOfNulls(5); //null filled int[] a = arrayOf(5, (int index) -> { return index * 5; //value of the array at that index });"}, {"post_id": 58837, "ts": "2026-08-31T12:49:12Z", "hours": 1.1706, "text": "Import some import names into unqualified co ntext Before: //import import list; //use list::List<str> myList = list::newList(); After: //import import list::*; //use List<str> myList = newList();"}, {"post_id": 58031, "ts": "2026-08-30T11:39:09Z", "hours": 1.2083, "text": "Pattern matching for sealed enums Previously if you wanted to check sealed enums types and use them, you had to do very ugly syntax for actually getting the variant instance: auto out = tryGet(); when(out) { Result.Success -> { auto suc = out as Result.Success; looks::say(\"Success! ${suc.out.x}\"); Now you don’t have to do all of this: when(tryGet()) { Result.Success suc -> { looks::say(\"Success! ${suc.out.x}\"); This is just syntax improvement, doesn’t change the generated code or anything, just helps the developer"}, {"post_id": 56767, "ts": "2026-08-28T17:36:33Z", "hours": 3.9356, "text": "ACTUAL ARRAYS!! Previously, scratcher “arrays” were just lists, you could add more items, it would dynamically resize, it was written in the kotlin DSL, so technically it was just a list. I removed the previous list code, reused some of it and added a new Array system Along with that, the normal lists got rewritten in 100% scratcher with no internal functions The new system is almost fully backwards compatible in source code, you just have to make a few changes The new implementation is more clear, more expressive and more like regular programming languages"}, {"post_id": 54379, "ts": "2026-08-25T10:59:05Z", "hours": 2.1919, "text": "I’m sorry For over 2 months, scratcher has had an “export” keyword, which was fully unused, until today: I implemented the export keyword on functions, which allows for code written in plain scratch to interact with scratcher code: export warp void myFunction() { ... } Export requires that your function arguments are all primitives and that the return is also a primitive, but other than that, it does not change anything, just exposes the function cleanly to regular scratch code. However, scratcher type checking still applies, so if the native scratch code passes in a string to a float argument, it will still cause a panic Even when you have obfuscation enabled, exports will stay and let native scratch use it with its original name"}, {"post_id": 52903, "ts": "2026-08-23T08:56:58Z", "hours": 3.9047, "text": "Sealed enums and faster GC I added a new type of object, sealed enums: sealed enum Animal { Cat(str name, int age, bool isMeowing), Dog(str name, int age), Unknown } They allow for storing data inside enums, they’re very similar to rust enums: sealed enum Result<T> { Success(T out), Failure } I also refactored lambdas to use a sealed enum instead of a big struct: //before struct LambdaCaptures(Lambda0Captures? c0, Lambda1Captures? c1, Lambda2Captures? c2); //after sealed enum LambdaCaptures { Lambda0Captures(Box$int capture0, ...), Lambda1Captures(Box$float capture0, ...) } Sealed enums only store a tag and a pointer, so if you use a lot of lambdas, this will save a TON of heap space Faster garbage collector! I made the marking phase of the mark and sweep collector faster by using an epoch based cleanup approach Now, instead of clearing and re-populating the marked list, we don’t ever clear it and we invalidate it by just increasing the epoch. This makes the isMarked check go from O(n) to O(1) while also improving marking speed because scratch doesn’t have to resize our list"}, {"post_id": 51327, "ts": "2026-08-20T22:21:05Z", "hours": 5.0097, "text": "MORE FUCKING ABSTRACTIONS!!! I added receiver/extension functions. These allow you to write code that takes in a type as a special argument You define them just like how it works in kotlin: warp <T, R> R T.let((T) -> R action) { return action(this); } It just compiles to a regular function warp <T, R> R let(T this, (T) -> R action) { return action(this); } But the compiler lets you call it with the special argument: thing.let((int a) -> ...); I also added a very big standard library module (written in scratcher!) with a ton of these functions built-in, they allow you to write more expressive code: triangles .filterNotNull() .filter((Triangle<float> t) -> t.x1 > 150) .filter((Triangle<float> t) -> t.y1 < 150) .forEach((Triangle<float> tri) -> ...) I also rewrote the entirety of string lib during this, now you have to use the extensions library to use strings, but its way more powerful (and written in scratcher)! I also added a new “char” type, which stores a single character (wow really???) I also added “safe dot calls” that allow you to use stuff as if they’re not null: triangles.forEach((Triangle<float>? t) -> { t?.x1?.let((float x1) -> { looks::say(\"x1: ${x1}\"); }); }); This only calls the let function if t?.x1 is not null There is a big problem with all this powerful new code though… the garbage collector can no longer keep up, a single mark and sweep takes over 1 second! Which is especially bad because the garbage collector needs the entire application to stop in order to run. You do not want your code to completely stop for a whole second(maybe you do? weirdo), so I have to fix this in my next few devlogs…"}, {"post_id": 49925, "ts": "2026-08-18T21:52:59Z", "hours": 6.2256, "text": "Lambdas I added lambdas to Scratcher! They allow you to write more expressive code like map(list, a -> a + 1) , which literally adds 1 to every element of list I also allow using outer variables within lambdas int a = ...; map(list, b -> { a++; b + a }); I allow this through boxing, the local variables become boxes and the lambdas get the local variable’s box, this makes lambdas more powerful than most languages as this allows for variables to be shared mutable state across lambdas, this also allows the local variables to get garbage collected. Of course, scratch doesn’t support this natively, so lambdas are 100% compiler sugar and just lowers to regular functions and uses function references(which is also 100% compiler sugar). void lambda::defunc@lambad@0(LambdaCaptures c, args...) { ... }"}, {"post_id": 46470, "ts": "2026-08-13T18:15:50Z", "hours": 1.7033, "text": "Fixed the garbage collector… turns out I broke it accidentally while cleaning up code in my last devlog, 3 line change but took a long time to find Made it so the stack allocator doesn’t do redundant operations like 1+1 and inlines them as 2 instead"}, {"post_id": 46037, "ts": "2026-08-12T23:23:02Z", "hours": 1.3453, "text": "100 hours! Evil hack part 4: Death of evil hack So I was using a really terrible hack to implement stuff like FunctionInlining, Safe dot and the elvis expression, the hack is basically (ab)using the when expression to do stuff like run code inside expressions and use local variables inside expressions. So to stop this from becoming a hack, I added it directly to the AST as StatementExpression(not to be confused with ExpressionStatement), which can be used to contain statements inside expressions. All of my evil hacks have been replaced by StatementExpression. I also added some small optimizations for StatementExpressions!"}, {"post_id": 45987, "ts": "2026-08-12T20:32:56Z", "hours": 5.7503, "text": "General language improvements Elvis expressions: If a value is nullable, it is not usable by anything that only accepts non-null values, to solve this, I added the elvis expression, which allows you to give a fallback for null values(compilation in image 2): //int doesn't have to be nullable because we have a fallback value! int x = functionThatReturnsNull()?: 5; String boxing and nullable primitives Previously, scratcher only supported having structs, enums and function references as nullable, now it also supports having primitive types as nullable: str? x = functionThatReturnsNullableString(); //distinguish between literal null and string null if(x == null) looks::say(\"null!\"); if(x == \"null\") looks::say(\"null as string!\"); //the compiler achieves this by boxing the string return with a struct: //struct StringBox(str value) //the actual type behind the scenes is: //StringBox? x = ...; Safe dot traversal If a struct instance is nullable, you cannot use regular struct.member because that may result in a NullPointerException, to solve this I added ?. which allows for null safe traversal(compilation in image 1): //if nullableTriangle == null, return null //if nullableTriangle != null, return nullableTriangle.x1 int? x1 = nullableTriangle?.x1; Deepseek fix I noticed that FunctionInlining completely ignored execution order, so I asked deepseek to solve it(this happened after I added string boxing). But I found a better solution to the same problem later on, so I reverted deepseek’s fix and wrote my own, which is 260 lines compared to deepseek’s 360 lines, over 100 lines shorter!"}, {"post_id": 42848, "ts": "2026-08-07T19:46:20Z", "hours": 7.4364, "text": "Second garbage collector! Added a second garbage collector! If your app does not contain any cyclic objects and needs high performance, you can now enable the ARC collector! This garbage collector works by automatically detecting when objects go out of scope and decrementing their reference count, if an object’s reference count goes to 0, it is freed. This is more performant than the mark and sweep collector because the objects are freed at the moment they are unused instead of stopping the entire program to collect garbage. This works for all cases, except for cases where there is a cyclic object. Because the cyclic object owns itself, so its reference count is always at 1."}, {"post_id": 32011, "ts": "2026-07-20T21:29:16Z", "hours": 4.2214, "text": "Even more abstractions please Added generics support, which allows the user to define generic functions/structs that apply with every type, for example: warp <T> void forEach(T[] a, (T) -> void action) { for(T t in a) { action(t); } } Depending on what type you used to call this, a new version of forEach gets generated, if you called it with an integer: warp void forEach@int(int[] a, (int) -> void action) { for(int t in a) { action(t); } } Of course I also allow this on structs: struct Triangle<Num>(Num x1, Num y1, Num x2, Num y2, Num x3, Num y3); Also did some small changes: Added an FPS counter to my test code Better optimizations that actually detect not(not(x)) Optimized triangle::fill even more (+2 fps) Made DynamicDispatchHandler actually use the apply return properly (it was always returning true)"}, {"post_id": 27929, "ts": "2026-07-13T21:08:14Z", "hours": 2.6361, "text": "More abstractions please! Added dynamic function dispatch which allows for functions to take in other functions as arguments, of course, this isn’t possible at all in normal scratch, so actually FunctionLiteral gets turned into an integer and a custom dispatch function gets created for every function literal’s signature which allows for a binary search to call the actual function Also made HeapConversion reuse stack slots instead of allocating one for every variable(mostly by AI)"}, {"post_id": 27608, "ts": "2026-07-13T10:50:48Z", "hours": 1.5486, "text": "Refactored the entire type system to use a sealed interface instead of an unsafe single class Nothing much to say, this doesn’t affect the input code or the output project, I did just cleanup"}, {"post_id": 27567, "ts": "2026-07-13T08:35:21Z", "hours": 0.8472, "text": "Did more syntax improvements Added ++ and – support: index++; Added type inference support: auto a = Triangle(5, 15, 60, -120, 240, 67); //type automatically becomes Triangle auto a = func(); //type automatically becomes the return type of func"}, {"post_id": 27415, "ts": "2026-07-12T23:35:13Z", "hours": 2.3778, "text": "Scratcher is at 100 commits! (Now 104 cause all of these refactors are different commits) Completely refactored all translation steps to use the ASTVisitor. Also did type resolving cleanup. Function Reachability : Went from 117 to 32 lines Function expression lowering : Went from 439 to 293 lines Re Parse Local Variables : Went from 34 to 27 lines Remove Empty Allocations : Went from 97 to 79 lines ConvertToHeapAccess : Biggest refactor of this whole devlog, went from 500 lines to 418, split into 5 files"}, {"post_id": 26200, "ts": "2026-07-10T21:13:19Z", "hours": 3.26, "text": "Fixed a lot of bugs with when expressions, also got deepseek to fix some of them Added If expressions, which allow using if statements inside other expressions, for example, here is some previously invalid code that is now valid: int max = if (a > b) a else b; str message = if (score >= 90) { looks::say(\"something\"); \"You win!\" } else { looks::say(\"something\"); \"You lose :(\" } triangles[15] = Triangle( utils::random(-240, 240), utils::random(-180, 180), utils::random(-240, 240), utils::random(-180, 180), utils::random(-240, 240), if(mode == TriangleRenderMode.OFF) { 5 } else { triangles[14].y3 } ); These still get lowered properly and just look like normal if statements in the final scratch code"}, {"post_id": 25224, "ts": "2026-07-09T10:42:23Z", "hours": 3.3289, "text": "Added more syntax improvements! Else if : Added support for else if, which replaces big blocks //Before: if(triangles[14].y1 >= 15) { looks::say(\">=15\"); } else { if(triangles[14].y2 >= 155) { looks::say(\"<=15\"); } else { looks::say(\"Both false!\"); } } //After: if(triangles[14].y1 >= 15) { looks::say(\">=15\"); } else if(triangles[14].y2 >= 155) { looks::say(\"<=15\"); } else { looks::say(\"Both false!\"); } Compound assignment : Added support for compound assignment //Before: triangles[15].y3 = triangles[15].y3 + 5; //After: triangles[15].y3 += 5; Enums : Added support for enums, which are just fancy integer wrappers enum TriangleRenderMode(OFF, RENDER, ITHINK); TriangleRenderMode mode = TriangleRenderMode.OFF; When : Added support for when expressions/statements that allow for matching a subject: //Before: if(answer == \"off\") { mode = TriangleRenderMode.OFF; } else if(answer == \"render\") { mode = TriangleRenderMode.RENDER; } else { mode = TriangleRenderMode.ITHINK; looks::say(\"If thinking is your power, what are you without it?\"); return; } //After: TriangleRenderMode mode = when(answer) { \"off\" -> TriangleRenderMode.OFF \"render\" -> TriangleRenderMode.RENDER else -> { looks::say(\"If thinking is your power, what are you without it?\"); TriangleRenderMode.ITHINK; } };"}, {"post_id": 24407, "ts": "2026-07-07T22:53:21Z", "hours": 2.6547, "text": "Tried to do turbowarp only return optimization, wasn’t able to make it very good… reverted it Improved the structure of CompilationConstants Added string::split and string::substring Made some of the list functions inlined (itemAt, clear, length)"}, {"post_id": 22179, "ts": "2026-07-04T14:42:02Z", "hours": 1.2922, "text": "Made the garbage collector treat top level variables as roots, this prevents top level variables from getting freed I added 2 modes to this Reflect: This uses a hacked block to read the variables by name and reduce script size if theres a lot of variables(this doesn’t render properly inside the editor but it works) NoReflect: Get all the top level variables at compile time and mark them one by one"}, {"post_id": 22122, "ts": "2026-07-04T12:41:23Z", "hours": 7.6808, "text": "Garbage collection Added a mark and sweep garbage collector to my language, it walks the roots, marks every used object, then frees all unused objects! Most impressive part of this(in my opinion) is that most of the garbage collector is actually written in my language Misc The garbage collector gets called automatically every 1 second, but you can turn it off (CompilationConstants.AUTOMATIC_GC) If you want to manage memory manually, you can turn off the garbage collector entirely (CompilationConstants.MANUAL_MEMORY)"}, {"post_id": 19412, "ts": "2026-06-30T18:41:23Z", "hours": 1.5931, "text": "Added a name parameter to alloc which acts as runtime type metadata, soon to be used."}, {"post_id": 18732, "ts": "2026-06-29T22:21:59Z", "hours": 0.6683, "text": "Added more compiler sugar for lists: list[index] replaces list::itemAt(list, index) list[index] = ...; replaces list::replace(list, item, index) for(type name in list) {} replaces int len = list::length(list); int i = 0; while (i < len) { type name = list::itemAt(list, i); i = i + 1; } (i am not proud of the shitcode that was used to get for(type name in list) working)"}, {"post_id": 18693, "ts": "2026-06-29T21:37:55Z", "hours": 3.1528, "text": "Added list support! A very barebones implementation that allows the user to create, add to, read from and delete items from lists!"}, {"post_id": 18194, "ts": "2026-06-29T08:15:19Z", "hours": 1.2822, "text": "Made “PromoteToGlobals” which is a more powerful version of OptimizeToGlobals which allows for recursive functions to have their locals turned into globals aswell This is something called liveness analysis, the compiler looks at the code paths and decides at which points a variable is “live”, which means it can’t get overwritten by a recursive call Example: warp int fib(int n) { return 0 if n <= 0; return 1 if n == 1; if (n == 2) { int b = n * 2; return otherFunc(b); } return fib(n - 1) + fib(n - 2); } In this function the “b” variable can be turned into a global because it cannot get overwritten by a recursive call, its used too early for that to happen"}, {"post_id": 17754, "ts": "2026-06-28T17:51:46Z", "hours": 1.5667, "text": "Did some compiler testing Fixed function inlining bugs Fixed a single use assignment bug Created a triangle library that allows for triangle rendering using the pen"}, {"post_id": 17603, "ts": "2026-06-28T13:52:43Z", "hours": 1.7214, "text": "Borrowed the “return expr if(cond)” syntax from ruby Implemented Tail call optimization which optimizes away recursion on tail calls Example: Before: str count(int amount) { return \"Done!\" if amount == 1; return count(amount - 1); } After: str count(int amount) { int tco@argument@amount = amount; while (true) { if (tco@argument@amount == 1) return \"Done !\"; tco@argument@amount = tco@argument@amount - 1; } }"}, {"post_id": 17283, "ts": "2026-06-28T00:21:23Z", "hours": 5.7767, "text": "Source code of the image: on GreenFlag { if(a() == 5) { looks::say(\"yo!\"); } int index = 0; index = index + 1; rgb(index, 5, 5); index = 5; while(true) { pen::eraseAll(); render(); } } The image is of the entire flow working perfectly: The index variable had their value propagated to “1” by the Sequential constant propagation optimization The variable got its uses removed by Inline single-use assignments Then the variable got fully removed by Dead store elimination The rgb function got inlined. Then while it was inlined, because the rgb function’s return wasn’t being used, it got fully removed(the inlining preserves side effects while removing its return value, but because it didn’t have any side effects it got fully removed) Same with the a() function: It got inlined Then the if statement became if(5 == 5) { looks::say(\"yo!\"); } Then Constant folding turned 5 == 5 into true Then Dead code elimination turned if(true) into just the then block I know most optimizations look like they aren’t that powerful, but when combined with other optimizations and ran in a loop, they can pile up and actually optimize code Optimizations Simplify boolean equality : Simplifies x == true to x , simplifies x == false to !x Simplify double negation : Simplifies !!x to x , simplifies --x to x Constant folding : Simplifies true == true to true , simplifies 5 + 5 to 10 Repeat to While : Converts repeat(amount) to a while loop Dead code elimination : Removes provably unreachable code blocks, eg: if(true) { ... } else { .. } turns into ... , removing the if and the else block entirely Now the big ones Sequential constant propagation : Analyzes the control flow of your program, removing useless variable assignments and inlining their expressions Inline single use assignment : Self explanatory Dead store elimination : Removes useless “set variable to x” blocks that don’t get used afterwards Function inlining : The compiler evaluates a cost for every function call is inside a function, if that total cost is less than 10,000, it gets inlined inside that function, removing call overhead and allowing for further optimization Other misc stuff: Fixed the while bug (if you called a function inside a while statement, it would only get called once) Made function lowering not allocate a stack slot if we’re ignoring return Made the OptimizeToGlobals optimization be called last to allow variable optimizations to happen first"}, {"post_id": 16526, "ts": "2026-06-26T21:46:14Z", "hours": 2.3836, "text": "Optimizations OptimizeToGlobals : If the compiler can prove that a function is not recursive and runs atomically(single threaded), it gets rid of the function’s primitive local variables, which improves performance as scratch’s list operations are more expensive than local variables InlineSingleUseVariables : Pretty self explanatory, if a variable is only used once, it will be inlined ConvertToHeapAccess : I did optimizations on the normal heap converter so that it doesn’t allocate a stack pointer for functions that don’t need one Images don’t show the OptimizeToGlobals optimization cause the testing function I have for that is too long Before and after on the RGB function"}, {"post_id": 16206, "ts": "2026-06-26T10:29:30Z", "hours": 1.5267, "text": "Created Motion and Pen library Added support for top level variables Made an optimization to get rid of useless “replace with -1” blocks(image 1 is before, image 2 is after), this greatly reduces the code size(images are only one example, it was being put everywhere)"}, {"post_id": 15894, "ts": "2026-06-25T20:34:04Z", "hours": 1.4264, "text": "Did warning cleanup Added a nullability “system”, I allow the ? to be put on struct fields, and you can put null as the argument on those fields, then you have to check if they are null and do !! to use them"}, {"post_id": 15790, "ts": "2026-06-25T17:47:54Z", "hours": 3.6944, "text": "Did a lot of refactors Created SensingLib and CalendarLib Made a system to allow standard libraries to be inlined into your code to reduce file size Added support for structs, Right now you have to manually free your structs"}, {"post_id": 15329, "ts": "2026-06-24T22:06:11Z", "hours": 1.2928, "text": "Created a library for casting primitives to other primitives Expanded the math library a lot Added duplicate function and struct detection(yes I forgot before) Added code to prioritize function(int) over function(float) if calling with an int Added “warp” and “export” modifiers to function declarations, the warp modifier maps to the “Run without screen refresh” field, and export is currently unused, but later it will be used to export a function so that its properly usable from normal scratch code"}, {"post_id": 15271, "ts": "2026-06-24T20:05:11Z", "hours": 1.885, "text": "Did general bug fixes Added more standard library functions Added runtime type checking and exceptions"}, {"post_id": 15169, "ts": "2026-06-24T17:20:15Z", "hours": 2.2017, "text": "Did a small refactor on obfuscation Created a type safe(kinda) kotlin DSL for making standard library functions way more readable and simpler to create I rewrote the Memory library with the kotlin DSL Image 1: Before Image 2: After"}, {"post_id": 15063, "ts": "2026-06-24T14:04:20Z", "hours": 1.6278, "text": "I added an event system, making it so your code can actually run on GreenFlag { main(); } on KeyPressed(W) { looks::say(\"W was pressed!\"); } These events are translated into functions and the compiler generates scratch events that call these on KeyPressed(W) { compiler@eventlistener@F(); } void compiler@eventlistener@F() { looks::say(\"W was pressed!\"); } The compiler also generates a initializer green flag block which clears the heap and reserves an index for every other entrypoint(image 2)"}, {"post_id": 14757, "ts": "2026-06-23T23:45:31Z", "hours": 8.0742, "text": "I finished the pipeline from my language’s AST to scratch, it was pretty mind numbing Stage 1: The code does reachability, from the source file(where the compilation started) and finds all functions that we can call from the source Stage 2: Using those functions, we lower call expressions to statements and returns to heap accesses, here’s how that looks in code: Before : void main() { looks::say(fib(5)); } After : void main() { int fibReturn = -1; fib(5, &fibReturn); looks::say(fibReturn); } Notice how the nested call turned into a seperate statement. Why do we need this? Because scratch does not support returning stuff from functions, only arguments. Stage 3: We re-parse all locals on the reachable functions because the last stage added more locals Stage 4: We add a parameter to all functions named “stack” Stage 5: We add free(stack) calls at the end or before the return statement, this frees our stack automatically. We also add alloc before function calls so that we have a stack to pass to the function Here’s how that looks like in code: Before : void main() { int fibReturn = -1; fib(5, &fibReturn); looks::say(fibReturn); } After : void main(int stack) { int fibReturn = -1; int fibStack = -1; alloc(UNKNOWN, &fibStack); //allocate a stack for fib fib(fibStack, 5, &fibReturn); looks::say(fibReturn); free(stack, UNKNOWN); //free our stack } Notice how we have UNKNOWN in place for a number in the allocation and freeing, this is because we just added more locals for the allocations and we can’t know how many slots we need. Standard library functions are already compiled to scratch statements so they don’t need a stack allocated for them Stage 6: We re-parse local variables so we have a count. Stage 7: We count the re-parsed locals for every function and figure out which local variables can be reached in every function Stage 8: We convert all local variables to heap slots We traverse all statements and expressions, replacing all variable accesses with heap[stack + variableIndex]. While in this process we also convert the unknowns into the actual sizes since we just counted the locals in stage 7 Here’s how this entire stage looks like in code: Before : void main(int stack) { int fibReturn = -1; int fibStack = -1; alloc(UNKNOWN, &fibStack); fib(fibStack, 5, &fibReturn); looks::say(fibReturn); free(stack, UNKNOWN); } After : void main(int stack) { heap[stack] = -1; heap[stack + 1] = -1; alloc(3, stack + 1); //we just pass the index here since alloc will write to that index fib(heap[stack + 1], 5, stack); looks::say(heap[stack]); free(stack, 2); //We have 2 locals } By using a stack we get access to a lot of things like returning, recursion and local variables. Scratch doesn’t even support local variables, so we have to hack it with a global list. Notice how we don’t free the allocation? That’s because all functions are compiled by the same compiler and that compiler added free() to all functions with a stack. Stage 9: If a function doesn’t have any local variables, this is where we delete their allocations and free’s so that they don’t mess up the heap For example : alloc(0, index); and the target function for this allocation will have its free(stack, 0) call removed. Stage 10: Finally we create dummy scratch functions for our very lowered AST And finally in stage 11 we create the code blocks for the scratch functions and write to disk And it successfully calculates fib(9) as 34"}, {"post_id": 13952, "ts": "2026-06-22T22:02:44Z", "hours": 2.9797, "text": "I made a wrapper for the raw opcode classes that make valid code easier to make, then I did a ton of bug fixes and did a small refactor"}, {"post_id": 13260, "ts": "2026-06-21T18:26:43Z", "hours": 0.5228, "text": "Did a refactor, and intellij decided to corrupt some of the files, so I had to fix it"}, {"post_id": 13207, "ts": "2026-06-21T17:10:57Z", "hours": 3.1617, "text": "Implemented 90% of scratch’s blocks in the wrapper"}, {"post_id": 13095, "ts": "2026-06-21T12:57:42Z", "hours": 2.4425, "text": "Worked on a very basic scratch wrapper, it can generate a recursive function, gonna add more scratch blocks so that actual logic can be generated in this wrapper"}, {"post_id": 12772, "ts": "2026-06-20T21:38:46Z", "hours": 0.7953, "text": "Added static type checking, which makes sure the correct types are used everywhere. It prevents the user from using a number in an if statement’s condition. It also prevents you from assigning a string to an integer field"}, {"post_id": 12746, "ts": "2026-06-20T20:50:32Z", "hours": 2.8928, "text": "I added the AST parsing, which is able to parse the ANTLR parse tree into an AST (sorry the image is bad, its all I can show)"}, {"post_id": 12579, "ts": "2026-06-20T15:22:11Z", "hours": 3.0503, "text": "Worked on the first stage of AST parsing: Only parse top level elements (imports, structs, variables) and don’t parse the insides of functions"}]...
|
Title: Scratcher by @BetterClient | Stardance
Dev Title: Scratcher by @BetterClient | Stardance
Devlogs:
Worked on the first stage of AST parsing: Only parse top level elements (imports, structs, variables) and don’t parse the insides of functions
I added the AST parsing, which is able to parse the ANTLR parse tree into an AST (sorry the image is bad, its all I can show)
Added static type checking, which makes sure the correct types are used everywhere. It prevents the user from using a number in an if statement’s condition. It also prevents you from assigning a string to an integer field
Worked on a very basic scratch wrapper, it can generate a recursive function, gonna add more scratch blocks so that actual logic can be generated in this wrapper
Implemented 90% of scratch’s blocks in the wrapper
Did a refactor, and intellij decided to corrupt some of the files, so I had to fix it
I made a wrapper for the raw opcode classes that make valid code easier to make, then I did a ton of bug fixes and did a small refactor
I finished the pipeline from my language’s AST to scratch, it was pretty mind numbing Stage 1: The code does reachability, from the source file(where the compilation started) and finds all functions that we can call from the source Stage 2: Using those functions, we lower call expressions to statements and returns to heap accesses, here’s how that looks in code: Before : void main() { looks::say(fib(5)); } After : void main() { int fibReturn = -1; fib(5, &fibReturn); looks::say(fibReturn); } Notice how the nested call turned into a seperate statement. Why do we need this? Because scratch does not support returning stuff from functions, only arguments. Stage 3: We re-parse all locals on the reachable functions because the last stage added more locals Stage 4: We add a parameter to all functions named “stack” Stage 5: We add free(stack) calls at the end or before the return statement, this frees our stack automatically. We also add alloc before function calls so that we have a stack to pass to the function Here’s how that looks like in code: Before : void main() { int fibReturn = -1; fib(5, &fibReturn); looks::say(fibReturn); } After : void main(int stack) { int fibReturn = -1; int fibStack = -1; alloc(UNKNOWN, &fibStack); //allocate a stack for fib fib(fibStack, 5, &fibReturn); looks::say(fibReturn); free(stack, UNKNOWN); //free our stack } Notice how we have UNKNOWN in place for a number in the allocation and freeing, this is because we just added more locals for the allocations and we can’t know how many slots we need. Standard library functions are already compiled to scratch statements so they don’t need a stack allocated for them Stage 6: We re-parse local variables so we have a count. Stage 7: We count the re-parsed locals for every function and figure out which local variables can be reached in every function Stage 8: We convert all local variables to heap slots We traverse all statements and expressions, replacing all variable accesses with heap[stack + variableIndex]. While in this process we also convert the unknowns into the actual sizes since we just counted the locals in stage 7 Here’s how this entire stage looks like in code: Before : void main(int stack) { int fibReturn = -1; int fibStack = -1; alloc(UNKNOWN, &fibStack); fib(fibStack, 5, &fibReturn); looks::say(fibReturn); free(stack, UNKNOWN); } After : void main(int stack) { heap[stack] = -1; heap[stack + 1] = -1; alloc(3, stack + 1); //we just pass the index here since alloc will write to that index fib(heap[stack + 1], 5, stack); looks::say(heap[stack]); free(stack, 2); //We have 2 locals } By using a stack we get access to a lot of things like returning, recursion and local variables. Scratch doesn’t even support local variables, so we have to hack it with a global list. Notice how we don’t free the allocation? That’s because all functions are compiled by the same compiler and that compiler added free() to all functions with a stack. Stage 9: If a function doesn’t have any local variables, this is where we delete their allocations and free’s so that they don’t mess up the heap For example : alloc(0, index); and the target function for this allocation will have its free(stack, 0) call removed. Stage 10: Finally we create dummy scratch functions for our very lowered AST And finally in stage 11 we create the code blocks for the scratch functions and write to disk And it successfully calculates fib(9) as 34
I added an event system, making it so your code can actually run on GreenFlag { main(); } on KeyPressed(W) { looks::say("W was pressed!"); } These events are translated into functions and the compiler generates scratch events that call these on KeyPressed(W) { compiler@eventlistener@F(); } void compiler@eventlistener@F() { looks::say("W was pressed!"); } The compiler also generates a initializer green flag block which clears the heap and reserves an index for every other entrypoint(image 2)
Did a small refactor on obfuscation Created a type safe(kinda) kotlin DSL for making standard library functions way more readable and simpler to create I rewrote the Memory library with the kotlin DSL Image 1: Before Image 2: After
Did general bug fixes Added more standard library functions Added runtime type checking and exceptions
Created a library for casting primitives to other primitives Expanded the math library a lot Added duplicate function and struct detection(yes I forgot before) Added code to prioritize function(int) over function(float) if calling with an int Added “warp” and “export” modifiers to function declarations, the warp modifier maps to the “Run without screen refresh” field, and export is currently unused, but later it will be used to export a function so that its properly usable from normal scratch code
Did a lot of refactors Created SensingLib and CalendarLib Made a system to allow standard libraries to be inlined into your code to reduce file size Added support for structs, Right now you have to manually free your structs
Did warning cleanup Added a nullability “system”, I allow the ? to be put on struct fields, and you can put null as the argument on those fields, then you have to check if they are null and do !! to use them
Created Motion and Pen library Added support for top level variables Made an optimization to get rid of useless “replace with -1” blocks(image 1 is before, image 2 is after), this greatly reduces the code size(images are only one example, it was being put everywhere)
Optimizations OptimizeToGlobals : If the compiler can prove that a function is not recursive and runs atomically(single threaded), it gets rid of the function’s primitive local variables, which improves performance as scratch’s list operations are more expensive than local variables InlineSingleUseVariables : Pretty self explanatory, if a variable is only used once, it will be inlined ConvertToHeapAccess : I did optimizations on the normal heap converter so that it doesn’t allocate a stack pointer for functions that don’t need one Images don’t show the OptimizeToGlobals optimization cause the testing function I have for that is too long Before and after on the RGB function
Source code of the image: on GreenFlag { if(a() == 5) { looks::say("yo!"); } int index = 0; index = index + 1; rgb(index, 5, 5); index = 5; while(true) { pen::eraseAll(); render(); } } The image is of the entire flow working perfectly: The index variable had their value propagated to “1” by the Sequential constant propagation optimization The variable got its uses removed by Inline single-use assignments Then the variable got fully removed by Dead store elimination The rgb function got inlined. Then while it was inlined, because the rgb function’s return wasn’t being used, it got fully removed(the inlining preserves side effects while removing its return value, but because it didn’t have any side effects it got fully removed) Same with the a() function: It got inlined Then the if statement became if(5 == 5) { looks::say("yo!"); } Then Constant folding turned 5 == 5 into true Then Dead code elimination turned if(true) into just the then block I know most optimizations look like they aren’t that powerful, but when combined with other optimizations and ran in a loop, they can pile up and actually optimize code Optimizations Simplify boolean equality : Simplifies x == true to x , simplifies x == false to !x Simplify double negation : Simplifies !!x to x , simplifies --x to x Constant folding : Simplifies true == true to true , simplifies 5 + 5 to 10 Repeat to While : Converts repeat(amount) to a while loop Dead code elimination : Removes provably unreachable code blocks, eg: if(true) { ... } else { .. } turns into ... , removing the if and the else block entirely Now the big ones Sequential constant propagation : Analyzes the control flow of your program, removing useless variable assignments and inlining their expressions Inline single use assignment : Self explanatory Dead store elimination : Removes useless “set variable to x” blocks that don’t get used afterwards Function inlining : The compiler evaluates a cost for every function call is inside a function, if that total cost is less than 10,000, it gets inlined inside that function, removing call overhead and allowing for further optimization Other misc stuff: Fixed the while bug (if you called a function inside a while statement, it would only get called once) Made function lowering not allocate a stack slot if we’re ignoring return Made the OptimizeToGlobals optimization be called last to allow variable optimizations to happen first
Borrowed the “return expr if(cond)” syntax from ruby Implemented Tail call optimization which optimizes away recursion on tail calls Example: Before: str count(int amount) { return "Done!" if amount == 1; return count(amount - 1); } After: str count(int amount) { int tco@argument@amount = amount; while (true) { if (tco@argument@amount == 1) return "Done !"; tco@argument@amount = tco@argument@amount - 1; } }
Did some compiler testing Fixed function inlining bugs Fixed a single use assignment bug Created a triangle library that allows for triangle rendering using the pen
Made “PromoteToGlobals” which is a more powerful version of OptimizeToGlobals which allows for recursive functions to have their locals turned into globals aswell This is something called liveness analysis, the compiler looks at the code paths and decides at which points a variable is “live”, which means it can’t get overwritten by a recursive call Example: warp int fib(int n) { return 0 if n <= 0; return 1 if n == 1; if (n == 2) { int b = n * 2; return otherFunc(b); } return fib(n - 1) + fib(n - 2); } In this function the “b” variable can be turned into a global because it cannot get overwritten by a recursive call, its used too early for that to happen
Added list support! A very barebones implementation that allows the user to create, add to, read from and delete items from lists!
Added more compiler sugar for lists: list[index] replaces list::itemAt(list, index) list[index] = ...; replaces list::replace(list, item, index) for(type name in list) {} replaces int len = list::length(list); int i = 0; while (i < len) { type name = list::itemAt(list, i); i = i + 1; } (i am not proud of the shitcode that was used to get for(type name in list) working)
Added a name parameter to alloc which acts as runtime type metadata, soon to be used.
Garbage collection Added a mark and sweep garbage collector to my language, it walks the roots, marks every used object, then frees all unused objects! Most impressive part of this(in my opinion) is that most of the garbage collector is actually written in my language Misc The garbage collector gets called automatically every 1 second, but you can turn it off (CompilationConstants.AUTOMATIC_GC) If you want to manage memory manually, you can turn off the garbage collector entirely (CompilationConstants.MANUAL_MEMORY)
Made the garbage collector treat top level variables as roots, this prevents top level variables from getting freed I added 2 modes to this Reflect: This uses a hacked block to read the variables by name and reduce script size if theres a lot of variables(this doesn’t render properly inside the editor but it works) NoReflect: Get all the top level variables at compile time and mark them one by one
Tried to do turbowarp only return optimization, wasn’t able to make it very good… reverted it Improved the structure of CompilationConstants Added string::split and string::substring Made some of the list functions inlined (itemAt, clear, length)
Added more syntax improvements! Else if : Added support for else if, which replaces big blocks //Before: if(triangles[14].y1 >= 15) { looks::say(">=15"); } else { if(triangles[14].y2 >= 155) { looks::say("<=15"); } else { looks::say("Both false!"); } } //After: if(triangles[14].y1 >= 15) { looks::say(">=15"); } else if(triangles[14].y2 >= 155) { looks::say("<=15"); } else { looks::say("Both false!"); } Compound assignment : Added support for compound assignment //Before: triangles[15].y3 = triangles[15].y3 + 5; //After: triangles[15].y3 += 5; Enums : Added support for enums, which are just fancy integer wrappers enum TriangleRenderMode(OFF, RENDER, ITHINK); TriangleRenderMode mode = TriangleRenderMode.OFF; When : Added support for when expressions/statements that allow for matching a subject: //Before: if(answer == "off") { mode = TriangleRenderMode.OFF; } else if(answer == "render") { mode = TriangleRenderMode.RENDER; } else { mode = TriangleRenderMode.ITHINK; looks::say("If thinking is your power, what are you without it?"); return; } //After: TriangleRenderMode mode = when(answer) { "off" -> TriangleRenderMode.OFF "render" -> TriangleRenderMode.RENDER else -> { looks::say("If thinking is your power, what are you without it?"); TriangleRenderMode.ITHINK; } };
Fixed a lot of bugs with when expressions, also got deepseek to fix some of them Added If expressions, which allow using if statements inside other expressions, for example, here is some previously invalid code that is now valid: int max = if (a > b) a else b; str message = if (score >= 90) { looks::say("something"); "You win!" } else { looks::say("something"); "You lose :(" } triangles[15] = Triangle( utils::random(-240, 240), utils::random(-180, 180), utils::random(-240, 240), utils::random(-180, 180), utils::random(-240, 240), if(mode == TriangleRenderMode.OFF) { 5 } else { triangles[14].y3 } ); These still get lowered properly and just look like normal if statements in the final scratch code
Scratcher is at 100 commits! (Now 104 cause all of these refactors are different commits) Completely refactored all translation steps to use the ASTVisitor. Also did type resolving cleanup. Function Reachability : Went from 117 to 32 lines Function expression lowering : Went from 439 to 293 lines Re Parse Local Variables : Went from 34 to 27 lines Remove Empty Allocations : Went from 97 to 79 lines ConvertToHeapAccess : Biggest refactor of this whole devlog, went from 500 lines to 418, split into 5 files
Did more syntax improvements Added ++ and – support: index++; Added type inference support: auto a = Triangle(5, 15, 60, -120, 240, 67); //type automatically becomes Triangle auto a = func(); //type automatically becomes the return type of func
Refactored the entire type system to use a sealed interface instead of an unsafe single class Nothing much to say, this doesn’t affect the input code or the output project, I did just cleanup
More abstractions please! Added dynamic function dispatch which allows for functions to take in other functions as arguments, of course, this isn’t possible at all in normal scratch, so actually FunctionLiteral gets turned into an integer and a custom dispatch function gets created for every function literal’s signature which allows for a binary search to call the actual function Also made HeapConversion reuse stack slots instead of allocating one for every variable(mostly by AI)
Even more abstractions please Added generics support, which allows the user to define generic functions/structs that apply with every type, for example: warp <T> void forEach(T[] a, (T) -> void action) { for(T t in a) { action(t); } } Depending on what type you used to call this, a new version of forEach gets generated, if you called it with an integer: warp void forEach@int(int[] a, (int) -> void action) { for(int t in a) { action(t); } } Of course I also allow this on structs: struct Triangle<Num>(Num x1, Num y1, Num x2, Num y2, Num x3, Num y3); Also did some small changes: Added an FPS counter to my test code Better optimizations that actually detect not(not(x)) Optimized triangle::fill even more (+2 fps) Made DynamicDispatchHandler actually use the apply return properly (it was always returning true)
Second garbage collector! Added a second garbage collector! If your app does not contain any cyclic objects and needs high performance, you can now enable the ARC collector! This garbage collector works by automatically detecting when objects go out of scope and decrementing their reference count, if an object’s reference count goes to 0, it is freed. This is more performant than the mark and sweep collector because the objects are freed at the moment they are unused instead of stopping the entire program to collect garbage. This works for all cases, except for cases where there is a cyclic object. Because the cyclic object owns itself, so its reference count is always at 1.
General language improvements Elvis expressions: If a value is nullable, it is not usable by anything that only accepts non-null values, to solve this, I added the elvis expression, which allows you to give a fallback for null values(compilation in image 2): //int doesn't have to be nullable because we have a fallback value! int x = functionThatReturnsNull()?: 5; String boxing and nullable primitives Previously, scratcher only supported having structs, enums and function references as nullable, now it also supports having primitive types as nullable: str? x = functionThatReturnsNullableString(); //distinguish between literal null and string null if(x == null) looks::say("null!"); if(x == "null") looks::say("null as string!"); //the compiler achieves this by boxing the string return with a struct: //struct StringBox(str value) //the actual type behind the scenes is: //StringBox? x = ...; Safe dot traversal If a struct instance is nullable, you cannot use regular struct.member because that may result in a NullPointerException, to solve this I added ?. which allows for null safe traversal(compilation in image 1): //if nullableTriangle == null, return null //if nullableTriangle != null, return nullableTriangle.x1 int? x1 = nullableTriangle?.x1; Deepseek fix I noticed that FunctionInlining completely ignored execution order, so I asked deepseek to solve it(this happened after I added string boxing). But I found a better solution to the same problem later on, so I reverted deepseek’s fix and wrote my own, which is 260 lines compared to deepseek’s 360 lines, over 100 lines shorter!
100 hours! Evil hack part 4: Death of evil hack So I was using a really terrible hack to implement stuff like FunctionInlining, Safe dot and the elvis expression, the hack is basically (ab)using the when expression to do stuff like run code inside expressions and use local variables inside expressions. So to stop this from becoming a hack, I added it directly to the AST as StatementExpression(not to be confused with ExpressionStatement), which can be used to contain statements inside expressions. All of my evil hacks have been replaced by StatementExpression. I also added some small optimizations for StatementExpressions!
Fixed the garbage collector… turns out I broke it accidentally while cleaning up code in my last devlog, 3 line change but took a long time to find Made it so the stack allocator doesn’t do redundant operations like 1+1 and inlines them as 2 instead
Lambdas I added lambdas to Scratcher! They allow you to write more expressive code like map(list, a -> a + 1) , which literally adds 1 to every element of list I also allow using outer variables within lambdas int a = ...; map(list, b -> { a++; b + a }); I allow this through boxing, the local variables become boxes and the lambdas get the local variable’s box, this makes lambdas more powerful than most languages as this allows for variables to be shared mutable state across lambdas, this also allows the local variables to get garbage collected. Of course, scratch doesn’t support this natively, so lambdas are 100% compiler sugar and just lowers to regular functions and uses function references(which is also 100% compiler sugar). void lambda::defunc@lambad@0(LambdaCaptures c, args...) { ... }
MORE FUCKING ABSTRACTIONS!!! I added receiver/extension functions. These allow you to write code that takes in a type as a special argument You define them just like how it works in kotlin: warp <T, R> R T.let((T) -> R action) { return action(this); } It just compiles to a regular function warp <T, R> R let(T this, (T) -> R action) { return action(this); } But the compiler lets you call it with the special argument: thing.let((int a) -> ...); I also added a very big standard library module (written in scratcher!) with a ton of these functions built-in, they allow you to write more expressive code: triangles .filterNotNull() .filter((Triangle<float> t) -> t.x1 > 150) .filter((Triangle<float> t) -> t.y1 < 150) .forEach((Triangle<float> tri) -> ...) I also rewrote the entirety of string lib during this, now you have to use the extensions library to use strings, but its way more powerful (and written in scratcher)! I also added a new “char” type, which stores a single character (wow really???) I also added “safe dot calls” that allow you to use stuff as if they’re not null: triangles.forEach((Triangle<float>? t) -> { t?.x1?.let((float x1) -> { looks::say("x1: ${x1}"); }); }); This only calls the let function if t?.x1 is not null There is a big problem with all this powerful new code though… the garbage collector can no longer keep up, a single mark and sweep takes over 1 second! Which is especially bad because the garbage collector needs the entire application to stop in order to run. You do not want your code to completely stop for a whole second(maybe you do? weirdo), so I have to fix this in my next few devlogs…
Sealed enums and faster GC I added a new type of object, sealed enums: sealed enum Animal { Cat(str name, int age, bool isMeowing), Dog(str name, int age), Unknown } They allow for storing data inside enums, they’re very similar to rust enums: sealed enum Result<T> { Success(T out), Failure } I also refactored lambdas to use a sealed enum instead of a big struct: //before struct LambdaCaptures(Lambda0Captures? c0, Lambda1Captures? c1, Lambda2Captures? c2); //after sealed enum LambdaCaptures { Lambda0Captures(Box$int capture0, ...), Lambda1Captures(Box$float capture0, ...) } Sealed enums only store a tag and a pointer, so if you use a lot of lambdas, this will save a TON of heap space Faster garbage collector! I made the marking phase of the mark and sweep collector faster by using an epoch based cleanup approach Now, instead of clearing and re-populating the marked list, we don’t ever clear it and we invalidate it by just increasing the epoch. This makes the isMarked check go from O(n) to O(1) while also improving marking speed because scratch doesn’t have to resize our list
I’m sorry For over 2 months, scratcher has had an “export” keyword, which was fully unused, until today: I implemented the export keyword on functions, which allows for code written in plain scratch to interact with scratcher code: export warp void myFunction() { ... } Export requires that your function arguments are all primitives and that the return is also a primitive, but other than that, it does not change anything, just exposes the function cleanly to regular scratch code. However, scratcher type checking still applies, so if the native scratch code passes in a string to a float argument, it will still cause a panic Even when you have obfuscation enabled, exports will stay and let native scratch use it with its original name
ACTUAL ARRAYS!! Previously, scratcher “arrays” were just lists, you could add more items, it would dynamically resize, it was written in the kotlin DSL, so technically it was just a list. I removed the previous list code, reused some of it and added a new Array system Along with that, the normal lists got rewritten in 100% scratcher with no internal functions The new system is almost fully backwards compatible in source code, you just have to make a few changes The new implementation is more clear, more expressive and more like regular programming languages
Pattern matching for sealed enums Previously if you wanted to check sealed enums types and use them, you had to do very ugly syntax for actually getting the variant instance: auto out = tryGet(); when(out) { Result.Success -> { auto suc = out as Result.Success; looks::say("Success! ${suc.out.x}"); Now you don’t have to do all of this: when(tryGet()) { Result.Success suc -> { looks::say("Success! ${suc.out.x}"); This is just syntax improvement, doesn’t change the generated code or anything, just helps the developer
Import some import names into unqualified co ntext Before: //import import list; //use list::List<str> myList = list::newList(); After: //import import list::*; //use List<str> myList = newList();
Operator overloading Added operator overloading, now you can define overloads for specific operators so that code looks cleaner Just use the operator keyword with the correct signature and you’re done! You can overload the operators: +, -, /, *, %, [], []= For example: warp operator <T> void T[].set(int index, T item) { self::replace(this, item, index); } //use array[index] = item //compiler translates to set(array, index, item) I also realized that my previous refactor of arrays broke my nullability system: int[] a = Array(int, 5); say(a[3]); This would print null , which my type system missed I fixed this by moving arrays to a standard library module, the same array import works, but you have to change how you create the array: //before: int[] a = Array(int, 5); //doesn't need to be marked as null!!! int[] a = Array(int, 5); a[0] = ...; a[1] = ...; ... //after int?[] a = arrayOfNulls(5); //null filled int[] a = arrayOf(5, (int index) -> { return index * 5; //value of the array at that index });
Privates Added a “private” keyword, anything declared private cannot be accessed from outside the current file. This prevents the user from messing with internal states of libraries they are using For example, the list library from the standard library. Now you can’t directly mess with the list pointer triangles.ptr[5] = ...; This now results in an error because “ptr” is private! I also added some small optimizations for lambdas.
DOCUMENTATION I do not want to touch any markdown ever again
QOL I added a shit ton of quality of life stuff: Tons of bug fixes Big array syntax: int[] myArray = [1, 2, 3, 4, 5, 6]; Safe casting for enums(previously a panic): Result.Success? a = res as? Result.Success; Out of memory detection: Scratch caps lists at 200k elements, after that it silently stops adding stuff to the list Compact int list: Store pretty much infinite integers without wasting heap space SHORT CIRCUITS: DONT EXECUTE RIGHT SIDE OF && or || if left side is false/true! If statements without braces: if(a) b++; CONTINUE AND BREAK: while(true) { if(a) break; if(b) continue; } STATIC LISTS: store data outside of the heap in scratch lists so that you dont run out of heap space: static str[] myList; This also allows for file reading: static str[] myList = "hello.json"; So you can properly store data(like ROMs) CASE SENSITIVE EQUALS: DID YOU KNOW THAT SCRATCH “=” BLOCK IS CASE INSENSITIVE??? And its pretty hard to make it case sensitive Now you can do “===” and its case sensitive: 'a' === 'A' RETURNS FALSE
List pools Static lists are cool, but they are very limited expressiveness wise because they must be known at compile time Pools fix this by having a pool of static lists that the user code can allocate at any time PooledList a = allocate(); But because the pool is limited, the pooled list must be freed when not needed, the garbage collector will not handle it(yet) a.free(); Other than that, the PooledList behaves just like a List and can do almost anything a List does I also added proper documentation for Out of memory errors.
Indexed repeat and general improvements Added a new indexed for and repeat statement which allows way easier index tracking: //Before: int index = 0; repeat(10) { ... index++; } //After: repeat(10) { index -> ... } I also made the PooledList get garbage collected with the refcount gc Did some really small refactors aswell
Demo programs and general improvements I added demo programs to scratcher, these show the language actually being used Try one out! https://scratch.mit.edu/projects/1385339395/ General improvements Bug fixes Dummy sprite Make the type checker ignored in inlined functions Make topLevelInit smaller and remove unused functions from final compilation TurboWarp specific compilation mode with faster operations on strings/lists (not compatible with vanilla scratch if enabled)
More demos and QOL Try it out: https://scratch.mit.edu/projects/1387804691/ Demos Math lexer, parser and interpreter: New demo that lets you input math expressions (eg: 1 + 1 ) and get the result. 3d cube renderer: a spinning 3d cube and player controls QOL Smarter inlining cost calculation A math centered optimization for removing identities Get rid of PromoteToGlobals (temp) GC documentation Codegen fixes (receiver functions generate the same block, causing scratch to get confused) Stack size optimization (reuse stack slots of the same type) Fix crash when the garbage collector is disabled
PROPER ERRORS Errors are the one thing that I knew were terrible but I could never build up the courage to fix. So I just fixed them. Now all errors in the language are formatted nicely, show you exactly where the error happened and give you a nice description. Along with this, I made a new system for collecting errors, so now the compiler won’t stop at the first error and will continue going and give you all errors at once. This makes fixing code a lot easier. This also opens up the possibility of an LSP server later on (before and after in images)
CLI I did some small refactors and added a new CLI, built with Clikt It’s very simple to use: scratcher check file --options //check the file for any compilation errors without compiling scratcher compile file --options outFile //compile into a .sb3 file scratcher standard-library //print out the standard library Clikt also provides easy to use help menus I also added a sort function to the array and list libraries...
|
1792482509.6003482
|
1793087309.6003482
|
|
67902
|
Refract by @mixidmb | Stardance
|
mixidmb
|
1
|
32.0
|
594
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T19:56:54Z", "hours": 32.0, "multiplier": 18.8, "payout": 594, "blessing": "neutral", "text": "Refract! Quest Games Translation Layer. Haii! I made a way to play Quest games like Batman, Iron Man VR and AC Nexus on PC, Or any PCVR headset. You can even play Resident Evil 4 now, which is one of the most requested one :P It runs on Windows or Linux. The Android Emulator on Windows is the most compatible one. Refract Native is also on Windows and runs the game’s ARM64 code directly on the CPU, so its faster but still experimental (While recording a demo i got a pink cube in AC nexus lol, but through android emulator works!). Linux uses waydroid that just shares kernel. It’s still experimental though, so not every game works yet. Here is a video of me yapping a ton about it, and showing some gameplay >_> https://youtu.be/OpW-374mX74", "repo": "https://github.com/MIXIDtheSilly/Refract", "demo": "https://github.com/MIXIDtheSilly/Refract/releases"}]...
|
[{"post_id": 81063, "ts": "202 [{"post_id": 81063, "ts": "2026-10-19T18:20:30Z", "hours": 6.1647, "text": "Bug fixes and compatibility Okay let’s start with the big things. Iron Man VR works and runs at 140+ fps. And one of the most requested games, Resident Evil 4, runs too! It’s at around 160+ fps. It uses the old VrApi, which now works (still experimental, and 32-bit games aren’t supported). Controller haptics, the Linux Android build tools fix (game imports work now), and viewer crash reporting also work. Crashes go to viewer.err with el reason."}, {"post_id": 80654, "ts": "2026-10-18T12:31:32Z", "hours": 8.0708, "text": "Its even faster now Since last devlog, I swapped default translation layer on linux to my optimized Digitalis, and from dynarmic to Digitalis on Refract Native (windows). AND DAMNN, no one can tell me dynarmic is faster lol, from 200 fps in one of the games to 300+. Batman also runs at 120+ Linux has a working launcher now, and windows got texture compression improvements (RIP Vram) Then there are a bunch of other fixes, like Meta audio SDK working on Linux, or /sdcard storage path now resolving properly. Oh and almost forgot, FINALLY OPTIMIZED THE MAIN THREAD! It can hit 100% now because of lighter code also being JIT. This was probably the last bottleneck."}, {"post_id": 79125, "ts": "2026-10-12T19:11:22Z", "hours": 9.4442, "text": "Refract without an emulator now hai again, so over the past week I worked on Linux support and Refract Native , now you can run Quest games directly (well, translation layer) on the CPU without using QEMU. Funny JIT floating point error lol, broke my friend’s rig apart. What about Linux progress? The games run great! I tried it on North Star and it’s hitting 80 fps, cuz as you probably know we also don’t have to emulate the kernel there as Linux and Android are basically the same thing. also I hit 12 issues on GitHub (help)"}, {"post_id": 77853, "ts": "2026-10-08T15:22:14Z", "hours": 7.9314, "text": "Haii! So some of you know i got banned for a while but i’m back! New Project Refract! (You can now play Meta Quest titles on PC & PCVR) Refract runs Quest games on a Windows PC (Linux support soon! ), and in a PC VR headset through SteamVR. The APK runs in Android on your machine, Refract gives it fake Quest calls, and the eye frames come back out to your headset. Refract is for games you own! credit required if you use the code :P It started as a fork of AXRB by Feline Reintgen (But now its using my code so ig we are superior lol), and the launcher’s Meta sign-in comes from RiftLift. Translator is Digitalis. Oh forgot to mention that i already worked on it for a while, but wasn’t able to track time because of the suspension. And here is my playing batman on it."}]...
|
Title: Refract by @mixidmb | Stardance
Devlogs:
H Title: Refract by @mixidmb | Stardance
Devlogs:
Haii! So some of you know i got banned for a while but i’m back! New Project Refract! (You can now play Meta Quest titles on PC & PCVR) Refract runs Quest games on a Windows PC (Linux support soon! ), and in a PC VR headset through SteamVR. The APK runs in Android on your machine, Refract gives it fake Quest calls, and the eye frames come back out to your headset. Refract is for games you own! credit required if you use the code :P It started as a fork of AXRB by Feline Reintgen (But now its using my code so ig we are superior lol), and the launcher’s Meta sign-in comes from RiftLift. Translator is Digitalis. Oh forgot to mention that i already worked on it for a while, but wasn’t able to track time because of the suspension. And here is my playing batman on it.
Refract without an emulator now hai again, so over the past week I worked on Linux support and Refract Native , now you can run Quest games directly (well, translation layer) on the CPU without using QEMU. Funny JIT floating point error lol, broke my friend’s rig apart. What about Linux progress? The games run great! I tried it on North Star and it’s hitting 80 fps, cuz as you probably know we also don’t have to emulate the kernel there as Linux and Android are basically the same thing. also I hit 12 issues on GitHub (help)
Its even faster now Since last devlog, I swapped default translation layer on linux to my optimized Digitalis, and from dynarmic to Digitalis on Refract Native (windows). AND DAMNN, no one can tell me dynarmic is faster lol, from 200 fps in one of the games to 300+. Batman also runs at 120+ Linux has a working launcher now, and windows got texture compression improvements (RIP Vram) Then there are a bunch of other fixes, like Meta audio SDK working on Linux, or /sdcard storage path now resolving properly. Oh and almost forgot, FINALLY OPTIMIZED THE MAIN THREAD! It can hit 100% now because of lighter code also being JIT. This was probably the last bottleneck.
Bug fixes and compatibility Okay let’s start with the big things. Iron Man VR works and runs at 140+ fps. And one of the most requested games, Resident Evil 4, runs too! It’s at around 160+ fps. It uses the old VrApi, which now works (still experimental, and 32-bit games aren’t supported). Controller haptics, the Linux Android build tools fix (game imports work now), and viewer crash reporting also work. Crashes go to viewer.err with el reason.
Ships:
Refract! Quest Games Translation Layer. Haii! I made a way to play Quest games like Batman, Iron Man VR and AC Nexus on PC, Or any PCVR headset. You can even play Resident Evil 4 now, which is one of the most requested one :P It runs on Windows or Linux. The Android Emulator on Windows is the most compatible one. Refract Native is also on Windows and runs the game’s ARM64 code directly on the CPU, so its faster but still experimental (While recording a demo i got a pink cube in AC nexus lol, but through android emulator works!). Linux uses waydroid that just shares kernel. It’s still experimental though, so not every game works yet. Here is a video of me yapping a ton about it, and showing some gameplay >_> https://youtu.be/OpW-374mX74...
|
1792857183.3555014
|
1792943583.3555014
|
|
67710
|
Self Learning AI Agents by @arushkalra52 | Stardan Self Learning AI Agents by @arushkalra52 | Stardance...
|
arushkalra52
|
0
|
4.8
|
0
|
[]
|
[{"post_id": 81069, "ts": "202 [{"post_id": 81069, "ts": "2026-10-19T19:05:32Z", "hours": 0.5494, "text": "Updated UI with Streamlit."}, {"post_id": 80235, "ts": "2026-10-16T20:21:02Z", "hours": 4.2467, "text": "I created a self-learning AI agent entirely from scratch using Python. It uses Google Gemini, carries out real-time web searches using DuckDuckGo, and retains all the information between sessions with the help of persistent JSON memory."}]...
|
Title: Self Learning AI Agents by @arushkalra52 | Title: Self Learning AI Agents by @arushkalra52 | Stardance
Devlogs:
I created a self-learning AI agent entirely from scratch using Python. It uses Google Gemini, carries out real-time web searches using DuckDuckGo, and retains all the information between sessions with the help of persistent JSON memory.
Updated UI with Streamlit....
|
1792468221.896966
|
1793073021.896966
|
|
2617
|
Mossy by @dayfit | Stardance
|
dayfit
|
0
|
100.57
|
0
|
[]
|
[{"post_id": 81070, "ts": "202 [{"post_id": 81070, "ts": "2026-10-19T19:09:33Z", "hours": 1.1372, "text": "Devlog 24 After reading and analizing this flow today, I’ve realized that it’s better to keep each vault with it’s own passkey (one leak won’t expose your all keys). Also right now if you have already registered passkey for that vault you can choose to use exising passkey (so it’ll look it up on your device), or create new one (it might overwrite your old one (for same vault)). After reviewing this PR by myself and finding nothing that would make this insecure, I’ve used GPT Astra 6 as well to review it, so now I’m pretty sure that this branch is ready to go on main. See ya!"}, {"post_id": 80793, "ts": "2026-10-18T20:06:37Z", "hours": 4.1375, "text": "Devlog 23 I added one really important thing. Before, Mossy used a 4-digit PIN to unlock the vault (it was used as a wrapping key (after going through HKDF and Argon2)). It was 10,000 combinations. Argon2 made it take longer, but after some time (a few hours), it could be cracked (if someone had your encrypted encryption key (sounds funny :d)). After this change: We use PRF from WebAuthn (really secure stuff) that uses Touch ID, Windows Hello, or Yubico Security Keys (and others) to give deterministic random bytes. Think of it like a random function that remembers what it returned for which argument. Assuming that an attacker would try to brute-force this encryption key, even with 10^18 tries per second, it’d take 1.8 x 10^51 years to crack it (kinda looooong time). Oh, and for those who can’t or don’t wanna use PRF, I’ve added regular passwords. They’re not as good as PRF, but it still takes a really long time to crack those. Those changes are still in an open PR, but it’s 10 PM, and I need to take a closer look at it tomorrow (already did a code review myself, but I’m kinda sleepy, and I’d like to keep y’all secure <3). See ya!"}, {"post_id": 80415, "ts": "2026-10-17T15:50:11Z", "hours": 7.7453, "text": "Devlog 22 Frontend: Added light, dark, and auto themes support (with settings tab!) Settings tab with themes options and links to request new features Added dashboard onboarding to help users setup their vault and add their first password Reworked key synchronization (now users will provide 6-character code instead of 6-digits code (Also it lacks of ambiguous characters like “l” and “I”) Backend: Complete rework of key-sync microservice (HTTP + SSE instead of WebSockets) (so user can access synchronized passwords up to 5 minutes after they are sent) Improved scallability by completely rethinking key-sync flow (that was kinda tricky)"}, {"post_id": 79105, "ts": "2026-10-12T18:01:50Z", "hours": 10.0319, "text": "Devlog 21 Changelogs Frontend: Standarized colors, boders, shadows, and button styles using globals.css system Updated typography: Syne for body text and Geologica for headings Centered headers navigation links Redesigned home page hero Fixed the footer so it stays at the bottom of the page Added leaf decorations on home page Based on feedback (from flavortown) I’ve decided to add some links to docs and instructions on how to set something up. Backend: Added SSE endpoint for live device enrollment updates I am working on delivering some more things before end of stardance. Stay tuned!"}, {"post_id": 70708, "ts": "2026-09-19T17:00:52Z", "hours": 5.3025, "text": "Devlog 20 Here is what happend after last devlog (lots of improvements :D) On frontend: Improved secured passwords chart, so it does only show integer values, centered chart’s line Added total count of passwords chart (as default mode) Added email verification interface Improved recent actions section Removed website icon from recent action card (API was broken, and it didn’t looked good anyway) On backend: Finished and integrated email verification system (verification link and code expires after 15 minutes) Added limits for incorrect codes, resend cooldowns, and hourly email deliveries Added rate limiting to public verification endpoint Emails are sent asynchronously through RabbitMQ That’s all for now. I’ll focus on design consistency & responsiveness for now."}, {"post_id": 65279, "ts": "2026-09-10T09:25:36Z", "hours": 7.6328, "text": "Devlog 19 It’s been a long time from last devlog. Here is changelog: On frontend: Vault loading, refreshing, selection, etc are now centralized in zustand store Removed redundant useVault hook Now user can select vault from dashboard view Added clearer selected-vault indicators and improved keyboard accessibility Made dashboard vault cards presentational and reusable On backend: Fixed critical bug in resource server logic (refresh token could be used as auth token (very bad :c)) Improved and refactored jwt validation & generation Added correct typ claim in JWT tokens Simplified refresh token claims (some were unused or not necessary) Updated Authentication.md documentation Expanded JWT generation, management, and decoder tests Work in progress: Currently I’m working on new feature, central microservice that will handle sending emails to users This is what I got so far: Batched async communication through RabbitMQ Integration with resend and some templates Retry queue with 30 secounds delay Service requeue mail only if something went wrong with sending (429 or 5XX response), if recipient doesn’t exist, there is no requeue Added tests for duplicates, pending commands, successful sends, permanent failures, and retryable failures. See ya!"}, {"post_id": 59672, "ts": "2026-09-01T16:25:07Z", "hours": 1.7078, "text": "Devlog 18 Mock API is finished, now I’m working on frontend design & consistency Changelog Finished Mock API Renamed RippleButton to Button as it’s generic right now Made Button component generic (support for icon, ghost buttons etc) Replaced all buttons with generic Button component Also I adjusted some colors so design is more consistent. See ya!"}, {"post_id": 59001, "ts": "2026-08-31T16:08:03Z", "hours": 7.1164, "text": "Devlog 17 Device manager is now up and running on production! in code review I noticed: some edge cases (mostly related with multi-threading) user could not change accounts (persisted device id was the issue) probably more, but stardance was down so I couldn’t write this devlog Now I’m working on creating Mock API so frontend development will no longer require running real backend. Stay tuned!"}, {"post_id": 46463, "ts": "2026-08-13T18:01:12Z", "hours": 1.7533, "text": "Devlog 16 Finally device manager is ready to go. Refactored frontend side logic for key-sync to work with new API Fixed bugs, improved error handling (so error message is not misleading) Removed .idea folder from repo Introduced mossy-reactor (way to test micro-services with their dependencies without deploying them to main before tests) Now it’s time to work on frontend features + design (typography, colors, globals <– boring stuff ://)"}, {"post_id": 45388, "ts": "2026-08-11T20:21:14Z", "hours": 3.4439, "text": "Devlog 15 I’ve integrated API with frontend, created new tab for managing devices. Fixed some bugs related to interation of cross-microservice communication (maybe I’ll write some integration tests? who knows) I’ve added detection of OS and device type via user agent (using Yauaa library). Now I’ll have to think about how to create good risk-engine when at same time not storing too much user informations (to keep it privacy-first) If you guys have some idea how to do that let me know! To merge this feature to develop branch I need to fix some really minor bugs. see ya!"}, {"post_id": 44650, "ts": "2026-08-10T15:43:24Z", "hours": 9.4775, "text": "Devlog 14 Soo… Recently I saw that there was no way to add new devices (** facepalm **). From last devlog I created nice enrollment system that will require already verified device to accept new one before trusting it. I’ve utilized JWT scopes for that, so client authenticated with enrollment token can only access specific endpoints. All of that probably sounds pretty easy but e g. I didn’t wanted to duplicate existing code, enrollment token is issued by same /login endpoint etc etc. basically it was quite a hustle. Hopefully, next devlog will be about how I integrated API with frontend (cross your fingers!) BTW: test count jumped from 31 to 72 from last devlog so you can see how big is the difference!"}, {"post_id": 34100, "ts": "2026-07-24T16:02:15Z", "hours": 5.6378, "text": "Devlog 13 Device manager is pretty much ready to go to production from API pov (there are some things that I still need to code tho), from last devlog I integrated it with Auth microservice, with each login / session refreshment it’s checked if given device is blocked, if so, Mossy will refuse to provide user new tokens. PS: look at those green tests (so cool)!"}, {"post_id": 29715, "ts": "2026-07-16T20:09:15Z", "hours": 4.5417, "text": "Hello there! From last devlog I’ve managed to add some features for this new Device Trust Microservice. Right now device can be blocked by another device (it will stop this device from access to account) Nonce challenge is working and has really good test coverage (this whole microservice does too) thanks to TDD I’ve finished implementing controllers & their tests It might look like TDD is slowing me down, but my code is getting really mature (each scenario is prepared). For whole process of developing this MS I didn’t opened insomnia even once - and that’s cool, because running tests without running whole MS (and it’s dependencies) is much faster. See ya!"}, {"post_id": 29114, "ts": "2026-07-15T19:34:36Z", "hours": 10.0033, "text": "Hello everyone, For last 10 hours I’ve made major progress on Mossy development. First of all my custom JWKS system got replaced by Spring Boot OAuth2 Resource Server Starter (looong name isn’t it?), it’ll make future maintance & coding much easier. In futher I’m going to migrate it to use Authorization Server Starter to achive full OAuth2 compatibility. Also I’ve been learning how TDD works, and for last 4 hours I’ve been using it during coding, it makes life so much easier! I’m currently working on new feature - Device Manager, it’s really huge feature (I need to refactor existing Device MS), but it’s really exciting, it’ll show you what devices are added to your account & analyze risk of each login (based on your common IP & MAC & OS & some more) it requires me to change old Device Microservice domain to just key-sync. Also I’ll create 2 new microservices - one called Device Trust (I’m working on it currently), it’ll tell my Authentication system to allow login or not (before cryptography was just for key-sync) by using challenge - client’ll receive randomly generated nonce and it’ll have to sign it with it’s key. Then if everything is alright it’ll ask Risk Engine if it should send user an alert or not (in future it might require MFA from client detected as higher risk) This is my biggest project ever Stay tuned!"}, {"post_id": 12018, "ts": "2026-06-19T16:35:36Z", "hours": 1.5044, "text": "Mossy now supports ssh public keys as well Refactored actions in frontend code to achive cleaner code Added validation of ssh keys"}, {"post_id": 11466, "ts": "2026-06-18T18:57:58Z", "hours": 2.0375, "text": "Mossy now supports SSH keys! Old Add Password form got removed, and replaced by new, cleaner one. Also I’m on my way to refactor code, and make lifting of Mossy’s extension UI. Support for public keys, and other SSH specific features will be introduce later, right now, only private key is supported"}, {"post_id": 10739, "ts": "2026-06-17T17:00:53Z", "hours": 2.2661, "text": "Notes system is ready and works like a charm, I had minor problem with JPA while implementing it ( Cascade.ALL ) fixed issue. Notes are encrypted with vault encryption key, so it’s suitable for sensitive data. Next up I’ll implement usage history!"}, {"post_id": 10186, "ts": "2026-06-16T20:00:41Z", "hours": 2.2619, "text": "Now, I’m working on implementing notes for passwords, backend is already ready, and frontend logic is half-way there, probably I’ll finish everything tommorow. Also I’ve made major refactor in vault request handlers logic by creating AbstractVaultRequestHandler to keep boilerplate-code in one place."}, {"post_id": 10021, "ts": "2026-06-16T15:59:05Z", "hours": 0.8125, "text": "Mossy’s search engine works like a charm!"}, {"post_id": 9322, "ts": "2026-06-15T17:15:42Z", "hours": 0.7514, "text": "Currently, I’m working on a search engine for Mossy using Fuse.js. There are still a few things to implement, such as the UI for query search, and some bugs in the tag search logic to fix."}, {"post_id": 8271, "ts": "2026-06-13T19:19:54Z", "hours": 2.9025, "text": "I’ve finaly finished system of managing tags! I really like how it turned out. Next up I’ll work on searching and filtering passwords!"}, {"post_id": 5828, "ts": "2026-06-09T19:26:39Z", "hours": 2.2906, "text": "Whole tag system is ready on backend, currently I’m working on integrating frontend with API in nice way. stay tuned !!!"}, {"post_id": 5145, "ts": "2026-06-08T20:42:33Z", "hours": 4.7406, "text": "I’ve created vault <—> backend communication for adding, assigning, and getting tags. Also adding logic is ready on frontend. Whole system ’ll be ready by tommorow 😱"}, {"post_id": 2856, "ts": "2026-06-05T18:23:25Z", "hours": 1.3331, "text": "Currently, I’m writing tag management system, that will include CRUD on tags, searching for passwords with tags. Adding tags already works! Also I’ve made really nice roadmap of Mossy Development!"}]...
|
Title: Mossy by @dayfit | Stardance
Devlogs:
Curr Title: Mossy by @dayfit | Stardance
Devlogs:
Currently, I’m writing tag management system, that will include CRUD on tags, searching for passwords with tags. Adding tags already works! Also I’ve made really nice roadmap of Mossy Development!
I’ve created vault <—> backend communication for adding, assigning, and getting tags. Also adding logic is ready on frontend. Whole system ’ll be ready by tommorow 😱
Whole tag system is ready on backend, currently I’m working on integrating frontend with API in nice way. stay tuned !!!
I’ve finaly finished system of managing tags! I really like how it turned out. Next up I’ll work on searching and filtering passwords!
Currently, I’m working on a search engine for Mossy using Fuse.js. There are still a few things to implement, such as the UI for query search, and some bugs in the tag search logic to fix.
Mossy’s search engine works like a charm!
Now, I’m working on implementing notes for passwords, backend is already ready, and frontend logic is half-way there, probably I’ll finish everything tommorow. Also I’ve made major refactor in vault request handlers logic by creating AbstractVaultRequestHandler to keep boilerplate-code in one place.
Notes system is ready and works like a charm, I had minor problem with JPA while implementing it ( Cascade.ALL ) fixed issue. Notes are encrypted with vault encryption key, so it’s suitable for sensitive data. Next up I’ll implement usage history!
Mossy now supports SSH keys! Old Add Password form got removed, and replaced by new, cleaner one. Also I’m on my way to refactor code, and make lifting of Mossy’s extension UI. Support for public keys, and other SSH specific features will be introduce later, right now, only private key is supported
Mossy now supports ssh public keys as well Refactored actions in frontend code to achive cleaner code Added validation of ssh keys
Hello everyone, For last 10 hours I’ve made major progress on Mossy development. First of all my custom JWKS system got replaced by Spring Boot OAuth2 Resource Server Starter (looong name isn’t it?), it’ll make future maintance & coding much easier. In futher I’m going to migrate it to use Authorization Server Starter to achive full OAuth2 compatibility. Also I’ve been learning how TDD works, and for last 4 hours I’ve been using it during coding, it makes life so much easier! I’m currently working on new feature - Device Manager, it’s really huge feature (I need to refactor existing Device MS), but it’s really exciting, it’ll show you what devices are added to your account & analyze risk of each login (based on your common IP & MAC & OS & some more) it requires me to change old Device Microservice domain to just key-sync. Also I’ll create 2 new microservices - one called Device Trust (I’m working on it currently), it’ll tell my Authentication system to allow login or not (before cryptography was just for key-sync) by using challenge - client’ll receive randomly generated nonce and it’ll have to sign it with it’s key. Then if everything is alright it’ll ask Risk Engine if it should send user an alert or not (in future it might require MFA from client detected as higher risk) This is my biggest project ever Stay tuned!
Hello there! From last devlog I’ve managed to add some features for this new Device Trust Microservice. Right now device can be blocked by another device (it will stop this device from access to account) Nonce challenge is working and has really good test coverage (this whole microservice does too) thanks to TDD I’ve finished implementing controllers & their tests It might look like TDD is slowing me down, but my code is getting really mature (each scenario is prepared). For whole process of developing this MS I didn’t opened insomnia even once - and that’s cool, because running tests without running whole MS (and it’s dependencies) is much faster. See ya!
Devlog 13 Device manager is pretty much ready to go to production from API pov (there are some things that I still need to code tho), from last devlog I integrated it with Auth microservice, with each login / session refreshment it’s checked if given device is blocked, if so, Mossy will refuse to provide user new tokens. PS: look at those green tests (so cool)!
Devlog 14 Soo… Recently I saw that there was no way to add new devices (** facepalm **). From last devlog I created nice enrollment system that will require already verified device to accept new one before trusting it. I’ve utilized JWT scopes for that, so client authenticated with enrollment token can only access specific endpoints. All of that probably sounds pretty easy but e g. I didn’t wanted to duplicate existing code, enrollment token is issued by same /login endpoint etc etc. basically it was quite a hustle. Hopefully, next devlog will be about how I integrated API with frontend (cross your fingers!) BTW: test count jumped from 31 to 72 from last devlog so you can see how big is the difference!
Devlog 15 I’ve integrated API with frontend, created new tab for managing devices. Fixed some bugs related to interation of cross-microservice communication (maybe I’ll write some integration tests? who knows) I’ve added detection of OS and device type via user agent (using Yauaa library). Now I’ll have to think about how to create good risk-engine when at same time not storing too much user informations (to keep it privacy-first) If you guys have some idea how to do that let me know! To merge this feature to develop branch I need to fix some really minor bugs. see ya!
Devlog 16 Finally device manager is ready to go. Refactored frontend side logic for key-sync to work with new API Fixed bugs, improved error handling (so error message is not misleading) Removed .idea folder from repo Introduced mossy-reactor (way to test micro-services with their dependencies without deploying them to main before tests) Now it’s time to work on frontend features + design (typography, colors, globals <– boring stuff ://)
Devlog 17 Device manager is now up and running on production! in code review I noticed: some edge cases (mostly related with multi-threading) user could not change accounts (persisted device id was the issue) probably more, but stardance was down so I couldn’t write this devlog Now I’m working on creating Mock API so frontend development will no longer require running real backend. Stay tuned!
Devlog 18 Mock API is finished, now I’m working on frontend design & consistency Changelog Finished Mock API Renamed RippleButton to Button as it’s generic right now Made Button component generic (support for icon, ghost buttons etc) Replaced all buttons with generic Button component Also I adjusted some colors so design is more consistent. See ya!
Devlog 19 It’s been a long time from last devlog. Here is changelog: On frontend: Vault loading, refreshing, selection, etc are now centralized in zustand store Removed redundant useVault hook Now user can select vault from dashboard view Added clearer selected-vault indicators and improved keyboard accessibility Made dashboard vault cards presentational and reusable On backend: Fixed critical bug in resource server logic (refresh token could be used as auth token (very bad :c)) Improved and refactored jwt validation & generation Added correct typ claim in JWT tokens Simplified refresh token claims (some were unused or not necessary) Updated Authentication.md documentation Expanded JWT generation, management, and decoder tests Work in progress: Currently I’m working on new feature, central microservice that will handle sending emails to users This is what I got so far: Batched async communication through RabbitMQ Integration with resend and some templates Retry queue with 30 secounds delay Service requeue mail only if something went wrong with sending (429 or 5XX response), if recipient doesn’t exist, there is no requeue Added tests for duplicates, pending commands, successful sends, permanent failures, and retryable failures. See ya!
Devlog 20 Here is what happend after last devlog (lots of improvements :D) On frontend: Improved secured passwords chart, so it does only show integer values, centered chart’s line Added total count of passwords chart (as default mode) Added email verification interface Improved recent actions section Removed website icon from recent action card (API was broken, and it didn’t looked good anyway) On backend: Finished and integrated email verification system (verification link and code expires after 15 minutes) Added limits for incorrect codes, resend cooldowns, and hourly email deliveries Added rate limiting to public verification endpoint Emails are sent asynchronously through RabbitMQ That’s all for now. I’ll focus on design consistency & responsiveness for now.
Devlog 21 Changelogs Frontend: Standarized colors, boders, shadows, and button styles using globals.css system Updated typography: Syne for body text and Geologica for headings Centered headers navigation links Redesigned home page hero Fixed the footer so it stays at the bottom of the page Added leaf decorations on home page Based on feedback (from flavortown) I’ve decided to add some links to docs and instructions on how to set something up. Backend: Added SSE endpoint for live device enrollment updates I am working on delivering some more things before end of stardance. Stay tuned!
Devlog 22 Frontend: Added light, dark, and auto themes support (with settings tab!) Settings tab with themes options and links to request new features Added dashboard onboarding to help users setup their vault and add their first password Reworked key synchronization (now users will provide 6-character code instead of 6-digits code (Also it lacks of ambiguous characters like “l” and “I”) Backend: Complete rework of key-sync microservice (HTTP + SSE instead of WebSockets) (so user can access synchronized passwords up to 5 minutes after they are sent) Improved scallability by completely rethinking key-sync flow (that was kinda tricky)
Devlog 23 I added one really important thing. Before, Mossy used a 4-digit PIN to unlock the vault (it was used as a wrapping key (after going through HKDF and Argon2)). It was 10,000 combinations. Argon2 made it take longer, but after some time (a few hours), it could be cracked (if someone had your encrypted encryption key (sounds funny :d)). After this change: We use PRF from WebAuthn (really secure stuff) that uses Touch ID, Windows Hello, or Yubico Security Keys (and others) to give deterministic random bytes. Think of it like a random function that remembers what it returned for which argument. Assuming that an attacker would try to brute-force this encryption key, even with 10^18 tries per second, it’d take 1.8 x 10^51 years to crack it (kinda looooong time). Oh, and for those who can’t or don’t wanna use PRF, I’ve added regular passwords. They’re not as good as PRF, but it still takes a really long time to crack those. Those changes are still in an open PR, but it’s 10 PM, and I need to take a closer look at it tomorrow (already did a code review myself, but I’m kinda sleepy, and I’d like to keep y’all secure <3). See ya!
Devlog 24 After reading and analizing this flow today, I’ve realized that it’s better to keep each vault with it’s own passkey (one leak won’t expose your all keys). Also right now if you have already registered passkey for that vault you can choose to use exising passkey (so it’ll look it up on your device), or create new one (it might overwrite your old one (for same vault)). After reviewing this PR by myself and finding nothing that would make this insecure, I’ve used GPT Astra 6 as well to review it, so now I’m pretty sure that this branch is ready to go on main. See ya!...
|
1792486412.4775856
|
1793091212.4775856
|
|
69580
|
Spider game for CardputerADV by @Grant19 | Stardan Spider game for CardputerADV by @Grant19 | Stardance...
|
Grant19
|
1
|
9.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T19:32:56Z", "hours": 9.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I attempted to make a recreation of Daddy Long Legs, an IOS game by setSnail, on the cardputer ADV with Arduino C++", "repo": "https://github.com/GitDog1203/DaddyLongLegs", "demo": "https://youtu.be/QfPZ_8-vjX0?si=IZk7pHv-R4PdxiLq"}]...
|
[{"post_id": 81071, "ts": "202 [{"post_id": 81071, "ts": "2026-10-19T19:27:51Z", "hours": 1.1536, "text": "finished up the movment!"}, {"post_id": 80727, "ts": "2026-10-18T17:00:34Z", "hours": 8.0569, "text": "I’ve gotten so far on this project! Walking, colors, text, highscores, I’m going to make walking more smooth but other than that I’m almost done!"}]...
|
Title: Spider game for CardputerADV by @Grant19 | Title: Spider game for CardputerADV by @Grant19 | Stardance
Devlogs:
I’ve gotten so far on this project! Walking, colors, text, highscores, I’m going to make walking more smooth but other than that I’m almost done!
finished up the movment!
Ships:
I attempted to make a recreation of Daddy Long Legs, an IOS game by setSnail, on the cardputer ADV with Arduino C++...
|
1792857155.710538
|
1792943555.710538
|
|
68239
|
Java Path Tracer by @Robodog81 | Stardance
|
Robodog81
|
1
|
22.22
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-17T03:56:37Z", "hours": 18.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "This is an early beta of a path tracer that I am working on. I belive there are still a few problems (fuzzy metals not quite right) but overall it still looks ok.", "repo": "https://github.com/Robodog81/Path-Tracer", "demo": "https://github.com/Robodog81/Path-Tracer/releases/tag/Beta"}]...
|
[{"post_id": 81078, "ts": "202 [{"post_id": 81078, "ts": "2026-10-19T19:53:24Z", "hours": 1.4683, "text": "Tonemap Update and Code Reformatting I haven’t done much in the way of large changes since last devlog but I have been reformatting much of my code to make it easier to read and use. The code should now look a lot cleaner. I also fixed the tonemapper as it was over over exposing the brighter spheres. I also added a new tone map option that seems to be significantly better at representing bright colours than my prior two. The first one is purely clamping the HDR value to sRGB. As you may guess this leads to bright lights of most colours appearing white. I did have an alternative Reinhard tonemapper (v / (v + 1)) but that made everything look gray and desaturated as it applied the map to every colour channel individually causing all colours to look similar. The fix was to run the tone map with the brightest colour of the channel. This new screenshot is done with the new tonemapper and is a great example of the new glass refraction. It is a bit dark sorry. This took >30min to render."}, {"post_id": 80880, "ts": "2026-10-19T04:40:56Z", "hours": 2.75, "text": "Java Path-Tracer A simple Java Path-tracer for rendering cool scenes written in a single java class. The main thing I have spent my time on is adding in a glass material. It has proved to be more of a pain than I originally thought. The book series Ray Tracing in One Weekend has once again proved very useful. Anyway, whyle developing it I would repetitively get a material that looks somewhat like glass (or some weird blob) or something that was overly noisy. at one point my glass started emitting blue and yellow light (not much of a clue why that happened. After a good few hours of hassle I finally got it refracting properly. The rest of the features (total internal reflection & reflection) were fairly straightforward after that. Even caustics (the focused light under a glass sphere) work really well. I also found that my metal bounce rays for fuzzie metals weren’t being normalised properly causing weird ring artefacts. That was an easy fix luckily. I think this project is coming along well. Here is a new Hi-Res test scene that I let my laptop suffer on for quite a while. for reference this is an 8th gen i5 laptop and this scene took around 15 minutes to render. I did have a fair bit of other stuff open though. Enjoy. :)"}, {"post_id": 80270, "ts": "2026-10-17T01:58:49Z", "hours": 8.0306, "text": "Over the past few days i have made a few improvements. I have focused a bit more on the performance side of things and implemented (fairly bad) CPU multi threading as it was running single threaded before. This resulted in a 2-3x performance increase even though I went from 1 to 8 threads. I believe this is due to my bad code and the fact I create 8 new Thread objects every frame. Other than performance optimisations I also expanded the functionality of the renderer. I added Lambertian scattering for more accurate matte surfaces. I gave metal a fuzziness propitiate that allows for more surface options. I also started to implement glass (which is an absolute pain) but it is still broken at the moment (see screenshots) :) I also did some general housekeeping and cleaned up the code making it easier to read. The code is now visible on github for anyone who is interested."}, {"post_id": 78982, "ts": "2026-10-12T07:57:37Z", "hours": 10.1758, "text": "This is my shot at making a (somewhat optimised) Path Tracer in Java. I have previously made one in scratch and am trying to make a better foundation to work off of so I can add more advanced features. I had already started making the ray traversal code but forgot to log it; my current time is a little on the low side. I primarily work of the online books ‘Ray Tracing In One Weekend’ as they contain most of the info I need. At the moment only spheres are supported and only can be matte or a light. Even now I have been able to make some cool renders of random spheres. I will soon add more surfaces (mirror, glass, etc), anti aliasing, and multi thread support for better performance. If I can I will add support for polygons and thus 3d models. I hope this is as cool to you as it is to me. Thanks for reading. :)"}]...
|
Title: Java Path Tracer by @Robodog81 | Stardance
Title: Java Path Tracer by @Robodog81 | Stardance
Devlogs:
This is my shot at making a (somewhat optimised) Path Tracer in Java. I have previously made one in scratch and am trying to make a better foundation to work off of so I can add more advanced features. I had already started making the ray traversal code but forgot to log it; my current time is a little on the low side. I primarily work of the online books ‘Ray Tracing In One Weekend’ as they contain most of the info I need. At the moment only spheres are supported and only can be matte or a light. Even now I have been able to make some cool renders of random spheres. I will soon add more surfaces (mirror, glass, etc), anti aliasing, and multi thread support for better performance. If I can I will add support for polygons and thus 3d models. I hope this is as cool to you as it is to me. Thanks for reading. :)
Over the past few days i have made a few improvements. I have focused a bit more on the performance side of things and implemented (fairly bad) CPU multi threading as it was running single threaded before. This resulted in a 2-3x performance increase even though I went from 1 to 8 threads. I believe this is due to my bad code and the fact I create 8 new Thread objects every frame. Other than performance optimisations I also expanded the functionality of the renderer. I added Lambertian scattering for more accurate matte surfaces. I gave metal a fuzziness propitiate that allows for more surface options. I also started to implement glass (which is an absolute pain) but it is still broken at the moment (see screenshots) :) I also did some general housekeeping and cleaned up the code making it easier to read. The code is now visible on github for anyone who is interested.
Java Path-Tracer A simple Java Path-tracer for rendering cool scenes written in a single java class. The main thing I have spent my time on is adding in a glass material. It has proved to be more of a pain than I originally thought. The book series Ray Tracing in One Weekend has once again proved very useful. Anyway, whyle developing it I would repetitively get a material that looks somewhat like glass (or some weird blob) or something that was overly noisy. at one point my glass started emitting blue and yellow light (not much of a clue why that happened. After a good few hours of hassle I finally got it refracting properly. The rest of the features (total internal reflection & reflection) were fairly straightforward after that. Even caustics (the focused light under a glass sphere) work really well. I also found that my metal bounce rays for fuzzie metals weren’t being normalised properly causing weird ring artefacts. That was an easy fix luckily. I think this project is coming along well. Here is a new Hi-Res test scene that I let my laptop suffer on for quite a while. for reference this is an 8th gen i5 laptop and this scene took around 15 minutes to render. I did have a fair bit of other stuff open though. Enjoy. :)
Tonemap Update and Code Reformatting I haven’t done much in the way of large changes since last devlog but I have been reformatting much of my code to make it easier to read and use. The code should now look a lot cleaner. I also fixed the tonemapper as it was over over exposing the brighter spheres. I also added a new tone map option that seems to be significantly better at representing bright colours than my prior two. The first one is purely clamping the HDR value to sRGB. As you may guess this leads to bright lights of most colours appearing white. I did have an alternative Reinhard tonemapper (v / (v + 1)) but that made everything look gray and desaturated as it applied the map to every colour channel individually causing all colours to look similar. The fix was to run the tone map with the brightest colour of the channel. This new screenshot is done with the new tonemapper and is a great example of the new glass refraction. It is a bit dark sorry. This took >30min to render.
Ships:
This is an early beta of a path tracer that I am working on. I belive there are still a few problems (fuzzy metals not quite right) but overall it still looks ok....
|
1792857192.8033333
|
1792943592.8033333
|
|
56007
|
Too Much Time In The Arcade by @iboo | Stardance
|
iboo
|
1
|
80.35
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-17T20:29:07Z", "hours": 63.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "“Too Much Time In The Arcade” is a WarioWare-style game that is set in an arcade, as you might guess. It has currently two minigames. These minigames are a platformer and a snake minigame. All of these minigames have their own respective arcade consoles that you can interact with. Your goal is to get a total of score of 400 points to win. You can get all of your points in the platformer or in the snake minigame. There are no limitations. I had a lot of fun time coding, designing and learning Godot for this project. This is my first attempt to develop a game and I find it pretty good for a first try. Although I faced some challenges, I managed to solve nearly all of them. I also learned how to debug code while doing this project. I am very proud of how it turned up. And I hope you have a great time playing it. If you want to try the game, click the “Try project ->” button. When you click it, you will be sent to my itch.io site and you will be able to play the game! To people testing my game. I want to let you know that the platformer minigame has a way smaller hitbox compared to the player sprite. This makes it a ton more doable. Thank you for all of your support I hope you have a FANTASTIC time playing my game!! Kendinize iyi bakın! Bye! Note: “Kendinize iyi bakın!” is “Take care of yourselves!” in my native language, Turkish :)", "repo": "https://github.com/iboobey/too-much-time-in-arcade", "demo": "https://ibrahimbeyinli.itch.io/too-much-time-in-the-arcade"}]...
|
[{"post_id": 81079, "ts": "202 [{"post_id": 81079, "ts": "2026-10-19T19:54:23Z", "hours": 10.9086, "text": "DEVLOG #009 - Dino Run Done! (Nearly…) Hope you had a good day. I finished (nearly) my fourth game, Dino Run ! It is my version of the game that you play when you don’t have internet in Chrome, Google Dino Run. I probably should stop explaining what these games are cause EVERYBODY, literally EVERYBODY knows what these games are. Fot the last time: Dino Run is a game that you are a dinosour -most of the time but it can change.- and you run. Obstacles and birds spawn while you run. You must jump when the obstacles get near, and ducck when the birds get near. Also you run faster and faster as the time goes on. Controls You can jump with SPACE and you can duck with SHIFT or CTRL . When you jump a timer starts, and you can’t jump until the timer timeouts. I said that I “NEARLY” finished the game. The unfinished part is actually a quiet important part. It is the losing mechanic. It is actually very easy to add but I didn’t want to get my hours wasted because of me not devlogging. I will finish that part until the next devlog and I might forget to mention adding that. You can think it as done for now. These are it for this devlog. I will probably add some sounds and some small updates to the existing games. And at the end of that If I have time left, I will ad more games. Thanks for being here. Kendinize iyi bakın! Cya!"}, {"post_id": 74942, "ts": "2026-09-28T17:26:36Z", "hours": 6.4428, "text": "DEVLOG #008 - TETRIS GAME DONE! Good Evening y’all! I was away for a few days making a project in thirdspace . Anyways I am working for this project at the side too. And this game was finished few days ago but I couldn’t find the time to post a devlog about it. Here it goes now! Since my last devlog I made my third minigame, Tetris ! I again don’t think that I have to explain what tetris is. LITTERALLY everybody knows it. But for those who lives under a rock: In the game “Tetris”, some blocks fall from the sky and you put them like a puzzle. There are a total of 7 different shaped called “tetrominoes”. They are randomly given to you so it is more complicated and more enjoyable. There is a grid that you are filling with these tetrominoes. When you fill a row with these tetrominoes they disappear and the ones on top of them fall down. Once you complete a row you also get 10 points. There are also some standart futures that every Tetris ccopy has. They are: When you hold “S” the tetrominoes fall faster, when you click “R” the tetrominoes rotate and there is a panel that shows you what piece is going to fall next. The way you lose is when you get nowhere left to place a tetrominoe. When you lose you can try again or quit to the arcade. Things I Will Add In The Future I plan to add some dificult setting in the future for snake and maybe to the other ones. I also plan to make at least 2 more minigames for my arcade. Thank you for reading this devlog! Görüşmek Üzere! See ya later!"}, {"post_id": 69790, "ts": "2026-09-17T19:53:34Z", "hours": 7.9931, "text": "DEVLOG #007 - LAST DEVLOG FROM THE FIRST SHIP! Good Evening Guyss!! I am ready to ship my project for the first warioware mission! Changes Added the winning screen, score system and most of the UIs. I also finished the timelapse that I was recording for a few days. And that Is included in the time spent for this devlog. Things I Want To Say I suspect that the I spent for this project will get deducted for unreasonable amount of time for a project. I want to say that I tried to do as much of the code as I can without getting it directly from the youtube tutorials and as a first time game dev that was reallly time consuming. I just wanted you to know that I tried my best to not to make any inflated time. That was all. :) If you are still here, thanks for reading. Hope the ship goes well! :D Görüşmek üzere! See you later!!"}, {"post_id": 68224, "ts": "2026-09-14T18:44:18Z", "hours": 12.4517, "text": "DEVLOG #006 - SNAKE MINIGAME DONE! Good Evening Everybody! My second minigame, snake, is DONE! Snake Minigame I don’t really want to explain what snake game is cause I don’t know a single person that is 10 - 20 years old and doesn’t know what snake game is. For Those Who Don’t Know: Snake is a game where you try to eat food (apples in my minigame) until you become too big. The main game mechanic is like this: You eat, you get longer and once you are too big to fit in the grid you win. I made the grid 20x20 so it would be big and a bit challenging. But to win the actual game you dont have to get all of the 400 cells in the grid. Also the texture of the apple changes and it has a easter egg. I have to say, It is not a very “suprising” easter egg. :) A Thing I Have To Do Before Shipping I have to add an ending and I also have to make the starting screen and the options page. Thank you a lot for reading this. Görüşmek üzere! See you later!"}, {"post_id": 65324, "ts": "2026-09-10T12:17:32Z", "hours": 2.0442, "text": "DEVLOG #005 - PLATFORMER MINIGAME DONE! Hey guys! I SOLVED THE BUG!! I also completed few other things. I will mention them later. Platformer Minigame Sooo this minigame is probably already known by everybody. But for those who don’t know it is like this: The main objective is to jump to the higher platforms. Your score increases higher you go. The catch is, there are 3 types of platforms. Normal Platform Breaking Platform Frozen Platform These work like this: Normal Platform: It works as you expect it to. It is a normal platform that doesn’t have a catch. You can wait until the end of time to think and plan your next move. Breaking Platform: This type of platform has a time limit how much you can wait on it. When you step on it for the first time a timer starts and when that timer finishes the platform breaks and you fall. It has 3 different sprites that you can see if you try. You can understand when it is about to break by looking at it. Frozen Platform: Lastly this type of platform is slippery. Just like ice. When you are on this platforms it is harder to build up momentum and wait in place. You generally want to be more cautious around this platform. But you also can use the slippery surface to your advantage in certain situations. At the very beginning the normal platforms spawn a lot more. But as you progress further breaking and frozen platforms starts to spawn a lot more. Having different types of platforms make the game harder and more enjoyable. The UI of the game These are a non-negotionable part of any game. When you enter to the minigame you see some red UI elemnts on the left side. They currently show 3 different things. Your current score, your highest score and your y level. The End (Death) Screen When you fall and die, this screen opens. It has 3 different elements in it. A highscore counter and 2 buttons. One of these buttons are to “Try Again” and the other one is “Quit Game”. You can click to whichever you want. THE MAIN GOAL OF THE GAME I don’t remember if I ever mentioned what is the main goal of the main game (Not the minigames). It is actually pretty simple. The goal is to earn a set amount of score from all of the minigames. I didn’t established an amount right now. That will probably be one of my last things to worry about. I also added some small features like the screen of the arcade console light up when you play the game."}, {"post_id": 65043, "ts": "2026-09-09T21:26:15Z", "hours": 11.4339, "text": "Devlog #004.5 - PLATFORMER UPDATES AND A PROBLEM Hi guys! Hope y’all are alright. Cause I have a big proble to solve. Platformer Minigame It is NEARLY done. It is actually 99.99 percent done. But because of a bug that I couldn’t figure out how to solve. I will explain how the minigame works when I am 100 percent done. I hopefully manage it out in a few hours. As for now I am making this devlog for logging my times to stardance. I’ll devlog when I manage to solve the bug! Cya!"}, {"post_id": 62837, "ts": "2026-09-06T11:23:40Z", "hours": 10.1958, "text": "DEVLOG #004 - PLATFORMER MINIGAME MECHANICS Good day everyobdy! Platformer Minigame Since the last devlog I coded the platformer minigame. I actually attempted to code it 3 times. These were how my attempts went like: It didn’t even work. The platform positioning was very bad. Most of the time it led to getting stuck. Best overall.The player can still get stuck, but it is way lower than to other attempts. I will use this for the minigame. Maybe I can play with the code little bit. I wanted to delete the platforms underneath to get rid of the unnecessary FPS loss. So I coded that. On top of that I made the ‘death_zone’, the zone you fall into when you fall from one of the platforms and lose, move when the player goes up. This makes the fall take much shorter and make the game way faster to replay. Platforms types for the minigame Before I start knoe that I currently use Godot’s own sprites for the platform but I will change that in the very near future. If you ever played something like Doodle Jump, you must know that there aren’t only 1 type of platform. There are like 3 types of it most of the time. Normal, breaking and 1 that makes you jump. I already made the normal platform. And I plan to make a few more to make it more interesting and to make it on the same tracks as the other minigames that are this. I want to make platforms with these features: 1. A platform that breakes. 2. A platform that it freezed and makes the player slide on it 3. A platform that makes the player jump higher. I will try to implement these until the next devlog. Other than that I have to make the assets for the minigame, I have to code the point system and some other little things. I probably am going to make devlog about this minigame again, after that I am going to start th e other minigames. Hope you had a good time reading this. İyi Günler! Bye!"}, {"post_id": 61398, "ts": "2026-09-04T09:12:43Z", "hours": 10.6069, "text": "DEVLOG #003 - TILESETS, ARCADE CONSOLES & INTERACTIONS Hi everyone! Hope y’all alright. I worked on my first tileset and my first interactive objects. Tilesets As I said, this was my first tileset. I wanted my game to be seen from a 40~45 degree angle. I wanted it to be look like a bit 3D although it is clearly 2D. I tried to do my best and I think it turned out pretty great. You can find the tileset in the end of this devlog. Arcade Consoles I first tried to make the sprites of these arcade consoles as a tileset to store it as one file. It turned out not so great. I rather use Godots Sprite2D node rather than using the TileMapLayer node. That way tweaking each sprite is a bit easier. But I can still change my mind cause I have an idea that I’ll be working on few days later. I first designed these sprites as a -I am not sure how to say it- directly front view. I already said that I wanted my art to be at a ~45 degree angle. So adjust the looks of the sprites. That made it a bit better but I am not really satisfied with them yet. I will probably redesign them. Interactions When I first started this project I didn’t had any ideas on how to make an interactable object in Godot. After watching some videos on youtube and a lot of trial and errors I manage to make an interactions system that works really good. The interactions is this: When you get close to any of the arcade consoles there is a text shown “[E] TO PLAY”, when you click “E” there will be a split second of the black screen on the console lighting up and shownig a screen accordingly to the game you are going to play after that split second you get sent into a new scene where the minigame will be. I didn’t yet coded nor drew the required thing for the screen lighting up but I will make them later. I think that these kinds of small things will be an important aspect of the gameplay feel. These are all of the things I have done until today. After these done I will start on making the first 2 minigames and finishing the menus. Hope you had a good time reading this, Görüşmek üzere! See ya later!"}, {"post_id": 59466, "ts": "2026-09-01T10:29:50Z", "hours": 7.6631, "text": "DEVLOG #002 - CHARACTER DESIGN I designed my first character !! I made the walking animation and the code for walking + sprinting. A thing I want this game to have is changeable skins. (e.g., different hair types, different shirt colors, different types of caps and more…) This made the code a lot more complicated. I also need to draw the sprites for all of these. I probably won’t make these feature until I ship this project for the WarioWare 1 mission. Minigame Ideas As you probably know this is a WarioWare game. Basically that means that there are a lot of minigames in it. And I wanted to make a list of the minigames I want to make to keep it as a note and show to you. List of Minigame Ideas: -Tetris -Chrome dino -Platformer -Frogger -Pong -Puzzle (This might be a little too big for a “mini”game) These are my ideas for now but I want to add more. I want at least 12 With this much minigames and things to do I probably have to make a save system and a scoreboard system. I’ll think about it more in the future. This is it for now! Thanks for reading :) Görüşürüz! See ya later!"}, {"post_id": 58191, "ts": "2026-08-30T15:26:59Z", "hours": 0.9497, "text": "DEVLOG #001 - New Project Hi everybody!! I was working on other hardware projects for a few weeks and I couldn’t seperate my time for stardance. This is my new project: “I am not sure about what to name it”. It is a game where you have to complete minigames and get to a certain score. With that score you can buy things from the shop. Like plushies, merch and other minigames. Your goal is to finish all of the minigames. I originally planned it to be about waiting and doing the minigames while you were bored of waiting. Thats why I named it “Waiting Room”. After some more thinkering I want to make it an arcade game. I thought that the arcade theme would fit the minigames and points thing. And the shop could be the point store. Right now I started to code the main things in Godot like the starting screen, character movements and some other stuff. Also my experience is very little with Godot so I will learn a lot of stuff with this project I plan to do the sprites for the main character next. It would probably easier to test the charactes with its sprites and animations. If you have any ideas for the name of the game, please write them in the comment section of this post. (I’m not really sure if it’s called that) Also I know that this post is very bad written and scrambled but that my bad. I will try to get it to be better :) Here is some photos of what I did:"}]...
|
Title: Too Much Time In The Arcade by @iboo | Star Title: Too Much Time In The Arcade by @iboo | Stardance
Devlogs:
DEVLOG #001 - New Project Hi everybody!! I was working on other hardware projects for a few weeks and I couldn’t seperate my time for stardance. This is my new project: “I am not sure about what to name it”. It is a game where you have to complete minigames and get to a certain score. With that score you can buy things from the shop. Like plushies, merch and other minigames. Your goal is to finish all of the minigames. I originally planned it to be about waiting and doing the minigames while you were bored of waiting. Thats why I named it “Waiting Room”. After some more thinkering I want to make it an arcade game. I thought that the arcade theme would fit the minigames and points thing. And the shop could be the point store. Right now I started to code the main things in Godot like the starting screen, character movements and some other stuff. Also my experience is very little with Godot so I will learn a lot of stuff with this project I plan to do the sprites for the main character next. It would probably easier to test the charactes with its sprites and animations. If you have any ideas for the name of the game, please write them in the comment section of this post. (I’m not really sure if it’s called that) Also I know that this post is very bad written and scrambled but that my bad. I will try to get it to be better :) Here is some photos of what I did:
DEVLOG #002 - CHARACTER DESIGN I designed my first character !! I made the walking animation and the code for walking + sprinting. A thing I want this game to have is changeable skins. (e.g., different hair types, different shirt colors, different types of caps and more…) This made the code a lot more complicated. I also need to draw the sprites for all of these. I probably won’t make these feature until I ship this project for the WarioWare 1 mission. Minigame Ideas As you probably know this is a WarioWare game. Basically that means that there are a lot of minigames in it. And I wanted to make a list of the minigames I want to make to keep it as a note and show to you. List of Minigame Ideas: -Tetris -Chrome dino -Platformer -Frogger -Pong -Puzzle (This might be a little too big for a “mini”game) These are my ideas for now but I want to add more. I want at least 12 With this much minigames and things to do I probably have to make a save system and a scoreboard system. I’ll think about it more in the future. This is it for now! Thanks for reading :) Görüşürüz! See ya later!
DEVLOG #003 - TILESETS, ARCADE CONSOLES & INTERACTIONS Hi everyone! Hope y’all alright. I worked on my first tileset and my first interactive objects. Tilesets As I said, this was my first tileset. I wanted my game to be seen from a 40~45 degree angle. I wanted it to be look like a bit 3D although it is clearly 2D. I tried to do my best and I think it turned out pretty great. You can find the tileset in the end of this devlog. Arcade Consoles I first tried to make the sprites of these arcade consoles as a tileset to store it as one file. It turned out not so great. I rather use Godots Sprite2D node rather than using the TileMapLayer node. That way tweaking each sprite is a bit easier. But I can still change my mind cause I have an idea that I’ll be working on few days later. I first designed these sprites as a -I am not sure how to say it- directly front view. I already said that I wanted my art to be at a ~45 degree angle. So adjust the looks of the sprites. That made it a bit better but I am not really satisfied with them yet. I will probably redesign them. Interactions When I first started this project I didn’t had any ideas on how to make an interactable object in Godot. After watching some videos on youtube and a lot of trial and errors I manage to make an interactions system that works really good. The interactions is this: When you get close to any of the arcade consoles there is a text shown “[E] TO PLAY”, when you click “E” there will be a split second of the black screen on the console lighting up and shownig a screen accordingly to the game you are going to play after that split second you get sent into a new scene where the minigame will be. I didn’t yet coded nor drew the required thing for the screen lighting up but I will make them later. I think that these kinds of small things will be an important aspect of the gameplay feel. These are all of the things I have done until today. After these done I will start on making the first 2 minigames and finishing the menus. Hope you had a good time reading this, Görüşmek üzere! See ya later!
DEVLOG #004 - PLATFORMER MINIGAME MECHANICS Good day everyobdy! Platformer Minigame Since the last devlog I coded the platformer minigame. I actually attempted to code it 3 times. These were how my attempts went like: It didn’t even work. The platform positioning was very bad. Most of the time it led to getting stuck. Best overall.The player can still get stuck, but it is way lower than to other attempts. I will use this for the minigame. Maybe I can play with the code little bit. I wanted to delete the platforms underneath to get rid of the unnecessary FPS loss. So I coded that. On top of that I made the ‘death_zone’, the zone you fall into when you fall from one of the platforms and lose, move when the player goes up. This makes the fall take much shorter and make the game way faster to replay. Platforms types for the minigame Before I start knoe that I currently use Godot’s own sprites for the platform but I will change that in the very near future. If you ever played something like Doodle Jump, you must know that there aren’t only 1 type of platform. There are like 3 types of it most of the time. Normal, breaking and 1 that makes you jump. I already made the normal platform. And I plan to make a few more to make it more interesting and to make it on the same tracks as the other minigames that are this. I want to make platforms with these features: 1. A platform that breakes. 2. A platform that it freezed and makes the player slide on it 3. A platform that makes the player jump higher. I will try to implement these until the next devlog. Other than that I have to make the assets for the minigame, I have to code the point system and some other little things. I probably am going to make devlog about this minigame again, after that I am going to start th e other minigames. Hope you had a good time reading this. İyi Günler! Bye!
Devlog #004.5 - PLATFORMER UPDATES AND A PROBLEM Hi guys! Hope y’all are alright. Cause I have a big proble to solve. Platformer Minigame It is NEARLY done. It is actually 99.99 percent done. But because of a bug that I couldn’t figure out how to solve. I will explain how the minigame works when I am 100 percent done. I hopefully manage it out in a few hours. As for now I am making this devlog for logging my times to stardance. I’ll devlog when I manage to solve the bug! Cya!
DEVLOG #005 - PLATFORMER MINIGAME DONE! Hey guys! I SOLVED THE BUG!! I also completed few other things. I will mention them later. Platformer Minigame Sooo this minigame is probably already known by everybody. But for those who don’t know it is like this: The main objective is to jump to the higher platforms. Your score increases higher you go. The catch is, there are 3 types of platforms. Normal Platform Breaking Platform Frozen Platform These work like this: Normal Platform: It works as you expect it to. It is a normal platform that doesn’t have a catch. You can wait until the end of time to think and plan your next move. Breaking Platform: This type of platform has a time limit how much you can wait on it. When you step on it for the first time a timer starts and when that timer finishes the platform breaks and you fall. It has 3 different sprites that you can see if you try. You can understand when it is about to break by looking at it. Frozen Platform: Lastly this type of platform is slippery. Just like ice. When you are on this platforms it is harder to build up momentum and wait in place. You generally want to be more cautious around this platform. But you also can use the slippery surface to your advantage in certain situations. At the very beginning the normal platforms spawn a lot more. But as you progress further breaking and frozen platforms starts to spawn a lot more. Having different types of platforms make the game harder and more enjoyable. The UI of the game These are a non-negotionable part of any game. When you enter to the minigame you see some red UI elemnts on the left side. They currently show 3 different things. Your current score, your highest score and your y level. The End (Death) Screen When you fall and die, this screen opens. It has 3 different elements in it. A highscore counter and 2 buttons. One of these buttons are to “Try Again” and the other one is “Quit Game”. You can click to whichever you want. THE MAIN GOAL OF THE GAME I don’t remember if I ever mentioned what is the main goal of the main game (Not the minigames). It is actually pretty simple. The goal is to earn a set amount of score from all of the minigames. I didn’t established an amount right now. That will probably be one of my last things to worry about. I also added some small features like the screen of the arcade console light up when you play the game.
DEVLOG #006 - SNAKE MINIGAME DONE! Good Evening Everybody! My second minigame, snake, is DONE! Snake Minigame I don’t really want to explain what snake game is cause I don’t know a single person that is 10 - 20 years old and doesn’t know what snake game is. For Those Who Don’t Know: Snake is a game where you try to eat food (apples in my minigame) until you become too big. The main game mechanic is like this: You eat, you get longer and once you are too big to fit in the grid you win. I made the grid 20x20 so it would be big and a bit challenging. But to win the actual game you dont have to get all of the 400 cells in the grid. Also the texture of the apple changes and it has a easter egg. I have to say, It is not a very “suprising” easter egg. :) A Thing I Have To Do Before Shipping I have to add an ending and I also have to make the starting screen and the options page. Thank you a lot for reading this. Görüşmek üzere! See you later!
DEVLOG #007 - LAST DEVLOG FROM THE FIRST SHIP! Good Evening Guyss!! I am ready to ship my project for the first warioware mission! Changes Added the winning screen, score system and most of the UIs. I also finished the timelapse that I was recording for a few days. And that Is included in the time spent for this devlog. Things I Want To Say I suspect that the I spent for this project will get deducted for unreasonable amount of time for a project. I want to say that I tried to do as much of the code as I can without getting it directly from the youtube tutorials and as a first time game dev that was reallly time consuming. I just wanted you to know that I tried my best to not to make any inflated time. That was all. :) If you are still here, thanks for reading. Hope the ship goes well! :D Görüşmek üzere! See you later!!
DEVLOG #008 - TETRIS GAME DONE! Good Evening y’all! I was away for a few days making a project in thirdspace . Anyways I am working for this project at the side too. And this game was finished few days ago but I couldn’t find the time to post a devlog about it. Here it goes now! Since my last devlog I made my third minigame, Tetris ! I again don’t think that I have to explain what tetris is. LITTERALLY everybody knows it. But for those who lives under a rock: In the game “Tetris”, some blocks fall from the sky and you put them like a puzzle. There are a total of 7 different shaped called “tetrominoes”. They are randomly given to you so it is more complicated and more enjoyable. There is a grid that you are filling with these tetrominoes. When you fill a row with these tetrominoes they disappear and the ones on top of them fall down. Once you complete a row you also get 10 points. There are also some standart futures that every Tetris ccopy has. They are: When you hold “S” the tetrominoes fall faster, when you click “R” the tetrominoes rotate and there is a panel that shows you what piece is going to fall next. The way you lose is when you get nowhere left to place a tetrominoe. When you lose you can try again or quit to the arcade. Things I Will Add In The Future I plan to add some dificult setting in the future for snake and maybe to the other ones. I also plan to make at least 2 more minigames for my arcade. Thank you for reading this devlog! Görüşmek Üzere! See ya later!
DEVLOG #009 - Dino Run Done! (Nearly…) Hope you had a good day. I finished (nearly) my fourth game, Dino Run ! It is my version of the game that you play when you don’t have internet in Chrome, Google Dino Run. I probably should stop explaining what these games are cause EVERYBODY, literally EVERYBODY knows what these games are. Fot the last time: Dino Run is a game that you are a dinosour -most of the time but it can change.- and you run. Obstacles and birds spawn while you run. You must jump when the obstacles get near, and ducck when the birds get near. Also you run faster and faster as the time goes on. Controls You can jump with SPACE and you can duck with SHIFT or CTRL . When you jump a timer starts, and you can’t jump until the timer timeouts. I said that I “NEARLY” finished the game. The unfinished part is actually a quiet important part. It is the losing mechanic. It is actually very easy to add but I didn’t want to get my hours wasted because of me not devlogging. I will finish that part until the next devlog and I might forget to mention adding that. You can think it as done for now. These are it for this devlog. I will probably add some sounds and some small updates to the existing games. And at the end of that If I have time left, I will ad more games. Thanks for being here. Kendinize iyi bakın! Cya!
Ships:
“Too Much Time In The Arcade” is a WarioWare-style game that is set in an arcade, as you might guess. It has currently two minigames. These minigames are a platformer and a snake minigame. All of these minigames have their own respective arcade consoles that you can interact with. Your goal is to get a total of score of 400 points to win. You can get all of your points in the platformer or in the snake minigame. There are no limitations. I had a lot of fun time coding, designing and learning Godot for this project. This is my first attempt to develop a game and I find it pretty good for a first try. Although I faced some challenges, I managed to solve nearly all of them. I also learned how to debug code while doing this project. I am very proud of how it turned up. And I hope you have a great time playing it. If you want to try the game, click the “Try project ->” button. When you click it, you will be sent to my itch.io site and you will be able to play the game! To people testing my game. I want to let you know that the platformer minigame has a way smaller hitbox compared to the player sprite. This makes it a ton more doable. Thank you for all of your support I hope you have a FANTASTIC time playing my game!! Kendinize iyi bakın! Bye! Note: “Kendinize iyi bakın!” is “Take care of yourselves!” in my native language, Turkish :)...
|
1792853650.5282974
|
1792940050.5282974
|
|
69868
|
catpad by @lollo22 | Stardance
|
lollo22
|
0
|
5.59
|
0
|
[]
|
[{"post_id": 81083, "ts": "202 [{"post_id": 81083, "ts": "2026-10-19T20:02:52Z", "hours": 5.5947, "text": "my catpad, an hackpad that resembles a cat i worked hard on this project, just need to make the firmware to complete the design"}]...
|
Title: catpad by @lollo22 | Stardance
Devlogs:
my Title: catpad by @lollo22 | Stardance
Devlogs:
my catpad, an hackpad that resembles a cat i worked hard on this project, just need to make the firmware to complete the design...
|
1792878647.703754
|
1793483447.703754
|
|
34259
|
DungeonMan by @avycado13 | Stardance
|
avycado13
|
1
|
3.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T20:05:14Z", "hours": 3.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a library to implement RPG fight mechanics for text based games", "repo": "https://github.com/avycado13/dungeonman", "demo": "https://pypi.org/project/dungeonman/"}]...
|
[{"post_id": 81084, "ts": "202 [{"post_id": 81084, "ts": "2026-10-19T20:03:52Z", "hours": 0.3539, "text": "I added Documentation for the libraryand got it render via sphinx."}, {"post_id": 80983, "ts": "2026-10-19T14:45:43Z", "hours": 0.5758, "text": "I set it up to also be a library so you can use the exposed functions and classes fro basic RPGs"}, {"post_id": 80884, "ts": "2026-10-19T04:51:37Z", "hours": 0.3697, "text": "I added a room system and in the rooms you can pick up items and fight that room’s monsters."}, {"post_id": 27522, "ts": "2026-07-13T04:48:35Z", "hours": 1.5, "text": "i made some basic mechanics for fighting"}]...
|
Title: DungeonMan by @avycado13 | Stardance
Devlo Title: DungeonMan by @avycado13 | Stardance
Devlogs:
i made some basic mechanics for fighting
I added a room system and in the rooms you can pick up items and fight that room’s monsters.
I set it up to also be a library so you can use the exposed functions and classes fro basic RPGs
I added Documentation for the libraryand got it render via sphinx.
Ships:
I made a library to implement RPG fight mechanics for text based games...
|
1792641308.7861814
|
1792727708.7861814
|
|
41271
|
Fleer by @johan | Stardance
|
johan
|
1
|
76.21
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-08-30T21:52:34Z", "hours": 64.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "School is coming back soon, Stardance may be ending tomorrow, and I’m currently at 15% of what I want to do. I got an entire planning on Linear on what to do now. Fleer is a toxic-love project for me because of the numbers of issues I encountered, but I still want it to be done so bad. And yeah, I know testing is kinda hard now, I can’t publish an hosted testing instance so you will need to host it yourself (just one 30 MB Docker image to compile on any system and any architecture).", "repo": "https://github.com/johan-perso/fleer-relay", "demo": "https://github.com/johan-perso/fleer-cli#installation"}]...
|
[{"post_id": 81085, "ts": "202 [{"post_id": 81085, "ts": "2026-10-19T20:04:48Z", "hours": 4.6358, "text": "Fleer is a decentralized platform, meaning anyone can host one or multiple relay servers. This devlog brings this concept even more to the Fleer CLI. Three lists of relay servers are hosted (on the GitHub repo, on my main website, and obviously on the Fleer landing page itself). These lists contain the URL for the currently only hosted relay. You can also add your own custom lists. In the future, the officials lists will include many more relays, from me or from anyone that contributes to the ecosystem, and the CLI is already prepared for that! I’m on a hotspot with like not even 1 Mbps so the video is just here for illustrative purposes 💀"}, {"post_id": 72709, "ts": "2026-09-23T15:38:39Z", "hours": 7.5769, "text": "After a few weeks without being able to do proper coding sessions (only got time to do it while being at school), I can finally release a new feature for Fleer! Integrity checking: after sending files, the receiver can ask the sender for a list of SHA-256 hashes. All communications are using encrypted messages to reduce the amount of things a malicious relay server can do. Integrity checking allows the receiver to be sure that files are identical from the sent one, and that the relay didn’t skipped chunks/files. I also added proper (and definitive) instructions for selfhosting a relay server by using Docker Compose (with prebuilt images via GitHub Actions), by building the image yourself with a Dockerfile, or to run from source. Reduce chunkSize when sending files if network conditions were really really bad before starting to send chunks."}, {"post_id": 58469, "ts": "2026-08-30T21:45:51Z", "hours": 7.2975, "text": "Not sure if Stardance will get extended until something like the end of September, so here am I (didn’t got many times to update the app and encountered many problems). A new command fleer relay followed by any Fleer Relay URL will output details about it. Receiver device name was sent in clear to the relay, it is now exchanged using encrypted messages. The transfer will be deleted if too many restarts happen (because messages size exceeds the limit for example). A structure containing all files, folders and path is included to give the receiver some visuals indications. If it’s too large, the structure will be dropped entirely. The amount of received/sent bytes will be displayed in Kbps instead of Mbps if it’s slow asf. Many bugs fixes and optimizations. The relay can now pauses transfers if it’s processing too many transfers at once. The indicated transfer size will include an estimated encryption overhead (the algorithm used can add some bytes to files). Transfers that shares MANY messages can use a feature from the relay that give clients ability to select the amount of cached bytes for messages and chunks. Inactives shares are deleted from the memory of the relay. The build version and latest commit pulled is returned to clients from the relay. Rate limits now apply to WebSocket messages."}, {"post_id": 53427, "ts": "2026-08-23T23:35:26Z", "hours": 3.7667, "text": "Didn’t wrote many lines of code on this project the last few days, was busy with personnal things so I’m listing what I pushed this week: User can decide what to do if a file already exist in the current directory (replace it, rename the new one, or skip this file). A new command fdd allows to start a download even faster, by checking the first parameter ( fdd <share_link> ) or any URL in the clipboard. fleer send command can generate a QR Code image, and display it for supported terminals (such as the incredible Ghostty). Download speed is displayed live in Mbps. Some fixes concerning security and downloading in specific conditions."}, {"post_id": 49259, "ts": "2026-08-17T23:04:04Z", "hours": 4.8894, "text": "A few minors QoL changes: The CLI is automatically closed when download is finished, synced for both sender and receiver through an encrypted message that acts as a signal to tell both party they have done their job. Share Link is automatically copied into the clipboard of the sender, even if he’s remotely connected via SSH to another server. The directory in which files are saved is displayed at the end of execution (default to current folder). Improved performances when downloading. Some more verifications with the relay server used. Protect against Path Traversal vulnerability."}, {"post_id": 46633, "ts": "2026-08-14T01:00:19Z", "hours": 8.6061, "text": "Okay, changelog required even though I wasn’t planning on publishing it right now. Apart from some additions such as: --debug-socket flag that logs every actions happening between the client and a relay server Encryption protocol indicator (which is used by clients to know what algorithm and settings to use) is NOT known by the server anymore, as it is transferred in the share link itself Proper exit (and closure of spinner animations) when using Ctrl+C A few optimizations for responsive logs Downloading files is ALMOST done, I’m currently having many issues with slow file upload, and many attempts at optimizing it (that litteraly give me the idea of just quitting this project) and I’m making this changelog now because I think we might not finish this part of the CLI before at least 2 days. In the meantime, I daydreamed about many things I want to introduce into the project that will hopefully make a difference with others apps, even if I don’t have the same speed as them."}, {"post_id": 45231, "ts": "2026-08-11T15:54:32Z", "hours": 1.0211, "text": "Made a command to explain how Fleer relays, encryption and decryption work - always with a nice focus on terminal design, with colors, responsive and auto resize"}, {"post_id": 44327, "ts": "2026-08-10T00:30:37Z", "hours": 7.3697, "text": "We can send files using the CLI! I have some optimizations to make because sending small files is just as slow as sending large files, causing super low speed upload 💀 We also display the URL, command, and keys (used by the server) to connect as a receiver and start downloading files. The protocol is kinda complex and I’m planning to write a documentation on how to use it for any matter (like automations or 3rd party clients), and a terminal generally being for nerds (especially when a desktop GUI app is planned) make this the best place to showcase how the relay system really work, so I implemented a flag --debug-performances that log every actions into a file, also useful to debug performances (if you didn’t guessed…). The sender sends files to the relay, one by one, chunk by chunk to the relay, which will pipe them to the receiver afterwards. Chunks are fully encrypted on both clients and server cannot access their content whatsoever. To ensure even better security, I also display a warning with confirmation before continuing if the server is using HTTP instead of HTTPS. There is many things happening that isn’t easy to see, and many little details (like some responsive resizing for low sized terminals) that many people may never encounteer, and I’m proud of how those devlogs are only like 7h long?? Anyway, here’s a video of where I currently am, and thanks for reading all of that garbage nonsense written by a french guy that isn’t quite good at telling things in foreign languages."}, {"post_id": 42308, "ts": "2026-08-06T23:19:36Z", "hours": 6.6911, "text": "Spent a few hours starting the CLI! For now it can only search for files and directory to send, while excluding socket and symlinks, and asking user if he want to excludes some others directory (like node_modules, cache or trashed files on macOS/Linux). Interface use colors, spinners and terminal screen width detection to avoid overflowing texts on another lines, providing a nice display when displaying large quantity of text, even if it’s only on screen for a few milliseconds. The files searching is really fast thank to Bun and some optimizations I did, here is a demo."}, {"post_id": 41111, "ts": "2026-08-05T03:10:10Z", "hours": 6.4781, "text": "Receiver can now receive chunks of data even if he wasn’t connected when the sender started sending them. Also, some communications are added between the receiver and the sender, such as a warning when the other one disconnect, or any other form of encrypted message. Senders were informed when they reached the max cached data limit, but are also now informed when this limit can be ignored (when the receiver download those cached data to free some space). And the thing you can see in the demo video: it is now possible to, as the receiver, restart an entire transfer if you connect to the download, disconnect, and reconnect again (because cached data are cleaned by the backend, which mean the sender has to send them again). I know “sender” and “receiver” are repeated 300x but idk how to explain this in a better way 😭🙏 (+ i’m french idk we’re all bad in this language tbh)"}, {"post_id": 38550, "ts": "2026-08-01T00:54:39Z", "hours": 6.45, "text": "After starting to get some progress on a test CLI (with both sending and receiving sides), we can now encrypt/send, and decrypt/download chunks on storage. I will make a few changes on how files saving will be handled because for now the receiver only get chunks data, and don’t know how to reassemble them. If you want, one of my git commit got this long ahh description: - Many more checks - Receiver can set their name (sender get notified) - Chunks are sent to receiver - receiver can acknowledge when they receive one, and chunks sending is paused if they have at least three chunks not ack. - An encryption protocol indicator is exchanged (not encrypted) to let clients know what encryption parameters to use - Chunks that are in the memory of the server has a maximum, afterwards we stop accepting more - Auto removal of all in-memory data of acknowledged chunks"}, {"post_id": 36745, "ts": "2026-07-29T00:19:25Z", "hours": 11.2589, "text": "Just started this new project! I’ve already wrote a loooong list of things I want to do (and how I want them to be done), will not post it here to avoid spoiling so wait a few changelog to know how the service will work! For now, I’ve only implemented a basic API that allows to create a share, returning a shareId that allows to request details about it ; I also started the implementation of a socket that will allow someone to download a file while it’s being uploaded. The backend will be done in Dart to allow the build of a light executable file, allowing an easier self-hosting while consuming less ressources. This language also enable me the possibility of including the server directly inside a Flutter made client, but I’m not sure I will use this possibility, I guess we will see!"}]...
|
Title: Fleer by @johan | Stardance
Devlogs:
Just Title: Fleer by @johan | Stardance
Devlogs:
Just started this new project! I’ve already wrote a loooong list of things I want to do (and how I want them to be done), will not post it here to avoid spoiling so wait a few changelog to know how the service will work! For now, I’ve only implemented a basic API that allows to create a share, returning a shareId that allows to request details about it ; I also started the implementation of a socket that will allow someone to download a file while it’s being uploaded. The backend will be done in Dart to allow the build of a light executable file, allowing an easier self-hosting while consuming less ressources. This language also enable me the possibility of including the server directly inside a Flutter made client, but I’m not sure I will use this possibility, I guess we will see!
After starting to get some progress on a test CLI (with both sending and receiving sides), we can now encrypt/send, and decrypt/download chunks on storage. I will make a few changes on how files saving will be handled because for now the receiver only get chunks data, and don’t know how to reassemble them. If you want, one of my git commit got this long ahh description: - Many more checks - Receiver can set their name (sender get notified) - Chunks are sent to receiver - receiver can acknowledge when they receive one, and chunks sending is paused if they have at least three chunks not ack. - An encryption protocol indicator is exchanged (not encrypted) to let clients know what encryption parameters to use - Chunks that are in the memory of the server has a maximum, afterwards we stop accepting more - Auto removal of all in-memory data of acknowledged chunks
Receiver can now receive chunks of data even if he wasn’t connected when the sender started sending them. Also, some communications are added between the receiver and the sender, such as a warning when the other one disconnect, or any other form of encrypted message. Senders were informed when they reached the max cached data limit, but are also now informed when this limit can be ignored (when the receiver download those cached data to free some space). And the thing you can see in the demo video: it is now possible to, as the receiver, restart an entire transfer if you connect to the download, disconnect, and reconnect again (because cached data are cleaned by the backend, which mean the sender has to send them again). I know “sender” and “receiver” are repeated 300x but idk how to explain this in a better way 😭🙏 (+ i’m french idk we’re all bad in this language tbh)
Spent a few hours starting the CLI! For now it can only search for files and directory to send, while excluding socket and symlinks, and asking user if he want to excludes some others directory (like node_modules, cache or trashed files on macOS/Linux). Interface use colors, spinners and terminal screen width detection to avoid overflowing texts on another lines, providing a nice display when displaying large quantity of text, even if it’s only on screen for a few milliseconds. The files searching is really fast thank to Bun and some optimizations I did, here is a demo.
We can send files using the CLI! I have some optimizations to make because sending small files is just as slow as sending large files, causing super low speed upload 💀 We also display the URL, command, and keys (used by the server) to connect as a receiver and start downloading files. The protocol is kinda complex and I’m planning to write a documentation on how to use it for any matter (like automations or 3rd party clients), and a terminal generally being for nerds (especially when a desktop GUI app is planned) make this the best place to showcase how the relay system really work, so I implemented a flag --debug-performances that log every actions into a file, also useful to debug performances (if you didn’t guessed…). The sender sends files to the relay, one by one, chunk by chunk to the relay, which will pipe them to the receiver afterwards. Chunks are fully encrypted on both clients and server cannot access their content whatsoever. To ensure even better security, I also display a warning with confirmation before continuing if the server is using HTTP instead of HTTPS. There is many things happening that isn’t easy to see, and many little details (like some responsive resizing for low sized terminals) that many people may never encounteer, and I’m proud of how those devlogs are only like 7h long?? Anyway, here’s a video of where I currently am, and thanks for reading all of that garbage nonsense written by a french guy that isn’t quite good at telling things in foreign languages.
Made a command to explain how Fleer relays, encryption and decryption work - always with a nice focus on terminal design, with colors, responsive and auto resize
Okay, changelog required even though I wasn’t planning on publishing it right now. Apart from some additions such as: --debug-socket flag that logs every actions happening between the client and a relay server Encryption protocol indicator (which is used by clients to know what algorithm and settings to use) is NOT known by the server anymore, as it is transferred in the share link itself Proper exit (and closure of spinner animations) when using Ctrl+C A few optimizations for responsive logs Downloading files is ALMOST done, I’m currently having many issues with slow file upload, and many attempts at optimizing it (that litteraly give me the idea of just quitting this project) and I’m making this changelog now because I think we might not finish this part of the CLI before at least 2 days. In the meantime, I daydreamed about many things I want to introduce into the project that will hopefully make a difference with others apps, even if I don’t have the same speed as them.
A few minors QoL changes: The CLI is automatically closed when download is finished, synced for both sender and receiver through an encrypted message that acts as a signal to tell both party they have done their job. Share Link is automatically copied into the clipboard of the sender, even if he’s remotely connected via SSH to another server. The directory in which files are saved is displayed at the end of execution (default to current folder). Improved performances when downloading. Some more verifications with the relay server used. Protect against Path Traversal vulnerability.
Didn’t wrote many lines of code on this project the last few days, was busy with personnal things so I’m listing what I pushed this week: User can decide what to do if a file already exist in the current directory (replace it, rename the new one, or skip this file). A new command fdd allows to start a download even faster, by checking the first parameter ( fdd <share_link> ) or any URL in the clipboard. fleer send command can generate a QR Code image, and display it for supported terminals (such as the incredible Ghostty). Download speed is displayed live in Mbps. Some fixes concerning security and downloading in specific conditions.
Not sure if Stardance will get extended until something like the end of September, so here am I (didn’t got many times to update the app and encountered many problems). A new command fleer relay followed by any Fleer Relay URL will output details about it. Receiver device name was sent in clear to the relay, it is now exchanged using encrypted messages. The transfer will be deleted if too many restarts happen (because messages size exceeds the limit for example). A structure containing all files, folders and path is included to give the receiver some visuals indications. If it’s too large, the structure will be dropped entirely. The amount of received/sent bytes will be displayed in Kbps instead of Mbps if it’s slow asf. Many bugs fixes and optimizations. The relay can now pauses transfers if it’s processing too many transfers at once. The indicated transfer size will include an estimated encryption overhead (the algorithm used can add some bytes to files). Transfers that shares MANY messages can use a feature from the relay that give clients ability to select the amount of cached bytes for messages and chunks. Inactives shares are deleted from the memory of the relay. The build version and latest commit pulled is returned to clients from the relay. Rate limits now apply to WebSocket messages.
After a few weeks without being able to do proper coding sessions (only got time to do it while being at school), I can finally release a new feature for Fleer! Integrity checking: after sending files, the receiver can ask the sender for a list of SHA-256 hashes. All communications are using encrypted messages to reduce the amount of things a malicious relay server can do. Integrity checking allows the receiver to be sure that files are identical from the sent one, and that the relay didn’t skipped chunks/files. I also added proper (and definitive) instructions for selfhosting a relay server by using Docker Compose (with prebuilt images via GitHub Actions), by building the image yourself with a Dockerfile, or to run from source. Reduce chunkSize when sending files if network conditions were really really bad before starting to send chunks.
Fleer is a decentralized platform, meaning anyone can host one or multiple relay servers. This devlog brings this concept even more to the Fleer CLI. Three lists of relay servers are hosted (on the GitHub repo, on my main website, and obviously on the Fleer landing page itself). These lists contain the URL for the currently only hosted relay. You can also add your own custom lists. In the future, the officials lists will include many more relays, from me or from anyone that contributes to the ecosystem, and the CLI is already prepared for that! I’m on a hotspot with like not even 1 Mbps so the video is just here for illustrative purposes 💀
Ships:
School is coming back soon, Stardance may be ending tomorrow, and I’m currently at 15% of what I want to do. I got an entire planning on Linear on what to do now. Fleer is a toxic-love project for me because of the numbers of issues I encountered, but I still want it to be done so bad. And yeah, I know testing is kinda hard now, I can’t publish an hosted testing instance so you will need to host it yourself (just one 30 MB Docker image to compile on any system and any architecture)....
|
1792824707.3111334
|
1792911107.3111334
|
|
15004
|
PixieR by @Cryskyy | Stardance
|
Cryskyy
|
1
|
7.0
|
95
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-12T07:36:32Z", "hours": 6.0, "multiplier": 15.1, "payout": 95, "blessing": "neutral", "text": "I make a project called “PixieR”, PixieR is a 100% client-side web tool that converts any image into pixel art directly in your browser. no backend, no API calls — everything happens locally using the HTML5 Canvas API. The Challenging part in my project is managing all the logic such as main.js and whole web logic system Im so proud that I can make this project without any trouble, and I hope everyone can test out my project :) Check up my github to try my project :))", "repo": "https://github.com/cryskyyexp-ux/PixieR-Project", "demo": "https://pixier.netlify.app/"}]...
|
[{"post_id": 8109, "ts": "2026 [{"post_id": 8109, "ts": "2026-06-13T15:13:52Z", "hours": 1.0, "text": "PixieR Project Devlog — Fixing the Stretching Bug & Other Issues Compare Slider stretching (main issue) Cause: syncCmpCanvas() set cmp.style.width='100%' and cmp.style.height='100%' together with objectFit:'contain' . object-fit only works on replaced elements like <img> and <video> — it has no effect on <canvas> , so the canvas was forced to fill the wrapper’s full 100% x 100% box regardless of its actual pixel aspect ratio, stretching the pixel art. Fix: Compute the display size manually based on the pixel canvas’s own aspect ratio ( src.width / src.height ), fit it within the wrapper width and a max height of 400px, then explicitly set cmp-canvas and cmp-orig-img width/height in pixels (with horizontal centering via marginLeft ). Both layers now share identical dimensions so the slider overlay aligns correctly. Pixel Only view overflow/stretch Cause: solo-canvas had a fixed inline max-width:100%;max-height:480px , while syncSoloCanvas() separately set style.width / style.height to width*zoom / height*zoom in px. At high zoom levels this could overflow the frame, and the max-width/max-height constraints distorted the aspect ratio independently on each axis. Fix: Removed the conflicting inline max-width/max-height. syncSoloCanvas() now computes the zoomed size, then uniformly scales both dimensions down by the same factor if it exceeds the frame’s width or a 480px height cap, preserving aspect ratio. Eyedropper coordinate mismatch Cause: pixelCanvas mousemove/click handlers divided mouse coordinates by the zoom slider value to find the pixel under the cursor. This breaks if the canvas’s rendered size ever differs from width * zoom (e.g. after future layout changes), giving wrong color picks. Fix: Replaced the zoom-based division with a ratio of the canvas’s actual bitmap size to its rendered bounding box size ( pixelCanvas.width / rect.width ), which is robust to any CSS scaling. Compare slider not resizing on window resize Cause: No resize handler existed for the compare/pixel-only views, so resizing the browser left stale dimensions and a stretched look. Fix: Added a resize listener that re-runs syncCmpCanvas() or syncSoloCanvas() depending on the active view. Dead/unused popup duplication Cause: The star popup markup was hardcoded in the page AND re-inserted via createPopupHTML() using insertAdjacentHTML , creating a duplicate #starPopup risk and unnecessary DOM bloat. Fix: Removed the redundant insertAdjacentHTML injection since the markup already exists in the page; createPopupHTML() now just guards against duplicates. Toast fallback dead code Cause: showToast() inside the popup IIFE recreated a whole second #toast element with inline styles if the existing one wasn’t found — but it always exists in the page, making this branch dead and bug-prone (it referenced var(--text, ...) colors that may not exist)."}, {"post_id": 7336, "ts": "2026-06-12T07:27:25Z", "hours": 0.0, "text": "Detailing My Project README.md and adding some detail"}, {"post_id": 7282, "ts": "2026-06-12T04:18:31Z", "hours": 3.0, "text": "Hi Guys this is my project explaination how does the Pixelate work on steps: Step 1: Shrink (this is where the magic happens) jsconst small = document.createElement(‘canvas’); small.width = 64; small.height = 64; small.getContext(‘2d’).drawImage(srcImg, 0, 0, 64, 64); Imagine your photo is 1920×1080 pixels. You squish it down into a 64×64 canvas. To fit a million pixrls into 64×64, the browser has to merge groups of pixels into one. It looks at a chunk of the original image (say, a 30×17 block) and blends them all into a single average color. Result: you now have a real, tiny image — 64×64 actual pixels, each one a blended color from a chunk of the original. Step 2: Blow it bacl up (with no smoothing) jscanvas.style.width = ‘384px’; // 64 × 6 canvas.style.height = ‘384px’; cssimage-rendering: pixelated; Now you take that tiny 64×64 image and stretch it to be way bigger on screen. Normally, browsers smooth out stretched images (blurry). The pixelated setting turns smoothing off. So each of the 64×64 pixels just gets copied into a big solid square — no blending, no blur. Result: big, crisp, blocky squares = the pixel art look. Putting It Together big detailed photo ↓ (squish down — merges pixels, loses detail) tiny 64×64 image ↓ (stretch up — no smoothing, just copy each pixel bigger) big blocky pixel art The squish is what creates the pixel art (real data, real file). The stretch is just so you can see it clearly on screen — it adds zero new information. Why the Download File is Small When you hit download, it saves the tiny 64×64 image (from Step 1) — not the big stretched version. The “blow it back up” part was only for your screen. And this done in client side, we dont collect your image or saving ur image"}, {"post_id": 6742, "ts": "2026-06-11T09:10:40Z", "hours": 1.0, "text": "DEVLOG : Project: PixieR Version: 2.0.0 Type: Web App (100% client-side) Stack: Vanilla JS + Canvas API + CSS License: MIT Status: Beta [+] Built: - Basic HTML structure with card-based UI - File upload with drag & drop support - Canvas setup for pixelation using Canvas API - Dark/light theme toggle with CSS custom properties - Interactive grid background with cursor glow effect [+] Pixelation Engine: - doPixelate() function that downsamples images - Three scale modes: Fit, Stretch, Crop - Realtime preview with 120ms debounce - Custom grid size input (4×4 to 1024×1024) - Preset chips: 16, 32, 64, 128, 256 - Linked dimensions toggle (🔗 / 🔓) [+] How pixelation works: Original Image ↓ drawImage(src, 0, 0, pixelW, pixelH) Tiny Canvas (W×H pixels) ↓ CSS image-rendering: pixelated Final display (zoomed with crisp edges) [+] Core Code Snippet: const small = document.createElement('canvas'); small.width = sw; small.height = sh; const sc = small.getContext('2d'); sc.drawImage(srcImg, 0, 0, sw, sh); out.getContext('2d').drawImage(small, 0, 0); [+] Key Decisions: - No frameworks → keep it lightweight (~18KB) - Single HTML file → easy to share, no build step - Canvas API → native browser support, fast [+] Challenges & Solutions: Challenge: Crop mode required calculating source coordinates Solution: Used aspect ratio comparison to determine sx, sy, sW, sH Challenge: Maintaining aspect ratio in Fit mode Solution: Compare pw/ph vs srcRatio to determine scaling axis Challenge: Making chips highlight correctly on value change Solution: setChipActive() toggles .on class based on value [+] View Modes: - Side by Side (split-view) - Compare Slider (drag to compare original vs pixelated) - Pixel Only (fullscreen pixel art display) [+] Compare Slider Implementation: /* Clip the pixelated layer */ #compare-pixel { clip-path: inset(0 50% 0 0); } Drag updates percentage → changes clip-path value dynamically. Supports both mouse and touch events for mobile. [+] Eyedropper Tool: - Hover over any pixel to see hex color - Click to copy hex code to clipboard - Tooltip follows cursor with color preview [+] Eyedropper Logic: pixelCanvas.addEventListener('mousemove', (e) => { const cx = Math.floor((e.clientX - rect.left) / zoom); const cy = Math.floor((e.clientY - rect.top) / zoom); const px = ctx.getImageData(cx, cy, 1, 1).data; const hex = '#' + px[0].toString(16) + ...; tip.innerHTML = `${hex} (${cx},${cy})`; }); [+] Export Features: - Download as PNG, JPG, or WebP - Automatic filename: pixier_{W}x{H}.ext [+] Zoom Slider: - Range: 1× to 20× - CSS-based scaling, doesn’t re-render - Maintains crisp pixelated edges [+] The “Pixelate!” Button Experience: - Disabled until image loaded - 5-second “processing” animation (UX theater) - Controls unlock after first conversion - Shimmer effect on completion - After first use: realtime updates (120ms debounce)"}]...
|
Title: PixieR by @Cryskyy | Stardance
Devlogs:
DE Title: PixieR by @Cryskyy | Stardance
Devlogs:
DEVLOG : Project: PixieR Version: 2.0.0 Type: Web App (100% client-side) Stack: Vanilla JS + Canvas API + CSS License: MIT Status: Beta [+] Built: - Basic HTML structure with card-based UI - File upload with drag & drop support - Canvas setup for pixelation using Canvas API - Dark/light theme toggle with CSS custom properties - Interactive grid background with cursor glow effect [+] Pixelation Engine: - doPixelate() function that downsamples images - Three scale modes: Fit, Stretch, Crop - Realtime preview with 120ms debounce - Custom grid size input (4×4 to 1024×1024) - Preset chips: 16, 32, 64, 128, 256 - Linked dimensions toggle (🔗 / 🔓) [+] How pixelation works: Original Image ↓ drawImage(src, 0, 0, pixelW, pixelH) Tiny Canvas (W×H pixels) ↓ CSS image-rendering: pixelated Final display (zoomed with crisp edges) [+] Core Code Snippet: const small = document.createElement('canvas'); small.width = sw; small.height = sh; const sc = small.getContext('2d'); sc.drawImage(srcImg, 0, 0, sw, sh); out.getContext('2d').drawImage(small, 0, 0); [+] Key Decisions: - No frameworks → keep it lightweight (~18KB) - Single HTML file → easy to share, no build step - Canvas API → native browser support, fast [+] Challenges & Solutions: Challenge: Crop mode required calculating source coordinates Solution: Used aspect ratio comparison to determine sx, sy, sW, sH Challenge: Maintaining aspect ratio in Fit mode Solution: Compare pw/ph vs srcRatio to determine scaling axis Challenge: Making chips highlight correctly on value change Solution: setChipActive() toggles .on class based on value [+] View Modes: - Side by Side (split-view) - Compare Slider (drag to compare original vs pixelated) - Pixel Only (fullscreen pixel art display) [+] Compare Slider Implementation: /* Clip the pixelated layer */ #compare-pixel { clip-path: inset(0 50% 0 0); } Drag updates percentage → changes clip-path value dynamically. Supports both mouse and touch events for mobile. [+] Eyedropper Tool: - Hover over any pixel to see hex color - Click to copy hex code to clipboard - Tooltip follows cursor with color preview [+] Eyedropper Logic: pixelCanvas.addEventListener('mousemove', (e) => { const cx = Math.floor((e.clientX - rect.left) / zoom); const cy = Math.floor((e.clientY - rect.top) / zoom); const px = ctx.getImageData(cx, cy, 1, 1).data; const hex = '#' + px[0].toString(16) + ...; tip.innerHTML = `${hex} (${cx},${cy})`; }); [+] Export Features: - Download as PNG, JPG, or WebP - Automatic filename: pixier_{W}x{H}.ext [+] Zoom Slider: - Range: 1× to 20× - CSS-based scaling, doesn’t re-render - Maintains crisp pixelated edges [+] The “Pixelate!” Button Experience: - Disabled until image loaded - 5-second “processing” animation (UX theater) - Controls unlock after first conversion - Shimmer effect on completion - After first use: realtime updates (120ms debounce)
Hi Guys this is my project explaination how does the Pixelate work on steps: Step 1: Shrink (this is where the magic happens) jsconst small = document.createElement(‘canvas’); small.width = 64; small.height = 64; small.getContext(‘2d’).drawImage(srcImg, 0, 0, 64, 64); Imagine your photo is 1920×1080 pixels. You squish it down into a 64×64 canvas. To fit a million pixrls into 64×64, the browser has to merge groups of pixels into one. It looks at a chunk of the original image (say, a 30×17 block) and blends them all into a single average color. Result: you now have a real, tiny image — 64×64 actual pixels, each one a blended color from a chunk of the original. Step 2: Blow it bacl up (with no smoothing) jscanvas.style.width = ‘384px’; // 64 × 6 canvas.style.height = ‘384px’; cssimage-rendering: pixelated; Now you take that tiny 64×64 image and stretch it to be way bigger on screen. Normally, browsers smooth out stretched images (blurry). The pixelated setting turns smoothing off. So each of the 64×64 pixels just gets copied into a big solid square — no blending, no blur. Result: big, crisp, blocky squares = the pixel art look. Putting It Together big detailed photo ↓ (squish down — merges pixels, loses detail) tiny 64×64 image ↓ (stretch up — no smoothing, just copy each pixel bigger) big blocky pixel art The squish is what creates the pixel art (real data, real file). The stretch is just so you can see it clearly on screen — it adds zero new information. Why the Download File is Small When you hit download, it saves the tiny 64×64 image (from Step 1) — not the big stretched version. The “blow it back up” part was only for your screen. And this done in client side, we dont collect your image or saving ur image
Detailing My Project README.md and adding some detail
PixieR Project Devlog — Fixing the Stretching Bug & Other Issues Compare Slider stretching (main issue) Cause: syncCmpCanvas() set cmp.style.width='100%' and cmp.style.height='100%' together with objectFit:'contain' . object-fit only works on replaced elements like <img> and <video> — it has no effect on <canvas> , so the canvas was forced to fill the wrapper’s full 100% x 100% box regardless of its actual pixel aspect ratio, stretching the pixel art. Fix: Compute the display size manually based on the pixel canvas’s own aspect ratio ( src.width / src.height ), fit it within the wrapper width and a max height of 400px, then explicitly set cmp-canvas and cmp-orig-img width/height in pixels (with horizontal centering via marginLeft ). Both layers now share identical dimensions so the slider overlay aligns correctly. Pixel Only view overflow/stretch Cause: solo-canvas had a fixed inline max-width:100%;max-height:480px , while syncSoloCanvas() separately set style.width / style.height to width*zoom / height*zoom in px. At high zoom levels this could overflow the frame, and the max-width/max-height constraints distorted the aspect ratio independently on each axis. Fix: Removed the conflicting inline max-width/max-height. syncSoloCanvas() now computes the zoomed size, then uniformly scales both dimensions down by the same factor if it exceeds the frame’s width or a 480px height cap, preserving aspect ratio. Eyedropper coordinate mismatch Cause: pixelCanvas mousemove/click handlers divided mouse coordinates by the zoom slider value to find the pixel under the cursor. This breaks if the canvas’s rendered size ever differs from width * zoom (e.g. after future layout changes), giving wrong color picks. Fix: Replaced the zoom-based division with a ratio of the canvas’s actual bitmap size to its rendered bounding box size ( pixelCanvas.width / rect.width ), which is robust to any CSS scaling. Compare slider not resizing on window resize Cause: No resize handler existed for the compare/pixel-only views, so resizing the browser left stale dimensions and a stretched look. Fix: Added a resize listener that re-runs syncCmpCanvas() or syncSoloCanvas() depending on the active view. Dead/unused popup duplication Cause: The star popup markup was hardcoded in the page AND re-inserted via createPopupHTML() using insertAdjacentHTML , creating a duplicate #starPopup risk and unnecessary DOM bloat. Fix: Removed the redundant insertAdjacentHTML injection since the markup already exists in the page; createPopupHTML() now just guards against duplicates. Toast fallback dead code Cause: showToast() inside the popup IIFE recreated a whole second #toast element with inline styles if the existing one wasn’t found — but it always exists in the page, making this branch dead and bug-prone (it referenced var(--text, ...) colors that may not exist).
Ships:
I make a project called “PixieR”, PixieR is a 100% client-side web tool that converts any image into pixel art directly in your browser. no backend, no API calls — everything happens locally using the HTML5 Canvas API. The Challenging part in my project is managing all the logic such as main.js and whole web logic system Im so proud that I can make this project without any trouble, and I hope everyone can test out my project :) Check up my github to try my project :))...
|
1792878745.9209418
|
1793742745.9209418
|
|
68717
|
Virtual Shopping Interface by @yoonha | Stardance
|
yoonha
|
0
|
6.4
|
0
|
[]
|
[{"post_id": 81093, "ts": "202 [{"post_id": 81093, "ts": "2026-10-19T20:55:01Z", "hours": 1.7808, "text": "Yesterday and two days ago, I worked on payment.html. I spent a lot of time trying to figure how to ensure the count variable of each product does not reset across pages (apparently they do, which was surprising). I tried many solutions, cannot figure out, so I got help to know how to save the cart’s contents. Now it works as intended, and have the code segment dealing with saving the cart across pages. That let me print the Review Order page and list every product in the cart, and have buttons to reset the count and go back the shopping part. The trouble is, I still don’t know how to allow users to remove individual items from the list (e.g. remove just one product without deleting the entire cart). It probably uses an if condition; I’d have to investigate further to know how that works. The other thing I wanted to do, but was unable to do, was things like dropdowns or spinboxes. Then, the user can add multiples of the product at the same time and that would become more useful. Shame on me for not knowing so much about website design, but I have to deal with what I have."}, {"post_id": 80295, "ts": "2026-10-17T05:18:53Z", "hours": 1.5644, "text": "Today, I drew a custom currency symbol (it looks like a pink quaver with a golden dollar sign) and was able to add it into the files instead of banal dollar signs ( that’s one reason why I began this project; most “build your storefront” features didn’t have this kind of things ). It correctly gets rendered in front of the price tag. I also improved more on the main page by implementing the ArrayList-sque solution. This means adding new products to the catalogue because more convenient; there’s no need to list the description, price, name, etc. directly into the HTML file which got chaotic very quickly. It was difficult and took a long time because, again, I’m not familiar with the language. You may notice the colour backgrounds have changed; that’s intentional. The custom currency symbol (it has transparent background) got blended in with one of the colours so I had to change it, so you can see my custom currency symbol better."}, {"post_id": 80067, "ts": "2026-10-16T04:19:14Z", "hours": 1.9439, "text": "I decided to add more products to the interface, and I felt that it’s quite repetitive to constantly add lines like document.getElementById(“price1”).innerHTML = price1;. If this was Java I would have used an ArrayList of Products objects with price, name, etc. and it was only today that I had learnt that there is that such feature exists in JS. The trouble is, it’s quite tricky for me to learn it, because it looks very complex. Changing and implementing my idea is still in progress. The biggest struggle is retrieving values in the .js file (that has the ArrayList) into the HTML file because it’s so hard… for your reference, I’m very new to website design. The other hardship is calculating the price and displaying in payment.html; I have no idea how to get variables to be universal and accessed from every file. Any help is appreciated!"}, {"post_id": 79135, "ts": "2026-10-12T19:46:14Z", "hours": 1.1094, "text": "Today I worked on making the website be able to have multiple products in one line. It took a long time to get the alignment perfectly, and to ensure the website doesn’t look awkward because some buttons are located at a higher place than other buttons and to ensure that the products are displayed with even gaps in between."}]...
|
Title: Virtual Shopping Interface by @yoonha | Sta Title: Virtual Shopping Interface by @yoonha | Stardance
Devlogs:
Today I worked on making the website be able to have multiple products in one line. It took a long time to get the alignment perfectly, and to ensure the website doesn’t look awkward because some buttons are located at a higher place than other buttons and to ensure that the products are displayed with even gaps in between.
I decided to add more products to the interface, and I felt that it’s quite repetitive to constantly add lines like document.getElementById(“price1”).innerHTML = price1;. If this was Java I would have used an ArrayList of Products objects with price, name, etc. and it was only today that I had learnt that there is that such feature exists in JS. The trouble is, it’s quite tricky for me to learn it, because it looks very complex. Changing and implementing my idea is still in progress. The biggest struggle is retrieving values in the .js file (that has the ArrayList) into the HTML file because it’s so hard… for your reference, I’m very new to website design. The other hardship is calculating the price and displaying in payment.html; I have no idea how to get variables to be universal and accessed from every file. Any help is appreciated!
Today, I drew a custom currency symbol (it looks like a pink quaver with a golden dollar sign) and was able to add it into the files instead of banal dollar signs ( that’s one reason why I began this project; most “build your storefront” features didn’t have this kind of things ). It correctly gets rendered in front of the price tag. I also improved more on the main page by implementing the ArrayList-sque solution. This means adding new products to the catalogue because more convenient; there’s no need to list the description, price, name, etc. directly into the HTML file which got chaotic very quickly. It was difficult and took a long time because, again, I’m not familiar with the language. You may notice the colour backgrounds have changed; that’s intentional. The custom currency symbol (it has transparent background) got blended in with one of the colours so I had to change it, so you can see my custom currency symbol better.
Yesterday and two days ago, I worked on payment.html. I spent a lot of time trying to figure how to ensure the count variable of each product does not reset across pages (apparently they do, which was surprising). I tried many solutions, cannot figure out, so I got help to know how to save the cart’s contents. Now it works as intended, and have the code segment dealing with saving the cart across pages. That let me print the Review Order page and list every product in the cart, and have buttons to reset the count and go back the shopping part. The trouble is, I still don’t know how to allow users to remove individual items from the list (e.g. remove just one product without deleting the entire cart). It probably uses an if condition; I’d have to investigate further to know how that works. The other thing I wanted to do, but was unable to do, was things like dropdowns or spinboxes. Then, the user can add multiples of the product at the same time and that would become more useful. Shame on me for not knowing so much about website design, but I have to deal with what I have....
|
1792472101.1841276
|
1793076901.1841276
|
|
30067
|
ThickBerryPi by @kapkupi | Stardance
|
kapkupi
|
1
|
24.73
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-10T20:52:06Z", "hours": 24.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Hello everybody! I present to you my compact clamshell raspberry pi 5 handheld. It features a little keyboard and a 3.2 inch screen. The whole thing is also assembled with almost no screws! The only screws you will need are for the screen. Isn’t it wild what is possible with 3D printing? I mean getting the hinge or the latches right wasn’t easy but in the end having it be assembled with almost no tools really is amazing. I at least think so. It also has no battery because the pi 5 is a bit to picky and I carry powerbanks with me anyway so I decided not to package a battery with my project. Besides the additional size needed for it of course. So I am excited for others to try it out and maybe expand on it!", "repo": "https://github.com/Kapkupi/RPI5-Palmtop", "demo": ""}]...
|
[{"post_id": 81096, "ts": "202 [{"post_id": 81096, "ts": "2026-10-19T21:04:59Z", "hours": 0.7253, "text": "So I have started working on it again. I mean there is not much more to do besides waiting for it to get approved but after using it for a bit I did in fact made some changes. So first thing as you may have noticed is the bigger buttons on the screen. Not only are they way easier to assemble but also easier to use as they are bigger. The old ones were just too small and these are just more satisfying to click. click click :3 … There are also a few other small changes I might tackle so I’ll try doing a bit until October 22nd👀"}, {"post_id": 76224, "ts": "2026-10-02T19:01:07Z", "hours": 0.3236, "text": "I feel like I need to do this devlog. As you may have noticed is that I still have not shipped. The reason for that is that I have not been able to finish it last weekend and then fell sick on monday and am still sick. I am In better shape now and want to finally finish my project and collect my promised startdust /j >:3. I am very relieved that the challenge has been extended and I am not sure what I would have done without that. You can see my progress on github. (The first picture you see there is just a place holder dw)"}, {"post_id": 71496, "ts": "2026-09-20T22:36:34Z", "hours": 0.4603, "text": "Wow, about 7 hours of hardware work (which I didn’t record because nobody needs to see that ¬w¬) which consists of pretty much only soldering is behind me. I completely butchered my cardkb but everything still works. My immaculate cable management is also questionable but it works so now time to write and then ship. I should probably go to bed but it’s fine."}, {"post_id": 71182, "ts": "2026-09-20T12:25:21Z", "hours": 1.2714, "text": "So, I have finished my design and I won’t be needing to make any more changes. I am currently waiting for my final print which has a few tweaks such as an additional latch but other then that I am done. I have also made a version with an open back so any heatsink should work, not only my specific one. Now I only need to do some soldering and documenting before I can finally ship! I am soo excited"}, {"post_id": 70875, "ts": "2026-09-19T22:15:13Z", "hours": 2.0283, "text": "Yes another devlog. I made my changes and am printing again! As you can see there is another latch in the back. Of course that is not all I did but it is the most notable change. Some small details to actually make it fit were my priorities and now that I am finished with them I am printing. Excited to wake up tomorrow and see if I am ready to ship or not."}, {"post_id": 70789, "ts": "2026-09-19T19:20:43Z", "hours": 0.8183, "text": "Intermission! I have reprinted the face plate in a different orientation and now the latches are strong enough! I will still add another one to the back. Also I am sorry if my pictures look like memories but I was to lazy to use my phone and instead just used a webcam :P"}, {"post_id": 70737, "ts": "2026-09-19T17:50:23Z", "hours": 2.5175, "text": "So, I have made the first print and it is looking very promising. The hinge only needs slight changes in terms of tolerance so it can be easily disassembled, it also seems sturdy enough! What did not work is, as you can see, the RPI did not fit. I will need to make some changes to the ports on the right side. The latches are also not too bad but they both broke off. I will also need to add another latch in the back because it is too sloppy for my taste. The screen and buttons for it are pretty good. Gives me hope for the power button. But for now time to make some changes before I ship hopefully tomorrow."}, {"post_id": 70249, "ts": "2026-09-18T20:02:27Z", "hours": 2.4361, "text": "I am almost finished with the first version! I only need to do some buttons and holes and a bit of little extras and then I am finished and can print. I will not ship yet because I want to make a few different versions so most people can find enjoyment in what fits for them but I will probably do that tomorrow. Today I did a majority of the hinge in terms of function. I made a spring which makes the hinge snap into different places and makes the lid stay shut. Which you can see in the picture bellow. I am excited to be almost finished!"}, {"post_id": 69817, "ts": "2026-09-17T20:44:27Z", "hours": 1.8333, "text": "oh wow, I have added the ports on the back. You can see the seam where the holes are split which divides it into the top part which snaps on to the bottom. Easy to assemble as long as the latches do not break. I am trying my best to make the print possible with normal PLA and a 0.4mm nozzle size which currently should still be possible. I am really confident that the final product (which I am pretty close to ;3) should not be too difficult to print for the average user but I need to print it to judge that which hopefully happens this week as I will not be able to work on it next week :<"}, {"post_id": 68282, "ts": "2026-09-14T20:51:48Z", "hours": 0.5514, "text": "Did the second hinge. Of course this is far from the finished design it would not even work right now but to at least have something. I am also not completely sure on how I should do the back. Like should I leave it open, cover it completely or partially. Well I will eventually find something which I like. But still not entirely sure on how the back will look like."}, {"post_id": 67692, "ts": "2026-09-13T21:27:06Z", "hours": 3.1181, "text": "So I have continued with the display case and have added most things already. I have also started with the hinge which gave me such a headache I spent too much time finding a solution for my space requirements but I have decided on my current setup which should work well enough. And an important decision I took is that the whole hinge will be completely 3D printed! This could fail miserably and then I would need to revert back to a more simpler design with screws but if it works which I am confident it will then that would be really cool."}, {"post_id": 66939, "ts": "2026-09-12T22:16:44Z", "hours": 1.2167, "text": "Started with the display case. Just some simple things to finish off the day. And also because y’all have not seen it yet here is a view from the top of my current progress where you can see the keyboard holder which will connect to the bottom via latches."}, {"post_id": 66819, "ts": "2026-09-12T18:36:11Z", "hours": 2.8147, "text": "Wow, I would say that I am almost completely done with the enclosure for the keyboard and raspberry pi. Now the screen remains and thus the hinge. Should not be too difficult but I need to watch out for the space I need for the HDMI cables. Could be a tight fit. Notable things I have done since the last devlog are: latches, I hope they will work after finally printing exhaust and additional heat dissipation openings intake “optimisation”; will probably not make a difference but still fun small additional details"}, {"post_id": 65403, "ts": "2026-09-10T14:59:11Z", "hours": 2.7164, "text": "Did a bunch of openings for i/o such as sd card, gpio, usb and such. The back is still open but that will be addressed later on. Opening for the cooling fan was also added, no exhaust tho. I also split my main case into top and bottom because I realised that I would not be able to assemble it otherwise. Also lost my sticky streak because I am lowkey delusional :<"}, {"post_id": 61814, "ts": "2026-09-04T21:58:43Z", "hours": 0.6942, "text": "After coming back from my vacation I continued working on my project. Had to stop the recording because I havent uploaded today. Streaks and all. Today I started building the main body of my case which is not nearly finished. Tomorrow I will probably do the side with usb and ethernet port and an opening for the gpio and heatsink entry and exit."}, {"post_id": 46314, "ts": "2026-08-13T13:42:10Z", "hours": 0.9797, "text": "Ok I lied. I did in fact not start building the next day but 10 days later . Well now I am working again. I did some reference planes of the pcbs so I can use them to create my case more easier. Edited cardkb. I also was very sceptical that lapse just did not record as there were some problems but it somehow still worked. Now I can really start working on it :3"}, {"post_id": 40381, "ts": "2026-08-03T20:58:47Z", "hours": 0.45, "text": "Added my components to my assembly :D Real building will start tomorrow :P"}]...
|
Title: ThickBerryPi by @kapkupi | Stardance
Devlo Title: ThickBerryPi by @kapkupi | Stardance
Devlogs:
Added my components to my assembly :D Real building will start tomorrow :P
Ok I lied. I did in fact not start building the next day but 10 days later . Well now I am working again. I did some reference planes of the pcbs so I can use them to create my case more easier. Edited cardkb. I also was very sceptical that lapse just did not record as there were some problems but it somehow still worked. Now I can really start working on it :3
After coming back from my vacation I continued working on my project. Had to stop the recording because I havent uploaded today. Streaks and all. Today I started building the main body of my case which is not nearly finished. Tomorrow I will probably do the side with usb and ethernet port and an opening for the gpio and heatsink entry and exit.
Did a bunch of openings for i/o such as sd card, gpio, usb and such. The back is still open but that will be addressed later on. Opening for the cooling fan was also added, no exhaust tho. I also split my main case into top and bottom because I realised that I would not be able to assemble it otherwise. Also lost my sticky streak because I am lowkey delusional :<
Wow, I would say that I am almost completely done with the enclosure for the keyboard and raspberry pi. Now the screen remains and thus the hinge. Should not be too difficult but I need to watch out for the space I need for the HDMI cables. Could be a tight fit. Notable things I have done since the last devlog are: latches, I hope they will work after finally printing exhaust and additional heat dissipation openings intake “optimisation”; will probably not make a difference but still fun small additional details
Started with the display case. Just some simple things to finish off the day. And also because y’all have not seen it yet here is a view from the top of my current progress where you can see the keyboard holder which will connect to the bottom via latches.
So I have continued with the display case and have added most things already. I have also started with the hinge which gave me such a headache I spent too much time finding a solution for my space requirements but I have decided on my current setup which should work well enough. And an important decision I took is that the whole hinge will be completely 3D printed! This could fail miserably and then I would need to revert back to a more simpler design with screws but if it works which I am confident it will then that would be really cool.
Did the second hinge. Of course this is far from the finished design it would not even work right now but to at least have something. I am also not completely sure on how I should do the back. Like should I leave it open, cover it completely or partially. Well I will eventually find something which I like. But still not entirely sure on how the back will look like.
oh wow, I have added the ports on the back. You can see the seam where the holes are split which divides it into the top part which snaps on to the bottom. Easy to assemble as long as the latches do not break. I am trying my best to make the print possible with normal PLA and a 0.4mm nozzle size which currently should still be possible. I am really confident that the final product (which I am pretty close to ;3) should not be too difficult to print for the average user but I need to print it to judge that which hopefully happens this week as I will not be able to work on it next week :<
I am almost finished with the first version! I only need to do some buttons and holes and a bit of little extras and then I am finished and can print. I will not ship yet because I want to make a few different versions so most people can find enjoyment in what fits for them but I will probably do that tomorrow. Today I did a majority of the hinge in terms of function. I made a spring which makes the hinge snap into different places and makes the lid stay shut. Which you can see in the picture bellow. I am excited to be almost finished!
So, I have made the first print and it is looking very promising. The hinge only needs slight changes in terms of tolerance so it can be easily disassembled, it also seems sturdy enough! What did not work is, as you can see, the RPI did not fit. I will need to make some changes to the ports on the right side. The latches are also not too bad but they both broke off. I will also need to add another latch in the back because it is too sloppy for my taste. The screen and buttons for it are pretty good. Gives me hope for the power button. But for now time to make some changes before I ship hopefully tomorrow.
Intermission! I have reprinted the face plate in a different orientation and now the latches are strong enough! I will still add another one to the back. Also I am sorry if my pictures look like memories but I was to lazy to use my phone and instead just used a webcam :P
Yes another devlog. I made my changes and am printing again! As you can see there is another latch in the back. Of course that is not all I did but it is the most notable change. Some small details to actually make it fit were my priorities and now that I am finished with them I am printing. Excited to wake up tomorrow and see if I am ready to ship or not.
So, I have finished my design and I won’t be needing to make any more changes. I am currently waiting for my final print which has a few tweaks such as an additional latch but other then that I am done. I have also made a version with an open back so any heatsink should work, not only my specific one. Now I only need to do some soldering and documenting before I can finally ship! I am soo excited
Wow, about 7 hours of hardware work (which I didn’t record because nobody needs to see that ¬w¬) which consists of pretty much only soldering is behind me. I completely butchered my cardkb but everything still works. My immaculate cable management is also questionable but it works so now time to write and then ship. I should probably go to bed but it’s fine.
I feel like I need to do this devlog. As you may have noticed is that I still have not shipped. The reason for that is that I have not been able to finish it last weekend and then fell sick on monday and am still sick. I am In better shape now and want to finally finish my project and collect my promised startdust /j >:3. I am very relieved that the challenge has been extended and I am not sure what I would have done without that. You can see my progress on github. (The first picture you see there is just a place holder dw)
So I have started working on it again. I mean there is not much more to do besides waiting for it to get approved but after using it for a bit I did in fact made some changes. So first thing as you may have noticed is the bigger buttons on the screen. Not only are they way easier to assemble but also easier to use as they are bigger. The old ones were just too small and these are just more satisfying to click. click click :3 … There are also a few other small changes I might tackle so I’ll try doing a bit until October 22nd👀
Ships:
Hello everybody! I present to you my compact clamshell raspberry pi 5 handheld. It features a little keyboard and a 3.2 inch screen. The whole thing is also assembled with almost no screws! The only screws you will need are for the screen. Isn’t it wild what is possible with 3D printing? I mean getting the hinge or the latches right wasn’t easy but in the end having it be assembled with almost no tools really is amazing. I at least think so. It also has no battery because the pi 5 is a bit to picky and I carry powerbanks with me anyway so I decided not to package a battery with my project. Besides the additional size needed for it of course. So I am excited for others to try it out and maybe expand on it!...
|
1792856928.040209
|
1792943328.040209
|
|
65574
|
Rep Bot by @Eternal | Stardance
|
Eternal
|
0
|
6.68
|
0
|
[]
|
[{"post_id": 81099, "ts": "202 [{"post_id": 81099, "ts": "2026-10-19T21:20:38Z", "hours": 0.6856, "text": "Okay, maybe I lied a little bit. There are a few more updates I want to make. I talked with Evan about adding it to #code and #hardware, and he agreed HURAYYYY YAY YOPRGLK ERL:G JRLSKJ KRLSHG KJWRHGKJ WEJHK SJ:GJK But he also made a few suggestions which I will be implementing. These changes here, though, are my own ideas. Previously, the format for giving someone thanks/points was very strict. The message has to start with “thanks” or “ty” or “thx” and then has to mention someone and has to be exactly 2 words long (the ping counts as a word). Now, it’s more flexible and the requirements for the bot to notice that the user is trying to give thanks is just to have the word “thanks” or “thank” or “ty” or “thx” and then ping the user. There can be other words in the message now. I also added a profile picture to the bot (suggestion by Evan). It’s stolen from Lapse’s leaderboard icon"}, {"post_id": 80051, "ts": "2026-10-16T02:32:01Z", "hours": 0.6681, "text": "Eyyyy! Whatcha look at that! Editing the leaderboard works now. so, I had to switch from using respond() to client.chat.update() which makes no sense to me but okay sure whatever it works now. Then, there was an error about duplicate action IDs which I used Gemini to figure out the fix for: Slack wants a unique action to be performed by each button so you need a new event handler. But I don’t want to duplicate code so I hovered over the “app.action” function and noticed that it except RegEx so I used the RegEx “/paginate_(next|prev)/” I’m so happy it works now though. Time to ship it!"}, {"post_id": 79659, "ts": "2026-10-14T23:21:28Z", "hours": 0.4258, "text": "HEY GUESS WHAT THE ISSUE WAS. GUESS WHAT. IT. WAS. FIXED. WITH. A. REBOOT. WHAT okay, so. Here’s the context, right. The user requests a command to be ran on the bot and the command is sometimes randomly delayed until after the 3 second timeout from Slack is over so Slack thinks the bot didn’t receive it but the bot didn’t even receive the command. I have a video attached. I thought it was my code’s fault, so I was messing around and adding logging and changing random things and googling and whatnot and nothing fixed it. And then I rebooted my computer. AND IT FIXED IT WHAT DO YOU MEAN???? IF IT WAS AN ISSUE WITH THE NETWORK CODE WHY DIDN’T WEBSITES TAKE SECONDS TO LOAD???? THEY LOADED FINE! WHYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"}, {"post_id": 79181, "ts": "2026-10-12T22:34:23Z", "hours": 2.6636, "text": "So, I got the leaderboard working..kind of. The leaderboard works and shows the top 10 people, but the “Next” button to show the next 10 people doesn’t work. Why? Who knows? Slack just complains of something being wrong and doesn’t give many details about what exactly is wrong. There’s also another issue: sometimes the bot won’t receive a message from Slack that a command was ran until after the timeout period of 3 seconds is over. And I know it’s not the code taking more than 3 seconds to run because the request is immediately ack’d and the entire code block takes less than 250ms on average (I timed it with console.time). So I have no idea what’s going on. That’s why this devlog is 2.5 hours. It took me 45 minutes to add the feature, and the rest of the time is trying to fix the feature. I’ll continue debugging it."}, {"post_id": 77693, "ts": "2026-10-07T22:58:00Z", "hours": 0.51, "text": "Added the /rep-bot-profile command which queries the database for your points + the amount of people that have more points than you and then tells you. Next up: a leaderboard command"}, {"post_id": 77156, "ts": "2026-10-05T20:23:25Z", "hours": 1.7267, "text": "I got the bot working! People who say “thanks” or “thank” or “thx” followed by pinging someone will give that person 1 rep point. I setup the SQLite database with Drizzle ORM. I had lots of trouble with getting the bot to recognize that messages were even sent, so I went to Stardance’s slack bot guide for help with setting up my bot properly. I don’t know what exactly I changed to fix it, but the bot started recognizing new messages sent in the channel after I added all the permissions the guide said to add."}]...
|
Title: Rep Bot by @Eternal | Stardance
Devlogs:
I Title: Rep Bot by @Eternal | Stardance
Devlogs:
I got the bot working! People who say “thanks” or “thank” or “thx” followed by pinging someone will give that person 1 rep point. I setup the SQLite database with Drizzle ORM. I had lots of trouble with getting the bot to recognize that messages were even sent, so I went to Stardance’s slack bot guide for help with setting up my bot properly. I don’t know what exactly I changed to fix it, but the bot started recognizing new messages sent in the channel after I added all the permissions the guide said to add.
Added the /rep-bot-profile command which queries the database for your points + the amount of people that have more points than you and then tells you. Next up: a leaderboard command
So, I got the leaderboard working..kind of. The leaderboard works and shows the top 10 people, but the “Next” button to show the next 10 people doesn’t work. Why? Who knows? Slack just complains of something being wrong and doesn’t give many details about what exactly is wrong. There’s also another issue: sometimes the bot won’t receive a message from Slack that a command was ran until after the timeout period of 3 seconds is over. And I know it’s not the code taking more than 3 seconds to run because the request is immediately ack’d and the entire code block takes less than 250ms on average (I timed it with console.time). So I have no idea what’s going on. That’s why this devlog is 2.5 hours. It took me 45 minutes to add the feature, and the rest of the time is trying to fix the feature. I’ll continue debugging it.
HEY GUESS WHAT THE ISSUE WAS. GUESS WHAT. IT. WAS. FIXED. WITH. A. REBOOT. WHAT okay, so. Here’s the context, right. The user requests a command to be ran on the bot and the command is sometimes randomly delayed until after the 3 second timeout from Slack is over so Slack thinks the bot didn’t receive it but the bot didn’t even receive the command. I have a video attached. I thought it was my code’s fault, so I was messing around and adding logging and changing random things and googling and whatnot and nothing fixed it. And then I rebooted my computer. AND IT FIXED IT WHAT DO YOU MEAN???? IF IT WAS AN ISSUE WITH THE NETWORK CODE WHY DIDN’T WEBSITES TAKE SECONDS TO LOAD???? THEY LOADED FINE! WHYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
Eyyyy! Whatcha look at that! Editing the leaderboard works now. so, I had to switch from using respond() to client.chat.update() which makes no sense to me but okay sure whatever it works now. Then, there was an error about duplicate action IDs which I used Gemini to figure out the fix for: Slack wants a unique action to be performed by each button so you need a new event handler. But I don’t want to duplicate code so I hovered over the “app.action” function and noticed that it except RegEx so I used the RegEx “/paginate_(next|prev)/” I’m so happy it works now though. Time to ship it!
Okay, maybe I lied a little bit. There are a few more updates I want to make. I talked with Evan about adding it to #code and #hardware, and he agreed HURAYYYY YAY YOPRGLK ERL:G JRLSKJ KRLSHG KJWRHGKJ WEJHK SJ:GJK But he also made a few suggestions which I will be implementing. These changes here, though, are my own ideas. Previously, the format for giving someone thanks/points was very strict. The message has to start with “thanks” or “ty” or “thx” and then has to mention someone and has to be exactly 2 words long (the ping counts as a word). Now, it’s more flexible and the requirements for the bot to notice that the user is trying to give thanks is just to have the word “thanks” or “thank” or “ty” or “thx” and then ping the user. There can be other words in the message now. I also added a profile picture to the bot (suggestion by Evan). It’s stolen from Lapse’s leaderboard icon...
|
1792454108.80059
|
1793058908.80059
|
|
67377
|
cat pet by @marygoat | Stardance
|
marygoat
|
0
|
6.95
|
0
|
[]
|
[{"post_id": 81101, "ts": "202 [{"post_id": 81101, "ts": "2026-10-19T21:23:51Z", "hours": 1.645, "text": "Virtual Pet DEVLOG: #5 endless runner game! it took me a bit, but i added in a minigame! Endless Runner: Based off no wifi dino game Uses a separate cat sprite Placeholder yellow square as collisions my biggest struggle was the collisions, i had forgotten how to properly use area2D and tried to do some more complicated math. i used claude which reminded me of said area2D and so i started messing with hitboxes. i am planning on adding a hurt animation for when you lose and stylizing the minigame and making it look way better!"}, {"post_id": 80829, "ts": "2026-10-18T22:39:58Z", "hours": 1.6339, "text": "Virtual Pet DEVLOG: #4 window, particles, sound effects! i have added NEW features such as: Meow when clicked on / thrown Heart particles when clicked on to imitate a pet Window that opens with the key h ( temporary ) i struggled with placing the meow effect in the right spot in the code, since I didn’t know if I wanted the cat to meow when landing or being thrown. i also struggled with the particles since i wanted to make it look like the guide but i went with a falling anim instead of an explosion."}, {"post_id": 80045, "ts": "2026-10-16T02:00:20Z", "hours": 1.4442, "text": "Virtual Pet DEVLOG: #3 sleep, feed, throw, menu! i have added a throwing mechanic and a menu that opens up when you right click onto the cat, giving you two actions as of now! i also added another idle anim where the cat will meow Sleep: Cat goes into a sleeping animation Feed: Cat goes into a eating animation i was struggling a lot with the throw mechanic, since i was confused on why the code didnt find delta. it was a simple scope issue, since i put the code into another section instead of the physics process function that took in delta as a parameter. i used claude to help me debug, which was because i just forgot to add a vector line."}, {"post_id": 79177, "ts": "2026-10-12T22:09:59Z", "hours": 1.0081, "text": "Virtual Pet DEVLOG: #2 fall onto taskbar! this took way longer than necessary, but i made it so when its dragged, it falls onto the taskbar! i used gemini to help me debug and figure out why my logic wasn’t working, which was because i placed the falling mechanism after the position, so itd call the position before the fall thing would ever occur. with my handy dandy itch.io warioware grant, i bought the rest of the asset pack since i really liked it! it now can sit instead of just standing as an idle, and i plan to add more stuff like feeding + minigames!"}, {"post_id": 78845, "ts": "2026-10-11T19:10:49Z", "hours": 1.2147, "text": "Virtual Pet DEVLOG: #1 starting it! this is my FIRST devlog for this project, which has been so fun so far! currently, this is what ive done: run animation bounce off edge draggable sometimes stops for an idle at edge throughout making this, i struggled with the idle animation a LOT because i could not remove the background of it, and i dont want a cat with a white background idling out of nowhere. for now, i have no idle animation, but i am going to fix it soon once i figure out how to remove the bg without making it look ugly. i also had an issue where my cat would not actually run, it’d just stay stuck. it took me too long to figure out that i just had the animations named differently, Walk_Right in code but Run in the actual animation itself. overall, i think this is going great! also, creds to tuff carysaurus for making these sprites! if you want these, you can find the free version at: https://carysaurus.itch.io/black-cat-sprites"}]...
|
Title: cat pet by @marygoat | Stardance
Devlogs:
Title: cat pet by @marygoat | Stardance
Devlogs:
Virtual Pet DEVLOG: #1 starting it! this is my FIRST devlog for this project, which has been so fun so far! currently, this is what ive done: run animation bounce off edge draggable sometimes stops for an idle at edge throughout making this, i struggled with the idle animation a LOT because i could not remove the background of it, and i dont want a cat with a white background idling out of nowhere. for now, i have no idle animation, but i am going to fix it soon once i figure out how to remove the bg without making it look ugly. i also had an issue where my cat would not actually run, it’d just stay stuck. it took me too long to figure out that i just had the animations named differently, Walk_Right in code but Run in the actual animation itself. overall, i think this is going great! also, creds to tuff carysaurus for making these sprites! if you want these, you can find the free version at: https://carysaurus.itch.io/black-cat-sprites
Virtual Pet DEVLOG: #2 fall onto taskbar! this took way longer than necessary, but i made it so when its dragged, it falls onto the taskbar! i used gemini to help me debug and figure out why my logic wasn’t working, which was because i placed the falling mechanism after the position, so itd call the position before the fall thing would ever occur. with my handy dandy itch.io warioware grant, i bought the rest of the asset pack since i really liked it! it now can sit instead of just standing as an idle, and i plan to add more stuff like feeding + minigames!
Virtual Pet DEVLOG: #3 sleep, feed, throw, menu! i have added a throwing mechanic and a menu that opens up when you right click onto the cat, giving you two actions as of now! i also added another idle anim where the cat will meow Sleep: Cat goes into a sleeping animation Feed: Cat goes into a eating animation i was struggling a lot with the throw mechanic, since i was confused on why the code didnt find delta. it was a simple scope issue, since i put the code into another section instead of the physics process function that took in delta as a parameter. i used claude to help me debug, which was because i just forgot to add a vector line.
Virtual Pet DEVLOG: #4 window, particles, sound effects! i have added NEW features such as: Meow when clicked on / thrown Heart particles when clicked on to imitate a pet Window that opens with the key h ( temporary ) i struggled with placing the meow effect in the right spot in the code, since I didn’t know if I wanted the cat to meow when landing or being thrown. i also struggled with the particles since i wanted to make it look like the guide but i went with a falling anim instead of an explosion.
Virtual Pet DEVLOG: #5 endless runner game! it took me a bit, but i added in a minigame! Endless Runner: Based off no wifi dino game Uses a separate cat sprite Placeholder yellow square as collisions my biggest struggle was the collisions, i had forgotten how to properly use area2D and tried to do some more complicated math. i used claude which reminded me of said area2D and so i started messing with hitboxes. i am planning on adding a hurt animation for when you lose and stylizing the minigame and making it look way better!...
|
1792464834.1579437
|
1793069634.1579437
|
|
68590
|
CAR HOME THEATER by @GOST | Stardance
|
GOST
|
0
|
10.96
|
0
|
[]
|
[{"post_id": 81102, "ts": "202 [{"post_id": 81102, "ts": "2026-10-19T21:26:02Z", "hours": 0.3175, "text": "sub bracket desine"}, {"post_id": 80363, "ts": "2026-10-17T12:40:33Z", "hours": 0.5156, "text": "stand for seround speaker"}, {"post_id": 79777, "ts": "2026-10-15T11:06:48Z", "hours": 0.9733, "text": "emproving the centre sound speaker"}, {"post_id": 79767, "ts": "2026-10-15T10:02:51Z", "hours": 9.1583, "text": "i am working one using car items to mack a home theater"}]...
|
Title: CAR HOME THEATER by @GOST | Stardance
Devl Title: CAR HOME THEATER by @GOST | Stardance
Devlogs:
i am working one using car items to mack a home theater
emproving the centre sound speaker
stand for seround speaker
sub bracket desine...
|
1792472000.871207
|
1793076800.871207
|
|
69481
|
My awesome macropad! by @FineDust | Stardance
|
FineDust
|
1
|
0.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T22:33:13Z", "hours": 0.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Hackpad From the mission my awesome macropad one of the biger problems I faced was not understanding the software properly witch I was useing. apart from that the rest of the project was more less smooth sailing", "repo": "https://github.com/xxfinedustxx/HackPad", "demo": ""}]...
|
[{"post_id": 81107, "ts": "202 [{"post_id": 81107, "ts": "2026-10-19T22:12:14Z", "hours": 2.7911, "text": "Hackpad Hackpad at 99% done design stage"}, {"post_id": 80753, "ts": "2026-10-18T18:20:21Z", "hours": 9.6578, "text": "Devlog 3 Hi everyone! It’s a lil’ update today. Just made my HackPad CAD case model so it can be checked off the list: PCB layout HackPad case modeled Code & firmware It took about 8 hours of compromising with the CAD software, but the enclosure layout is roughly 90% done. So it’s about time to start cooking up some custom firmware."}, {"post_id": 80009, "ts": "2026-10-15T23:25:18Z", "hours": 4.5928, "text": "2. Devlog ~01:00 16.10.2026 Hey everyone! I’ve just finished the PCB layout for my HackPad project! Next up, I’ll be diving into the 3D design phase for the case. That’s all for this update—if you have any suggestions or questions, feel free to drop them below!"}, {"post_id": 79653, "ts": "2026-10-14T22:31:15Z", "hours": 1.6694, "text": "I did some work on the PCB but not that much to make a devlog. So here; who wants to rate my Linux setup x/10."}, {"post_id": 79417, "ts": "2026-10-13T21:43:00Z", "hours": 1.4689, "text": "This is a PCB (not yet, but still a PCB); it’s going to be a great Stream Deck one day."}]...
|
Title: My awesome macropad! by @FineDust | Stardan Title: My awesome macropad! by @FineDust | Stardance
Devlogs:
This is a PCB (not yet, but still a PCB); it’s going to be a great Stream Deck one day.
I did some work on the PCB but not that much to make a devlog. So here; who wants to rate my Linux setup x/10.
2. Devlog ~01:00 16.10.2026 Hey everyone! I’ve just finished the PCB layout for my HackPad project! Next up, I’ll be diving into the 3D design phase for the case. That’s all for this update—if you have any suggestions or questions, feel free to drop them below!
Devlog 3 Hi everyone! It’s a lil’ update today. Just made my HackPad CAD case model so it can be checked off the list: PCB layout HackPad case modeled Code & firmware It took about 8 hours of compromising with the CAD software, but the enclosure layout is roughly 90% done. So it’s about time to start cooking up some custom firmware.
Hackpad Hackpad at 99% done design stage
Ships:
Hackpad From the mission my awesome macropad one of the biger problems I faced was not understanding the software properly witch I was useing. apart from that the rest of the project was more less smooth sailing...
|
1792857040.6893466
|
1792943440.6893466
|
|
70556
|
80mm velocity stack by @kapkupi | Stardance
|
kapkupi
|
0
|
1.42
|
0
|
[]
|
[{"post_id": 81108, "ts": "202 [{"post_id": 81108, "ts": "2026-10-19T22:12:43Z", "hours": 1.42, "text": "Yeah while waiting for a print of another project to finish I decided to make this velocity stack. Nothing to difficult or complicated but useful maybe. Will probably get a crisp 10 stardust from this but who cares. It is not about the money it is about the airflow ,’) … I think it is a tad bit too big There is never too big >.>"}]...
|
Title: 80mm velocity stack by @kapkupi | Stardance Title: 80mm velocity stack by @kapkupi | Stardance
Devlogs:
Yeah while waiting for a print of another project to finish I decided to make this velocity stack. Nothing to difficult or complicated but useful maybe. Will probably get a crisp 10 stardust from this but who cares. It is not about the money it is about the airflow ,’) … I think it is a tad bit too big There is never too big >.>...
|
1792450027.6041567
|
1793054827.6041567
|
|
35722
|
GBWeb by @Doodl0 | Stardance
|
Doodl0
|
0
|
50.76
|
0
|
[]
|
[{"post_id": 81110, "ts": "202 [{"post_id": 81110, "ts": "2026-10-19T22:32:59Z", "hours": 6.6672, "text": "Devlog 10 - (basically) Finishing the CPU After the last devlog, I did some cleaning up with the graphics, which included fixing the last scanline not being rendered, and also adding a screen before the ROM is loaded, telling the user which key to press to load the ROM. I also set up some functions to allow easier access to the I/O registers related to the PPU, such as the x and y scroll and the control flags. Afterwards, I felt a bit burnt out of the PPU, so I went back to finish off most of the CPU. This started with implementing the CFL, CPL, CF, CPL, SCF, SLA, SRA, RL, RLA, RLC, RRC, RLCA, and RRCA instructions, most of which are bit rotations, so once I had a few implemented, it got easier to add the rest. This allowed me to pass CPU test ROM 9. Then, I implemented the rest of the CB prefix instructions, which were all bit related; BIT, RES and SET, which allowed me to pass ROM 10 After those, I implemented some stack pointer related instructions; ADD SP,d and LD HL SP+d, which then allowed me to pass ROM 3 Finally, I added DAA. This one is a bit more unique, as it is designed to convert the result of an add or subtract with binary coded decimal numbers, into a binary coded decimal number. This gets a bit complicated, but I used these resources ( Demystifying the GameBoy/SM83’s DAA Instruction and the RGBDS assembler/linker instruction documentation ) to implement this properly, allowing me to also pass test ROM 1 With a semi-functioning PPU, and some fixes, I was also able to boot into the copyright screen of Tetris for the first time, although I couldn’t get any further without implementing interrupts. The image below shows that, and my emulator passing all of the previously mentioned test ROMs. The only test ROM I haven’t passed yet is the 2nd one, which also requires interrupts."}, {"post_id": 80353, "ts": "2026-10-17T11:17:07Z", "hours": 4.04, "text": "Devlog 9 - Basic graphics (finally) I’ve finally gotten some basic picture processing unit (PPU) functionality implemented into the emulator, which will hopefully make debugging a lot easier going forward. Firstly, to implement this, I had to move the timing logic out of cpu.c and into cycles.c . This was so that, when the loop calls a CPU step, it also calls a PPU step at the same time. I also refactored some of the cycle functions and removed the ones that were no longer being used Then, I implemented the timing code for the PPU. This part and the actual rendering were mostly based on this tutorial series that shows you how to make a GB emulator in javascript, which I based my C code on. Basically, the PPU runs on the clock as the CPU, and a ‘dot’ on the PPU is equal to a T-cycle on the CPU. The PPU renders progressively, like a CRT television, and so also has modes to move the nonexistent electron beam down and back to the start of a scanline before it continutes rendering, known as VBLANK and HBLANK, (vertical and horizontal blank). The Pan Docs were also quite helpful for understanding the basic functionality, although the tutorial was useful to understand the programmatic side. The PPU also has 2 other modes, used for scanning the Object Attribute Memory (OAM) and actually drawing, and all 4 modes have a precise amount of dots that they run for. In terms of actual rendering, the Gameboy doesn’t have a full framebuffer, and instead uses different tiles to create a full image. I implemented a function that, when the CPU writes to VRAM, also updates the data in a separate tileset variables, for easier access in the render pipeline. Each tile is 16 bytes, with 2 bits per pixel colour depth, and 8 x 8 pixels per tile. As the Gameboy renders progressively, I then implemented the function to draw a scanline to the screen, based on the tile data in the background layer. The afformentioned tutorial series helped a lot here, as the tiles need to have a specific offset and mapping applied which would be quite hard to figure out on my own. Then, that function calls a draw pixel function for each each of the 160 pixels in a scanline, which writes the corresponding colour from the palette to an SDL_Surface as the framebuffer. Once the frame is finished, the surface is converted into a texture, which is then scaled to fit the screen size and rendered, with another frame being made afterwards. Below you can see the screen of the previously mentioned blargg’s test ROM 7."}, {"post_id": 79179, "ts": "2026-10-12T22:23:50Z", "hours": 6.5228, "text": "Devlog 8 - Organisation, and timing, again Ok, so this didn’t exactly go how I wanted (again), but most of this devlog time was spent fixing the past devlog, and organising code in a better way Firstly: I realised that before, my timing code checked based on M-cycles, rather than T-cycles. There’s a specific reason for the distinction, but for now all you need to know is that there’s 4 T-cycles in an M-cycle, so my code was targeting a 4x faster speed. I changed this to be correct, but changed it again later so it doesn’t really matter. Then, I cleaned up a lot of cpu.c , changing functions to return values directly rather than using a local variable first, pre-calculating some variables, et cetera. This was an attempt to speed up the CPU, as I was having a bit of trouble meeting the target speed with debug builds (mentioned in devlog 7), but again, this was a bit pointless because I changed the way the timing worked later. While doing this, I also replaced all of the numerical types with their stdint.h counterparts; for example, an unsigned char became a Uint8 (SDL has macros for the stdint types, so they have a slight naming difference from standard C in my code). This was mainly done for specificity and some Hail Mary for performance (although fruitless), and should make the code at least a bit more portable and easy to maintain. I also implemented a couple of new instructions; RST and SWAP. RST effectively calls from a set of pre-specified addresses , and SWAP just swaps the upper and lower 8 bits in a byte, so these weren’t too hard. I also had to fix some bugs with the flags register´s value after an SBC A instruction, which admittedly did take me a while to fix because I basically banged my head against the wall to fix it. The main change in this devlog was switching the timing system (again). Previously, the CPU ran one instruction for each loop of the SDL_AppIterate function. After reading the documentation and realising that this function is supposed to run each frame, I realised that I was causing all of my speed issues by only doing one cycle per iteration. Instead, the code now does as many instructions as it can until it has run enough T-cycles for a full frame to render (70224). It then renders (to be implemented), and moves on to the next iteration. This is way more performant, and has the added benefit of being more cross-platform, as SDL specifies that sometimes AppIterate may only run at the refresh rate on some devices. Tbh, this took me a while, maybe too long, to conceptualise and implement, and basically made all of the time on the other timing system wasted, but in the end it was worth it for a much better system. You can see the uncapped FPS (in a debug build mind you) here, although when actually playing games, the framerate will be locked to around 60 FPS. Finally, there was a few more miscellaneous changes: copying a ROM file into memory uses memcpy instead of a loop, which may or may not be faster; memory is now a union of smaller arrays of memory banks, for each function, such as work ram (WRAM), high ram (HRAM), ROM banks 0-n and etc; and lastly, some register code has been moved out of cpu.c for organisation."}, {"post_id": 77175, "ts": "2026-10-05T22:31:28Z", "hours": 5.0036, "text": "Devlog 7 - Timing The next main thing I implemented were some more instructions - namely SRL, RR, RRA and ADD HL. These weren’t too hard, as the first 3 are similar to regular bit shifts, and ADD HL is just adding. While I was working on these, I also fixed some bugs with the existing instructions This allowed me to finally pass the cpu_instrs 6 test ROM, which although not really a massive goal, did help to signify the progress I had made. I then moved onto the 7th test, for which I implemented some load functions for the stack pointer register The biggest improvement of this devlog was getting everything timing correctly. The Gameboy is supposed to run at 4.19 MHz and 59.7 FPS, but at the time, the emulator was just running as fast as possible. To solve this, I first made each instruction call a function to add the amount of cycles it takes to a unwaitedCycles variable. Then, I saved the current time in nanoseconds since the program started (provided by the SDL_GetTicksNS() function) into a variable at the start of an instruction’s execution. After the instruction is executed, a function is then called that finds the expected execution time the by doing the amount of cycles multiplied by the period of 4.19MHz (about 238 nanoseconds). This expected time is then subtracted from the actual time, which is the start time stored previously subtracted from the current time. The program is then delayed by the result, which should keep the CPU at around 4.19MHz, unless it takes too long. I did have some concerns with my emulator’s performance, as when running as a debug build, it wasn’t running nearly fast enough to reach 4.19MHz, but after compiling as a release build with optimisation, it was much faster and ran under the required time. However, I’m not sure how consistent this will be between devices, so I may have to optimise later Finally, I added a similar function to limit the FPS to around 60 (technically 59.7), which just checks the time since the last frame was rendered, and if it hasn’t been long enough, it continues CPU execution and doesn’t render. You can see the frame limit working in the screenshot, where the frametime is a consistent 16.8 ms and the FPS is locked to 60, as opposed to before where it was unlimited. (Ignore the text, it doesn’t change yet to show a ROM has been loaded)"}, {"post_id": 76068, "ts": "2026-10-02T07:40:09Z", "hours": 5.4931, "text": "Devlog 6 - An unfortunate amount of debugging This devlog is probably going to be shorter than the other, simply because I haven’t done as much as I hoped The main reason for this is that I got completely stuck on a bug, and wasted so much time trying to find it. I first noticed this bug when I got this error message (screenshot) in gameboy-doctor, with a mismatch with a load from memory not being the right value. This got me so stuck, because I didn’t know where to find when the memory was supposed to be written to, so I was basically blindly guessing what was wrong with any previous loads or register writes. Eventually, I caved and asked for help online, and I got my answer after asking on the EmuDev subreddit , where I found out it was an issue with my implementation of the LD (FF00+u8), A instructions, where I wrote LD_n16_n8((0xFF00 + address + 1), registers.a); instead of the correct LD_n16_n8((0xFF00 + ReadMemory(address + 1)), registers.a); so basically any writes to memory using that function were in the complete wrong location. Stupid mistake on my part, and I wasted way too much time on it. I also did implement some basic instructions, like EI and RETI. EI simply enables the emi register, and RETI basically just does that, then calls RET to return from a subroutine. In addition, I also restructured quite a lot of the code, as too much was piling up in the cpu.c file, and I also renamed quite a few functions to follow a Component_Function syntax, so it was easier to tell where they were located in the code"}, {"post_id": 73310, "ts": "2026-09-24T20:22:22Z", "hours": 6.5411, "text": "Devlog 5 - Adding instructions, the stack and lots of debugging After the last devlog, the first think I did was implement some more instructions, namely the jump instructions, and the increment and decrement functions. Luckily these were pretty simple; all the jumps do are set the program counter (effectively the next instruction) to a specified value, and the increment and decrement are pretty self explanatory, increasing or decreasing a register or memory byte by 1; After this, I started implementing the stack. The stack is a section of memory that is ordered, with values being written to it (pushed) and read off of it (popped). You must read the “top” value, meaning the most recently pushed, which is then removed and the next highest is the next available to read. This wasn’t too hard, although I did have to introduce a new register, the stack pointer (sp). While I was at it, I also implemented load functions, which load data into a specified memory byte or register. After realising it would cause issues down the line, I walked back my previous decision to make the flags register a struct of booleans, and instead made it a single byte with 4 bits representing the 4 flags, making it more accurate. I also made some functions to easily set or reset each flag, rather than use bitwise operations everywhere. Finally, I implemented logging support, so that I could use Gameboy Doctor , a brilliant debugging script that reads a log file from your emulator with a known ROM, and compares it to the correct result. All you have to do is write a line to a log file with all the register values and some memory bytes after each instruction, and it automatically tells you where the first error is, what register or piece of memory is wrong, and even the last instruction to give you a hint as to the problem. This didn’t take much time to implement, but I did spend a considerable amount of time debugging, as previously I hadn’t actually got a way to check that my functions worked correctly (which is why this devlog has quite a few more hours on it). You can see an example of a error in the screenshot; I intentionally changed the SUB instruction to add instead because I forgot to take screenshots of the actual errors 🥀. Next time, I want to implement more of the CPU, especially more complex behaviours like halting and interrupts, and also implement some of the graphics, so that the games can actually be seen visually."}, {"post_id": 71263, "ts": "2026-09-20T15:22:40Z", "hours": 5.355, "text": "Devlog 4 - Memory mapping and instruction stepping The next thing I worked on was getting a basic function set up for stepping through instructions and calling the execute function. To do this, I also had to make a program counter, which is a 16 bit register storing the address of the next instruction. Currently, the step function is pretty barebones, but it simply calls the execute function, passes it the PC as a parameter, and then sets the program counter to be the returned address. The execute function has also been modified, meaning it reads the instruction from memory (more on that later) rather than being passed it directly, and return the address plus 1 to 3 bytes, depending on the instruction that was executed. The next bit I made was the Game Boy’s memory. This is simply an char array with 64K values, equivalent to 64KiB of memory. Then, any address can be accessed simply by accessing the array value at an address. After working on the other parts of the CPU, I went back to working on some instructions, implementing the rest of the disassembly tables , including the condition call table, which checks the flags register before executing an instruction. I also implemented some of the instructions that require inputting an address in memory to use instead of a number or register. Finally, I also worked on some quality of life features. First, I made a function to replace missing functions, which simply sends an error message with the function name, and quits with an error code. Secondly, I made / edited some functions to actually move the loaded ROM file into the main GB memory rather than the program memory. I had a little trouble troubleshooting this, as I didn’t at first have a reliable way to verify that the data had been copied successfully, and after I did, I still had trouble with pointers, as I am still pretty new to C’s manual memory management (I usually just keep things in the stack, or have global variables that will persist throughout the program’s lifetime.). I also added basic functionality for loading a ROM on desktop rather than the web, but it doesn’t use the system dialog yet, only loading a rom.gb file in the executable directory. After everything was working, I added a debug message to send the ROM’s header title, showing that it actually works. You can see this in the screenshot. It sends the message twice, once when the file is loaded, and once when it’s moved to GB memory, which I did to make sure that the transfer didn’t mess up the data accidentally."}, {"post_id": 68852, "ts": "2026-09-15T21:21:15Z", "hours": 3.9186, "text": "Devlog 3 - Algorithmically parsing opcodes After getting things functioning well in the browser, I wanted to move onto the actual emulator bit of the project. Firstly, I looked at a bunch of examples and info, mostly compiled from gbdev.io . At first, I followed both the development blog of Cinoop and the guide DMG-01 . I used these guides to first write the register struct, which is basically just a struct of bytes (in char form as I’m using C), as well as the flags register, which I took inspiration from DMG-01 by making it primarily a struct of 4 bools rather than a binary value, for easier setting. I also wrote functions for converting this into binary though so that I didn’t lose compatibility. Next, I used Decoding Gameboy Z80 Opcodes to write an algorithmic way to decide which instruction correlates to an opcode, instead of a large switch case (although admittedly it does have a lot of nested switch cases). Finally, I added in the “alu” table instructions as the first few instructions, which also happened to be quite simple as they were basically just addition, subtraction and some bitwise operations. Next, I plan to fill in the remaining instructions, add them all to the algorithm and get started on the actual control flow for the CPU"}, {"post_id": 47709, "ts": "2026-08-15T20:02:53Z", "hours": 3.5792, "text": "Devlog 2 - SDL3 and File Loading After setting up the project basics, I spent some time on another project, also using SDL, but a desktop app. This used SDL3 instead of SDL2, which is default for Emscripten. I decided to switch this project to SDL3 as well, since I feel more comfortable with it and it has some features like main callbacks that should help with Emscripten. Instead of using the SDL library bundled with Emscripten, I instead added the SDL3 repo as a submodule, so I should be able to make a desktop version of the program later relatively easily. After switching to SDL3, I researched how to load a file from the user in the web browser into the webasm program. I found a StackOverflow thread that helped a lot, which included a link to a more developed header library, however I opted not to use this, as it was C++ based, and I wanted to remain using C. Instead I just implemented the bits I needed from the thread in C, which wasn’t too hard, although included some JS, which I’ve never used and some pointers which I made a few stupid mistakes with, causing me to think it didn’t work for a while. Finally, I also added a keybind to open the file dialog, which currently is tab, and also made sure that the keys only register on the down press, and not the up as well."}, {"post_id": 29056, "ts": "2026-07-15T18:26:42Z", "hours": 3.6419, "text": "Devlog 1 - Setup and basic input I took a while to find a toolchain that I liked, but I’ve settled on using Emscripten, and it’s built in version of SDL2. Emscripten is a library and compiler for CXX that allows direct compilation to web assembly and JavaScript, also allowing graphics and input with SDL. This makes it a lot easier for me to write the program, as I don’t really need to know as much JS or find multiple different libraries to use. Originally I wanted to use SDL3, but I couldn’t get the input to work automatically with Emscripten, and with this being my first major C and web project, I decided to take the easier path and simply use the fully supported SDL2. I also spent some time setting up a simple CMake system and some scripts for building and running, which took me a while to figure out, especially as I was also learning Emscripten for the first time, however it will hopefully save me time in the long run. Just to test my implementation, I set up some keybinds for the eventual emulator to come. I just used SDL scancodes to check for the key press, and they printed the corresponding Gameboy button to the output. You can see this in the video below. For simplicity, I decided to just set keys in code, with WASD being the dpad, J being A, K being B, Return being Start and Backspace being select."}]...
|
Title: GBWeb by @Doodl0 | Stardance
Devlogs:
Devl Title: GBWeb by @Doodl0 | Stardance
Devlogs:
Devlog 1 - Setup and basic input I took a while to find a toolchain that I liked, but I’ve settled on using Emscripten, and it’s built in version of SDL2. Emscripten is a library and compiler for CXX that allows direct compilation to web assembly and JavaScript, also allowing graphics and input with SDL. This makes it a lot easier for me to write the program, as I don’t really need to know as much JS or find multiple different libraries to use. Originally I wanted to use SDL3, but I couldn’t get the input to work automatically with Emscripten, and with this being my first major C and web project, I decided to take the easier path and simply use the fully supported SDL2. I also spent some time setting up a simple CMake system and some scripts for building and running, which took me a while to figure out, especially as I was also learning Emscripten for the first time, however it will hopefully save me time in the long run. Just to test my implementation, I set up some keybinds for the eventual emulator to come. I just used SDL scancodes to check for the key press, and they printed the corresponding Gameboy button to the output. You can see this in the video below. For simplicity, I decided to just set keys in code, with WASD being the dpad, J being A, K being B, Return being Start and Backspace being select.
Devlog 2 - SDL3 and File Loading After setting up the project basics, I spent some time on another project, also using SDL, but a desktop app. This used SDL3 instead of SDL2, which is default for Emscripten. I decided to switch this project to SDL3 as well, since I feel more comfortable with it and it has some features like main callbacks that should help with Emscripten. Instead of using the SDL library bundled with Emscripten, I instead added the SDL3 repo as a submodule, so I should be able to make a desktop version of the program later relatively easily. After switching to SDL3, I researched how to load a file from the user in the web browser into the webasm program. I found a StackOverflow thread that helped a lot, which included a link to a more developed header library, however I opted not to use this, as it was C++ based, and I wanted to remain using C. Instead I just implemented the bits I needed from the thread in C, which wasn’t too hard, although included some JS, which I’ve never used and some pointers which I made a few stupid mistakes with, causing me to think it didn’t work for a while. Finally, I also added a keybind to open the file dialog, which currently is tab, and also made sure that the keys only register on the down press, and not the up as well.
Devlog 3 - Algorithmically parsing opcodes After getting things functioning well in the browser, I wanted to move onto the actual emulator bit of the project. Firstly, I looked at a bunch of examples and info, mostly compiled from gbdev.io . At first, I followed both the development blog of Cinoop and the guide DMG-01 . I used these guides to first write the register struct, which is basically just a struct of bytes (in char form as I’m using C), as well as the flags register, which I took inspiration from DMG-01 by making it primarily a struct of 4 bools rather than a binary value, for easier setting. I also wrote functions for converting this into binary though so that I didn’t lose compatibility. Next, I used Decoding Gameboy Z80 Opcodes to write an algorithmic way to decide which instruction correlates to an opcode, instead of a large switch case (although admittedly it does have a lot of nested switch cases). Finally, I added in the “alu” table instructions as the first few instructions, which also happened to be quite simple as they were basically just addition, subtraction and some bitwise operations. Next, I plan to fill in the remaining instructions, add them all to the algorithm and get started on the actual control flow for the CPU
Devlog 4 - Memory mapping and instruction stepping The next thing I worked on was getting a basic function set up for stepping through instructions and calling the execute function. To do this, I also had to make a program counter, which is a 16 bit register storing the address of the next instruction. Currently, the step function is pretty barebones, but it simply calls the execute function, passes it the PC as a parameter, and then sets the program counter to be the returned address. The execute function has also been modified, meaning it reads the instruction from memory (more on that later) rather than being passed it directly, and return the address plus 1 to 3 bytes, depending on the instruction that was executed. The next bit I made was the Game Boy’s memory. This is simply an char array with 64K values, equivalent to 64KiB of memory. Then, any address can be accessed simply by accessing the array value at an address. After working on the other parts of the CPU, I went back to working on some instructions, implementing the rest of the disassembly tables , including the condition call table, which checks the flags register before executing an instruction. I also implemented some of the instructions that require inputting an address in memory to use instead of a number or register. Finally, I also worked on some quality of life features. First, I made a function to replace missing functions, which simply sends an error message with the function name, and quits with an error code. Secondly, I made / edited some functions to actually move the loaded ROM file into the main GB memory rather than the program memory. I had a little trouble troubleshooting this, as I didn’t at first have a reliable way to verify that the data had been copied successfully, and after I did, I still had trouble with pointers, as I am still pretty new to C’s manual memory management (I usually just keep things in the stack, or have global variables that will persist throughout the program’s lifetime.). I also added basic functionality for loading a ROM on desktop rather than the web, but it doesn’t use the system dialog yet, only loading a rom.gb file in the executable directory. After everything was working, I added a debug message to send the ROM’s header title, showing that it actually works. You can see this in the screenshot. It sends the message twice, once when the file is loaded, and once when it’s moved to GB memory, which I did to make sure that the transfer didn’t mess up the data accidentally.
Devlog 5 - Adding instructions, the stack and lots of debugging After the last devlog, the first think I did was implement some more instructions, namely the jump instructions, and the increment and decrement functions. Luckily these were pretty simple; all the jumps do are set the program counter (effectively the next instruction) to a specified value, and the increment and decrement are pretty self explanatory, increasing or decreasing a register or memory byte by 1; After this, I started implementing the stack. The stack is a section of memory that is ordered, with values being written to it (pushed) and read off of it (popped). You must read the “top” value, meaning the most recently pushed, which is then removed and the next highest is the next available to read. This wasn’t too hard, although I did have to introduce a new register, the stack pointer (sp). While I was at it, I also implemented load functions, which load data into a specified memory byte or register. After realising it would cause issues down the line, I walked back my previous decision to make the flags register a struct of booleans, and instead made it a single byte with 4 bits representing the 4 flags, making it more accurate. I also made some functions to easily set or reset each flag, rather than use bitwise operations everywhere. Finally, I implemented logging support, so that I could use Gameboy Doctor , a brilliant debugging script that reads a log file from your emulator with a known ROM, and compares it to the correct result. All you have to do is write a line to a log file with all the register values and some memory bytes after each instruction, and it automatically tells you where the first error is, what register or piece of memory is wrong, and even the last instruction to give you a hint as to the problem. This didn’t take much time to implement, but I did spend a considerable amount of time debugging, as previously I hadn’t actually got a way to check that my functions worked correctly (which is why this devlog has quite a few more hours on it). You can see an example of a error in the screenshot; I intentionally changed the SUB instruction to add instead because I forgot to take screenshots of the actual errors 🥀. Next time, I want to implement more of the CPU, especially more complex behaviours like halting and interrupts, and also implement some of the graphics, so that the games can actually be seen visually.
Devlog 6 - An unfortunate amount of debugging This devlog is probably going to be shorter than the other, simply because I haven’t done as much as I hoped The main reason for this is that I got completely stuck on a bug, and wasted so much time trying to find it. I first noticed this bug when I got this error message (screenshot) in gameboy-doctor, with a mismatch with a load from memory not being the right value. This got me so stuck, because I didn’t know where to find when the memory was supposed to be written to, so I was basically blindly guessing what was wrong with any previous loads or register writes. Eventually, I caved and asked for help online, and I got my answer after asking on the EmuDev subreddit , where I found out it was an issue with my implementation of the LD (FF00+u8), A instructions, where I wrote LD_n16_n8((0xFF00 + address + 1), registers.a); instead of the correct LD_n16_n8((0xFF00 + ReadMemory(address + 1)), registers.a); so basically any writes to memory using that function were in the complete wrong location. Stupid mistake on my part, and I wasted way too much time on it. I also did implement some basic instructions, like EI and RETI. EI simply enables the emi register, and RETI basically just does that, then calls RET to return from a subroutine. In addition, I also restructured quite a lot of the code, as too much was piling up in the cpu.c file, and I also renamed quite a few functions to follow a Component_Function syntax, so it was easier to tell where they were located in the code
Devlog 7 - Timing The next main thing I implemented were some more instructions - namely SRL, RR, RRA and ADD HL. These weren’t too hard, as the first 3 are similar to regular bit shifts, and ADD HL is just adding. While I was working on these, I also fixed some bugs with the existing instructions This allowed me to finally pass the cpu_instrs 6 test ROM, which although not really a massive goal, did help to signify the progress I had made. I then moved onto the 7th test, for which I implemented some load functions for the stack pointer register The biggest improvement of this devlog was getting everything timing correctly. The Gameboy is supposed to run at 4.19 MHz and 59.7 FPS, but at the time, the emulator was just running as fast as possible. To solve this, I first made each instruction call a function to add the amount of cycles it takes to a unwaitedCycles variable. Then, I saved the current time in nanoseconds since the program started (provided by the SDL_GetTicksNS() function) into a variable at the start of an instruction’s execution. After the instruction is executed, a function is then called that finds the expected execution time the by doing the amount of cycles multiplied by the period of 4.19MHz (about 238 nanoseconds). This expected time is then subtracted from the actual time, which is the start time stored previously subtracted from the current time. The program is then delayed by the result, which should keep the CPU at around 4.19MHz, unless it takes too long. I did have some concerns with my emulator’s performance, as when running as a debug build, it wasn’t running nearly fast enough to reach 4.19MHz, but after compiling as a release build with optimisation, it was much faster and ran under the required time. However, I’m not sure how consistent this will be between devices, so I may have to optimise later Finally, I added a similar function to limit the FPS to around 60 (technically 59.7), which just checks the time since the last frame was rendered, and if it hasn’t been long enough, it continues CPU execution and doesn’t render. You can see the frame limit working in the screenshot, where the frametime is a consistent 16.8 ms and the FPS is locked to 60, as opposed to before where it was unlimited. (Ignore the text, it doesn’t change yet to show a ROM has been loaded)
Devlog 8 - Organisation, and timing, again Ok, so this didn’t exactly go how I wanted (again), but most of this devlog time was spent fixing the past devlog, and organising code in a better way Firstly: I realised that before, my timing code checked based on M-cycles, rather than T-cycles. There’s a specific reason for the distinction, but for now all you need to know is that there’s 4 T-cycles in an M-cycle, so my code was targeting a 4x faster speed. I changed this to be correct, but changed it again later so it doesn’t really matter. Then, I cleaned up a lot of cpu.c , changing functions to return values directly rather than using a local variable first, pre-calculating some variables, et cetera. This was an attempt to speed up the CPU, as I was having a bit of trouble meeting the target speed with debug builds (mentioned in devlog 7), but again, this was a bit pointless because I changed the way the timing worked later. While doing this, I also replaced all of the numerical types with their stdint.h counterparts; for example, an unsigned char became a Uint8 (SDL has macros for the stdint types, so they have a slight naming difference from standard C in my code). This was mainly done for specificity and some Hail Mary for performance (although fruitless), and should make the code at least a bit more portable and easy to maintain. I also implemented a couple of new instructions; RST and SWAP. RST effectively calls from a set of pre-specified addresses , and SWAP just swaps the upper and lower 8 bits in a byte, so these weren’t too hard. I also had to fix some bugs with the flags register´s value after an SBC A instruction, which admittedly did take me a while to fix because I basically banged my head against the wall to fix it. The main change in this devlog was switching the timing system (again). Previously, the CPU ran one instruction for each loop of the SDL_AppIterate function. After reading the documentation and realising that this function is supposed to run each frame, I realised that I was causing all of my speed issues by only doing one cycle per iteration. Instead, the code now does as many instructions as it can until it has run enough T-cycles for a full frame to render (70224). It then renders (to be implemented), and moves on to the next iteration. This is way more performant, and has the added benefit of being more cross-platform, as SDL specifies that sometimes AppIterate may only run at the refresh rate on some devices. Tbh, this took me a while, maybe too long, to conceptualise and implement, and basically made all of the time on the other timing system wasted, but in the end it was worth it for a much better system. You can see the uncapped FPS (in a debug build mind you) here, although when actually playing games, the framerate will be locked to around 60 FPS. Finally, there was a few more miscellaneous changes: copying a ROM file into memory uses memcpy instead of a loop, which may or may not be faster; memory is now a union of smaller arrays of memory banks, for each function, such as work ram (WRAM), high ram (HRAM), ROM banks 0-n and etc; and lastly, some register code has been moved out of cpu.c for organisation.
Devlog 9 - Basic graphics (finally) I’ve finally gotten some basic picture processing unit (PPU) functionality implemented into the emulator, which will hopefully make debugging a lot easier going forward. Firstly, to implement this, I had to move the timing logic out of cpu.c and into cycles.c . This was so that, when the loop calls a CPU step, it also calls a PPU step at the same time. I also refactored some of the cycle functions and removed the ones that were no longer being used Then, I implemented the timing code for the PPU. This part and the actual rendering were mostly based on this tutorial series that shows you how to make a GB emulator in javascript, which I based my C code on. Basically, the PPU runs on the clock as the CPU, and a ‘dot’ on the PPU is equal to a T-cycle on the CPU. The PPU renders progressively, like a CRT television, and so also has modes to move the nonexistent electron beam down and back to the start of a scanline before it continutes rendering, known as VBLANK and HBLANK, (vertical and horizontal blank). The Pan Docs were also quite helpful for understanding the basic functionality, although the tutorial was useful to understand the programmatic side. The PPU also has 2 other modes, used for scanning the Object Attribute Memory (OAM) and actually drawing, and all 4 modes have a precise amount of dots that they run for. In terms of actual rendering, the Gameboy doesn’t have a full framebuffer, and instead uses different tiles to create a full image. I implemented a function that, when the CPU writes to VRAM, also updates the data in a separate tileset variables, for easier access in the render pipeline. Each tile is 16 bytes, with 2 bits per pixel colour depth, and 8 x 8 pixels per tile. As the Gameboy renders progressively, I then implemented the function to draw a scanline to the screen, based on the tile data in the background layer. The afformentioned tutorial series helped a lot here, as the tiles need to have a specific offset and mapping applied which would be quite hard to figure out on my own. Then, that function calls a draw pixel function for each each of the 160 pixels in a scanline, which writes the corresponding colour from the palette to an SDL_Surface as the framebuffer. Once the frame is finished, the surface is converted into a texture, which is then scaled to fit the screen size and rendered, with another frame being made afterwards. Below you can see the screen of the previously mentioned blargg’s test ROM 7.
Devlog 10 - (basically) Finishing the CPU After the last devlog, I did some cleaning up with the graphics, which included fixing the last scanline not being rendered, and also adding a screen before the ROM is loaded, telling the user which key to press to load the ROM. I also set up some functions to allow easier access to the I/O registers related to the PPU, such as the x and y scroll and the control flags. Afterwards, I felt a bit burnt out of the PPU, so I went back to finish off most of the CPU. This started with implementing the CFL, CPL, CF, CPL, SCF, SLA, SRA, RL, RLA, RLC, RRC, RLCA, and RRCA instructions, most of which are bit rotations, so once I had a few implemented, it got easier to add the rest. This allowed me to pass CPU test ROM 9. Then, I implemented the rest of the CB prefix instructions, which were all bit related; BIT, RES and SET, which allowed me to pass ROM 10 After those, I implemented some stack pointer related instructions; ADD SP,d and LD HL SP+d, which then allowed me to pass ROM 3 Finally, I added DAA. This one is a bit more unique, as it is designed to convert the result of an add or subtract with binary coded decimal numbers, into a binary coded decimal number. This gets a bit complicated, but I used these resources ( Demystifying the GameBoy/SM83’s DAA Instruction and the RGBDS assembler/linker instruction documentation ) to implement this properly, allowing me to also pass test ROM 1 With a semi-functioning PPU, and some fixes, I was also able to boot into the copyright screen of Tetris for the first time, although I couldn’t get any further without implementing interrupts. The image below shows that, and my emulator passing all of the previously mentioned test ROMs. The only test ROM I haven’t passed yet is the 2nd one, which also requires interrupts....
|
1792587169.3497012
|
1793191969.3497012
|
|
44323
|
FormCheck by @cluelessfr | Stardance
|
cluelessfr
|
0
|
52.92
|
0
|
[]
|
[{"post_id": 81112, "ts": "202 [{"post_id": 81112, "ts": "2026-10-19T22:36:03Z", "hours": 6.5611, "text": "Devlog 14: I started preparing for the feedback. I am planning to mostly give feedback on timing/tempos, so I started adding some functions for that. The first thing I did was correct the scaling of video coordinates before calculating knee angles to ensure higher accuracy. Then I added a lowering-time estimator that looks for sustained movement instead of just angles at timestamps. I ensured to account for rectangular frames, leg switches, observation gaps, and timing integration. All tests passed. The next steps are actually providing feedback from this data, and then connecting this to the UI."}, {"post_id": 77869, "ts": "2026-10-08T16:33:46Z", "hours": 3.5961, "text": "Devlog 13: This devlog was mostly some final touches. I did add 3 things, though. The first of which is a frame progress display on the UI. This shows the user of many of the total frames have been processed after they start the analysis. Second, I added some text that was a disclaimer on the limitations of the analysis. The third thing I added was a reset between long gaps. So if the squat takes too long to get to the next state, then the detection resets and it starts looking for another starting squat. The first test I did was that I sampled different repetition intervals to determine which had the most detail but didn’t take too long to process. I landed on sampling frames every 250 Ms. Then I tested all the different UI states on the emulator using different videos. I then added tests for all the new features that I just mentioned to you. The next step is probably going to be actually implementing feedback."}, {"post_id": 75113, "ts": "2026-09-29T05:01:41Z", "hours": 8.2819, "text": "Devlog 12: I added some more meaningful upgrades this time. I added functionality so that the app could detect a real squat repetition. This works by combining this with the pose sequence analyzer, which contains poses and their timestamps. By mapping the angle formed by the hip, knee, and ankle at different intervals of the video, the app is able to detect if the angle got gradually lower, then gradually got higher. If these angles pass the thresholds needed to create a straight leg angle and a squatted down angle, then we can conclude that a squat repetition was performed. To accomplish this I added many different smaller functions, then combined them all together to get the final result. This allowed me to test each part individually to ensure they all worked. I also added this to the UI of the app, which you can see in the image. Finally I added real video validation, which basically means that I tested the current state of the app with a real video of a person doing a squat. The app was able to successfully recognize the repetition of the squat."}, {"post_id": 70842, "ts": "2026-09-19T21:02:38Z", "hours": 6.1419, "text": "Devlog 11: Now I added a few things. First I added a function that can sample frames at different intervals and stores the MediaPipe result with the timestamp of the frame. I also added hip/knee/ankle extraction for both sides and also confidence-based leg section. Codex wrote a few methods (2-3), and I wrote the rest. I then added timestamped knee angle measurements, and also connected the leg selector to the angle calculator. Finally, I added a sequence analyzer that keeps the valid measurements and skips the unclear frames. I added test for all these functions. There is a little more than this, but this is the gist of what I have been working on right now."}, {"post_id": 65756, "ts": "2026-09-11T03:20:19Z", "hours": 6.9169, "text": "Devlog 10: This time was some meaningful upgrades. First of all I added a function to extract a bitmap from a video given a timestamp. Then I added a separate function in order to convert that bitmap into an MPImage. This allows me to access it from anywhere. Finally I created a new class that combines the decoding, conversion, and pose processing tasks into one pipeline. I also added tests for all of these. Currently only one frame processes, but soon I will start to improve this."}, {"post_id": 63969, "ts": "2026-09-08T01:55:46Z", "hours": 8.5042, "text": "Devlog 09: Now the app stores the selected video’s Uri in an activity field, meaning it can be accessed for later processing instead of only the status text. Also frame timestamps can now be generated. This means that you can input the video duration as well as the interval that you want the timestamps to be generated, then you will get a set of timestamps for the video. The video metadata can also now be read. It uses Android’s MediaMetadataRetriever to open the video. Currently only the duration of the video can be retrieved, but later you will be able to decode individual frames. Finally I added tests for all of these. For the metadata retriever specifically I uploaded a test video to confirm that I could get an accurate measurement. Also updated the documentation."}, {"post_id": 47722, "ts": "2026-08-15T20:26:10Z", "hours": 3.5783, "text": "Devlog 08: I finally added the MediaPipe dependency, as well as a few functions. First of all I also added the Pose Landmarker Full model for it to actually detect poses. Then I created a manager function to initialize and close MediaPipe. I then added a function that could process an already decoded video frame with a timestamp using MediaPipe. I added tests for all of these to ensure they work when the app runs, and updated all the logs."}, {"post_id": 46085, "ts": "2026-08-13T01:19:04Z", "hours": 1.9819, "text": "Devlog 07: I changed the emulator from being on device to remote via Firebase. This allows me to test the app cleanly without lagging my computer. The only problem is I get a limited 30 minutes per month, so I have to use them wisely. I also updated the Point2D function to reject non-finite points. This prevents errors on the future. I also added a class that combines all the other functionality into one. It returns an OptionalDouble, which is useful when you don’t know if you are going to get a result. This new function accepts three LandmarkObservations, Then if the result is valid, it returns the angle degrees between the points. If not, it returns nothing."}, {"post_id": 44348, "ts": "2026-08-10T01:32:26Z", "hours": 1.3133, "text": "Devlog 06: I added the landmark quality gate, which helps determine whether the visibility and presence of the point meet the minimum requirements. If it does, then it passes. If it doesn’t, then the point fails. From here there are two options, either the app tries to find another point, or the app says it cannot reliably determine your form from that video I also added the AI use log. I mainly did this because I will be submitting this to the Congressional App Challenge."}, {"post_id": 44307, "ts": "2026-08-09T23:40:20Z", "hours": 1.0214, "text": "Devlog 05: Today I added landmark storage and reliability tests. What this is is basically a new object that can store a point, its visibility, and presence. The point is the point itself, the visibility says how well the object can be seen, and the presence determines how much of the object is actually in the video frame. These three factors help determine how well the video can be analyzed. If the video cannot be analyzed well enough, then FormCheck will send a message saying so (This hasn’t been implemented yet, but this is the basic idea of why this is there in the first place)."}, {"post_id": 43747, "ts": "2026-08-09T05:12:50Z", "hours": 1.1897, "text": "Devlog 04: I added functions for measuring the angle based on three points (the joints). Basically how this works is that it first takes in three points, the first endpoint, a vertex, and a second endpoint. Then it uses the dot product formula with the two vectors to find the angle between the two lines."}, {"post_id": 43080, "ts": "2026-08-08T04:48:16Z", "hours": 1.5214, "text": "Devlog 03: I added the file picking dialogue. Now whenever you click the “Select a video” button the android folder picker opens and you can choose a video. I think next is working on the actual pose detection logic."}, {"post_id": 42951, "ts": "2026-08-07T22:46:59Z", "hours": 1.3858, "text": "Devlog 02: I added the initial video selection interface. I added some text to describe the app, and a button for the user to be able to select a video to upload. Currently, the button does not do anything. Next I will have to continue working on the button and the actual pose estimation part of this."}, {"post_id": 41569, "ts": "2026-08-05T21:12:03Z", "hours": 0.9278, "text": "Devlog 01: This is the first devlog of the FormCheck project, an Android app that helps you check your form during workouts. Currently I just set everything up in Android Studio, connected Hackatime, and set up GitHub."}]...
|
Title: FormCheck by @cluelessfr | Stardance
Devlo Title: FormCheck by @cluelessfr | Stardance
Devlogs:
Devlog 01: This is the first devlog of the FormCheck project, an Android app that helps you check your form during workouts. Currently I just set everything up in Android Studio, connected Hackatime, and set up GitHub.
Devlog 02: I added the initial video selection interface. I added some text to describe the app, and a button for the user to be able to select a video to upload. Currently, the button does not do anything. Next I will have to continue working on the button and the actual pose estimation part of this.
Devlog 03: I added the file picking dialogue. Now whenever you click the “Select a video” button the android folder picker opens and you can choose a video. I think next is working on the actual pose detection logic.
Devlog 04: I added functions for measuring the angle based on three points (the joints). Basically how this works is that it first takes in three points, the first endpoint, a vertex, and a second endpoint. Then it uses the dot product formula with the two vectors to find the angle between the two lines.
Devlog 05: Today I added landmark storage and reliability tests. What this is is basically a new object that can store a point, its visibility, and presence. The point is the point itself, the visibility says how well the object can be seen, and the presence determines how much of the object is actually in the video frame. These three factors help determine how well the video can be analyzed. If the video cannot be analyzed well enough, then FormCheck will send a message saying so (This hasn’t been implemented yet, but this is the basic idea of why this is there in the first place).
Devlog 06: I added the landmark quality gate, which helps determine whether the visibility and presence of the point meet the minimum requirements. If it does, then it passes. If it doesn’t, then the point fails. From here there are two options, either the app tries to find another point, or the app says it cannot reliably determine your form from that video I also added the AI use log. I mainly did this because I will be submitting this to the Congressional App Challenge.
Devlog 07: I changed the emulator from being on device to remote via Firebase. This allows me to test the app cleanly without lagging my computer. The only problem is I get a limited 30 minutes per month, so I have to use them wisely. I also updated the Point2D function to reject non-finite points. This prevents errors on the future. I also added a class that combines all the other functionality into one. It returns an OptionalDouble, which is useful when you don’t know if you are going to get a result. This new function accepts three LandmarkObservations, Then if the result is valid, it returns the angle degrees between the points. If not, it returns nothing.
Devlog 08: I finally added the MediaPipe dependency, as well as a few functions. First of all I also added the Pose Landmarker Full model for it to actually detect poses. Then I created a manager function to initialize and close MediaPipe. I then added a function that could process an already decoded video frame with a timestamp using MediaPipe. I added tests for all of these to ensure they work when the app runs, and updated all the logs.
Devlog 09: Now the app stores the selected video’s Uri in an activity field, meaning it can be accessed for later processing instead of only the status text. Also frame timestamps can now be generated. This means that you can input the video duration as well as the interval that you want the timestamps to be generated, then you will get a set of timestamps for the video. The video metadata can also now be read. It uses Android’s MediaMetadataRetriever to open the video. Currently only the duration of the video can be retrieved, but later you will be able to decode individual frames. Finally I added tests for all of these. For the metadata retriever specifically I uploaded a test video to confirm that I could get an accurate measurement. Also updated the documentation.
Devlog 10: This time was some meaningful upgrades. First of all I added a function to extract a bitmap from a video given a timestamp. Then I added a separate function in order to convert that bitmap into an MPImage. This allows me to access it from anywhere. Finally I created a new class that combines the decoding, conversion, and pose processing tasks into one pipeline. I also added tests for all of these. Currently only one frame processes, but soon I will start to improve this.
Devlog 11: Now I added a few things. First I added a function that can sample frames at different intervals and stores the MediaPipe result with the timestamp of the frame. I also added hip/knee/ankle extraction for both sides and also confidence-based leg section. Codex wrote a few methods (2-3), and I wrote the rest. I then added timestamped knee angle measurements, and also connected the leg selector to the angle calculator. Finally, I added a sequence analyzer that keeps the valid measurements and skips the unclear frames. I added test for all these functions. There is a little more than this, but this is the gist of what I have been working on right now.
Devlog 12: I added some more meaningful upgrades this time. I added functionality so that the app could detect a real squat repetition. This works by combining this with the pose sequence analyzer, which contains poses and their timestamps. By mapping the angle formed by the hip, knee, and ankle at different intervals of the video, the app is able to detect if the angle got gradually lower, then gradually got higher. If these angles pass the thresholds needed to create a straight leg angle and a squatted down angle, then we can conclude that a squat repetition was performed. To accomplish this I added many different smaller functions, then combined them all together to get the final result. This allowed me to test each part individually to ensure they all worked. I also added this to the UI of the app, which you can see in the image. Finally I added real video validation, which basically means that I tested the current state of the app with a real video of a person doing a squat. The app was able to successfully recognize the repetition of the squat.
Devlog 13: This devlog was mostly some final touches. I did add 3 things, though. The first of which is a frame progress display on the UI. This shows the user of many of the total frames have been processed after they start the analysis. Second, I added some text that was a disclaimer on the limitations of the analysis. The third thing I added was a reset between long gaps. So if the squat takes too long to get to the next state, then the detection resets and it starts looking for another starting squat. The first test I did was that I sampled different repetition intervals to determine which had the most detail but didn’t take too long to process. I landed on sampling frames every 250 Ms. Then I tested all the different UI states on the emulator using different videos. I then added tests for all the new features that I just mentioned to you. The next step is probably going to be actually implementing feedback.
Devlog 14: I started preparing for the feedback. I am planning to mostly give feedback on timing/tempos, so I started adding some functions for that. The first thing I did was correct the scaling of video coordinates before calculating knee angles to ensure higher accuracy. Then I added a lowering-time estimator that looks for sustained movement instead of just angles at timestamps. I ensured to account for rectangular frames, leg switches, observation gaps, and timing integration. All tests passed. The next steps are actually providing feedback from this data, and then connecting this to the UI....
|
1792583275.8698568
|
1793188075.8698568
|
|
67984
|
supder by @allenlin0728 | Stardance
|
allenlin0728
|
0
|
0.36
|
0
|
[]
|
[{"post_id": 81116, "ts": "202 [{"post_id": 81116, "ts": "2026-10-19T23:13:05Z", "hours": 0.3614, "text": "Set spooder back up After realizing all my old components were a little fried, I bought replacements on amazon and replaced them. Additionally, I put in the esp32-s3 dev board, however I had to use double sided tape to mount it because the screw holes for the raspbery pi did not fit the dev board. after I finished this, I rewired the entire thing. However, I realised I rewired it wrong, where I made one leg have three pins in sequential order, like where FRH was 0, FRF was 1, and FRT was 2, instead of 0, 3, 6. I decided to fix this in code instead of hardware because it was cleaner anyways and easier to do Lastly I had to reroute the new wires for i2c. The accelerometer I bought never arrived so i will not be doing anything PID cause im too stupid and my old one was fried. Also because I don’t have enough time I probably won’t set up the led matrix very well and might not even work, i just want reinbursements for now. tomorrow I want to actually start testing my code and see if i have to still do the stupid homing of all my servos again, also because all my code is in arduino ide, it has not been logged, and I JUST set it up for stardance, but I was told hours do not matter for just hardware reinbursements. hopefully i will finish and not be in debt anymore"}]...
|
Title: supder by @allenlin0728 | Stardance
Devlog Title: supder by @allenlin0728 | Stardance
Devlogs:
Set spooder back up After realizing all my old components were a little fried, I bought replacements on amazon and replaced them. Additionally, I put in the esp32-s3 dev board, however I had to use double sided tape to mount it because the screw holes for the raspbery pi did not fit the dev board. after I finished this, I rewired the entire thing. However, I realised I rewired it wrong, where I made one leg have three pins in sequential order, like where FRH was 0, FRF was 1, and FRT was 2, instead of 0, 3, 6. I decided to fix this in code instead of hardware because it was cleaner anyways and easier to do Lastly I had to reroute the new wires for i2c. The accelerometer I bought never arrived so i will not be doing anything PID cause im too stupid and my old one was fried. Also because I don’t have enough time I probably won’t set up the led matrix very well and might not even work, i just want reinbursements for now. tomorrow I want to actually start testing my code and see if i have to still do the stupid homing of all my servos again, also because all my code is in arduino ide, it has not been logged, and I JUST set it up for stardance, but I was told hours do not matter for just hardware reinbursements. hopefully i will finish and not be in debt anymore...
|
1792468424.4133172
|
1793073224.4133172
|
|
69248
|
Life in the country by @Will_boss | Stardance
|
Will_boss
|
0
|
7.59
|
0
|
[]
|
[{"post_id": 81119, "ts": "202 [{"post_id": 81119, "ts": "2026-10-19T23:35:11Z", "hours": 1.8783, "text": "Hey so i started working on the lombering part with my axe and i made a trees, apples on the tree and made the tree’s health reduce each time i hit it with the axe. I made the tree change color using the materials in the inspector area"}, {"post_id": 80846, "ts": "2026-10-19T00:18:52Z", "hours": 2.7492, "text": "Hey I started working on the actions the player does and how it affects her environment. I made a plant scene, added some code to be able to plant seeds, I used tilemaplayer to craete land and use it to also be able to tail the soil with the hoe. Next i made the fishing rode work only in the water form If the action is activated on the ground a not fishing text will appear in your ternimal"}, {"post_id": 80517, "ts": "2026-10-17T23:40:18Z", "hours": 1.3072, "text": "In this section I was just coding in data and creating some global scripts that I need and made my player other animation like planting, watering, cutting and killing with her different tools"}, {"post_id": 80490, "ts": "2026-10-17T20:31:10Z", "hours": 1.6564, "text": "ated my player and level and made my player walk using animationPlayer and animation tree where the animationplayer hold all the actions of my player and animation tree plays those actions in the game"}]...
|
Title: Life in the country by @Will_boss | Stardan Title: Life in the country by @Will_boss | Stardance
Devlogs:
ated my player and level and made my player walk using animationPlayer and animation tree where the animationplayer hold all the actions of my player and animation tree plays those actions in the game
In this section I was just coding in data and creating some global scripts that I need and made my player other animation like planting, watering, cutting and killing with her different tools
Hey I started working on the actions the player does and how it affects her environment. I made a plant scene, added some code to be able to plant seeds, I used tilemaplayer to craete land and use it to also be able to tail the soil with the hoe. Next i made the fishing rode work only in the water form If the action is activated on the ground a not fishing text will appear in your ternimal
Hey so i started working on the lombering part with my axe and i made a trees, apples on the tree and made the tree’s health reduce each time i hit it with the axe. I made the tree change color using the materials in the inspector area...
|
1792475797.9623036
|
1793080597.9623036
|
|
562
|
Chess in Python Turtle 🐢 by @Mehmet | Stardance
|
Mehmet
|
1
|
7.0
|
80
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-16T21:01:01Z", "hours": 7.0, "multiplier": 12.05, "payout": 80, "blessing": "neutral", "text": "I built pure chess inside Python Turtle. The entire idea of making a fully fledged game in Python’s Turtle seemed absurd, but there is tangible proof now. I’m proud of how I handled the piece moving and square highlighting code snippets; those were really fun to work on. Here are some tests you can do to see if my project holds up: Try clicking outside the board to move a piece, and you’ll see that it doesn’t. Try moving a piece outside the board. Try moving kings to squares that opposing pieces see. Try double pushing pawns. Right now, I haven’t added en passant or castling, but a 99% fledged chess game inside Python Turtle is ready for you to play.", "repo": "https://github.com/SameRainbows/Python-Turtle-Chess", "demo": "https://github.com/SameRainbows/Python-Turtle-Chess/releases/tag/V1"}]...
|
[{"post_id": 8112, "ts": "2026 [{"post_id": 8112, "ts": "2026-06-13T15:19:39Z", "hours": 1.8964, "text": "Finally, I can say that I’ve built chess—fully fledged chess—in Python Turtle. I added check, checks, checkmates, and all the logic that makes them up. I also created a new function called has_legal_moves, which takes one parameter to see if the attacker is white. In total, I defined 11 functions back to back in the Python file. It seems funny, but that’s what was needed. Thank you, every1!"}, {"post_id": 7080, "ts": "2026-06-11T21:14:12Z", "hours": 0.5017, "text": "Added basic promotions when the pawns go to the opposite side (for now they default to only queen promotions, more coming soon) and right now started working on the final boss of chess programming… Checks and checkmates. Wish me luck!"}, {"post_id": 5677, "ts": "2026-06-09T15:40:24Z", "hours": 0.9253, "text": "Welcome back to my pit of inevitable doom, where I’m trying to build fully fledged chess inside pure Python turtle. This devlog is because I finally managed to get a glimpse of the sunlight and add the special moves and captures for pawns. Before right now, pawns could only move one step forward no matter the place, and they actually captured by going forward into the enemy. If you play chess, you know it’s not like that. I have now implemented the following: Two-step support for pawns going on their first move. Logic so that pawns cannot capture pieces directly in front of them. Support for pawns capturing pieces only on their front diagonals. Follow along if you want to see if I ever get out of this!!! :D"}, {"post_id": 2915, "ts": "2026-06-05T20:22:29Z", "hours": 0.9917, "text": "Added legal moves and support for the knight, king, rook and pawn. The bishop is on the way"}, {"post_id": 2776, "ts": "2026-06-05T16:03:50Z", "hours": 0.7839, "text": "Added coordinates for the chessboard with a new function called print_coordinates. I also added a bouncer function to check if a piece is trying to move to a square that has a piece of the same color. If it’s trying to capture its own piece, it doesn’t allow the move. I implemented this by creating a new function called is_legal_move."}, {"post_id": 2264, "ts": "2026-06-04T17:37:49Z", "hours": 1.1539, "text": "Created functions for repeated tasks."}, {"post_id": 980, "ts": "2026-06-02T19:18:29Z", "hours": 0.47, "text": "Making fully fledged chess inside Python Turtle."}]...
|
Title: Chess in Python Turtle 🐢 by @Mehmet | Stard Title: Chess in Python Turtle 🐢 by @Mehmet | Stardance
Devlogs:
Making fully fledged chess inside Python Turtle.
Created functions for repeated tasks.
Added coordinates for the chessboard with a new function called print_coordinates. I also added a bouncer function to check if a piece is trying to move to a square that has a piece of the same color. If it’s trying to capture its own piece, it doesn’t allow the move. I implemented this by creating a new function called is_legal_move.
Added legal moves and support for the knight, king, rook and pawn. The bishop is on the way
Welcome back to my pit of inevitable doom, where I’m trying to build fully fledged chess inside pure Python turtle. This devlog is because I finally managed to get a glimpse of the sunlight and add the special moves and captures for pawns. Before right now, pawns could only move one step forward no matter the place, and they actually captured by going forward into the enemy. If you play chess, you know it’s not like that. I have now implemented the following: Two-step support for pawns going on their first move. Logic so that pawns cannot capture pieces directly in front of them. Support for pawns capturing pieces only on their front diagonals. Follow along if you want to see if I ever get out of this!!! :D
Added basic promotions when the pawns go to the opposite side (for now they default to only queen promotions, more coming soon) and right now started working on the final boss of chess programming… Checks and checkmates. Wish me luck!
Finally, I can say that I’ve built chess—fully fledged chess—in Python Turtle. I added check, checks, checkmates, and all the logic that makes them up. I also created a new function called has_legal_moves, which takes one parameter to see if the attacker is white. In total, I defined 11 functions back to back in the Python file. It seems funny, but that’s what was needed. Thank you, every1!
Ships:
I built pure chess inside Python Turtle. The entire idea of making a fully fledged game in Python’s Turtle seemed absurd, but there is tangible proof now. I’m proud of how I handled the piece moving and square highlighting code snippets; those were really fun to work on. Here are some tests you can do to see if my project holds up: Try clicking outside the board to move a piece, and you’ll see that it doesn’t. Try moving a piece outside the board. Try moving kings to squares that opposing pieces see. Try double pushing pawns. Right now, I haven’t added en passant or castling, but a 99% fledged chess game inside Python Turtle is ready for you to play....
|
1792846203.5605648
|
1792932603.5605648
|
|
43700
|
ngarnsworthy.dev by @ngarnsworthy | Stardance
|
ngarnsworthy
|
0
|
30.82
|
0
|
[]
|
[{"post_id": 81120, "ts": "202 [{"post_id": 81120, "ts": "2026-10-19T23:38:02Z", "hours": 14.3867, "text": "I got lost in the sauce and went over 10hrs Done Switched to express Added index page Project showcase Started blog TODO Guest book Outlinks Styling Retrospective It has been nice returning to express.js. I feel React and other modern web development tools are useful but are also cumbersome for many projects. I overall have enjoyed my experience with this “older” tool-chain. It has taken away a lot of the unnecessary abstraction I have seen through react. It has also let me look into accessibility way more so my website can be as accessible as possible! Reasoning When I started work on Termsite I was ready to delete a lot of the project structure from my personal website as Termsite rebuilt that functionality in a even better way. I just ended up deleting everything and starting again from scratch lol, but I like this web concept way more overall!"}, {"post_id": 69141, "ts": "2026-09-16T13:34:43Z", "hours": 7.7217, "text": "Done Added persistent env that can be used to store values between commands. Commands ls: created, a command to see the files in your current directory cat: created, a command to look at the contents of a file cd: created, a command to change your directory theme: created, a command to change your theme to one of the valid themes help: improved, added new commands to help TODO Add more themes Create mobile friendly interaction Create accessible interaction"}, {"post_id": 65025, "ts": "2026-09-09T20:36:07Z", "hours": 8.7106, "text": "Created a fake web terminal interface with each command running without state. Created the following test commands : help , startup, error. The error command is used when a command is not found. The startup command is ran on start and can be used to output usage information and setup state (when that is implemented). The help command outputs help information on all commands."}]...
|
Title: ngarnsworthy.dev by @ngarnsworthy | Stardan Title: ngarnsworthy.dev by @ngarnsworthy | Stardance
Devlogs:
Created a fake web terminal interface with each command running without state. Created the following test commands : help , startup, error. The error command is used when a command is not found. The startup command is ran on start and can be used to output usage information and setup state (when that is implemented). The help command outputs help information on all commands.
Done Added persistent env that can be used to store values between commands. Commands ls: created, a command to see the files in your current directory cat: created, a command to look at the contents of a file cd: created, a command to change your directory theme: created, a command to change your theme to one of the valid themes help: improved, added new commands to help TODO Add more themes Create mobile friendly interaction Create accessible interaction
I got lost in the sauce and went over 10hrs Done Switched to express Added index page Project showcase Started blog TODO Guest book Outlinks Styling Retrospective It has been nice returning to express.js. I feel React and other modern web development tools are useful but are also cumbersome for many projects. I overall have enjoyed my experience with this “older” tool-chain. It has taken away a lot of the unnecessary abstraction I have seen through react. It has also let me look into accessibility way more so my website can be as accessible as possible! Reasoning When I started work on Termsite I was ready to delete a lot of the project structure from my personal website as Termsite rebuilt that functionality in a even better way. I just ended up deleting everything and starting again from scratch lol, but I like this web concept way more overall!...
|
1792558281.4008505
|
1793163081.4008505
|
|
66919
|
Babio-Ware by @squidman | Stardance
|
squidman
|
0
|
22.26
|
0
|
[]
|
[{"post_id": 81121, "ts": "202 [{"post_id": 81121, "ts": "2026-10-19T23:45:45Z", "hours": 1.4011, "text": "Big props if you can guess what I’m making, mostly because I don’t really know myself. I didn’t really have any ideas today so I made this hand thingy. My plan is to have you pick up stuff. A very fun job. Given. To you. By me. I don’t know how to make a joke here. Anyway, probably more actual content tomorrow. Other than that, I worked a bit on making other systems actually work like I wanted them to. Although I should really just keep making more stuff before I go back to old stuff."}, {"post_id": 80854, "ts": "2026-10-19T01:00:03Z", "hours": 1.0289, "text": "I decided that the drawing wouldn’t really make for a good minigame, so, now introducing… Babio Paint! A very original and in development idea. I’m sure this is what all of us were desperately asking for, so don’t get all your eggs in a knot. Either way, Babio liked this idea SO MUCH, he asked for another button of his face, and now expects even more “eastered eggs” out of me. Cya!"}, {"post_id": 80841, "ts": "2026-10-18T23:49:25Z", "hours": 0.9094, "text": "While trying to code a way to cut 2D images into pieces, I accidentally made it so that you can draw? I guess I can actually make this into two minigames now so be fortunate for our happy accidents. Nevertheless, the little code snipper in the first two seconds is all of this scene so feel free to copy that if you want to do something with this. Babio says I shouldn’t share “company secrets” but it’s okay to break the rules sometimes, right?"}, {"post_id": 80518, "ts": "2026-10-17T23:55:07Z", "hours": 0.4031, "text": "Ok, so, there I was, hard at work and hardly working, when all of a sudden my manager, Mr. Babio, checks up on me. Kindly, he says “let me use your laptop for a sec, chump.” Now, I am not intimidated by someone who is 3’1” (94cm), but I didn’t feel like losing my job. So, in my infinite kindness, I handed it to him. However, upon receiving my laptop back, I was told by VSCode this bug, that my globals didn’t have a definition for “SpriteBatch.” Now, I wrote the code so I knew that it was called sb, which is why I typed sb, which is why I am utterly baffled at this bug. How on earth is it telling me that the bug is on the line where it literally isn’t? So, being upset, I immediately went straight back to Mr. Babio’s office to beat on him, meaning I cowered and politely asked what he could’ve done to my laptop. He tells me that he doesn’t know, and he “only wrote a few lines testing”, which isn’t true, because he just took it and stared at the screen for half an hour. Nevertheless, you can imagine my then and continued confusion when I was told by the terminal that there is an imaginary bug. This can only mean I am fighting fourth dimensional entities I cannot perceive, which is good content for a minigame, so maybe expect that. Content drops will return once I beat these beings and find my way back to the IDE."}, {"post_id": 80262, "ts": "2026-10-17T00:17:31Z", "hours": 0.3347, "text": "As far as news today goes… I hope that puns are good enough! If you can call them that. Either way, no need to wagyuu any fingers at me. Orange you glad you get to cook food in Babio Ware™? Are the jokes too corny for you? But you can’t be shellfish about it because I’m doing it for brie! Alright, alright… I walnut make any more food puns. I think this minigame will be pretty fun dough."}, {"post_id": 80059, "ts": "2026-10-16T03:21:44Z", "hours": 0.3006, "text": "I guess it’s a bit hard for me to get work done right now. A bit tired, had stuff to do. Sorry for a bad devlog today. You’re amazing, and you make Babio proud."}, {"post_id": 79669, "ts": "2026-10-15T00:51:58Z", "hours": 0.7761, "text": "Apparently, you AREN’T supposed to name your variables sentences. Babio informed me of this during his routine check in. He said, “if you don’t add at least 3 more demon types, you are fired!!!!” Which would be nice if “fired” meant I get be ignited and burn. But no, it means that I have to lose my game. No thanks Mr. Babio. That means 15 more frames of demons are coming soon."}, {"post_id": 79452, "ts": "2026-10-14T02:02:20Z", "hours": 0.4758, "text": "Okay, so basically, this is what it’s like in hell. And that’s the truth, love it or hate it. Yep, Neddy really is the Devil. I’d know, Babio and I went to hell on a trip to find a Toys R Us back in 2022, but it turns out they’d all shut down I thinks. Long story short, pokemon cards were on 75% sale and I managed to snag like a ton of boxes. Babio got nothing because he was broke, but he’s rolling in it after all the promotions. This minigame is a very accurate representation of a moment on our journey into hell, or as Babio said “tartarus.” Well Babio, the only “tar tar” I know is steak, and it’s pretty gross."}, {"post_id": 79449, "ts": "2026-10-14T01:26:55Z", "hours": 0.9703, "text": "I don’t have the energy for any puns or absurdity today. I added some sound effects, more stuff, 5/50 minigames are basically complete. When #50 is done the game will be public and free. Then I’ll just keep uploading minigames as updates from there. Please understand squids can get tired too… But hey, I understand the SoundEffect class as well as I can now, I think."}, {"post_id": 79081, "ts": "2026-10-12T16:16:29Z", "hours": 0.9586, "text": "Added a SUPER EVIL DEMON to be killed. The bullets aren’t really implemented yet but for some reason everything is becoming super jiggly. Babio was the one who said we needed animations because “who want’s to play a game with a bunch of static images”, but apparently these aren’t good enough? You let me know."}, {"post_id": 78903, "ts": "2026-10-11T23:55:52Z", "hours": 1.3467, "text": "It may not look it right now, but soon enough scary demons will come from this pit. They’re from when Babio tried to summon these unsavory creatures. No jokes today pal, it’s serious time."}, {"post_id": 78204, "ts": "2026-10-09T23:28:49Z", "hours": 0.6861, "text": "Apparently you need to make something a sound effect to adjust the pitch. I was teething with rage. (not typo). (it’s in context) (it makes sense if you know the context) (it’s because the joke is funny if you get the context). So making it an instance of a sound effect lets me make the pitch go up and down. Coming soon to the cinema, you can hear the blessed sounds of Babio’s game oscillating between a high and low pitch."}, {"post_id": 77961, "ts": "2026-10-09T00:04:08Z", "hours": 0.4828, "text": "Soon Babio will have me cooking his food. He really likes steak, raw on one side and well done on the other. No salt and heaps of mayo. Lookout for this, Babio might soon want you in his kitchen making some food for him. And the last time I was in there it had a little bit of an infestation problem, some roaches some mice, nothing a good chef can’t handle. No? I don’t really have a photo though. I also added a criminal to the court, but I might get a cheeky takedown so don’t expect this auspicious kind individual to remain."}, {"post_id": 77712, "ts": "2026-10-08T01:21:44Z", "hours": 1.1456, "text": "Apparently I’ve worked for like some friggin 1hr 8m, I didn’t know that. So allegedly, Babio likes basket ball. So I thought, logically, where do people play basketball? That’s right, the courthouse. My last time in court for vehicular manslaughter did NOT end well, so this time the judge (YOU 🫵🫵🫵) will decide who is guilty by “shooting hoops” and “shredding gnar.” Unfortunately, as a 96 year old man living in Wisconsin, I am no longer able to do these things, so please live out my dream for me."}, {"post_id": 77459, "ts": "2026-10-07T02:36:36Z", "hours": 0.3264, "text": "A lot of people think Babio won’t put his food in the game, but this actually very far from the truth. Babio’s food is what gives you the magic ability to survive any situation (but only once per food!!!!), which is actually how I survived many days out with Babio. So whenever you don’t die forever because you lost in a minigame, just remember to thank Babio’s snacks for the mystical magical marvelous mysterious market? I don’t know I ran out of M words, does anyone know any M-words? Anyway, Squid On."}, {"post_id": 77418, "ts": "2026-10-06T21:55:14Z", "hours": 1.1264, "text": "The courtroom is coming… and babio STILL hasn’t said thank you! Can you believe it?!? I code a whole game for this guy and he just asks for more. Apparently you get to judge people and you have to get 3 correct in 6 seconds or you fail or something. I don’t know."}, {"post_id": 76915, "ts": "2026-10-05T02:27:19Z", "hours": 2.5156, "text": "Apparently, when you pay TOO much for heat, they light your house on fire. This happened to Babio true story. We also met CeeLo that same day. This minigame is based off that day, where Babio and I put out the fires in his house. CeeLo will be added into the minigame too, soon."}, {"post_id": 76771, "ts": "2026-10-04T15:08:52Z", "hours": 0.6372, "text": "Today I spent a couple minutes to add Babio’s hands. Don’t hit them or else Babio gets pretty angry (spoiler, they turn RED in ANGER.) Babio said he was pleased, but this minigame needs a bit more polish before I can move onto the next."}, {"post_id": 76469, "ts": "2026-10-03T16:55:11Z", "hours": 1.5194, "text": "added some funny curtains because who doesn’t like curtains? I don’t have a picture, babio told me they look like bad. here is a picture of the curtain tho, thank you google"}, {"post_id": 76286, "ts": "2026-10-03T02:40:05Z", "hours": 1.7258, "text": "Implemented Babio’s flies better, now they can die, and they can move, and you can hit them. Babio wants me to add a cool number that floats when you hit them, so I will work on that next, and then after that he tells me I must work on the scene transitions so it doesn’t just cut. You ask for too much Mr. Babio, but it will be done."}, {"post_id": 76025, "ts": "2026-10-02T03:21:06Z", "hours": 3.1925, "text": "Today, Babio told me to make him a fly game, so I did. I coded it in an hour, and Babio was not happy with the quality, so I will continue with my work on it later to help Babio make his game. (Made in Monogame)"}]...
|
Title: Babio-Ware by @squidman | Stardance
Devlog Title: Babio-Ware by @squidman | Stardance
Devlogs:
Today, Babio told me to make him a fly game, so I did. I coded it in an hour, and Babio was not happy with the quality, so I will continue with my work on it later to help Babio make his game. (Made in Monogame)
Implemented Babio’s flies better, now they can die, and they can move, and you can hit them. Babio wants me to add a cool number that floats when you hit them, so I will work on that next, and then after that he tells me I must work on the scene transitions so it doesn’t just cut. You ask for too much Mr. Babio, but it will be done.
added some funny curtains because who doesn’t like curtains? I don’t have a picture, babio told me they look like bad. here is a picture of the curtain tho, thank you google
Today I spent a couple minutes to add Babio’s hands. Don’t hit them or else Babio gets pretty angry (spoiler, they turn RED in ANGER.) Babio said he was pleased, but this minigame needs a bit more polish before I can move onto the next.
Apparently, when you pay TOO much for heat, they light your house on fire. This happened to Babio true story. We also met CeeLo that same day. This minigame is based off that day, where Babio and I put out the fires in his house. CeeLo will be added into the minigame too, soon.
The courtroom is coming… and babio STILL hasn’t said thank you! Can you believe it?!? I code a whole game for this guy and he just asks for more. Apparently you get to judge people and you have to get 3 correct in 6 seconds or you fail or something. I don’t know.
A lot of people think Babio won’t put his food in the game, but this actually very far from the truth. Babio’s food is what gives you the magic ability to survive any situation (but only once per food!!!!), which is actually how I survived many days out with Babio. So whenever you don’t die forever because you lost in a minigame, just remember to thank Babio’s snacks for the mystical magical marvelous mysterious market? I don’t know I ran out of M words, does anyone know any M-words? Anyway, Squid On.
Apparently I’ve worked for like some friggin 1hr 8m, I didn’t know that. So allegedly, Babio likes basket ball. So I thought, logically, where do people play basketball? That’s right, the courthouse. My last time in court for vehicular manslaughter did NOT end well, so this time the judge (YOU 🫵🫵🫵) will decide who is guilty by “shooting hoops” and “shredding gnar.” Unfortunately, as a 96 year old man living in Wisconsin, I am no longer able to do these things, so please live out my dream for me.
Soon Babio will have me cooking his food. He really likes steak, raw on one side and well done on the other. No salt and heaps of mayo. Lookout for this, Babio might soon want you in his kitchen making some food for him. And the last time I was in there it had a little bit of an infestation problem, some roaches some mice, nothing a good chef can’t handle. No? I don’t really have a photo though. I also added a criminal to the court, but I might get a cheeky takedown so don’t expect this auspicious kind individual to remain.
Apparently you need to make something a sound effect to adjust the pitch. I was teething with rage. (not typo). (it’s in context) (it makes sense if you know the context) (it’s because the joke is funny if you get the context). So making it an instance of a sound effect lets me make the pitch go up and down. Coming soon to the cinema, you can hear the blessed sounds of Babio’s game oscillating between a high and low pitch.
It may not look it right now, but soon enough scary demons will come from this pit. They’re from when Babio tried to summon these unsavory creatures. No jokes today pal, it’s serious time.
Added a SUPER EVIL DEMON to be killed. The bullets aren’t really implemented yet but for some reason everything is becoming super jiggly. Babio was the one who said we needed animations because “who want’s to play a game with a bunch of static images”, but apparently these aren’t good enough? You let me know.
I don’t have the energy for any puns or absurdity today. I added some sound effects, more stuff, 5/50 minigames are basically complete. When #50 is done the game will be public and free. Then I’ll just keep uploading minigames as updates from there. Please understand squids can get tired too… But hey, I understand the SoundEffect class as well as I can now, I think.
Okay, so basically, this is what it’s like in hell. And that’s the truth, love it or hate it. Yep, Neddy really is the Devil. I’d know, Babio and I went to hell on a trip to find a Toys R Us back in 2022, but it turns out they’d all shut down I thinks. Long story short, pokemon cards were on 75% sale and I managed to snag like a ton of boxes. Babio got nothing because he was broke, but he’s rolling in it after all the promotions. This minigame is a very accurate representation of a moment on our journey into hell, or as Babio said “tartarus.” Well Babio, the only “tar tar” I know is steak, and it’s pretty gross.
Apparently, you AREN’T supposed to name your variables sentences. Babio informed me of this during his routine check in. He said, “if you don’t add at least 3 more demon types, you are fired!!!!” Which would be nice if “fired” meant I get be ignited and burn. But no, it means that I have to lose my game. No thanks Mr. Babio. That means 15 more frames of demons are coming soon.
I guess it’s a bit hard for me to get work done right now. A bit tired, had stuff to do. Sorry for a bad devlog today. You’re amazing, and you make Babio proud.
As far as news today goes… I hope that puns are good enough! If you can call them that. Either way, no need to wagyuu any fingers at me. Orange you glad you get to cook food in Babio Ware™? Are the jokes too corny for you? But you can’t be shellfish about it because I’m doing it for brie! Alright, alright… I walnut make any more food puns. I think this minigame will be pretty fun dough.
Ok, so, there I was, hard at work and hardly working, when all of a sudden my manager, Mr. Babio, checks up on me. Kindly, he says “let me use your laptop for a sec, chump.” Now, I am not intimidated by someone who is 3’1” (94cm), but I didn’t feel like losing my job. So, in my infinite kindness, I handed it to him. However, upon receiving my laptop back, I was told by VSCode this bug, that my globals didn’t have a definition for “SpriteBatch.” Now, I wrote the code so I knew that it was called sb, which is why I typed sb, which is why I am utterly baffled at this bug. How on earth is it telling me that the bug is on the line where it literally isn’t? So, being upset, I immediately went straight back to Mr. Babio’s office to beat on him, meaning I cowered and politely asked what he could’ve done to my laptop. He tells me that he doesn’t know, and he “only wrote a few lines testing”, which isn’t true, because he just took it and stared at the screen for half an hour. Nevertheless, you can imagine my then and continued confusion when I was told by the terminal that there is an imaginary bug. This can only mean I am fighting fourth dimensional entities I cannot perceive, which is good content for a minigame, so maybe expect that. Content drops will return once I beat these beings and find my way back to the IDE.
While trying to code a way to cut 2D images into pieces, I accidentally made it so that you can draw? I guess I can actually make this into two minigames now so be fortunate for our happy accidents. Nevertheless, the little code snipper in the first two seconds is all of this scene so feel free to copy that if you want to do something with this. Babio says I shouldn’t share “company secrets” but it’s okay to break the rules sometimes, right?
I decided that the drawing wouldn’t really make for a good minigame, so, now introducing… Babio Paint! A very original and in development idea. I’m sure this is what all of us were desperately asking for, so don’t get all your eggs in a knot. Either way, Babio liked this idea SO MUCH, he asked for another button of his face, and now expects even more “eastered eggs” out of me. Cya!
Big props if you can guess what I’m making, mostly because I don’t really know myself. I didn’t really have any ideas today so I made this hand thingy. My plan is to have you pick up stuff. A very fun job. Given. To you. By me. I don’t know how to make a joke here. Anyway, probably more actual content tomorrow. Other than that, I worked a bit on making other systems actually work like I wanted them to. Although I should really just keep making more stuff before I go back to old stuff....
|
1792464478.7713704
|
1793069278.7713704
|
|
69065
|
Having fun messing with Godot Networking by @Flame Having fun messing with Godot Networking by @FlameWing | Stardance...
|
FlameWing
|
1
|
6.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-20T00:52:46Z", "hours": 6.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Pretty simple Godot game that shows the concepts of Godot’s networking tools. Simple host/join, with player data syncing across clients. Simple chatting, and spawning physics bodies. Also, local server broadcasting to easily join servers hosted on your local network. One of the first times I used Godot, and had a fun time learning the technical side of it. Got to learn how to use both Godot’s High Level Multiplayer, and Godot’s lower level networking to handle local broadcasting.", "repo": "https://github.com/FlameWing-Code/Godot-Networking-Testing", "demo": "https://github.com/FlameWing-Code/Godot-Networking-Testing/releases/tag/v1"}]...
|
[{"post_id": 81125, "ts": "202 [{"post_id": 81125, "ts": "2026-10-19T23:50:39Z", "hours": 3.1672, "text": "Added local server broadcasting When you host a game, it will constantly send a small packet to 255.255.255.255, which gets sent to every device in the local network. Its a small little packet that simply contains the server’s username and the port their hosting on. Clients can pick up this packet, and it gets displayed so you can join easily. Had to rely on godot’s lower level networking, compared to the rest of the project."}, {"post_id": 78633, "ts": "2026-10-11T04:19:44Z", "hours": 2.6972, "text": "Got chat and usernames working"}]...
|
Title: Having fun messing with Godot Networking by Title: Having fun messing with Godot Networking by @FlameWing | Stardance
Devlogs:
Got chat and usernames working
Added local server broadcasting When you host a game, it will constantly send a small packet to 255.255.255.255, which gets sent to every device in the local network. Its a small little packet that simply contains the server’s username and the port their hosting on. Clients can pick up this packet, and it gets displayed so you can join easily. Had to rely on godot’s lower level networking, compared to the rest of the project.
Ships:
Pretty simple Godot game that shows the concepts of Godot’s networking tools. Simple host/join, with player data syncing across clients. Simple chatting, and spawning physics bodies. Also, local server broadcasting to easily join servers hosted on your local network. One of the first times I used Godot, and had a fun time learning the technical side of it. Got to learn how to use both Godot’s High Level Multiplayer, and Godot’s lower level networking to handle local broadcasting....
|
1792857218.9583044
|
1792943618.9583044
|
|
46895
|
Wi-Fi Latency Analyzer by @aaryan_s | Stardance
|
aaryan_s
|
0
|
33.63
|
0
|
[]
|
[{"post_id": 81126, "ts": "202 [{"post_id": 81126, "ts": "2026-10-19T23:56:01Z", "hours": 3.4781, "text": "• Day 21 – Modern GUI and FlatLaf Setup – 10/19 • I installed FlatLaf, an open source java library for Java Swing applications . The goal with FlatLaf is to slowly “modernize” my app and overall make it look a lot more appealing to the user compared to it’s old basic java swing vibe. I struggled a lot with implementing FlatLaf and connecting it to my java swing application in VsCode, so I had to use some AI to figure out how to install FlatLat onto VsCode on a Windows desktop. I made a seperate folder called “Lib” and added the FlatLaf download file. For now, I have the core ping functionality/logic down, the basic GUI, and my next steps are clear: I want to have a working, publicly appealing app. Hopefully I can submit this into the Congressional App Challenge within the next week! • P.S: Starting from this post, from now on, I am beginning to change the format of my Devlogs. Originally, they were very structured and bullet pointed. However, after double checking StarDance guidelines for a proper post, I want to make my posts more understandable and readable starting now. Thank you!"}, {"post_id": 74297, "ts": "2026-09-27T04:19:12Z", "hours": 3.1344, "text": "Day 20 — UI Polish & APP Refinement/Debugging Further developed the UI to be more presentable to users: Consistent color theme: light background, blue primary color, dark text, and light-gray section backgrounds Improved the title section with a larger blue title and a subtitle describing the application’s purpose. Redesigned the test configuration section by grouping the DNS target, number of tests, and delay controls into a single bordered panel. o Added recognizable DNS provider names to the target dropdown, such as Cloudflare and Google, instead of displaying only IP addresses. Added a clean border and light-gray background to test configuration panel to match Live Results section. Improved Start Test button, including styling and a play-button icon. Worked on removing the default blue selection highlighting from the dropdown and customizing it renderer/colors. Redesigned LIVE RESULTS so it appears as a proper section heading above a bordered results box rather than relying on Swing’s default titled border. Added light-gray background + border to the Live Results panel for consistent dashboard-like appearance. Learned more about Swing layouts, panels, borders, colors, renderers, component alignment, etc. Core functionality is now running, with the desktop application connected to the existing ping backend and displaying latency statistics."}, {"post_id": 73738, "ts": "2026-09-25T20:14:06Z", "hours": 2.8808, "text": "Day 19 — Connecting the Desktop Application Connected the GUI to the existing src.ping() backend o Integrated calculations for average latency, min/max latency, packet loss, and jitter Added user input for number of tests and delay between tests o Added input validation for test count and delay values Used ArrayList to store multiple ping results Connected the calculated results to the GUI’s live result labels Learned why Double.MAX_VALUE is useful when calculating a minimum value and how Thread.sleep() creates the delay between tests Next: Test the full workflow, fix any bugs, and make the GUI responsive before moving toward final polish/shipping :DD"}, {"post_id": 73378, "ts": "2026-09-25T01:24:33Z", "hours": 1.4611, "text": "Day 18 - Desktop UI & Connecting the Program · Connected the UI to the existing src.java ping functionality · Connecting public classes and calling methods from src.java · Changed ping() to be accessible from the UI - Learned how classes communicate with each other · Learned how LatencyAnalyzerWindow → src.ping() → PingResult → GUI works · Crucial for connecting jitter, packet loss, etc. later · Kept latency stored as a double and only formatted it for display 3 days left, with ~6–7 hours planned to finish, test, and polish the project :D"}, {"post_id": 72860, "ts": "2026-09-23T21:36:03Z", "hours": 3.9839, "text": "Day 17 – Beginning the Desktop App Interface 1. Core program: (everything I have been doing thus far): o Improved name input validation, including rejecting blank/space-only names. o Made the name switch case-insensitive using .toLowerCase() 2. Desktop App: o Began building a Java desktop app version of my Wi‑Fi Latency Analyzer using Java Swing · Created LatencyAnalyzerWindow.java, which opens a real application window o Learned the purpose of Swing components such as JFrame, JPanel, JLabel, JButton o Added a target-selection dropdown with Cloudflare and Google DNS options · Added fields for the number of tests and delay between tests o Added a Start Test button and status message area o Added Live Results section, placeholders for latency, average latency, packet loss, and jitter · Edited the ReadMe to better reflect status of project and AI usage during the project · Planned to connect the interface to real ping data next"}, {"post_id": 72396, "ts": "2026-09-22T20:29:12Z", "hours": 3.64, "text": "Day 15/16 - Debugging, Jitter, Project Organization 15: · Reorganized my programming workspace so each project has a folder · Set up a “Coding Projects” folder to keep my future projects under one large folder · Kept my Wi‑Fi Latency Analyzer in its own project folder o its Java code, README, license, and VS Code settings stay together · Created separate Java Practice folder for smaller programs that help me practice Java concepts · Reviewed the project files and learned what each one is used for · Found and removed an empty unused Java folder from the project · Made sure my project folders are synced and accessible through OneDrive · Overall, continued building good habits for keeping my code organized, separate, and easy to find 16: · Removed duplicate for loop that was double-counting successful latency data · Added jitter to the Wi-Fi Latency Analyzer o Learned to calculate jitter by comparing each successful ping to the previous successful ping o Used Math.abs() to find the absolute latency difference · Added handling for cases where jitter can’t be calculated, displaying N/A (if/else) · Tested multiple cases to make sure the new jitter calculations and edge cases worked correctly"}, {"post_id": 60617, "ts": "2026-09-03T02:20:12Z", "hours": 0.8453, "text": "Day 14 – Terminal Readability / Debugging (Continuation of Day 13) · Made average/min/max display N/A when there are no successful tests o Improved failed-test output so failed pings don’t misleadingly show 0 ms · Fixed the test-number display (TEST 1 OF 2, TEST 2 OF 2) · Fixed the duplicate results caused by nested loops (loop within another loop) · Tested failed hostnames and verified that it results in a 100% packet loss · Kept debugging messages temporarily · Deferred method refactoring for later"}, {"post_id": 60010, "ts": "2026-09-02T03:14:31Z", "hours": 0.9733, "text": "Day 13 – Readability / Displaying Clean Info on User Terminal · Improved the readability of individual ping results by labeling each test (TEST 1 OF 2, TEST 2 OF 2, etc.) o Fixed the successful-test counter so successful tests are counted correctly · Fixed the duplicate test display caused by accidentally using nested loops (loop inside of another loop) · Added the foundation for minimum and maximum latency calculations · Added success/failure, total latency, + min/max latency analysis into stored results analysis section · Fixed a variable declaration issue with totalLatency and successfulLatencyTests (order matters in code) · Overall: Day 13 focused on making the output cleaner and turning the stored ping data into more useful statistics"}, {"post_id": 59281, "ts": "2026-08-31T23:56:46Z", "hours": 0.7761, "text": "Day 12 – Formatting and Proper Displaying of Data – 8/31/26 · Added packet-loss formatting using printf to display percentages to 2 decimal places. o Improved the final ping-test summary for readability. · Verified the program correctly calculates and displays: o Successful tests o Failed tests o Packet loss o Average latency · Debugged an issue where the old println formatting was still being used. · Learned how Java printf formatting works, including %.2f, %%, and %n. · Chose to postpone additional rounding/refinement work until later if needed. · Day 12 milestone: The analyzer can now perform multiple ping tests, store the results, analyze them, and presents the key network statistics in a clean summary to the user."}, {"post_id": 58374, "ts": "2026-08-30T19:44:01Z", "hours": 1.6194, "text": "Day 11 – Analyzing Multiple Ping Tests (Collecting Data) · Added successful and failed test tracking using PingResult.success. o Calculated the number of successful tests and failed tests. · Added packet loss calculation: o Failed Tests ÷ Total Tests × 100 · Implemented average latency calculation using ONLY successful tests o Failed tests do not measure any latency, so do not include within calculation · Fixed the average latency calculation by properly incrementing successfulLatencyTests. · Verified that multiple ping results are correctly stored in the ArrayList. · Added a final PING TEST SUMMARY displaying: o Successful Tests o Failed Tests o Packet Loss o Average Latency · Tested the program with 3 pings to Google, successfully producing: o 3 successful tests o 0 failed tests o 0% packet loss o ~11.67 ms average latency"}, {"post_id": 55263, "ts": "2026-08-26T23:10:31Z", "hours": 1.5486, "text": "Day 10 - Multiple Ping Tests & Result Storage Implemented an ArrayList to store results from multiple ping tests. Added user input for the number of ping tests to run Added input validation to ensure the number of tests is a valid positive whole number Created a for loop to automatically run the requested number of ping tests Stored each PingResult in the ArrayList after every successful test. Added a results counter using results.size() to verify that results are being stored correctly. Confirmed the program successfully ran 3 separate tests to Google and stored all 3 results Debugged the output and identified/removing the unnecessary extra ping test result Verified latency extraction, success/failure detection, and timestamp functionality alongside new multi-test Ping system for my code Key milestone: The analyzer can now run multiple"}, {"post_id": 54887, "ts": "2026-08-26T03:13:56Z", "hours": 1.1456, "text": "Day 9 – Heavy debugging and Two-Step Verification · Debugged and refined the program’s user-input and control-flow systems. o Implemented a two-step verification process using if / else if / else logic to confirm intended program usage before proceeding. · Improved the survey consent workflow, allowing users to decline the survey while still accessing the Wi-Fi Latency Analyzer. · Debugged several issues involving conditional statements, loops, and program termination o Including changing Scanner object name to Input (more consistent and widely accepted) · Improved timestamp readability o Replacing Java’s default timestamp format with a user-friendly date/time format o Continued testing the analyzer with real network connection o Verified that latency measurements and timestamps were being returned correctly. · Edited/added more relevant comments"}, {"post_id": 54206, "ts": "2026-08-25T02:57:30Z", "hours": 0.7028, "text": "Day 8 – Debugging and Data Collection (beta version) · Debugged and improved the control flow (survey ProcessBuilder, pingResult… etc.) o Fixed “if else” function displaying semi-colon o Added safer handling for latency extraction by checking whether “ms” was successfully found (extracting the number) · Verified the latency parser o Located time= o Extracted Latency text o Identified numerical value o Converting “[String]” à double · Tested program with multiple real DNS servers to verify successful connections · Kept detailed debugging output in terminal (eg. Time= …) to verify source code is running properly · Edited a few comments to be accurate/up to date · Began real world analysis and data collection (very important for future) · Refined the project’s architecture and long-term direction: desktop application as the actual tool + website as the project’s documentation, research, data, and presentation layer o Further down the road when I begin developing the GUI/user interface o Reasoning for choosing desktop app as tool: websites would only run ping analysis from my computer, not from user’s computer"}, {"post_id": 53398, "ts": "2026-08-23T22:45:49Z", "hours": 1.3758, "text": "Day 7 – 8/23/26 – Development and Debugging Improved survey/user-flow logic Changed the survey from automatically terminating the program when the user selects “no.” Added an option for users to skip the survey and continue to the Wi-Fi Latency Analyzer. Added if / else if / else control flow to handle valid and invalid responses. Improved input validation Continued using equalsIgnoreCase() so inputs such as YES, Yes, and yes are treated consistently. Added handling for invalid responses instead of allowing unexpected input to break the program. Identified and corrected an issue where multiple scanner.nextLine() calls were accidentally being used before the program needed the second input. Debugging and code cleanup Identified a major issue where scanner.close() was accidentally placed inside the age-validation loop. Recognized that closing the scanner could prevent the rest of program from receiving user input. Kept scanner closure at the end of the program instead. · Began Day 7 latency extraction Built on the existing BufferedReader that reads the operating system’s ping output. Added detection for lines containing “time=”. Used indexOf() to locate the position of the latency information within the ping output. Began learning how substring() can isolate the latency portion of the returned text. Next step of extracting the numerical ms value and converting it with Double.parseDouble() Improved program methodology Continued developing the project incrementally Practiced debugging by testing individual sections Key challenge/cool change: The program is becoming more user-friendly and robust. Users can now decline the optional survey without losing access to the actual Wi-Fi Latency Analyzer, while the program separately handles survey consent and analyzer participation."}, {"post_id": 48318, "ts": "2026-08-16T17:02:05Z", "hours": 1.1478, "text": "Day 5 — Detecting Ping Success or Failure. Today I implemented and debugged the logic needed to determine whether a real ping to a DNS server succeeds or fails. I learned how ProcessBuilder, waitFor(), and exit codes work together to interact with the operating system, and how they actually evaluate the result of a network test. I also strengthened my understanding of input validation, control flow, methods, and user inputs, including using if/else if/else logic and System.exit(0) terminating the program. I tested the program with both valid and invalid targets and confirmed that it can now identify successful and unsuccessful connections. I also updated my README to better reflect the project’s current development. Next: Day 6 — extract the latency measurement in milliseconds from successful ping results."}, {"post_id": 47673, "ts": "2026-08-15T18:49:14Z", "hours": 1.7606, "text": "Day 4 progress: I broke my Ping Latency Analyzer’s source code into two classes: one handling the intro, simple setup, and survey questions, and the other managing the actual ping measurements and user input. Most of today was spent debugging and reorganizing that structure, and I started tracking my work directly in comments (e.g., // Day4:) to keep changes easy to follow over time. I also ensure the project used a single, consistent Scanner object in the Main class instead of creating multiple instances. On the technical side, I learned how ProcessBuilder, Process, start(), and getInputStream() work together to launch and read output from an external process, and I looked into the difference between declaring void on a main method versus omitting it. I applied .equalsIgnoreCase() to make my survey questions case-insensitive, and I compared using while loops versus if/else blocks for validating user input, particularly useful for handling simple yes/no responses."}, {"post_id": 46672, "ts": "2026-08-14T03:35:01Z", "hours": 1.8378, "text": "Day 2/3: Learned what a target like Cloudfare or Google DNS is within the world of Cloud and Data Engineering. Public IP Addresses for Website Domains. Learned Arrays/List ( [] ). Learned purpose of Classes/Objects (other than Public Class). Create a numbered menu with safe public test targets. Cloudfare: 1.1.1.1; Google DNS: 8.8.8.8. Let the user choose one target. Print the chosen target back to them"}, {"post_id": 45463, "ts": "2026-08-11T23:09:17Z", "hours": 1.3167, "text": "Day 1: Hi! My name is Aaryan, and this is the very beginning of my journey towards creating my first long-term project with Java. I am very new to Java and this program, and the code below represents the beginning of my User Info data collection for my Wi-Fi Latency Analyzer Project. Any comments or suggestions towards my project would be well appreciated! This is NOT a traditional Wi-Fi speed test, and I am aiming to measure metrics like Packet Loss, Latency, and stability of connections during gaming and video calls."}]...
|
Title: Wi-Fi Latency Analyzer by @aaryan_s | Stard Title: Wi-Fi Latency Analyzer by @aaryan_s | Stardance
Devlogs:
Day 1: Hi! My name is Aaryan, and this is the very beginning of my journey towards creating my first long-term project with Java. I am very new to Java and this program, and the code below represents the beginning of my User Info data collection for my Wi-Fi Latency Analyzer Project. Any comments or suggestions towards my project would be well appreciated! This is NOT a traditional Wi-Fi speed test, and I am aiming to measure metrics like Packet Loss, Latency, and stability of connections during gaming and video calls.
Day 2/3: Learned what a target like Cloudfare or Google DNS is within the world of Cloud and Data Engineering. Public IP Addresses for Website Domains. Learned Arrays/List ( [] ). Learned purpose of Classes/Objects (other than Public Class). Create a numbered menu with safe public test targets. Cloudfare: 1.1.1.1; Google DNS: 8.8.8.8. Let the user choose one target. Print the chosen target back to them
Day 4 progress: I broke my Ping Latency Analyzer’s source code into two classes: one handling the intro, simple setup, and survey questions, and the other managing the actual ping measurements and user input. Most of today was spent debugging and reorganizing that structure, and I started tracking my work directly in comments (e.g., // Day4:) to keep changes easy to follow over time. I also ensure the project used a single, consistent Scanner object in the Main class instead of creating multiple instances. On the technical side, I learned how ProcessBuilder, Process, start(), and getInputStream() work together to launch and read output from an external process, and I looked into the difference between declaring void on a main method versus omitting it. I applied .equalsIgnoreCase() to make my survey questions case-insensitive, and I compared using while loops versus if/else blocks for validating user input, particularly useful for handling simple yes/no responses.
Day 5 — Detecting Ping Success or Failure. Today I implemented and debugged the logic needed to determine whether a real ping to a DNS server succeeds or fails. I learned how ProcessBuilder, waitFor(), and exit codes work together to interact with the operating system, and how they actually evaluate the result of a network test. I also strengthened my understanding of input validation, control flow, methods, and user inputs, including using if/else if/else logic and System.exit(0) terminating the program. I tested the program with both valid and invalid targets and confirmed that it can now identify successful and unsuccessful connections. I also updated my README to better reflect the project’s current development. Next: Day 6 — extract the latency measurement in milliseconds from successful ping results.
Day 7 – 8/23/26 – Development and Debugging Improved survey/user-flow logic Changed the survey from automatically terminating the program when the user selects “no.” Added an option for users to skip the survey and continue to the Wi-Fi Latency Analyzer. Added if / else if / else control flow to handle valid and invalid responses. Improved input validation Continued using equalsIgnoreCase() so inputs such as YES, Yes, and yes are treated consistently. Added handling for invalid responses instead of allowing unexpected input to break the program. Identified and corrected an issue where multiple scanner.nextLine() calls were accidentally being used before the program needed the second input. Debugging and code cleanup Identified a major issue where scanner.close() was accidentally placed inside the age-validation loop. Recognized that closing the scanner could prevent the rest of program from receiving user input. Kept scanner closure at the end of the program instead. · Began Day 7 latency extraction Built on the existing BufferedReader that reads the operating system’s ping output. Added detection for lines containing “time=”. Used indexOf() to locate the position of the latency information within the ping output. Began learning how substring() can isolate the latency portion of the returned text. Next step of extracting the numerical ms value and converting it with Double.parseDouble() Improved program methodology Continued developing the project incrementally Practiced debugging by testing individual sections Key challenge/cool change: The program is becoming more user-friendly and robust. Users can now decline the optional survey without losing access to the actual Wi-Fi Latency Analyzer, while the program separately handles survey consent and analyzer participation.
Day 8 – Debugging and Data Collection (beta version) · Debugged and improved the control flow (survey ProcessBuilder, pingResult… etc.) o Fixed “if else” function displaying semi-colon o Added safer handling for latency extraction by checking whether “ms” was successfully found (extracting the number) · Verified the latency parser o Located time= o Extracted Latency text o Identified numerical value o Converting “[String]” à double · Tested program with multiple real DNS servers to verify successful connections · Kept detailed debugging output in terminal (eg. Time= …) to verify source code is running properly · Edited a few comments to be accurate/up to date · Began real world analysis and data collection (very important for future) · Refined the project’s architecture and long-term direction: desktop application as the actual tool + website as the project’s documentation, research, data, and presentation layer o Further down the road when I begin developing the GUI/user interface o Reasoning for choosing desktop app as tool: websites would only run ping analysis from my computer, not from user’s computer
Day 9 – Heavy debugging and Two-Step Verification · Debugged and refined the program’s user-input and control-flow systems. o Implemented a two-step verification process using if / else if / else logic to confirm intended program usage before proceeding. · Improved the survey consent workflow, allowing users to decline the survey while still accessing the Wi-Fi Latency Analyzer. · Debugged several issues involving conditional statements, loops, and program termination o Including changing Scanner object name to Input (more consistent and widely accepted) · Improved timestamp readability o Replacing Java’s default timestamp format with a user-friendly date/time format o Continued testing the analyzer with real network connection o Verified that latency measurements and timestamps were being returned correctly. · Edited/added more relevant comments
Day 10 - Multiple Ping Tests & Result Storage Implemented an ArrayList to store results from multiple ping tests. Added user input for the number of ping tests to run Added input validation to ensure the number of tests is a valid positive whole number Created a for loop to automatically run the requested number of ping tests Stored each PingResult in the ArrayList after every successful test. Added a results counter using results.size() to verify that results are being stored correctly. Confirmed the program successfully ran 3 separate tests to Google and stored all 3 results Debugged the output and identified/removing the unnecessary extra ping test result Verified latency extraction, success/failure detection, and timestamp functionality alongside new multi-test Ping system for my code Key milestone: The analyzer can now run multiple
Day 11 – Analyzing Multiple Ping Tests (Collecting Data) · Added successful and failed test tracking using PingResult.success. o Calculated the number of successful tests and failed tests. · Added packet loss calculation: o Failed Tests ÷ Total Tests × 100 · Implemented average latency calculation using ONLY successful tests o Failed tests do not measure any latency, so do not include within calculation · Fixed the average latency calculation by properly incrementing successfulLatencyTests. · Verified that multiple ping results are correctly stored in the ArrayList. · Added a final PING TEST SUMMARY displaying: o Successful Tests o Failed Tests o Packet Loss o Average Latency · Tested the program with 3 pings to Google, successfully producing: o 3 successful tests o 0 failed tests o 0% packet loss o ~11.67 ms average latency
Day 12 – Formatting and Proper Displaying of Data – 8/31/26 · Added packet-loss formatting using printf to display percentages to 2 decimal places. o Improved the final ping-test summary for readability. · Verified the program correctly calculates and displays: o Successful tests o Failed tests o Packet loss o Average latency · Debugged an issue where the old println formatting was still being used. · Learned how Java printf formatting works, including %.2f, %%, and %n. · Chose to postpone additional rounding/refinement work until later if needed. · Day 12 milestone: The analyzer can now perform multiple ping tests, store the results, analyze them, and presents the key network statistics in a clean summary to the user.
Day 13 – Readability / Displaying Clean Info on User Terminal · Improved the readability of individual ping results by labeling each test (TEST 1 OF 2, TEST 2 OF 2, etc.) o Fixed the successful-test counter so successful tests are counted correctly · Fixed the duplicate test display caused by accidentally using nested loops (loop inside of another loop) · Added the foundation for minimum and maximum latency calculations · Added success/failure, total latency, + min/max latency analysis into stored results analysis section · Fixed a variable declaration issue with totalLatency and successfulLatencyTests (order matters in code) · Overall: Day 13 focused on making the output cleaner and turning the stored ping data into more useful statistics
Day 14 – Terminal Readability / Debugging (Continuation of Day 13) · Made average/min/max display N/A when there are no successful tests o Improved failed-test output so failed pings don’t misleadingly show 0 ms · Fixed the test-number display (TEST 1 OF 2, TEST 2 OF 2) · Fixed the duplicate results caused by nested loops (loop within another loop) · Tested failed hostnames and verified that it results in a 100% packet loss · Kept debugging messages temporarily · Deferred method refactoring for later
Day 15/16 - Debugging, Jitter, Project Organization 15: · Reorganized my programming workspace so each project has a folder · Set up a “Coding Projects” folder to keep my future projects under one large folder · Kept my Wi‑Fi Latency Analyzer in its own project folder o its Java code, README, license, and VS Code settings stay together · Created separate Java Practice folder for smaller programs that help me practice Java concepts · Reviewed the project files and learned what each one is used for · Found and removed an empty unused Java folder from the project · Made sure my project folders are synced and accessible through OneDrive · Overall, continued building good habits for keeping my code organized, separate, and easy to find 16: · Removed duplicate for loop that was double-counting successful latency data · Added jitter to the Wi-Fi Latency Analyzer o Learned to calculate jitter by comparing each successful ping to the previous successful ping o Used Math.abs() to find the absolute latency difference · Added handling for cases where jitter can’t be calculated, displaying N/A (if/else) · Tested multiple cases to make sure the new jitter calculations and edge cases worked correctly
Day 17 – Beginning the Desktop App Interface 1. Core program: (everything I have been doing thus far): o Improved name input validation, including rejecting blank/space-only names. o Made the name switch case-insensitive using .toLowerCase() 2. Desktop App: o Began building a Java desktop app version of my Wi‑Fi Latency Analyzer using Java Swing · Created LatencyAnalyzerWindow.java, which opens a real application window o Learned the purpose of Swing components such as JFrame, JPanel, JLabel, JButton o Added a target-selection dropdown with Cloudflare and Google DNS options · Added fields for the number of tests and delay between tests o Added a Start Test button and status message area o Added Live Results section, placeholders for latency, average latency, packet loss, and jitter · Edited the ReadMe to better reflect status of project and AI usage during the project · Planned to connect the interface to real ping data next
Day 18 - Desktop UI & Connecting the Program · Connected the UI to the existing src.java ping functionality · Connecting public classes and calling methods from src.java · Changed ping() to be accessible from the UI - Learned how classes communicate with each other · Learned how LatencyAnalyzerWindow → src.ping() → PingResult → GUI works · Crucial for connecting jitter, packet loss, etc. later · Kept latency stored as a double and only formatted it for display 3 days left, with ~6–7 hours planned to finish, test, and polish the project :D
Day 19 — Connecting the Desktop Application Connected the GUI to the existing src.ping() backend o Integrated calculations for average latency, min/max latency, packet loss, and jitter Added user input for number of tests and delay between tests o Added input validation for test count and delay values Used ArrayList to store multiple ping results Connected the calculated results to the GUI’s live result labels Learned why Double.MAX_VALUE is useful when calculating a minimum value and how Thread.sleep() creates the delay between tests Next: Test the full workflow, fix any bugs, and make the GUI responsive before moving toward final polish/shipping :DD
Day 20 — UI Polish & APP Refinement/Debugging Further developed the UI to be more presentable to users: Consistent color theme: light background, blue primary color, dark text, and light-gray section backgrounds Improved the title section with a larger blue title and a subtitle describing the application’s purpose. Redesigned the test configuration section by grouping the DNS target, number of tests, and delay controls into a single bordered panel. o Added recognizable DNS provider names to the target dropdown, such as Cloudflare and Google, instead of displaying only IP addresses. Added a clean border and light-gray background to test configuration panel to match Live Results section. Improved Start Test button, including styling and a play-button icon. Worked on removing the default blue selection highlighting from the dropdown and customizing it renderer/colors. Redesigned LIVE RESULTS so it appears as a proper section heading above a bordered results box rather than relying on Swing’s default titled border. Added light-gray background + border to the Live Results panel for consistent dashboard-like appearance. Learned more about Swing layouts, panels, borders, colors, renderers, component alignment, etc. Core functionality is now running, with the desktop application connected to the existing ping backend and displaying latency statistics.
• Day 21 – Modern GUI and FlatLaf Setup – 10/19 • I installed FlatLaf, an open source java library for Java Swing applications . The goal with FlatLaf is to slowly “modernize” my app and overall make it look a lot more appealing to the user compared to it’s old basic java swing vibe. I struggled a lot with implementing FlatLaf and connecting it to my java swing application in VsCode, so I had to use some AI to figure out how to install FlatLat onto VsCode on a Windows desktop. I made a seperate folder called “Lib” and added the FlatLaf download file. For now, I have the core ping functionality/logic down, the basic GUI, and my next steps are clear: I want to have a working, publicly appealing app. Hopefully I can submit this into the Congressional App Challenge within the next week! • P.S: Starting from this post, from now on, I am beginning to change the format of my Devlogs. Originally, they were very structured and bullet pointed. However, after double checking StarDance guidelines for a proper post, I want to make my posts more understandable and readable starting now. Thank you!...
|
1792493337.907051
|
1793098137.907051
|
|
20340
|
Audio Codec Module by @pui4 | Stardance
|
pui4
|
0
|
7.87
|
0
|
[]
|
[{"post_id": 81127, "ts": "202 [{"post_id": 81127, "ts": "2026-10-20T00:07:01Z", "hours": 1.2197, "text": "I finally got it working. This is a shot devlog just before I ship. I have found an issue with the design (that I have now fixed), I forgot to breakout the output pin on the chip meaning that the mic input doesn’t work. However speaker output works! Here I have attached a video of it hooked up to a pi pico acting as a usb audio device (ignore the messy desk)"}, {"post_id": 63906, "ts": "2026-09-07T22:54:44Z", "hours": 1.4167, "text": "THE BOARDS HAVE ARRIVED!!! JLC has finally delivered the boards and they look fantastic. But do they work? I will get to that shortly. Ordering the boards was a pain in the ass. When I added the boards to my cart and filled everything in, I got a price of 60 USD. I made my application for a grant for 60 USD and got accepted. Then when I later went to purchase the boards, I got hit with 11 USD of hidden taxes that JLC doesn’t show you until after you have already put you card information in and are ready to buy it. So I was 11 USD short to order my boards; so I made a support ticket on the slack to get my grant increased - just for it to get a couple (honestly useless) replies. So in desperation I looked to see if I could decrease the price to fit inside my grant budget and I was able to using a JLC coupon. So I purchased the boards and received an email asking me the orientation of the single IC that is on the board. They had the dot in the top right when it needed to be in the top left. I corrected them and even attached a screenshot from KiCad to further illustrate my point. They thanked me for correcting them and that was the end of it. Fast forward to yesterday and the boards arrived. I was filled with excitement and I hastily soldered on the headers to the board. I then went to test it with an esp32 and a simple vibe-coded (calm down it’s just for testing) esphome app. I wired everything up correctly and saw nothing on the I2C bus. I was scared I made a mistake but all the voltages and pins were where they were supposed to be. Then I noticed it, the IC was rotated 90 degrees from where it should have been; on all of the boards. It was in the original orientation that JLC sent me and not the corrected one that they confirmed. Even though I don’t have the correct tools for the job I attempted at fixing one. The one with the header already on it would have been annoying as I would have had to remove the headers which is a major pain in the ass. So I stuck another board on top of the hotplate that I got from hackclub blueprint and tried. The first attempt ended in destruction as I was using the wrong type of tweezers and so when I went to place the chip down it pinged off and knocked a capacitor and resistor off the board; and I chose to use absolutely tiny passives as the footprints in KiCad are incomprehensible and trying to compare them to LCSC parts was hard. On the third board and attempt I did (or at least I think I did as I don’t have a microscope to properly check it). I ran over to my computer to test it and I saw it on the I2C bus. Then esphome wasn’t letting me use it as a WiFi speaker so I played some rttti sounds on it and it worked! Of course all of this time was not logged (4-5~ hours of work) so what was the 1 hour and 25 mins. Well the original purpose for this board was to be used with Linux SBCs and so I tried to get it to work with the pi zero 2w. I picked the 2w to test with as it has 6.18 kernel which includes a driver for the es8311. However I know next to nothing about Linux embedded development, even though I’ve dail drove Linux on my pc for almost 2 years now - I know it more as a user than a developer. In other words, I couldn’t figure out how to properly write the device trees to get it to work and I couldn’t vibe-code it either as that didn’t work. Now I have to try and get this working on the pi before the end of Star dance so I can ship it. If you are reading this and have any experience in embedded Linux or device trees, please message me on slack: @pui4 . Thanks for reading, I hope to get this done soon. Also I have sent an email complaining about the boards to JLC and I will report when I have any news."}, {"post_id": 26093, "ts": "2026-07-10T17:57:38Z", "hours": 1.7836, "text": "Finally going to submit!! I’ve finished the PCB and the readme (for now). I made blender renders of the PCB. I used a random HDRI I found online and hit render. Also I had to change the PCB as the footprint I was using for the resistors and capacitors were too small for the ones that I actually wanted to use. In fairness to me; it’s difficult to pick the right one when all the footprint names are “R_0201_0603Metric”. It’s so confusing that even claude got it wrong. It said that the second number was metric and the first was imperial and that LCSC has there components listed in metric. That’s wrong, I’m not sure what part of it is wrong - all I know is that the number I wanted for LCSC was the first one. I also changed the footprints so they aren’t the hand-solder ones. This is after @heki told me that it may cause issues, yesterday. This will not be my final post on this design as I guarantee that there will be some issue with the design or repo that requires me to re-submit but we’ll see. I also updated the readme to a some-what final state (until I actually get the boards). It has more info if you want to check it out. The repo is a bit messy at the minute so I need to tidy that up at a later date. Now I just need to wait to get it rejected to do any more work on it. Until then, thanks for reading !!"}, {"post_id": 25557, "ts": "2026-07-09T21:33:20Z", "hours": 0.9833, "text": "I think I’m done. I finished the PCB and fixed some things with the help of @heki (thanks). I did a BOM with the help of the JLC kicad extension and uploaded it to JLC and got a price of $40! I still need to do a render and submit it but I think I’m done for today. Thank you for reading. (I spent a lot longer on this but forgot to record it)"}, {"post_id": 25420, "ts": "2026-07-09T18:06:17Z", "hours": 1.7333, "text": "Hopefully finished routing the PCB. As I said in my last post; I’m not entirely sure on if I have picked the correct footprints for my resistors and capacitors. I picked small ones as it won’t draw much power and is 3.3 volts anyway. Also I ended up keeping the aux jacks and fit them in as shown in the screenshot. Next I need to make a BOM for JLC to assemble it as I currently don’t have the capabilities or expertise to solder SMD components. I have never made a BOM before and I don’t really know how to start - if anyone can help me, please comment on this post or reach out to me on slack. After the BOM is complete, then I will need to see the cost of producing these modules and submit the project for funding. Also excuse the poor quality of my routing and the large amount of Vias, as this is my second PCB ever and I’m just learning by trial and error. I mean my last PCB worked (with some bodges) so surely this vastly more complex one will work too; right? I also need to add some art to the PCB as currently it is very bland (yes the text is in comic sans). I will also do a render in blender and properly add the models for components in a future devlog. I’m also going to post the PCB and the schematic into the slack to see if their is any obvious issues that I have overlooked. If you (the person reading this) spots any issues - comment them or reach me on slack. Thanks for reading and hopefully I’ll get this done soon. :))"}, {"post_id": 24959, "ts": "2026-07-08T20:59:19Z", "hours": 0.7328, "text": "(little annoyed as I am having to re-write this entire thing again as stardance refused to accept my last one) I have just finished the schematic for the module. It is copied from an implementation by waveshare in one of their ESP32 boards here. I’m not 100% sure that it is correct as I’m not good enough at electronics yet to read and understand datasheets. I haven’t yet assigned the footprints to the symbols yet as I need to do more research into the different sizes of SMD resistors and caps. It has 2 aux jacks - one for input and one for output, I’m not fully sure whether or not I’m going to keep these in the final design as they are already broken out to the pin headers; but they are there for now. They are also TRS jacks even though they are both mono, this is due to me requiring a TRS jack for the mic I plan to use for my other project (a Rode videomic shotgun mic). I know that a mono jack would work too, but I’ve chosen to use TRS jacks also because they are easier to obtain. The pin headers are separated into 2 groups of 6 as to keep it small and bread-board compatible - so I can use this module for prototyping other projects more easily. Right now I’m going to submit this schematic into the outpost and stardance slacks to ask for others opinions. I have no intention to go to open sauce as it is too expensive for me to go as I am in the UK; so I’m hoping for as much star dust as possible :) If you have any questions (or you spotted an issue in the design) feel free to reach out to me on slack @pui4 . Thank you for reading and being interested in my project :))"}]...
|
Title: Audio Codec Module by @pui4 | Stardance
De Title: Audio Codec Module by @pui4 | Stardance
Devlogs:
(little annoyed as I am having to re-write this entire thing again as stardance refused to accept my last one) I have just finished the schematic for the module. It is copied from an implementation by waveshare in one of their ESP32 boards here. I’m not 100% sure that it is correct as I’m not good enough at electronics yet to read and understand datasheets. I haven’t yet assigned the footprints to the symbols yet as I need to do more research into the different sizes of SMD resistors and caps. It has 2 aux jacks - one for input and one for output, I’m not fully sure whether or not I’m going to keep these in the final design as they are already broken out to the pin headers; but they are there for now. They are also TRS jacks even though they are both mono, this is due to me requiring a TRS jack for the mic I plan to use for my other project (a Rode videomic shotgun mic). I know that a mono jack would work too, but I’ve chosen to use TRS jacks also because they are easier to obtain. The pin headers are separated into 2 groups of 6 as to keep it small and bread-board compatible - so I can use this module for prototyping other projects more easily. Right now I’m going to submit this schematic into the outpost and stardance slacks to ask for others opinions. I have no intention to go to open sauce as it is too expensive for me to go as I am in the UK; so I’m hoping for as much star dust as possible :) If you have any questions (or you spotted an issue in the design) feel free to reach out to me on slack @pui4 . Thank you for reading and being interested in my project :))
Hopefully finished routing the PCB. As I said in my last post; I’m not entirely sure on if I have picked the correct footprints for my resistors and capacitors. I picked small ones as it won’t draw much power and is 3.3 volts anyway. Also I ended up keeping the aux jacks and fit them in as shown in the screenshot. Next I need to make a BOM for JLC to assemble it as I currently don’t have the capabilities or expertise to solder SMD components. I have never made a BOM before and I don’t really know how to start - if anyone can help me, please comment on this post or reach out to me on slack. After the BOM is complete, then I will need to see the cost of producing these modules and submit the project for funding. Also excuse the poor quality of my routing and the large amount of Vias, as this is my second PCB ever and I’m just learning by trial and error. I mean my last PCB worked (with some bodges) so surely this vastly more complex one will work too; right? I also need to add some art to the PCB as currently it is very bland (yes the text is in comic sans). I will also do a render in blender and properly add the models for components in a future devlog. I’m also going to post the PCB and the schematic into the slack to see if their is any obvious issues that I have overlooked. If you (the person reading this) spots any issues - comment them or reach me on slack. Thanks for reading and hopefully I’ll get this done soon. :))
I think I’m done. I finished the PCB and fixed some things with the help of @heki (thanks). I did a BOM with the help of the JLC kicad extension and uploaded it to JLC and got a price of $40! I still need to do a render and submit it but I think I’m done for today. Thank you for reading. (I spent a lot longer on this but forgot to record it)
Finally going to submit!! I’ve finished the PCB and the readme (for now). I made blender renders of the PCB. I used a random HDRI I found online and hit render. Also I had to change the PCB as the footprint I was using for the resistors and capacitors were too small for the ones that I actually wanted to use. In fairness to me; it’s difficult to pick the right one when all the footprint names are “R_0201_0603Metric”. It’s so confusing that even claude got it wrong. It said that the second number was metric and the first was imperial and that LCSC has there components listed in metric. That’s wrong, I’m not sure what part of it is wrong - all I know is that the number I wanted for LCSC was the first one. I also changed the footprints so they aren’t the hand-solder ones. This is after @heki told me that it may cause issues, yesterday. This will not be my final post on this design as I guarantee that there will be some issue with the design or repo that requires me to re-submit but we’ll see. I also updated the readme to a some-what final state (until I actually get the boards). It has more info if you want to check it out. The repo is a bit messy at the minute so I need to tidy that up at a later date. Now I just need to wait to get it rejected to do any more work on it. Until then, thanks for reading !!
THE BOARDS HAVE ARRIVED!!! JLC has finally delivered the boards and they look fantastic. But do they work? I will get to that shortly. Ordering the boards was a pain in the ass. When I added the boards to my cart and filled everything in, I got a price of 60 USD. I made my application for a grant for 60 USD and got accepted. Then when I later went to purchase the boards, I got hit with 11 USD of hidden taxes that JLC doesn’t show you until after you have already put you card information in and are ready to buy it. So I was 11 USD short to order my boards; so I made a support ticket on the slack to get my grant increased - just for it to get a couple (honestly useless) replies. So in desperation I looked to see if I could decrease the price to fit inside my grant budget and I was able to using a JLC coupon. So I purchased the boards and received an email asking me the orientation of the single IC that is on the board. They had the dot in the top right when it needed to be in the top left. I corrected them and even attached a screenshot from KiCad to further illustrate my point. They thanked me for correcting them and that was the end of it. Fast forward to yesterday and the boards arrived. I was filled with excitement and I hastily soldered on the headers to the board. I then went to test it with an esp32 and a simple vibe-coded (calm down it’s just for testing) esphome app. I wired everything up correctly and saw nothing on the I2C bus. I was scared I made a mistake but all the voltages and pins were where they were supposed to be. Then I noticed it, the IC was rotated 90 degrees from where it should have been; on all of the boards. It was in the original orientation that JLC sent me and not the corrected one that they confirmed. Even though I don’t have the correct tools for the job I attempted at fixing one. The one with the header already on it would have been annoying as I would have had to remove the headers which is a major pain in the ass. So I stuck another board on top of the hotplate that I got from hackclub blueprint and tried. The first attempt ended in destruction as I was using the wrong type of tweezers and so when I went to place the chip down it pinged off and knocked a capacitor and resistor off the board; and I chose to use absolutely tiny passives as the footprints in KiCad are incomprehensible and trying to compare them to LCSC parts was hard. On the third board and attempt I did (or at least I think I did as I don’t have a microscope to properly check it). I ran over to my computer to test it and I saw it on the I2C bus. Then esphome wasn’t letting me use it as a WiFi speaker so I played some rttti sounds on it and it worked! Of course all of this time was not logged (4-5~ hours of work) so what was the 1 hour and 25 mins. Well the original purpose for this board was to be used with Linux SBCs and so I tried to get it to work with the pi zero 2w. I picked the 2w to test with as it has 6.18 kernel which includes a driver for the es8311. However I know next to nothing about Linux embedded development, even though I’ve dail drove Linux on my pc for almost 2 years now - I know it more as a user than a developer. In other words, I couldn’t figure out how to properly write the device trees to get it to work and I couldn’t vibe-code it either as that didn’t work. Now I have to try and get this working on the pi before the end of Star dance so I can ship it. If you are reading this and have any experience in embedded Linux or device trees, please message me on slack: @pui4 . Thanks for reading, I hope to get this done soon. Also I have sent an email complaining about the boards to JLC and I will report when I have any news.
I finally got it working. This is a shot devlog just before I ship. I have found an issue with the design (that I have now fixed), I forgot to breakout the output pin on the chip meaning that the mic input doesn’t work. However speaker output works! Here I have attached a video of it hooked up to a pi pico acting as a usb audio device (ignore the messy desk)...
|
1792698589.5127926
|
1793303389.5127926
|
|
66920
|
My own site! by @PhantomStorm | Stardance
|
PhantomStorm
|
1
|
11.3
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-07T01:14:13Z", "hours": 6.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made an All about Me website, that portrays my skills, hobbies, and my profile. It was challenging to fit enough time into making this. I am really proud of the UI.", "repo": "https://github.com/Rephantom-Vortex/My-Personal-Website", "demo": "https://my-bio.boomurl.me/"}]...
|
[{"post_id": 81128, "ts": "202 [{"post_id": 81128, "ts": "2026-10-20T00:14:07Z", "hours": 0.2531, "text": "I WILL CRASH OUT, HOW AM I SUPPOSED TO LOWER AI USAGE IF I DIDN’T USE IT ALL. I am literally crying, I wish AI never existed, i took literally 11 hours to do this and I am still being accused of AI, like literally check the code, it is so messed up, there are DIVs everywhere, and random class names cuz I couldn’t make them up."}, {"post_id": 80226, "ts": "2026-10-16T19:50:37Z", "hours": 0.4592, "text": "Y r my projects always flagged as AI, I didn’t use it"}, {"post_id": 80021, "ts": "2026-10-16T00:17:11Z", "hours": 1.9803, "text": "I finished redoing the CSS!"}, {"post_id": 79162, "ts": "2026-10-12T20:56:21Z", "hours": 2.6044, "text": "Had to Redo the CSS, cuz it was flagged as AI. This time I DID NOT use a AI for anything (except for searching how to center a div)"}, {"post_id": 77441, "ts": "2026-10-07T00:55:58Z", "hours": 2.5144, "text": "FINALLY, Finished!"}, {"post_id": 77204, "ts": "2026-10-06T02:49:05Z", "hours": 0.7017, "text": "Got Started On CSS"}, {"post_id": 77194, "ts": "2026-10-06T01:14:40Z", "hours": 3.2092, "text": "Finished the HTML of My Personal Website, Got CSS Left"}]...
|
Title: My own site! by @PhantomStorm | Stardance
Title: My own site! by @PhantomStorm | Stardance
Devlogs:
Finished the HTML of My Personal Website, Got CSS Left
Got Started On CSS
FINALLY, Finished!
Had to Redo the CSS, cuz it was flagged as AI. This time I DID NOT use a AI for anything (except for searching how to center a div)
I finished redoing the CSS!
Y r my projects always flagged as AI, I didn’t use it
I WILL CRASH OUT, HOW AM I SUPPOSED TO LOWER AI USAGE IF I DIDN’T USE IT ALL. I am literally crying, I wish AI never existed, i took literally 11 hours to do this and I am still being accused of AI, like literally check the code, it is so messed up, there are DIVs everywhere, and random class names cuz I couldn’t make them up.
Ships:
I made an All about Me website, that portrays my skills, hobbies, and my profile. It was challenging to fit enough time into making this. I am really proud of the UI....
|
1792817370.034788
|
1792903770.034788
|
|
55085
|
Tidal-keys by @ElGOATFilipino | Stardance
|
ElGOATFilipino
|
0
|
43.53
|
0
|
[]
|
[{"post_id": 81131, "ts": "202 [{"post_id": 81131, "ts": "2026-10-20T00:44:53Z", "hours": 0.7167, "text": "Started making the BOM! Probably the thing that shocked me most were the Cherry MX2A prices (20 dollars for 36 keys!), so I tried hunting for the best key-value deal. In the end I settled for a 29 dollar 70 pcs on Aliexpress (cheapest option)"}, {"post_id": 80826, "ts": "2026-10-18T22:23:44Z", "hours": 0.9831, "text": "Finished debugging my code! It took a suprisingly long time since I had to wait like 5 minutes in between fixing sessions (16 git pushes!) to determine where the error is, though it was mainly syntax errors here and there."}, {"post_id": 80223, "ts": "2026-10-16T19:47:46Z", "hours": 1.3489, "text": "Finished the zmk code! Hi! Today I just added missing features like bluetooth, rgb, and battery level, though it took me a while because I constantly got lost in the guide and didnt understand what I was reading (especially the bluetooth part). Now all thats left is the bom and the github repo!"}, {"post_id": 80183, "ts": "2026-10-16T16:31:48Z", "hours": 4.16, "text": "Finished assembly!! Mainly took a bit longer on it because I had to fix some model errors, but apart from that everything went smoothly, the keyboard case is done! Also started working on the code, which is actually pretty simple, since im just following the zmk firmware guide."}, {"post_id": 77442, "ts": "2026-10-07T00:58:37Z", "hours": 7.2786, "text": "Hi everyone!! Sorry for not devolging in like what, more than 2 weeks? I just haven’t had a lot of time lately, had to study for a lot of test + school dances, ect,etc,etc. This means not a lot has happened these days, I’ve mainly been doing the assembly (which is almost completed) + modifying some parts bercause they didnt fit. I had a huge derail on this project, because I thought that each keycap had a litte 1mm spacing in between them, turn out that was definitely not true, so I had to work +3 hours to fix all that in the board and CAD. (I wish I had known that sooner! 😭) Trying to find keycaps for it is an actual PAIN, I really cant find 3u keycaps for DSA, so I had to improvise (just scaled a 1u horizontally, all add in the stumps later) *Right side is still in process! Also the enter key is kinda off scale, have to look into that."}, {"post_id": 70656, "ts": "2026-09-19T15:07:26Z", "hours": 5.9494, "text": "Right side CAD complete!! As planned in my figma sketch, I went with the beach themed right side split, I even added little starfish in that little empty space in the bottom right. I also decided to keep the dent that the left side has, that way they look symmetrical. Plus, I made a lid for the battery compartment with corresponding colors for each one! Now all thats left is to make the assembly! Shouldnt take long. I think I’ll do three designs: One for the left, the other for the right, and a 3rd one where both of them are together (for the picture!)"}, {"post_id": 68889, "ts": "2026-09-15T23:26:52Z", "hours": 3.9442, "text": "Finished the left splits components! Today I finished polishing the bottom part of the split, like adding the battery wire hole, and screw holes. I also made the top part of the split! I used the color stackup I said I was going to use in my figma sketch, mainly dark tones of blue. I also added white arrows (which appear in the TW title screen) on a little raised platform, and a few little bubbles as extra deco). An import change I made was changing the screws from M3 → M2, since the M2 are smaller and leave more space for clearances. Now all thats left is to make the assembly design of it! That means every single screw, key, keycap, heatset insert. And after that would come the right split and firmware!"}, {"post_id": 67682, "ts": "2026-09-13T21:02:03Z", "hours": 3.7714, "text": "(Almost) Finished making the bottom plate of the left side of my split keyboard!! As soon as I started modeling the plate, I realized I’m incredibly slow and bad at CAD, It took me almost 3 hours just to do it. Rewatching my recordings, I was probably anxious and kind of confused about the measurements and how the stackup will be. Hoepfully with the other plates I take less (I already know what to do). All I did was follow my figma drawings and I added a few modifications, such as a little wrist rest and a little thing at the top (planning to put the drawings there). Also added the little battery compartment on the bottom, and as I’m writing this, I just noticed that the battery box has no where to connect to the pcb, so I have to add that still. Another thing: I’m going to see what’s up with the hours I logged becasue according to stardance I’ve worked 4, but when I look at my lapse it only sums up to around 3 hours, so I’m going to ask in slack."}, {"post_id": 63137, "ts": "2026-09-06T19:31:10Z", "hours": 2.4481, "text": "Design time!!!!! 🌠🌠 Ok, so I didnt have much time to work on the split keyboard because I had to study for a LOT of tests. Usually before I desing something in fusion 360, I like to sketch it out first, I usually do it on my phone, but I decided to give figma a shot for this project. I probably took more time trying to figure out how properly use figma, I made some very messy stuff in it. I had two main ideas while working: First idea : Left → Wave Right → Beach But the little fleck that a wave has at the back would be bothersame while gaming. Second Idea : Based off the tidal wave title screen Left → top part of t.s Right → bottom part of t.s Cool color palette (Dark + Bright) Long story short, second idea won because its simpler and cleaner than the first one. Thats why its good to sketch it out first! Because if I had gone with my first idea immediately in fusion, I would’ve had to design all over again because I would’ve noticed the bad fleck- So now all thats left is to design the CAD!"}, {"post_id": 58429, "ts": "2026-08-30T20:56:12Z", "hours": 4.1267, "text": "PCB Finished!!! I am SUPER happy because I finished the split keyboards PCB! Though I had to redo some parts because I got confused with the footprints, so like an hour wasted right there because of a small mistake. Long story short , the LCSC SK6803 MINI-E footprint was NOT right, I discovered that all the leds in the SK series are reverse mounted (the LCSC was not), meaning that every single led in my pcb was wrong, and therefore, every single trace tied to it . Also, there were like 10000 DRC errors, because of the same LED footprint, the copper is incredibly close to the cut-out, so KiCAD just started freaking out. The cherry on top🍒🎂 : KiCAD crashed as soon as I finished everything that I just mentioned, so I had to do EVERYTHING again in 20 minutes. Other changes!: I moved some of the battery pads so I could route the LEDS easier Made all silkscreen texts face the same way so it’s easier to read + cool GD wave drawings Made each split keyboard have their own gnd net (KiCAD was trying to tie them together) Mousebites in between🐭 Assigned all the 3D models for every component! Soo, I could say the split keyboards PCB is finished , so now the next step is CAD, I still don’t know how I’m going to design the case so it looks like Tidal wave, probably going to make it cyan with fish maybe? I’ll see later."}, {"post_id": 57635, "ts": "2026-08-29T20:47:38Z", "hours": 3.6208, "text": "Almost finished with the second half of the split keyboard! I spent most of my time fighting with KiCad’s UI and trying to get the measurements of the board right, at some point I made the mistake of making the board 11.75cm and not the 11.73cm it was supposed to be (took me like 40 minutes to try and fix it), so all the wires and stuff had to be moved and replaced. I want to make each side of the board click somehow? Like not actually click but something like giving the illusion that you can merge them. Fun thing: I discovered that the key footprint library I’m using has more than just plain old keys, it has fun shapes! Like the “enter” key, plus, they are compatible with the Kailh hotswap I’m using! Another thing that I forgot to mention was that I added an extra button to the matrix, because there were some very big empty spaces near the thumb that could use an extra button, so the total button count for the split keyboard is 48. Also some keys that will use spaces slightly bigger than 1u (such as CAPS and Right shift) that are too small for the stabilizers (smallest is 2u), are a bit farther apart so they fit in the keyboard, and use the space they are supposed to. Right now I still have to check the DRC for errors + some power routing I forgot on the right side. I’m also thinking about adding some silkscreen designs to some of the free spaces on the board, so it doesnt look empty."}, {"post_id": 56781, "ts": "2026-08-28T18:00:22Z", "hours": 3.8422, "text": "Today I completed the left half of my split keyboard! I had a bit of a problem with the LED model I was going to use, since I was planning to sue the SK6812MINI-e, but discovered that it actually needs 5V to work, which is bad since we only have 3.7V coming from a 1S LiPo Battery. So, I switched to its 3mA counterpart “SK6803MINI-E” which can operate at 3.4V instead of 5. Routing wasn’t that much of a problem, a few vias usually fixed the problem. I still don’t know about the battery pads, I feel like they shouldn’t go where they are (maybe they are too close to the edge?). But apart from that, everything is ok! Now I just have to make the right side of the keyboard"}, {"post_id": 56217, "ts": "2026-08-27T21:47:10Z", "hours": 1.3364, "text": "Started making the schematic for the keyboard! I decided to go with the popular XIAO nRF52840 module, since it has wireless capabilities. The big problem for me was trying to manage my GPIO’s, since for 5 rows and 5 columns I need 10 GPIO’s, + a battery sensor, which is 11 gpio’s total (MCU max), but I was looking forward to adding sk6812mini-e leds. But I discovered that the nRF52840 has a battery sensor integrated so that would free up the necesary gpio for the leds. Another problem I had was trying to manage the button count, I was constantly switching from 6 rows, 4 columns to 5 rows 5 columns, and so on. I decided to use a 5x5 layout but leave one row (lowest one) with 3 thumb keys, which would be space, Lctrl, and LAlt. For the diodes, I decided to go with the classic 1N5819, and for the switches I decided to use the Kailh hotswap footprints."}]...
|
Title: Tidal-keys by @ElGOATFilipino | Stardance
Title: Tidal-keys by @ElGOATFilipino | Stardance
Devlogs:
Started making the schematic for the keyboard! I decided to go with the popular XIAO nRF52840 module, since it has wireless capabilities. The big problem for me was trying to manage my GPIO’s, since for 5 rows and 5 columns I need 10 GPIO’s, + a battery sensor, which is 11 gpio’s total (MCU max), but I was looking forward to adding sk6812mini-e leds. But I discovered that the nRF52840 has a battery sensor integrated so that would free up the necesary gpio for the leds. Another problem I had was trying to manage the button count, I was constantly switching from 6 rows, 4 columns to 5 rows 5 columns, and so on. I decided to use a 5x5 layout but leave one row (lowest one) with 3 thumb keys, which would be space, Lctrl, and LAlt. For the diodes, I decided to go with the classic 1N5819, and for the switches I decided to use the Kailh hotswap footprints.
Today I completed the left half of my split keyboard! I had a bit of a problem with the LED model I was going to use, since I was planning to sue the SK6812MINI-e, but discovered that it actually needs 5V to work, which is bad since we only have 3.7V coming from a 1S LiPo Battery. So, I switched to its 3mA counterpart “SK6803MINI-E” which can operate at 3.4V instead of 5. Routing wasn’t that much of a problem, a few vias usually fixed the problem. I still don’t know about the battery pads, I feel like they shouldn’t go where they are (maybe they are too close to the edge?). But apart from that, everything is ok! Now I just have to make the right side of the keyboard
Almost finished with the second half of the split keyboard! I spent most of my time fighting with KiCad’s UI and trying to get the measurements of the board right, at some point I made the mistake of making the board 11.75cm and not the 11.73cm it was supposed to be (took me like 40 minutes to try and fix it), so all the wires and stuff had to be moved and replaced. I want to make each side of the board click somehow? Like not actually click but something like giving the illusion that you can merge them. Fun thing: I discovered that the key footprint library I’m using has more than just plain old keys, it has fun shapes! Like the “enter” key, plus, they are compatible with the Kailh hotswap I’m using! Another thing that I forgot to mention was that I added an extra button to the matrix, because there were some very big empty spaces near the thumb that could use an extra button, so the total button count for the split keyboard is 48. Also some keys that will use spaces slightly bigger than 1u (such as CAPS and Right shift) that are too small for the stabilizers (smallest is 2u), are a bit farther apart so they fit in the keyboard, and use the space they are supposed to. Right now I still have to check the DRC for errors + some power routing I forgot on the right side. I’m also thinking about adding some silkscreen designs to some of the free spaces on the board, so it doesnt look empty.
PCB Finished!!! I am SUPER happy because I finished the split keyboards PCB! Though I had to redo some parts because I got confused with the footprints, so like an hour wasted right there because of a small mistake. Long story short , the LCSC SK6803 MINI-E footprint was NOT right, I discovered that all the leds in the SK series are reverse mounted (the LCSC was not), meaning that every single led in my pcb was wrong, and therefore, every single trace tied to it . Also, there were like 10000 DRC errors, because of the same LED footprint, the copper is incredibly close to the cut-out, so KiCAD just started freaking out. The cherry on top🍒🎂 : KiCAD crashed as soon as I finished everything that I just mentioned, so I had to do EVERYTHING again in 20 minutes. Other changes!: I moved some of the battery pads so I could route the LEDS easier Made all silkscreen texts face the same way so it’s easier to read + cool GD wave drawings Made each split keyboard have their own gnd net (KiCAD was trying to tie them together) Mousebites in between🐭 Assigned all the 3D models for every component! Soo, I could say the split keyboards PCB is finished , so now the next step is CAD, I still don’t know how I’m going to design the case so it looks like Tidal wave, probably going to make it cyan with fish maybe? I’ll see later.
Design time!!!!! 🌠🌠 Ok, so I didnt have much time to work on the split keyboard because I had to study for a LOT of tests. Usually before I desing something in fusion 360, I like to sketch it out first, I usually do it on my phone, but I decided to give figma a shot for this project. I probably took more time trying to figure out how properly use figma, I made some very messy stuff in it. I had two main ideas while working: First idea : Left → Wave Right → Beach But the little fleck that a wave has at the back would be bothersame while gaming. Second Idea : Based off the tidal wave title screen Left → top part of t.s Right → bottom part of t.s Cool color palette (Dark + Bright) Long story short, second idea won because its simpler and cleaner than the first one. Thats why its good to sketch it out first! Because if I had gone with my first idea immediately in fusion, I would’ve had to design all over again because I would’ve noticed the bad fleck- So now all thats left is to design the CAD!
(Almost) Finished making the bottom plate of the left side of my split keyboard!! As soon as I started modeling the plate, I realized I’m incredibly slow and bad at CAD, It took me almost 3 hours just to do it. Rewatching my recordings, I was probably anxious and kind of confused about the measurements and how the stackup will be. Hoepfully with the other plates I take less (I already know what to do). All I did was follow my figma drawings and I added a few modifications, such as a little wrist rest and a little thing at the top (planning to put the drawings there). Also added the little battery compartment on the bottom, and as I’m writing this, I just noticed that the battery box has no where to connect to the pcb, so I have to add that still. Another thing: I’m going to see what’s up with the hours I logged becasue according to stardance I’ve worked 4, but when I look at my lapse it only sums up to around 3 hours, so I’m going to ask in slack.
Finished the left splits components! Today I finished polishing the bottom part of the split, like adding the battery wire hole, and screw holes. I also made the top part of the split! I used the color stackup I said I was going to use in my figma sketch, mainly dark tones of blue. I also added white arrows (which appear in the TW title screen) on a little raised platform, and a few little bubbles as extra deco). An import change I made was changing the screws from M3 → M2, since the M2 are smaller and leave more space for clearances. Now all thats left is to make the assembly design of it! That means every single screw, key, keycap, heatset insert. And after that would come the right split and firmware!
Right side CAD complete!! As planned in my figma sketch, I went with the beach themed right side split, I even added little starfish in that little empty space in the bottom right. I also decided to keep the dent that the left side has, that way they look symmetrical. Plus, I made a lid for the battery compartment with corresponding colors for each one! Now all thats left is to make the assembly! Shouldnt take long. I think I’ll do three designs: One for the left, the other for the right, and a 3rd one where both of them are together (for the picture!)
Hi everyone!! Sorry for not devolging in like what, more than 2 weeks? I just haven’t had a lot of time lately, had to study for a lot of test + school dances, ect,etc,etc. This means not a lot has happened these days, I’ve mainly been doing the assembly (which is almost completed) + modifying some parts bercause they didnt fit. I had a huge derail on this project, because I thought that each keycap had a litte 1mm spacing in between them, turn out that was definitely not true, so I had to work +3 hours to fix all that in the board and CAD. (I wish I had known that sooner! 😭) Trying to find keycaps for it is an actual PAIN, I really cant find 3u keycaps for DSA, so I had to improvise (just scaled a 1u horizontally, all add in the stumps later) *Right side is still in process! Also the enter key is kinda off scale, have to look into that.
Finished assembly!! Mainly took a bit longer on it because I had to fix some model errors, but apart from that everything went smoothly, the keyboard case is done! Also started working on the code, which is actually pretty simple, since im just following the zmk firmware guide.
Finished the zmk code! Hi! Today I just added missing features like bluetooth, rgb, and battery level, though it took me a while because I constantly got lost in the guide and didnt understand what I was reading (especially the bluetooth part). Now all thats left is the bom and the github repo!
Finished debugging my code! It took a suprisingly long time since I had to wait like 5 minutes in between fixing sessions (16 git pushes!) to determine where the error is, though it was mainly syntax errors here and there.
Started making the BOM! Probably the thing that shocked me most were the Cherry MX2A prices (20 dollars for 36 keys!), so I tried hunting for the best key-value deal. In the end I settled for a 29 dollar 70 pcs on Aliexpress (cheapest option)...
|
1792482543.9873607
|
1793087343.9873607
|
|
65850
|
blockers by @evmaagca | Stardance
|
evmaagca
|
0
|
68.94
|
0
|
[]
|
[{"post_id": 81132, "ts": "202 [{"post_id": 81132, "ts": "2026-10-20T00:45:18Z", "hours": 9.955, "text": "devlog #14 : added sparks when spear hits drone, fixed bugs in achivement manager, added dissolve shader (had to search for a tutorial for this ) for both drones (made it kinda break apart piece by piece), fixed multiple scripts (like all of them took around 4 ish hours) as the code was bothering me"}, {"post_id": 80277, "ts": "2026-10-17T02:38:47Z", "hours": 9.5736, "text": "devlog #13 : added achievements ⭐ !!, added achievements into the title screen, changed level button to extra button then put that into there, changed the heart charge ❤️ , added/changed the regdrone and elecdrone scripts to flicker and disappear when dying also created a video for this!!"}, {"post_id": 79418, "ts": "2026-10-13T21:46:58Z", "hours": 6.2628, "text": "devlog #12 : added dust when moving with player flashlight, hearts drop sometimes when enemy dies, fixed issue when player died (took like 2 hours ), fixed bug with mobile ver"}, {"post_id": 78869, "ts": "2026-10-11T20:18:22Z", "hours": 8.56, "text": "devlog #11 : added a fade for the hearts, tried again to fix the levellist , added a glow around the vending machine so that if your light turns off you can find a vending machine , added small dust particles, added another level"}, {"post_id": 78216, "ts": "2026-10-10T00:25:52Z", "hours": 8.6956, "text": "devlog #10 : made 2 new levels, redid some of the notes and added more, and tried to fix a bug I think I genuinely spent like 7 hours straight just trying to debug this one issue with my script that was making the levellist not showing up on mobile (ps it didnt even work )"}, {"post_id": 77448, "ts": "2026-10-07T01:32:20Z", "hours": 3.3167, "text": "devlog #9: made uh the levelselect (which took forever btw genuinely worst experience of my entire existence of life), level 5 made, levelselect bg with canva 🐐 , also side note not with the actual time of godot but I figured out how to view my projects on my phone!!"}, {"post_id": 77182, "ts": "2026-10-05T23:32:14Z", "hours": 2.8656, "text": "devlog #8 : fixed the switches script, added esc button/esc box, made level 3+4!"}, {"post_id": 76894, "ts": "2026-10-04T23:45:23Z", "hours": 4.1417, "text": "devlog #7 : added mobile!!! + used canva 🐐 for this!, changed title music, added transition between titlescreen and actual game"}, {"post_id": 76003, "ts": "2026-10-02T00:41:57Z", "hours": 3.655, "text": "devlog #6 : added a trashcan = heart pickups, made level 2, added extra noises (+ redid some of the volume of them), made the start of the titlescreen + the buttons for it, redid some bugs ( bro took me like 40 minutes of one and I genually feel like death after )"}, {"post_id": 75030, "ts": "2026-09-28T22:22:37Z", "hours": 1.115, "text": "devlog #5 : made the continuation of the level one, updated music, added another blocker (the drones)!"}, {"post_id": 74623, "ts": "2026-09-27T19:51:56Z", "hours": 5.64, "text": "devlog #4 : added the flashlight on and off function, made the vending machines refill the light, made the light bar, made all health, made the potholes + the destinations (still debugging), added better music/different sounds"}, {"post_id": 74033, "ts": "2026-09-26T15:50:20Z", "hours": 5.1569, "text": "devlog #1-3 : added collision tiles, player movement, bg music, decorations, and the start of enemies (so sorry in advance for the bad devlogs)"}]...
|
Title: blockers by @evmaagca | Stardance
Devlogs: Title: blockers by @evmaagca | Stardance
Devlogs:
devlog #1-3 : added collision tiles, player movement, bg music, decorations, and the start of enemies (so sorry in advance for the bad devlogs)
devlog #4 : added the flashlight on and off function, made the vending machines refill the light, made the light bar, made all health, made the potholes + the destinations (still debugging), added better music/different sounds
devlog #5 : made the continuation of the level one, updated music, added another blocker (the drones)!
devlog #6 : added a trashcan = heart pickups, made level 2, added extra noises (+ redid some of the volume of them), made the start of the titlescreen + the buttons for it, redid some bugs ( bro took me like 40 minutes of one and I genually feel like death after )
devlog #7 : added mobile!!! + used canva 🐐 for this!, changed title music, added transition between titlescreen and actual game
devlog #8 : fixed the switches script, added esc button/esc box, made level 3+4!
devlog #9: made uh the levelselect (which took forever btw genuinely worst experience of my entire existence of life), level 5 made, levelselect bg with canva 🐐 , also side note not with the actual time of godot but I figured out how to view my projects on my phone!!
devlog #10 : made 2 new levels, redid some of the notes and added more, and tried to fix a bug I think I genuinely spent like 7 hours straight just trying to debug this one issue with my script that was making the levellist not showing up on mobile (ps it didnt even work )
devlog #11 : added a fade for the hearts, tried again to fix the levellist , added a glow around the vending machine so that if your light turns off you can find a vending machine , added small dust particles, added another level
devlog #12 : added dust when moving with player flashlight, hearts drop sometimes when enemy dies, fixed issue when player died (took like 2 hours ), fixed bug with mobile ver
devlog #13 : added achievements ⭐ !!, added achievements into the title screen, changed level button to extra button then put that into there, changed the heart charge ❤️ , added/changed the regdrone and elecdrone scripts to flicker and disappear when dying also created a video for this!!
devlog #14 : added sparks when spear hits drone, fixed bugs in achivement manager, added dissolve shader (had to search for a tutorial for this ) for both drones (made it kinda break apart piece by piece), fixed multiple scripts (like all of them took around 4 ish hours) as the code was bothering me...
|
1792457423.2325487
|
1793062223.2325487
|
|
16795
|
MAGNUS: DIY chess playing robot by @Leo_Zannoni | MAGNUS: DIY chess playing robot by @Leo_Zannoni | Stardance...
|
Leo_Zannoni
|
0
|
8.74
|
0
|
[]
|
[{"post_id": 81134, "ts": "202 [{"post_id": 81134, "ts": "2026-10-20T01:00:50Z", "hours": 8.3128, "text": "What MAGNUS is MAGNUS is a robot that plays chess on a real board against a person and says its moves out loud in Spanish. I’m building it for PRONAFECYT 2026, Costa Rica’s national science fair, and the voice is there for accessibility: you can follow the game without looking at a screen. I started on february with my first 3D models. Today it plays full games by itself and narrates them. About the hours Hackatime only logged about 8.5 h, because it only counts time in the code editor when i downloaded the app. Most of the work was CAD, printing, assembling and testing the arm. My log puts the real total at 350+ hours Vision Every piece is a 22.5 mm disc with an ArUco 4x4_50 marker and a white ring around it for contrast. The four board corners have their own markers, so the board is found from any camera angle. The camera is my phone through Iriun. A piece only counts after 5 detections in a row, and a GameTracker compares what the camera sees against every legal move to work out what the human played, including castling and en passant. Engine Stockfish runs through python-chess with 10 difficulty levels. Stockfish can’t play below about 1320 Elo, so the four easiest levels choose worse moves on purpose. Every move comes with metadata for captures, castling, en passant and promotion, so the arm never has to know any chess. The arm Shoulder and elbow use the encoder motors from the mBot2 kit on a CyberPi, with a LEGO Technic frame plus printed parts. I tried a 3:1 reduction on the shoulder, couldn’t make it work, and direct drive turned out to be enough. Instead of inverse kinematics I recorded the motor angles for all 64 squares once (teach and playback), with the motors powered, because the arm bends differently when you move it by hand. The encoders are incremental, so the arm homes against physical stops every time it starts. Magnets and the gripper The arm carries a 12x3 mm N52 magnet that grabs a piece from about 8 mm away. Each piece has two 10x2 mm magnets, one on top for the arm and one underneath for the board, and every square has a 6x3 mm magnet below it. Neighboring pieces 32 mm away don’t move. A servo lowers the magnet, lifts the piece and releases it. Without the lift step the arm dragged pieces and knocked over the neighbors. Problems I had to solve Magnet holes modeled at exactly 10 mm were too tight, so I made them 10.1 to 10.2 mm to allow for FDM tolerance. The CyberPi doesn’t report its IP, so my Mac runs a TCP server and the CyberPi connects to it as a client. The CyberPi only sees 2.4 GHz WiFi. mBlock’s mlink kept the serial port locked until I ran pkill -f mlink. How the software is organized There are three nodes (vision, engine and arm) that talk through typed messages, ROS2 style. Each hardware part has a fake backend, so the 482 tests run without the robot, and there’s a fully simulated pipeline for testing a whole game. What’s next Tuning arm precision: re-recording the squares where the magnet doesn’t land centered and testing the robot more with people with blind people. Also im working on a demo video with the robot working coming soon"}, {"post_id": 7867, "ts": "2026-06-13T03:49:51Z", "hours": 0.4319, "text": "Added the 3d chess models for the project"}]...
|
Title: MAGNUS: DIY chess playing robot by @Leo_Zan Title: MAGNUS: DIY chess playing robot by @Leo_Zannoni | Stardance
Devlogs:
Added the 3d chess models for the project
What MAGNUS is MAGNUS is a robot that plays chess on a real board against a person and says its moves out loud in Spanish. I’m building it for PRONAFECYT 2026, Costa Rica’s national science fair, and the voice is there for accessibility: you can follow the game without looking at a screen. I started on february with my first 3D models. Today it plays full games by itself and narrates them. About the hours Hackatime only logged about 8.5 h, because it only counts time in the code editor when i downloaded the app. Most of the work was CAD, printing, assembling and testing the arm. My log puts the real total at 350+ hours Vision Every piece is a 22.5 mm disc with an ArUco 4x4_50 marker and a white ring around it for contrast. The four board corners have their own markers, so the board is found from any camera angle. The camera is my phone through Iriun. A piece only counts after 5 detections in a row, and a GameTracker compares what the camera sees against every legal move to work out what the human played, including castling and en passant. Engine Stockfish runs through python-chess with 10 difficulty levels. Stockfish can’t play below about 1320 Elo, so the four easiest levels choose worse moves on purpose. Every move comes with metadata for captures, castling, en passant and promotion, so the arm never has to know any chess. The arm Shoulder and elbow use the encoder motors from the mBot2 kit on a CyberPi, with a LEGO Technic frame plus printed parts. I tried a 3:1 reduction on the shoulder, couldn’t make it work, and direct drive turned out to be enough. Instead of inverse kinematics I recorded the motor angles for all 64 squares once (teach and playback), with the motors powered, because the arm bends differently when you move it by hand. The encoders are incremental, so the arm homes against physical stops every time it starts. Magnets and the gripper The arm carries a 12x3 mm N52 magnet that grabs a piece from about 8 mm away. Each piece has two 10x2 mm magnets, one on top for the arm and one underneath for the board, and every square has a 6x3 mm magnet below it. Neighboring pieces 32 mm away don’t move. A servo lowers the magnet, lifts the piece and releases it. Without the lift step the arm dragged pieces and knocked over the neighbors. Problems I had to solve Magnet holes modeled at exactly 10 mm were too tight, so I made them 10.1 to 10.2 mm to allow for FDM tolerance. The CyberPi doesn’t report its IP, so my Mac runs a TCP server and the CyberPi connects to it as a client. The CyberPi only sees 2.4 GHz WiFi. mBlock’s mlink kept the serial port locked until I ran pkill -f mlink. How the software is organized There are three nodes (vision, engine and arm) that talk through typed messages, ROS2 style. Each hardware part has a fake backend, so the 482 tests run without the robot, and there’s a fully simulated pipeline for testing a whole game. What’s next Tuning arm precision: re-recording the squares where the magnet doesn’t land centered and testing the robot more with people with blind people. Also im working on a demo video with the robot working coming soon...
|
1792630225.427695
|
1793235025.427695
|
|
42860
|
Devlogs+ by @armadillomike | Stardance
|
armadillomike
|
0
|
90.31
|
0
|
[]
|
[{"post_id": 81135, "ts": "202 [{"post_id": 81135, "ts": "2026-10-20T01:00:52Z", "hours": 1.2564, "text": "I fully added docker support for both the backend and frontend. Both repos have dockerfiles and the main repo has a docker-compose file and env files for both in the parent repo. Since i am going to use this from now it helps me replicate what is on the server side."}, {"post_id": 78214, "ts": "2026-10-10T00:10:45Z", "hours": 1.1578, "text": "When creating a devlog it now automatically adds time spent since the last devlog/project creation. It shows the time spent as soon as you select a project in the devlog creation menu. Also, in the project page it shows time spent."}, {"post_id": 76543, "ts": "2026-10-03T21:50:14Z", "hours": 5.5261, "text": "There is now a full system (on the backend) to add time to a devlog. The wakatime part was way easier to implement as you could just use oauth to get time spent, but hackatime your had to get both the user id and api key just to get the time spent. That being said, there are also new routes to get the time since the last devlog (or since 1900 if there is not one)."}, {"post_id": 74196, "ts": "2026-09-26T22:06:39Z", "hours": 6.7117, "text": "I have added full wakatime/hackatime support to the website. Once your Hackatime/Wakatime accounts are connected you can connect time project to Devlog+ projects. Once those are connected you can view all time logged for projects. This was one of the hardest parts to setup as when I updated what the api expected on the backend, i kept forgetting to update what the frontend was sending."}, {"post_id": 68905, "ts": "2026-09-16T00:37:46Z", "hours": 3.8442, "text": "I have made it so you can link your hackatime and wakatime account. There are buttons on your profile that redirect to oauth pages for their respective platforms. Once connected the button will change to disconnect hackatime/wakatime"}, {"post_id": 66286, "ts": "2026-09-12T01:08:10Z", "hours": 2.5411, "text": "I have unified the time tracking and added the ability to add time spent to both projects and devlogs. By unifying the time spent It is way easier to get time spent and other factors. I will soon implement all of the stuff I have worked on to the frontend."}, {"post_id": 63152, "ts": "2026-09-06T19:54:01Z", "hours": 2.5064, "text": "I have added support for wakatime. Just like the hackatime integration it only has the api routes right now."}, {"post_id": 61171, "ts": "2026-09-03T23:30:38Z", "hours": 1.8917, "text": "I have added hackatime support (kinda) I have only added it to the backend so if you somehow call the backend (i have CORS) you can link your hackatime account and view your projects"}, {"post_id": 58498, "ts": "2026-08-30T22:31:38Z", "hours": 0.8897, "text": "I have updated the nav bar to be more stylish. I found that react router has a NavLink component which is designed for navigation panels."}, {"post_id": 57755, "ts": "2026-08-30T01:09:14Z", "hours": 1.1883, "text": "I have made it easier to add a collaborator for a project. Instead of entering the user id, you now enter the users email. This is in both the add and remove collaborator forms."}, {"post_id": 56967, "ts": "2026-08-29T00:42:18Z", "hours": 0.8475, "text": "I have made some changes to the collaborator pages. Instead of user ids, it now displays their display name. I also added back buttons to most form."}, {"post_id": 56280, "ts": "2026-08-27T23:45:54Z", "hours": 0.3936, "text": "I have added a small QoL update to the unpublished devlogs page, before the devlogs publish and edit button were not part of the devlog card and you had a hard time knowing what devlog it was for, now the devlog info, publish and edit button are all grouped together."}, {"post_id": 55284, "ts": "2026-08-27T00:39:28Z", "hours": 0.9608, "text": "I added a small improvement to the create a devlog page. Instead of inputting a devlog id, you can now click on a dropdown that shows all the projects you own/collaborate on. Even though this is quite small, I think it will be a big QoL update."}, {"post_id": 54837, "ts": "2026-08-26T00:20:03Z", "hours": 0.7464, "text": "You can now view the projects a user has made! Below the users info on their page there is a section with all their projects. The backend is essentially just the get projects route but instead of /projects it is /projects/user/user_id"}, {"post_id": 53456, "ts": "2026-08-24T00:54:49Z", "hours": 3.6408, "text": "I have fully added a system to reset your password. Using the previously setup resend service I setup the ability to get sent password reset emails to your email. Inside the email there is a link to the password reset form that asks for your new password twice. To request a password reset email there is a link on the bottom of the login page that redirects to the reset page."}, {"post_id": 50706, "ts": "2026-08-20T01:11:18Z", "hours": 2.2603, "text": "I setup resend for email sending. I chose to use a subdomain (email.devlogs.plus) instead of the base domain because if its reputation is lowered it wont affect the base domain, only the subdomain. I tested it out with some help from my little brother."}, {"post_id": 48594, "ts": "2026-08-17T01:34:45Z", "hours": 1.3717, "text": "I have added a way to change your password. There is a new button on your user page that redirects to a password change form. The form requires your old password and the new password."}, {"post_id": 48485, "ts": "2026-08-16T21:09:45Z", "hours": 0.3103, "text": "I have setup an actual domain for Devlogs+ instead of the provided render domain ( https://devlogs-plus-frontend.onrender.com ) I have bought https://devlogs.plus . Nothing in the codebase itself has really changed except for some simple bug changes."}, {"post_id": 47829, "ts": "2026-08-16T01:34:33Z", "hours": 1.3636, "text": "I added page titles to all (it think) pages across Devlogs+. And by everything I mean every component that renders a full page. I also added a favicon to look more ✨professional✨"}, {"post_id": 47720, "ts": "2026-08-15T20:22:50Z", "hours": 0.7208, "text": "I fixed a couple small bugs that stem from deleting users. The first was one where the user card was not showing for deleted users which was kinda easy to fix. The second one was on the backend where the user id 0 (which is for deleted users) was not getting made. It was like that because the deployed backend uses Gunicorn instead of the Flask dev server (which I was using) uses a different way to start up the server."}, {"post_id": 47242, "ts": "2026-08-15T01:13:46Z", "hours": 1.9656, "text": "I have added the ability for users to delete their accounts. Deleting ones account removes their account, sets the user id for projects and devlogs to 0, and removes them as a collaborator"}, {"post_id": 46642, "ts": "2026-08-14T01:30:55Z", "hours": 0.6589, "text": "I added another OAuth option, HackClub! a new user can now sign up with their HackClub account (if they have one) or login (if the emails match) I will soon make it so you can link accounts to existing accounts even if the email does not match"}, {"post_id": 46570, "ts": "2026-08-13T21:57:34Z", "hours": 2.3122, "text": "I have implemented a system to login/register with Github. I chose to use Authlib for the OAuth implementation beacuse if I want to (hint hint) I can easily add other OAuth systems."}, {"post_id": 45965, "ts": "2026-08-12T19:48:34Z", "hours": 2.5303, "text": "I added a system to upload avatars and add them to your user page. It currently uses hackclub cdn to upload the files. I have also added a default avatar for anybody that has not set an avatar. Avatar images have been added to basically everything that uses a user. User page User card Your user page (/me) Edit page On the edit page it is instead used a preview window."}, {"post_id": 45407, "ts": "2026-08-11T20:40:10Z", "hours": 1.1653, "text": "I finally added a feed for devlogs. It works by using the route provided by the backend, getting the devlog id, using getSingleProject to get the rest of the details and then puts it all in a DevlogCard. The feed shows all the devlogs posted in order of recency across all projects (As long as they are published)"}, {"post_id": 44865, "ts": "2026-08-10T21:59:46Z", "hours": 1.4372, "text": "I added a couple things A seperate page for each user A card for each user The card for each user displays the display name and user id The user page shows everything (including email) The user card shows up on the individual pages for devlogs and projects"}, {"post_id": 44344, "ts": "2026-08-10T01:21:59Z", "hours": 1.4228, "text": "I added 2 things to the frontend a page to view your own info a page to edit your info. On the backend i added a bit more then 2 Get a users info by email Get a users info by user id Edit your own user info I will soon make it so you can view other peoples profiles (thats what the backend stuff is for)"}, {"post_id": 44217, "ts": "2026-08-09T20:39:48Z", "hours": 1.9647, "text": "I did a bit more styling fixes and also added field validation The field validation i added was to the login and register pages to only allow valid emails, and also to add collaborator and make devlog page to only allow numbers for things like project id and user id"}, {"post_id": 43570, "ts": "2026-08-08T21:58:59Z", "hours": 1.2872, "text": "More styling I styling the link on the navbar, Styled the project cards to match the devlogs card, Added a border to both of the devlog and project cards, Styled the markdown renderer, And fixed some styling issues like some buttons not being the new <Button> component"}, {"post_id": 43489, "ts": "2026-08-08T19:48:09Z", "hours": 2.3425, "text": "I started with some basic styling for the site. The color theme I choose to use was nord. I choose it because I like the blue. The styles that I did was basic site wide styling with the background and font. The font I chose was Stack Sans Text. I have also styled the input, textarea, and buttons components."}, {"post_id": 42368, "ts": "2026-08-07T01:40:11Z", "hours": 1.1581, "text": "I added the ability to remove collaborators from a project. There is a button on the project page blah blah blah New page to remove collaborators blah blah blah While making this I found a small bug because I forgot to put {} around 2 variables which broke the entire page and I didn’t spot it until 20 mins later"}, {"post_id": 42262, "ts": "2026-08-06T21:51:36Z", "hours": 1.8364, "text": "I added a way for everyone to view the collaborators for a project. Once again, there is a button on the project page that redirects to a separate page. On the collaborator page it shows the owner of the project and all the collaborator user ids."}, {"post_id": 41683, "ts": "2026-08-06T01:51:51Z", "hours": 1.4222, "text": "I added a way to add collaborators to a project. There is a button on the project page that redirects you to the page to add collaborators by their user id. Right now collaborators are just a fancy title but soon they will be able to post devlogs. You can view your own user id from the home page now."}, {"post_id": 40991, "ts": "2026-08-04T21:20:48Z", "hours": 0.3333, "text": "I just added a very simple feature. There is now a button on the unpublished devlogs page that brings you to the edit page. You could still edit devlogs that were unpublished but now it is easier to edit them."}, {"post_id": 40951, "ts": "2026-08-04T20:14:58Z", "hours": 1.2297, "text": "I added a way for you to unpublish your devlogs. On the devlog page if you are the owner. Clicking the button redirects you to a page where you can unpublish it. When you unpublish it (without and error) it redirects you backwards. After that you can republish it from the unpublished devlog page."}, {"post_id": 40486, "ts": "2026-08-04T01:37:14Z", "hours": 1.3139, "text": "I made it so you can now edit devlogs You can edit a devlog you made by the url /projects/projectid/devlogs/devlogid/edit You can change the title and the markdown body. There is also a button on the devlog page the shows up if you are the owner."}, {"post_id": 39810, "ts": "2026-08-03T01:31:45Z", "hours": 1.2967, "text": "I added a way to view a full devlog on its on specific page. The page has the devlogs title, body, published at, project id, and devlog id. You can also get to this page by clicking on the individual devlogs on the project page"}, {"post_id": 39213, "ts": "2026-08-02T01:08:28Z", "hours": 0.5239, "text": "I made it so you can add multiple lines to the body for projects and devlogs by changing the to I also added a markdown renderer to render the markdown correctly."}, {"post_id": 39165, "ts": "2026-08-01T22:13:48Z", "hours": 23.975, "text": "Bringing over time I am bringing over all my time that was spent on unfold as it ended $ next to it means backend only route Features Auth Login Register Logout View your info $ Projects Create a project View all projects Get singular project Edit a project Delete a project Add a collaborator to the project $ Remove a collaborator $ Devlogs Get all devlogs for a project Create a devlog Get singular devlog $ Edit a devlog $ Publish a devlog Unpublish a devlog $ Get your unpublished devlogs"}]...
|
Title: Devlogs+ by @armadillomike | Stardance
Dev Title: Devlogs+ by @armadillomike | Stardance
Devlogs:
Bringing over time I am bringing over all my time that was spent on unfold as it ended $ next to it means backend only route Features Auth Login Register Logout View your info $ Projects Create a project View all projects Get singular project Edit a project Delete a project Add a collaborator to the project $ Remove a collaborator $ Devlogs Get all devlogs for a project Create a devlog Get singular devlog $ Edit a devlog $ Publish a devlog Unpublish a devlog $ Get your unpublished devlogs
I made it so you can add multiple lines to the body for projects and devlogs by changing the to I also added a markdown renderer to render the markdown correctly.
I added a way to view a full devlog on its on specific page. The page has the devlogs title, body, published at, project id, and devlog id. You can also get to this page by clicking on the individual devlogs on the project page
I made it so you can now edit devlogs You can edit a devlog you made by the url /projects/projectid/devlogs/devlogid/edit You can change the title and the markdown body. There is also a button on the devlog page the shows up if you are the owner.
I added a way for you to unpublish your devlogs. On the devlog page if you are the owner. Clicking the button redirects you to a page where you can unpublish it. When you unpublish it (without and error) it redirects you backwards. After that you can republish it from the unpublished devlog page.
I just added a very simple feature. There is now a button on the unpublished devlogs page that brings you to the edit page. You could still edit devlogs that were unpublished but now it is easier to edit them.
I added a way to add collaborators to a project. There is a button on the project page that redirects you to the page to add collaborators by their user id. Right now collaborators are just a fancy title but soon they will be able to post devlogs. You can view your own user id from the home page now.
I added a way for everyone to view the collaborators for a project. Once again, there is a button on the project page that redirects to a separate page. On the collaborator page it shows the owner of the project and all the collaborator user ids.
I added the ability to remove collaborators from a project. There is a button on the project page blah blah blah New page to remove collaborators blah blah blah While making this I found a small bug because I forgot to put {} around 2 variables which broke the entire page and I didn’t spot it until 20 mins later
I started with some basic styling for the site. The color theme I choose to use was nord. I choose it because I like the blue. The styles that I did was basic site wide styling with the background and font. The font I chose was Stack Sans Text. I have also styled the input, textarea, and buttons components.
More styling I styling the link on the navbar, Styled the project cards to match the devlogs card, Added a border to both of the devlog and project cards, Styled the markdown renderer, And fixed some styling issues like some buttons not being the new <Button> component
I did a bit more styling fixes and also added field validation The field validation i added was to the login and register pages to only allow valid emails, and also to add collaborator and make devlog page to only allow numbers for things like project id and user id
I added 2 things to the frontend a page to view your own info a page to edit your info. On the backend i added a bit more then 2 Get a users info by email Get a users info by user id Edit your own user info I will soon make it so you can view other peoples profiles (thats what the backend stuff is for)
I added a couple things A seperate page for each user A card for each user The card for each user displays the display name and user id The user page shows everything (including email) The user card shows up on the individual pages for devlogs and projects
I finally added a feed for devlogs. It works by using the route provided by the backend, getting the devlog id, using getSingleProject to get the rest of the details and then puts it all in a DevlogCard. The feed shows all the devlogs posted in order of recency across all projects (As long as they are published)
I added a system to upload avatars and add them to your user page. It currently uses hackclub cdn to upload the files. I have also added a default avatar for anybody that has not set an avatar. Avatar images have been added to basically everything that uses a user. User page User card Your user page (/me) Edit page On the edit page it is instead used a preview window.
I have implemented a system to login/register with Github. I chose to use Authlib for the OAuth implementation beacuse if I want to (hint hint) I can easily add other OAuth systems.
I added another OAuth option, HackClub! a new user can now sign up with their HackClub account (if they have one) or login (if the emails match) I will soon make it so you can link accounts to existing accounts even if the email does not match
I have added the ability for users to delete their accounts. Deleting ones account removes their account, sets the user id for projects and devlogs to 0, and removes them as a collaborator
I fixed a couple small bugs that stem from deleting users. The first was one where the user card was not showing for deleted users which was kinda easy to fix. The second one was on the backend where the user id 0 (which is for deleted users) was not getting made. It was like that because the deployed backend uses Gunicorn instead of the Flask dev server (which I was using) uses a different way to start up the server.
I added page titles to all (it think) pages across Devlogs+. And by everything I mean every component that renders a full page. I also added a favicon to look more ✨professional✨
I have setup an actual domain for Devlogs+ instead of the provided render domain ( https://devlogs-plus-frontend.onrender.com ) I have bought https://devlogs.plus . Nothing in the codebase itself has really changed except for some simple bug changes.
I have added a way to change your password. There is a new button on your user page that redirects to a password change form. The form requires your old password and the new password.
I setup resend for email sending. I chose to use a subdomain (email.devlogs.plus) instead of the base domain because if its reputation is lowered it wont affect the base domain, only the subdomain. I tested it out with some help from my little brother.
I have fully added a system to reset your password. Using the previously setup resend service I setup the ability to get sent password reset emails to your email. Inside the email there is a link to the password reset form that asks for your new password twice. To request a password reset email there is a link on the bottom of the login page that redirects to the reset page.
You can now view the projects a user has made! Below the users info on their page there is a section with all their projects. The backend is essentially just the get projects route but instead of /projects it is /projects/user/user_id
I added a small improvement to the create a devlog page. Instead of inputting a devlog id, you can now click on a dropdown that shows all the projects you own/collaborate on. Even though this is quite small, I think it will be a big QoL update.
I have added a small QoL update to the unpublished devlogs page, before the devlogs publish and edit button were not part of the devlog card and you had a hard time knowing what devlog it was for, now the devlog info, publish and edit button are all grouped together.
I have made some changes to the collaborator pages. Instead of user ids, it now displays their display name. I also added back buttons to most form.
I have made it easier to add a collaborator for a project. Instead of entering the user id, you now enter the users email. This is in both the add and remove collaborator forms.
I have updated the nav bar to be more stylish. I found that react router has a NavLink component which is designed for navigation panels.
I have added hackatime support (kinda) I have only added it to the backend so if you somehow call the backend (i have CORS) you can link your hackatime account and view your projects
I have added support for wakatime. Just like the hackatime integration it only has the api routes right now.
I have unified the time tracking and added the ability to add time spent to both projects and devlogs. By unifying the time spent It is way easier to get time spent and other factors. I will soon implement all of the stuff I have worked on to the frontend.
I have made it so you can link your hackatime and wakatime account. There are buttons on your profile that redirect to oauth pages for their respective platforms. Once connected the button will change to disconnect hackatime/wakatime
I have added full wakatime/hackatime support to the website. Once your Hackatime/Wakatime accounts are connected you can connect time project to Devlog+ projects. Once those are connected you can view all time logged for projects. This was one of the hardest parts to setup as when I updated what the api expected on the backend, i kept forgetting to update what the frontend was sending.
There is now a full system (on the backend) to add time to a devlog. The wakatime part was way easier to implement as you could just use oauth to get time spent, but hackatime your had to get both the user id and api key just to get the time spent. That being said, there are also new routes to get the time since the last devlog (or since 1900 if there is not one).
When creating a devlog it now automatically adds time spent since the last devlog/project creation. It shows the time spent as soon as you select a project in the devlog creation menu. Also, in the project page it shows time spent.
I fully added docker support for both the backend and frontend. Both repos have dockerfiles and the main repo has a docker-compose file and env files for both in the parent repo. Since i am going to use this from now it helps me replicate what is on the server side....
|
1792525961.1655416
|
1793130761.1655416
|
|
57660
|
Program Framework by @Wiiwhbfidow | Stardance
|
Wiiwhbfidow
|
1
|
21.67
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-25T00:15:56Z", "hours": 14.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a simple framework that builds on the Single DirectMedia Library (an existing library) which helps to take care of some boilerplate and streamline programming projects. I finished the basics like rendering and a component system, but I plan to add more soon! Attached is a rough design diagram (made in Microsoft Paint)", "repo": "https://github.com/User-Name54321/BPFramework", "demo": "https://github.com/User-Name54321/BPFramework/releases/tag/Binaries"}]...
|
[{"post_id": 81136, "ts": "202 [{"post_id": 81136, "ts": "2026-10-20T01:04:45Z", "hours": 3.3481, "text": "New functioning audio system In the past few days, I have been working on implementing an audio system that relies on SDL_Mixer, a separate library from SDL. I decided to use SDL_Mixer because I did not want to manually manage the mixing of sounds and management of the different audio streams, like that of which I would need to do if I used SDL’s built in audio tools. I also dropped SDL_image from the library right now because it adds too many dependencies, and I don’t think the additional overhead is needed for my intended functionality right now. In the future, I was looking into incorporating WUFFS, which is a programming language that is built to guarantee memory safety when loading files. (link: https://github.com/google/wuffs ) I wasn’t really sure of what to put for my image, so I put an image of me stepping through and debugging my code because nothing was played. (Spoiler alert: I flipped an operator)"}, {"post_id": 78910, "ts": "2026-10-12T00:30:07Z", "hours": 4.3239, "text": "First, I worked a bit more on my observer system under the hood. Instead of relying on observer objects, the subject just takes a reference to a callback which is intended to be called on the subject’s notify(). The picture is a demo where anytime I press a key it prints “test.” I also went through my code and tried to leave comments which clarify the functions and usage of certain things, which should help to make it more usable. Also, my Git connection keeps breaking, which is enraging!"}, {"post_id": 73362, "ts": "2026-09-25T00:05:25Z", "hours": 0.5894, "text": "I finished wiring up a simple test render which uses the framework’s systems. I also worked a bit on cleaning up some of the code and labelling my intentions/future plans. I also verified that my build configurations were ok, and made sure I had no more memory issues."}, {"post_id": 72486, "ts": "2026-09-23T02:07:10Z", "hours": 6.6931, "text": "I cobbled together a component system which allows for the creation of two types of containers. One strictly contains data, while the other one is slower but can also contain references to other components and functions. I based quite a bit of this on some of the patterns I read in “Game Programming Patterns” by Robert Nystrom, and I really recommend it if you are interested. In addition to that, I had a “small” (massive) memory leak which resulted from me misunderstanding the way SDL handles rendering, so I got it to render stuff and clear the command queue which fixed that. I also started a little bit on a logging system which also uses SDL, but I want to make it more natural to use and more fitting with the way I designed this library."}, {"post_id": 69876, "ts": "2026-09-17T23:50:57Z", "hours": 6.8017, "text": "Started basic window management, input systems, and texture rendering. More soon!"}]...
|
Title: Program Framework by @Wiiwhbfidow | Stardan Title: Program Framework by @Wiiwhbfidow | Stardance
Devlogs:
Started basic window management, input systems, and texture rendering. More soon!
I cobbled together a component system which allows for the creation of two types of containers. One strictly contains data, while the other one is slower but can also contain references to other components and functions. I based quite a bit of this on some of the patterns I read in “Game Programming Patterns” by Robert Nystrom, and I really recommend it if you are interested. In addition to that, I had a “small” (massive) memory leak which resulted from me misunderstanding the way SDL handles rendering, so I got it to render stuff and clear the command queue which fixed that. I also started a little bit on a logging system which also uses SDL, but I want to make it more natural to use and more fitting with the way I designed this library.
I finished wiring up a simple test render which uses the framework’s systems. I also worked a bit on cleaning up some of the code and labelling my intentions/future plans. I also verified that my build configurations were ok, and made sure I had no more memory issues.
First, I worked a bit more on my observer system under the hood. Instead of relying on observer objects, the subject just takes a reference to a callback which is intended to be called on the subject’s notify(). The picture is a demo where anytime I press a key it prints “test.” I also went through my code and tried to leave comments which clarify the functions and usage of certain things, which should help to make it more usable. Also, my Git connection keeps breaking, which is enraging!
New functioning audio system In the past few days, I have been working on implementing an audio system that relies on SDL_Mixer, a separate library from SDL. I decided to use SDL_Mixer because I did not want to manually manage the mixing of sounds and management of the different audio streams, like that of which I would need to do if I used SDL’s built in audio tools. I also dropped SDL_image from the library right now because it adds too many dependencies, and I don’t think the additional overhead is needed for my intended functionality right now. In the future, I was looking into incorporating WUFFS, which is a programming language that is built to guarantee memory safety when loading files. (link: https://github.com/google/wuffs ) I wasn’t really sure of what to put for my image, so I put an image of me stepping through and debugging my code because nothing was played. (Spoiler alert: I flipped an operator)
Ships:
I made a simple framework that builds on the Single DirectMedia Library (an existing library) which helps to take care of some boilerplate and streamline programming projects. I finished the basics like rendering and a component system, but I plan to add more soon! Attached is a rough design diagram (made in Microsoft Paint)...
|
1792853842.2136784
|
1792940242.2136784
|
|
70564
|
Orbit by @amirmzte13 | Stardance
|
amirmzte13
|
0
|
10.31
|
0
|
[]
|
[{"post_id": 81137, "ts": "202 [{"post_id": 81137, "ts": "2026-10-20T01:04:53Z", "hours": 10.3089, "text": "Currently working on organizing the folders and linking this to vercel."}]...
|
Title: Orbit by @amirmzte13 | Stardance
Devlogs:
Title: Orbit by @amirmzte13 | Stardance
Devlogs:
Currently working on organizing the folders and linking this to vercel....
|
1792460826.878622
|
1793065626.878622
|
|
41865
|
Dungeon climber by @SiddhantVerma_04 | Stardance
|
SiddhantVerma_04
|
1
|
33.41
|
399
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-08-20T14:28:37Z", "hours": 20.0, "multiplier": 19.54, "payout": 399, "blessing": "neutral", "text": "Dungeon Climber A 2d platformer made in Godot 4 about a knight stuck in a dungeon. This is my game about a knight stuck in a dungeon trying to escape while opening chests along the way and not dying. This is my first Godot game that i made after a long time and it took me a while to learn Godot’s language and system, but I came back to it because I love creating games and I want to make many more in the future. You can play it on it’s itch.io page by clicking the button below. Please give me some feedback for future projects. Thank you for your time!", "repo": "https://github.com/siddhantverma04/dungeon-climber", "demo": "https://hacr7.itch.io/dungeon-climber"}]...
|
[{"post_id": 81138, "ts": "202 [{"post_id": 81138, "ts": "2026-10-20T01:20:13Z", "hours": 3.1644, "text": "Devlog 9 Finished level 2 I added a lot of new features since the last devlog but the most prominent maybe would be dialogue! I basically created a villager that you can talk to just to give you some instruction on what to do. Other than that I added more to the actual level and added another fox near the end. And I ended it with a castle that you have to enter."}, {"post_id": 72052, "ts": "2026-09-22T02:44:30Z", "hours": 5.7467, "text": "Devlog 8 Big update Continued building the game, and started by adding another level. This level will be above ground, with new enemies and features. So far I have set it up for building, as well as added a fox, that took way too much time to code its death, and animations. I will also add other animals soon. I finished up the enemies in the first level too. But currently haven’t added any more sound effects or music for the new stuff."}, {"post_id": 68366, "ts": "2026-09-15T00:46:53Z", "hours": 4.4953, "text": "Devlog 7 Added simple enemies. Shipped a while ago but decided to continue on the game. I chose to first start making some new enemies. It was easy until I had to code the animations and health loss, so a lot of my time went into that. But I pretty much got it to work. I still need to code the death of the enemy though."}, {"post_id": 51005, "ts": "2026-08-20T14:25:21Z", "hours": 1.0708, "text": "Devlog 6 Finished the game! Made some tweaks and then exported the game. I then made my own page on itch.io and uploaded the game there. Dungeon Climber is now live so go check it out!"}, {"post_id": 49902, "ts": "2026-08-18T21:19:03Z", "hours": 2.9467, "text": "Devlog 5 Added a win screen and a game over screen I created a simple win and lose screen with a restart and quit option each. It took a long time to make the win screen animation, but the music for both of them was really easy. I’m fairly done with the game, and just need to make some tweaks and fixes until I’m ready to ship."}, {"post_id": 48341, "ts": "2026-08-16T17:32:01Z", "hours": 4.0333, "text": "Devlog 4 Added music and sound effects. Put some background music for the main menu and level, and had to figure out how to make transitions between them using tweens. Also made some sound effects for stuff like opening chests and taking damage."}, {"post_id": 46430, "ts": "2026-08-13T17:04:46Z", "hours": 4.4311, "text": "Devlog 3 Added a health and points system. Created a simple health system with 3 lives that resets the level when you lose all of them. Took a long time for debugging and fixing the code to make the player die properly but I was finally able to make it work. Along with that I also made a point system which just counts the amount of chests you open, which was easy enough. Also made some changes to the main menu animations."}, {"post_id": 44923, "ts": "2026-08-11T00:04:59Z", "hours": 3.8533, "text": "Devlog 2 Finished level building, and added a main menu. It took about an hour just to find and extend the image for the animation, but actually making the animation was relatively easy. I also made sure the character can’t move after going in the exit door."}, {"post_id": 43004, "ts": "2026-08-08T01:06:07Z", "hours": 4.0833, "text": "Devlog 1/Catch up: Over the summer I was working on a 2d platformer in Godot about a knight that’s stuck in a dungeon. However, I just turned 13 so I couldn’t track those hours or post any updates. So this will serve as a “catch up” of everything I did in that time. I also followed some Coco Code tutorials along the way but mainly did it myself and did my own things. I have separated everything I did into 4 parts, with the last being what the currently logged hours are for. Part 1: I found and imported some asset packs (sprites, backgrounds, tilesheets) into the project. Created a tilemap and background(also added physics collisions). Started building some of the game. Added a CharacterBody2d, and its AnimatedSprite2d and collision shape. Also added the animations for the character. Wrote the core movement for the character set up player input mappings for wasd and arrow keys. Part 2: Added a Camera2d to the player so that the camera follows the player. Created ladders using the tilemap and coded their movement. Made moving and static platforms using an AnimatableBody2d and an AnimationPlayer(for the moving ones). Also added chests that you can find throughout the level and open(they currently don’t give or do anything). Part 3: Added traps(spikes), that reset the level. Continued building the level. Added an exit door and made its animation. Added an animation for ladder climbing."}]...
|
Title: Dungeon climber by @SiddhantVerma_04 | Star Title: Dungeon climber by @SiddhantVerma_04 | Stardance
Devlogs:
Devlog 1/Catch up: Over the summer I was working on a 2d platformer in Godot about a knight that’s stuck in a dungeon. However, I just turned 13 so I couldn’t track those hours or post any updates. So this will serve as a “catch up” of everything I did in that time. I also followed some Coco Code tutorials along the way but mainly did it myself and did my own things. I have separated everything I did into 4 parts, with the last being what the currently logged hours are for. Part 1: I found and imported some asset packs (sprites, backgrounds, tilesheets) into the project. Created a tilemap and background(also added physics collisions). Started building some of the game. Added a CharacterBody2d, and its AnimatedSprite2d and collision shape. Also added the animations for the character. Wrote the core movement for the character set up player input mappings for wasd and arrow keys. Part 2: Added a Camera2d to the player so that the camera follows the player. Created ladders using the tilemap and coded their movement. Made moving and static platforms using an AnimatableBody2d and an AnimationPlayer(for the moving ones). Also added chests that you can find throughout the level and open(they currently don’t give or do anything). Part 3: Added traps(spikes), that reset the level. Continued building the level. Added an exit door and made its animation. Added an animation for ladder climbing.
Devlog 2 Finished level building, and added a main menu. It took about an hour just to find and extend the image for the animation, but actually making the animation was relatively easy. I also made sure the character can’t move after going in the exit door.
Devlog 3 Added a health and points system. Created a simple health system with 3 lives that resets the level when you lose all of them. Took a long time for debugging and fixing the code to make the player die properly but I was finally able to make it work. Along with that I also made a point system which just counts the amount of chests you open, which was easy enough. Also made some changes to the main menu animations.
Devlog 4 Added music and sound effects. Put some background music for the main menu and level, and had to figure out how to make transitions between them using tweens. Also made some sound effects for stuff like opening chests and taking damage.
Devlog 5 Added a win screen and a game over screen I created a simple win and lose screen with a restart and quit option each. It took a long time to make the win screen animation, but the music for both of them was really easy. I’m fairly done with the game, and just need to make some tweaks and fixes until I’m ready to ship.
Devlog 6 Finished the game! Made some tweaks and then exported the game. I then made my own page on itch.io and uploaded the game there. Dungeon Climber is now live so go check it out!
Devlog 7 Added simple enemies. Shipped a while ago but decided to continue on the game. I chose to first start making some new enemies. It was easy until I had to code the animations and health loss, so a lot of my time went into that. But I pretty much got it to work. I still need to code the death of the enemy though.
Devlog 8 Big update Continued building the game, and started by adding another level. This level will be above ground, with new enemies and features. So far I have set it up for building, as well as added a fox, that took way too much time to code its death, and animations. I will also add other animals soon. I finished up the enemies in the first level too. But currently haven’t added any more sound effects or music for the new stuff.
Devlog 9 Finished level 2 I added a lot of new features since the last devlog but the most prominent maybe would be dialogue! I basically created a villager that you can talk to just to give you some instruction on what to do. Other than that I added more to the actual level and added another fox near the end. And I ended it with a castle that you have to enter.
Ships:
Dungeon Climber A 2d platformer made in Godot 4 about a knight stuck in a dungeon. This is my game about a knight stuck in a dungeon trying to escape while opening chests along the way and not dying. This is my first Godot game that i made after a long time and it took me a while to learn Godot’s language and system, but I came back to it because I love creating games and I want to make many more in the future. You can play it on it’s itch.io page by clicking the button below. Please give me some feedback for future projects. Thank you for your time!...
|
1792842834.4387908
|
1792929234.4387908
|
|
4994
|
Tamagochi pet by @S0l4Ce | Stardance
|
S0l4Ce
|
1
|
52.03
|
0
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-09-20T05:08:22Z", "hours": 45.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a tamagotchi pet (i am aware that throughout the project, the spelling of it has been inconsistent) But anyway, what i found most challenging was having to look through the loop constantly making adjustments based off minor errors during each test run and incorrect wiring making me feel like i had the code wrong. I am proud that I learned surprisingly a lot. The screenshot is merely just part of it and you should check it out yourself! both the source for the software and hardware is in there. The latest software build is in a separate branch and you may need to scope around for the latest hardware build. PLEASE note that all of the hardware additions - if you truly want to build it yourself, is pushing the limits of the esp32 so please run it while using a powerful cable.", "repo": "https://github.com/mootonlee/tamagotchi-", "demo": ""}]...
|
[{"post_id": 81143, "ts": "202 [{"post_id": 81143, "ts": "2026-10-20T02:14:13Z", "hours": 1.0578, "text": "spent this hour troubleshooting and figuring out how to add wires. was super unsucessful and wasted my time. im pretty annoyed"}, {"post_id": 80851, "ts": "2026-10-19T00:50:55Z", "hours": 2.3, "text": "Finished adding modules like the LEDs, resistors, etc. All i need now is the wiring which i heard is tedious"}, {"post_id": 80585, "ts": "2026-10-18T07:04:57Z", "hours": 1.4167, "text": "Im very proud of my work! i finished up the screen, fixed misalignments, ensured precision, and in the end, everything fit perfectly!"}, {"post_id": 80513, "ts": "2026-10-17T22:48:45Z", "hours": 2.26, "text": "got mad countless times. Im doing my CAD for my project because youll now get permanently rejected if you miss it and i never knew. Im making the screen myself because i cant find it online. Below is a picture of how its assembled so far, and i would post the part im making right now but this just looks better. Also, does the CAD have to be fully accurate? ive never done a CAD before so parts i make myself may look off but ill try my best to make the measurements right."}, {"post_id": 70980, "ts": "2026-09-20T04:48:45Z", "hours": 6.0014, "text": "finally finished the 2nd personality. will be shipping my project. only thing left to do is fix bugs (i already scanned software and hardware for bugs. though the code seems somewhat contradictory to itself, it still works but please report bugs under this one’s comment and check out my submission and the demo video!"}, {"post_id": 63407, "ts": "2026-09-07T07:10:06Z", "hours": 1.4625, "text": "im starting work on the radiobuttons for interchangable personality to wrap up the project. im using placeholders so the face looks red if the radiobuttons are selected so it would look unpleasant to see but yeah"}, {"post_id": 59986, "ts": "2026-09-02T02:11:14Z", "hours": 2.4203, "text": "Got back on track, finally! It now gets visibly dim below 50 value on light, and dark below 25, along with squint and sleep. Im now going to begin working on the other expressions after I finish adding the dim to smile and alone faces. This thing is ending soon so idk if i will be able to add the computer control functions as promised :( I also switched to cachyos so Idk how that would go either. Check out the hardware version on my page though! its finished"}, {"post_id": 52633, "ts": "2026-08-22T21:16:19Z", "hours": 0.5211, "text": "My windows OS broke, not sure how, so im running on my second SSD and my most recent work has been erased! (software version) random thumbnail ig but im gonna be re-doing whatever has been erased.."}, {"post_id": 41108, "ts": "2026-08-05T03:07:48Z", "hours": 3.4297, "text": "finally added a sleep system, dimming system, and a fully fixed and functional lonely system. when lights are at or below 50, the lights will go dim, and below 25, they will go even dimmer, and it will sleep (software) I will the face variants next, and then actual interactive computer controls. shy and moody are still not ready yet"}, {"post_id": 34593, "ts": "2026-07-25T13:29:57Z", "hours": 2.5967, "text": "added lonely, smile, and neutral, also added placeholders for the soon to be added personalities and a brightness slider. Both are unfunctional and i only have the 3 faces for now. go check out my hardware version, its fully functional"}, {"post_id": 32247, "ts": "2026-07-21T09:09:49Z", "hours": 1.2072, "text": "working on a software version of my project 🔥 I main micropython but I’m adjusting to python for this and learning the different ways things are written, and figuring out how to make faces. Can anyone tell me if theres a designer that gives you the code when you draw something on a canvas? similar to lopaka?? The software version is projected to have more features for computer control than the hardware version. After finishing the faces and overall logic, I will add the additional side controls for it, like light and stuff"}, {"post_id": 32144, "ts": "2026-07-21T03:23:42Z", "hours": 9.8794, "text": "built an extension for the pet. It connects to the pet using gnd and 4 labeled gpio pins, though the 4th one connects to 0 and not 40. It works somewhat like a stream deck; It opens 2 games, 2 code editors, a browser, and shuts off or closes tabs on my computer without needing special permissions, it is built for windows though. Most of the hours logged came from trial and error. Most of the time the buttons wouldnt register, spam the same commands, double clicks wouldnt register, and it was a mess for hours. did some bugfixes involving screen bugs during personality swaps, and the pet “forgetting” its personality. please suggest additional ideas."}, {"post_id": 30476, "ts": "2026-07-18T02:37:34Z", "hours": 1.7375, "text": "Rewired to remove clutter. Back isn’t looking too good but the front is, when I run out of ideas ill probably build a shell for it please make recommendations"}, {"post_id": 30124, "ts": "2026-07-17T13:22:42Z", "hours": 2.4481, "text": "Added another personality, shy. added “cores” that determine the personality when plugged in, red for moody and blue for shy. unplug for normal. The shy personality features new unique faces. led colors and shaken face remain same"}, {"post_id": 29977, "ts": "2026-07-17T06:07:54Z", "hours": 1.6644, "text": "Ignore devlog: Tried making online demo but i pressed a button and all my tabs refreshed all at once and reset my work. Im publishing the devlog because i still did the work and i dont want it to go to waste (IGNORE THIS DEVLOG)"}, {"post_id": 29812, "ts": "2026-07-16T23:08:57Z", "hours": 3.2333, "text": "Added extra personality. If you plug a red LED in, it will get a more of a moody personality. It will look angry, sleep angry, and will usually just be angry (shaken face does not change.) unplugging the red LED will make it instantly revert to default personality let me know other interchangeable personalities I should add, or other software and hardware suggestions. Thanks."}, {"post_id": 28868, "ts": "2026-07-15T13:02:50Z", "hours": 2.6472, "text": "Added a gyroscope so the pet can become dizzy when shook. It features a red backlight, and remains dizzy for about 5 seconds. It was really a 20-30 minute setup after learning how to code and use one, and installing the libraries, but that extra addition turned into hours of additional troubleshooting since I was unfamiliar with the hardware. I eventually got it working after plenty of trial and error, and the real issue was just a couple lines of code. I’m unfortunately not getting much views, which is discouraging, but if you do come across this and decide to click on it, please suggest something in the comments. Thanks."}, {"post_id": 28151, "ts": "2026-07-14T08:19:06Z", "hours": 0.6217, "text": "Added status lights; finishing off full basic functionality for the pet. any additional features would be improvements, hardware additions, and wiring. full explanation of functions below: The “pet” is a TFT resistive touchscreen. Its face, as you can see, is a simple white and black pixelated look. 4 functions (for now): lonely - after 30 seconds of no interaction, after waking up or not being pet, it will become lonely, which is a sad face of course. The backlight glows a gloomy blue, slightly purple. neutral - base face, the pet is neutral when it isn’t lonely, had just woken up, and had recently been pet. the 3 other moods can occur when it is neutral. the backlight is white. sleeping - when the ambient light is low enough the pet will sleep. It cannot be disturbed and cannot become lonely until woken up. This is what i personally thought was a nice addition to the pet and would bring more realism and life to the pet. This is done by having a photocell near the face for most light accuracy. the backlight features a light purple blue. happy - when you pet it (or interact with the screen), it will smile. the blush being blue and not red was both intentional and unintentional feature. The color system is inverted same with the screen rotation. I did not know how to correct it but i felt the blue looked different and I kinda liked it so I didn’t spend extra time troubleshooting. the backlight features a bright hot pink color. PLEASE add any suggestions and I will likely consider, like adding a thermistor, weather, USB OTG, etc. When i feel like it, I may add a USB mode where it can do things on my computer when plugged in, like opening an app or powering off my computer. (the 35 minutes logged was for fixing the code and adding the lights. Not the full code itself.)"}, {"post_id": 27970, "ts": "2026-07-13T22:34:39Z", "hours": 3.7561, "text": "added functionality to the pet and added made a separate smaller one. It now has multiple moods with the ability to sleep when lights are dimmed enough."}, {"post_id": 16541, "ts": "2026-06-26T22:02:40Z", "hours": 1.0939, "text": "working on the wiring of the tomogachi pet n stuff no coding yet has a touchscreen now"}]...
|
Title: Tamagochi pet by @S0l4Ce | Stardance
Devlo Title: Tamagochi pet by @S0l4Ce | Stardance
Devlogs:
working on the wiring of the tomogachi pet n stuff no coding yet has a touchscreen now
added functionality to the pet and added made a separate smaller one. It now has multiple moods with the ability to sleep when lights are dimmed enough.
Added status lights; finishing off full basic functionality for the pet. any additional features would be improvements, hardware additions, and wiring. full explanation of functions below: The “pet” is a TFT resistive touchscreen. Its face, as you can see, is a simple white and black pixelated look. 4 functions (for now): lonely - after 30 seconds of no interaction, after waking up or not being pet, it will become lonely, which is a sad face of course. The backlight glows a gloomy blue, slightly purple. neutral - base face, the pet is neutral when it isn’t lonely, had just woken up, and had recently been pet. the 3 other moods can occur when it is neutral. the backlight is white. sleeping - when the ambient light is low enough the pet will sleep. It cannot be disturbed and cannot become lonely until woken up. This is what i personally thought was a nice addition to the pet and would bring more realism and life to the pet. This is done by having a photocell near the face for most light accuracy. the backlight features a light purple blue. happy - when you pet it (or interact with the screen), it will smile. the blush being blue and not red was both intentional and unintentional feature. The color system is inverted same with the screen rotation. I did not know how to correct it but i felt the blue looked different and I kinda liked it so I didn’t spend extra time troubleshooting. the backlight features a bright hot pink color. PLEASE add any suggestions and I will likely consider, like adding a thermistor, weather, USB OTG, etc. When i feel like it, I may add a USB mode where it can do things on my computer when plugged in, like opening an app or powering off my computer. (the 35 minutes logged was for fixing the code and adding the lights. Not the full code itself.)
Added a gyroscope so the pet can become dizzy when shook. It features a red backlight, and remains dizzy for about 5 seconds. It was really a 20-30 minute setup after learning how to code and use one, and installing the libraries, but that extra addition turned into hours of additional troubleshooting since I was unfamiliar with the hardware. I eventually got it working after plenty of trial and error, and the real issue was just a couple lines of code. I’m unfortunately not getting much views, which is discouraging, but if you do come across this and decide to click on it, please suggest something in the comments. Thanks.
Added extra personality. If you plug a red LED in, it will get a more of a moody personality. It will look angry, sleep angry, and will usually just be angry (shaken face does not change.) unplugging the red LED will make it instantly revert to default personality let me know other interchangeable personalities I should add, or other software and hardware suggestions. Thanks.
Ignore devlog: Tried making online demo but i pressed a button and all my tabs refreshed all at once and reset my work. Im publishing the devlog because i still did the work and i dont want it to go to waste (IGNORE THIS DEVLOG)
Added another personality, shy. added “cores” that determine the personality when plugged in, red for moody and blue for shy. unplug for normal. The shy personality features new unique faces. led colors and shaken face remain same
Rewired to remove clutter. Back isn’t looking too good but the front is, when I run out of ideas ill probably build a shell for it please make recommendations
built an extension for the pet. It connects to the pet using gnd and 4 labeled gpio pins, though the 4th one connects to 0 and not 40. It works somewhat like a stream deck; It opens 2 games, 2 code editors, a browser, and shuts off or closes tabs on my computer without needing special permissions, it is built for windows though. Most of the hours logged came from trial and error. Most of the time the buttons wouldnt register, spam the same commands, double clicks wouldnt register, and it was a mess for hours. did some bugfixes involving screen bugs during personality swaps, and the pet “forgetting” its personality. please suggest additional ideas.
working on a software version of my project 🔥 I main micropython but I’m adjusting to python for this and learning the different ways things are written, and figuring out how to make faces. Can anyone tell me if theres a designer that gives you the code when you draw something on a canvas? similar to lopaka?? The software version is projected to have more features for computer control than the hardware version. After finishing the faces and overall logic, I will add the additional side controls for it, like light and stuff
added lonely, smile, and neutral, also added placeholders for the soon to be added personalities and a brightness slider. Both are unfunctional and i only have the 3 faces for now. go check out my hardware version, its fully functional
finally added a sleep system, dimming system, and a fully fixed and functional lonely system. when lights are at or below 50, the lights will go dim, and below 25, they will go even dimmer, and it will sleep (software) I will the face variants next, and then actual interactive computer controls. shy and moody are still not ready yet
My windows OS broke, not sure how, so im running on my second SSD and my most recent work has been erased! (software version) random thumbnail ig but im gonna be re-doing whatever has been erased..
Got back on track, finally! It now gets visibly dim below 50 value on light, and dark below 25, along with squint and sleep. Im now going to begin working on the other expressions after I finish adding the dim to smile and alone faces. This thing is ending soon so idk if i will be able to add the computer control functions as promised :( I also switched to cachyos so Idk how that would go either. Check out the hardware version on my page though! its finished
im starting work on the radiobuttons for interchangable personality to wrap up the project. im using placeholders so the face looks red if the radiobuttons are selected so it would look unpleasant to see but yeah
finally finished the 2nd personality. will be shipping my project. only thing left to do is fix bugs (i already scanned software and hardware for bugs. though the code seems somewhat contradictory to itself, it still works but please report bugs under this one’s comment and check out my submission and the demo video!
got mad countless times. Im doing my CAD for my project because youll now get permanently rejected if you miss it and i never knew. Im making the screen myself because i cant find it online. Below is a picture of how its assembled so far, and i would post the part im making right now but this just looks better. Also, does the CAD have to be fully accurate? ive never done a CAD before so parts i make myself may look off but ill try my best to make the measurements right.
Im very proud of my work! i finished up the screen, fixed misalignments, ensured precision, and in the end, everything fit perfectly!
Finished adding modules like the LEDs, resistors, etc. All i need now is the wiring which i heard is tedious
spent this hour troubleshooting and figuring out how to add wires. was super unsucessful and wasted my time. im pretty annoyed
Ships:
I made a tamagotchi pet (i am aware that throughout the project, the spelling of it has been inconsistent) But anyway, what i found most challenging was having to look through the loop constantly making adjustments based off minor errors during each test run and incorrect wiring making me feel like i had the code wrong. I am proud that I learned surprisingly a lot. The screenshot is merely just part of it and you should check it out yourself! both the source for the software and hardware is in there. The latest software build is in a separate branch and you may need to scope around for the latest hardware build. PLEASE note that all of the hardware additions - if you truly want to build it yourself, is pushing the limits of the esp32 so please run it while using a powerful cable....
|
1792853584.076833
|
1792939984.076833
|