|
67515
|
My awesome macropad! by @veltrix | Stardance
|
veltrix
|
0
|
14.51
|
0
|
[]
|
[{"post_id": 79489, "ts": "202 [{"post_id": 79489, "ts": "2026-10-14T08:48:02Z", "hours": 5.7189, "text": "finally! MY PCB IS DONEEE!! YAYYY!! >.<"}, {"post_id": 77857, "ts": "2026-10-08T15:40:00Z", "hours": 0.3061, "text": "iam a little busy today T^T"}, {"post_id": 77586, "ts": "2026-10-07T15:32:31Z", "hours": 0.8289, "text": "PCB part 4 TvT"}, {"post_id": 77312, "ts": "2026-10-06T14:51:34Z", "hours": 0.8964, "text": "PCB part 3 TwT."}, {"post_id": 77057, "ts": "2026-10-05T14:41:18Z", "hours": 0.7558, "text": "PCB part 2šš"}, {"post_id": 76768, "ts": "2026-10-04T15:04:03Z", "hours": 1.3244, "text": "PCB design part-1"}, {"post_id": 76313, "ts": "2026-10-03T05:02:53Z", "hours": 0.4122, "text": "YAYYY!! done with schematics!"}, {"post_id": 76220, "ts": "2026-10-02T18:29:43Z", "hours": 4.2664, "text": "My first build!! Iām working on a hackpad."}]...
|
Title: My awesome macropad! by @veltrix | Stardanc Title: My awesome macropad! by @veltrix | Stardance
Devlogs:
My first build!! Iām working on a hackpad.
YAYYY!! done with schematics!
PCB design part-1
PCB part 2šš
PCB part 3 TwT.
PCB part 4 TvT
iam a little busy today T^T
finally! MY PCB IS DONEEE!! YAYYY!! >.<...
|
1793112543.070326
|
1793717343.070326
|
|
69629
|
BetterW4 by @jonbng | Stardance
|
jonbng
|
1
|
6.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-21T10:38:47Z", "hours": 6.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Hey everybody! This is my first launch of my project BetterW4! It is a mobile app for my own high school that allows students to interact with the school platform we use (W4). Its a mobile app made in kotlin for Android and Swift (UI) for ios. We released it on both on the play and app store and already more than 80% of my school is using it. It has several features, the mainof them being easily being able to see your schedule and if classes are canceled and seeing your abences.", "repo": "https://github.com/jonbng/betterw4", "demo": "https://play.google.com/store/apps/details?id=dk.jonathanb.w4"}]...
|
[{"post_id": 79493, "ts": "202 [{"post_id": 79493, "ts": "2026-10-14T09:25:01Z", "hours": 5.6669, "text": "Released the first public version of the BetterW4 app to both android and IOS! To make the app I based it off of another app i made (BetterLectio) and modified it to work with the W4 platform. The app is already being used by more than 80% of my school of around 200 students already which is really cool :)"}]...
|
Title: BetterW4 by @jonbng | Stardance
Devlogs:
R Title: BetterW4 by @jonbng | Stardance
Devlogs:
Released the first public version of the BetterW4 app to both android and IOS! To make the app I based it off of another app i made (BetterLectio) and modified it to work with the W4 platform. The app is already being used by more than 80% of my school of around 200 students already which is really cool :)
Ships:
Hey everybody! This is my first launch of my project BetterW4! It is a mobile app for my own high school that allows students to interact with the school platform we use (W4). Its a mobile app made in kotlin for Android and Swift (UI) for ios. We released it on both on the play and app store and already more than 80% of my school is using it. It has several features, the mainof them being easily being able to see your schedule and if classes are canceled and seeing your abences....
|
1793155929.5660388
|
1793242329.5660388
|
|
69619
|
Ferrari chrome by @sqnder_ | Stardance
|
sqnder_
|
1
|
1.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T09:48:36Z", "hours": 1.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I built a daily ferari generator. Every day it shows a diffrent ferrari, you can go back to past dates.", "repo": "https://github.com/sqnder0/ferrari-of-the-day", "demo": "https://sqnder0.github.io/ferrari-of-the-day/"}]...
|
[{"post_id": 79496, "ts": "202 [{"post_id": 79496, "ts": "2026-10-14T09:47:34Z", "hours": 1.2575, "text": "This was a rather short project ācause I already have a lot of expierence developing frontend stuff. It was a rather interesting project ācause I didnāt now I could use vite for gh pages and havenāt really ever written a github workflow."}]...
|
Title: Ferrari chrome by @sqnder_ | Stardance
Dev Title: Ferrari chrome by @sqnder_ | Stardance
Devlogs:
This was a rather short project ācause I already have a lot of expierence developing frontend stuff. It was a rather interesting project ācause I didnāt now I could use vite for gh pages and havenāt really ever written a github workflow.
Ships:
I built a daily ferari generator. Every day it shows a diffrent ferrari, you can go back to past dates....
|
1793155923.6068454
|
1793242323.6068454
|
|
29560
|
WarioWare Game by @NC | Stardance
|
NC
|
2
|
9.0
|
6
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T10:02:59Z", "hours": 2.0, "multiplier": 3.42, "payout": 6, "blessing": "neutral", "text": "I made my WarioWare Game for the 2nd mission. Something I changed was all the assets. I made them all by myself in Piskel! I made 5 minigames Minigame 1 - Collect all the pieces of garlic as Wario before the timer runs out Minigame 2 - Click all the pieces of garlic before the timer runs out Minigame 3 - Dodge the Boulders until the timer runs out Minigame 4 - Parkour up the platforms as the orange lava rises Minigame 5 - Jump over the Koopa Shells before time runs out", "repo": "https://github.com/NCGameMaking/WarioWare", "demo": "https://ncgamemaking.itch.io/warioware"}, {"ship_num": 2, "ts": "2026-07-04T01:46:29Z", "hours": 7.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "A Warioware style minigame project. Fast-paced levels with a life system. Custom lose screen interface tracking score. I made a WarioWare themed game with 5 minigames in total. You have to beat all 5 minigames What I found was challenging was designing and creating my own minigames as well as linking my own minigames to the ones in the guide. What I am most proud of is how polished the game feels especially and how fun the games turned out to be. The controls are intuitive and easy to learn as in most of the minigames, you only use the arrow keys", "repo": "https://github.com/NCGameMaking/WarioWare", "demo": "https://ncgamemaking.itch.io/warioware"}]...
|
[{"post_id": 79499, "ts": "202 [{"post_id": 79499, "ts": "2026-10-14T09:55:38Z", "hours": 0.4294, "text": "Finished the README Just added a few pics and description no big deal"}, {"post_id": 67103, "ts": "2026-09-13T05:05:04Z", "hours": 1.0717, "text": "Update on Game Assets and Minigame 4 I have made my own asset for the game, the Wario, the boulders, the koopa shells myself now and adjusted the platform layout for the lava rising level to make it easier for the player."}, {"post_id": 21838, "ts": "2026-07-03T23:42:02Z", "hours": 1.9581, "text": "its done⦠Just spent time fixing on Warioware game, it took a really long, I was trying to figure out why my level for some reason, was going on level 1,2,3 straight to 5! What happened to my level 4. I literally just exported the game, uploaded it on itch.io played it, then realised HUH? for the next hour I just sat there staring at lines of code scrutinizing every individual variable line of code, (heck I even paid attention to the yellow labels!) I realised that I had been giving an extra command Global.minigames_done += 1 when my timer screen was already running that command, so the Global variable will run twice causing it to skip the 4th level. And also it happened that the lose screen buttons happened to not work, it was so annoying, RAAAAH. After another whole hour, it works! I had this function func _process ( delta ): if lives == 0 : lives = 5 get_tree () . change_scene_to_file ( \"res://lose_screen.tscn\" ) so i just added a line in front of the get_tree() function lives = 5 . Itās finally working now!!"}, {"post_id": 21188, "ts": "2026-07-03T00:16:07Z", "hours": 0.7503, "text": "Minigames 3, 4, & 5 Complete! Just made minigames 3, 4, and 5! The code the course provided was really helpful. It was incredibly modular , in fact, almost like a copy-paste job, other than the individual logic behind each minigame. Minigame 3: Boulder Dodge Type : Dodging game Mechanic : Boulders fall out of the sky. Objective : Wario has to dodge them until the timer runs out. Minigame 4: The Floor is Lava Type : Survival Parkour Mechanic : Orange lava slowly rises up to catch you. It rises faster and faster as time goes on! Objective : Wario has to parkour up the platforms and survive the full 10 seconds by climbing up. Minigame 5: Koopa Shell dodge Type : Horizontal Dodging game Mechanic : Instead of boulders falling from the sky, Koopa Shells fly across the ground. Objective : Wario has to jump over the Koopa Shells and dodge them until the timer runs out!"}, {"post_id": 21110, "ts": "2026-07-02T22:09:07Z", "hours": 1.3694, "text": "Forgot to say I added minigame 1, yeah Wario just collects the Garlics, you have to collect the garlics before the timer runs out"}, {"post_id": 20551, "ts": "2026-07-02T05:07:12Z", "hours": 2.2422, "text": "Just made minigame 2, code is fairly simple its working, now onto the third game my own choice, I am thinking of making a dodging game. Boulder fall out of the sky and Wario has to dodge them before by the time the timer runs out"}, {"post_id": 20373, "ts": "2026-07-01T23:18:31Z", "hours": 0.7239, "text": "Just made the title slide and level lives thingy. Put basic functions for the buttons, yeah, its looking good. Now making the player for platformer"}]...
|
Title: WarioWare Game by @NC | Stardance
Devlogs: Title: WarioWare Game by @NC | Stardance
Devlogs:
Just made the title slide and level lives thingy. Put basic functions for the buttons, yeah, its looking good. Now making the player for platformer
Just made minigame 2, code is fairly simple its working, now onto the third game my own choice, I am thinking of making a dodging game. Boulder fall out of the sky and Wario has to dodge them before by the time the timer runs out
Forgot to say I added minigame 1, yeah Wario just collects the Garlics, you have to collect the garlics before the timer runs out
Minigames 3, 4, & 5 Complete! Just made minigames 3, 4, and 5! The code the course provided was really helpful. It was incredibly modular , in fact, almost like a copy-paste job, other than the individual logic behind each minigame. Minigame 3: Boulder Dodge Type : Dodging game Mechanic : Boulders fall out of the sky. Objective : Wario has to dodge them until the timer runs out. Minigame 4: The Floor is Lava Type : Survival Parkour Mechanic : Orange lava slowly rises up to catch you. It rises faster and faster as time goes on! Objective : Wario has to parkour up the platforms and survive the full 10 seconds by climbing up. Minigame 5: Koopa Shell dodge Type : Horizontal Dodging game Mechanic : Instead of boulders falling from the sky, Koopa Shells fly across the ground. Objective : Wario has to jump over the Koopa Shells and dodge them until the timer runs out!
its done⦠Just spent time fixing on Warioware game, it took a really long, I was trying to figure out why my level for some reason, was going on level 1,2,3 straight to 5! What happened to my level 4. I literally just exported the game, uploaded it on itch.io played it, then realised HUH? for the next hour I just sat there staring at lines of code scrutinizing every individual variable line of code, (heck I even paid attention to the yellow labels!) I realised that I had been giving an extra command Global.minigames_done += 1 when my timer screen was already running that command, so the Global variable will run twice causing it to skip the 4th level. And also it happened that the lose screen buttons happened to not work, it was so annoying, RAAAAH. After another whole hour, it works! I had this function func _process ( delta ): if lives == 0 : lives = 5 get_tree () . change_scene_to_file ( "res://lose_screen.tscn" ) so i just added a line in front of the get_tree() function lives = 5 . Itās finally working now!!
Update on Game Assets and Minigame 4 I have made my own asset for the game, the Wario, the boulders, the koopa shells myself now and adjusted the platform layout for the lava rising level to make it easier for the player.
Finished the README Just added a few pics and description no big deal
Ships:
A Warioware style minigame project. Fast-paced levels with a life system. Custom lose screen interface tracking score. I made a WarioWare themed game with 5 minigames in total. You have to beat all 5 minigames What I found was challenging was designing and creating my own minigames as well as linking my own minigames to the ones in the guide. What I am most proud of is how polished the game feels especially and how fun the games turned out to be. The controls are intuitive and easy to learn as in most of the minigames, you only use the arrow keys
I made my WarioWare Game for the 2nd mission. Something I changed was all the assets. I made them all by myself in Piskel! I made 5 minigames Minigame 1 - Collect all the pieces of garlic as Wario before the timer runs out Minigame 2 - Click all the pieces of garlic before the timer runs out Minigame 3 - Dodge the Boulders until the timer runs out Minigame 4 - Parkour up the platforms as the orange lava rises Minigame 5 - Jump over the Koopa Shells before time runs out...
|
1793138124.6598969
|
1793224524.6598969
|
|
67813
|
NASA BLOG by @Lalith | Stardance
|
Lalith
|
1
|
10.87
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-07T19:01:08Z", "hours": 10.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Mission Log is a NASA-themed full-stack blog built with Next.js, React, Mongoose, and MongoDB, featuring Markdown articles, accounts, search, NASA data explorers, saved articles, and an editorial studio. The biggest challenges were connecting Atlas and Vercel, configuring environment variables, fixing author login, and restoring the redesigned site after an older deployment replaced it. The part Iām proudest of is how the original blog idea grew into a space publication where people can read stories, explore related data, and save what interests them. To test it, visit Mission Log, open articles, browse topics, try search, and explore the NASA data pages; account features include saving articles and following topics, while publishing requires authorization. Database credential recovery is still unfinished, so database-backed features may fail until configuration is updated. The project was developed with slight AI assistance, and Mission Log is not affiliated with NASA.", "repo": "https://github.com/Hustlenix/mission-log", "demo": "https://mission-log-omega.vercel.app/"}]...
|
[{"post_id": 79502, "ts": "202 [{"post_id": 79502, "ts": "2026-10-14T10:25:53Z", "hours": 0.8728, "text": "I wrote the whole read me by myself, ig it wil get shipped!"}, {"post_id": 77645, "ts": "2026-10-07T18:51:58Z", "hours": 0.7572, "text": "Iāve sucess fully finished this project, thats what i gi=uess. This was a good journey of that API keys and making a full stack website"}, {"post_id": 77280, "ts": "2026-10-06T12:38:11Z", "hours": 2.3531, "text": "NASA"}, {"post_id": 77092, "ts": "2026-10-05T16:54:38Z", "hours": 2.0228, "text": "It just looks like i have sorted everything out, and it is ready to be shipped, but this has few major problems like: the search isnt good the blog is not brodned to match a complete blog, this all feels kinda mid and not finished, so i set my AI to plan, research, and webscrape NASA and help me build a good blog site for NASA!!!"}, {"post_id": 76754, "ts": "2026-10-04T14:27:19Z", "hours": 1.4617, "text": "I have finished the overall UI/Ux of it and now i am on the mission to do those ENV files to make it a Full stack website, man why is it soo hard to make a full stack website man? i was well of when i was just useing my github pages for everytingšš, setting up the keys is way harder. Like creating a project, pushing the code, signing in for mongoDB or smtg. and also after doing all of these it will still say, deployment failedšš»š"}, {"post_id": 76594, "ts": "2026-10-04T03:12:52Z", "hours": 2.9228, "text": "I am on the mission to make a better blog than Nasaās Blog, using their API keyās help and also webscrape them and use it. You can also get one from this link: https://api.nasa.gov/ that too for free"}]...
|
Title: NASA BLOG by @Lalith | Stardance
Devlogs:
Title: NASA BLOG by @Lalith | Stardance
Devlogs:
I am on the mission to make a better blog than Nasaās Blog, using their API keyās help and also webscrape them and use it. You can also get one from this link: https://api.nasa.gov/ that too for free
I have finished the overall UI/Ux of it and now i am on the mission to do those ENV files to make it a Full stack website, man why is it soo hard to make a full stack website man? i was well of when i was just useing my github pages for everytingšš, setting up the keys is way harder. Like creating a project, pushing the code, signing in for mongoDB or smtg. and also after doing all of these it will still say, deployment failedšš»š
It just looks like i have sorted everything out, and it is ready to be shipped, but this has few major problems like: the search isnt good the blog is not brodned to match a complete blog, this all feels kinda mid and not finished, so i set my AI to plan, research, and webscrape NASA and help me build a good blog site for NASA!!!
NASA
Iāve sucess fully finished this project, thats what i gi=uess. This was a good journey of that API keys and making a full stack website
I wrote the whole read me by myself, ig it wil get shipped!
Ships:
Mission Log is a NASA-themed full-stack blog built with Next.js, React, Mongoose, and MongoDB, featuring Markdown articles, accounts, search, NASA data explorers, saved articles, and an editorial studio. The biggest challenges were connecting Atlas and Vercel, configuring environment variables, fixing author login, and restoring the redesigned site after an older deployment replaced it. The part Iām proudest of is how the original blog idea grew into a space publication where people can read stories, explore related data, and save what interests them. To test it, visit Mission Log, open articles, browse topics, try search, and explore the NASA data pages; account features include saving articles and following topics, while publishing requires authorization. Database credential recovery is still unfinished, so database-backed features may fail until configuration is updated. The project was developed with slight AI assistance, and Mission Log is not affiliated with NASA....
|
1793062276.489962
|
1793148676.489962
|
|
69638
|
BetterLectio infra/website by @jonbng | Stardance
|
jonbng
|
1
|
10.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T10:39:14Z", "hours": 10.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I created the BetterLectio website, it is the landing page for when people search up BetterLectio. BetterLectio is an improvement upon the danish school system āLectioā, therefore the site is also in Danish. While developing the app i learned a lot about how to make a website that convert, and i spent a lot of time making the stats page, that shows like the impact of the project. Putting the project in good light of the public", "repo": "https://github.com/jonbng/betterlectio-website", "demo": "https://betterlectio.dk/"}]...
|
[{"post_id": 79503, "ts": "202 [{"post_id": 79503, "ts": "2026-10-14T10:37:43Z", "hours": 9.7608, "text": "Created the initial version of the website and published it! While developing the website I have had a lot of focus on making sure that the site converts well to getting people onboarded onto BetterLectio. I especially spent a lot of time on the stats page at https://betterlectio.dk/stats it highlights the impact and selected stats about the app (for example that over 3k people downloaded BetterLectio). Beaware, the site is in Danish"}]...
|
Title: BetterLectio infra/website by @jonbng | Sta Title: BetterLectio infra/website by @jonbng | Stardance
Devlogs:
Created the initial version of the website and published it! While developing the website I have had a lot of focus on making sure that the site converts well to getting people onboarded onto BetterLectio. I especially spent a lot of time on the stats page at https://betterlectio.dk/stats it highlights the impact and selected stats about the app (for example that over 3k people downloaded BetterLectio). Beaware, the site is in Danish
Ships:
I created the BetterLectio website, it is the landing page for when people search up BetterLectio. BetterLectio is an improvement upon the danish school system āLectioā, therefore the site is also in Danish. While developing the app i learned a lot about how to make a website that convert, and i spent a lot of time making the stats page, that shows like the impact of the project. Putting the project in good light of the public...
|
1793155942.773168
|
1793242342.773168
|
|
69637
|
BetterLectio Mobile by @jonbng | Stardance
|
jonbng
|
0
|
7.27
|
0
|
[]
|
[{"post_id": 79505, "ts": "202 [{"post_id": 79505, "ts": "2026-10-14T10:46:34Z", "hours": 7.2708, "text": "I developed the first version of the BetterLectio mobile app for both Android and IOS. We published it to the Google play store and the Apple App Store. It has already been downloaded by hundreds of student on android and almost a thousand on IOS. The development included a lot of reverse engineering the original Lectio platform, and thinking about the UI/UX of the app."}]...
|
Title: BetterLectio Mobile by @jonbng | Stardance
Title: BetterLectio Mobile by @jonbng | Stardance
Devlogs:
I developed the first version of the BetterLectio mobile app for both Android and IOS. We published it to the Google play store and the Apple App Store. It has already been downloaded by hundreds of student on android and almost a thousand on IOS. The development included a lot of reverse engineering the original Lectio platform, and thinking about the UI/UX of the app....
|
1792857268.1226792
|
1793462068.1226792
|
|
69627
|
BetterLectio by @jonbng | Stardance
|
jonbng
|
0
|
15.65
|
0
|
[]
|
[{"post_id": 79507, "ts": "202 [{"post_id": 79507, "ts": "2026-10-14T10:58:58Z", "hours": 15.65, "text": "Since June I have made a lot of improvements across all platforms, I have added mobile platform support, notification systems, customizability, a referral program, we have grown more than 6x in users and have had to make some substancial infrastructure upgrades to the entire project."}]...
|
Title: BetterLectio by @jonbng | Stardance
Devlog Title: BetterLectio by @jonbng | Stardance
Devlogs:
Since June I have made a lot of improvements across all platforms, I have added mobile platform support, notification systems, customizability, a referral program, we have grown more than 6x in users and have had to make some substancial infrastructure upgrades to the entire project....
|
1792857258.1745458
|
1793462058.1745458
|
|
52743
|
SnakeBot by @leeianiop | Stardance
|
leeianiop
|
0
|
56.29
|
0
|
[]
|
[{"post_id": 79508, "ts": "202 [{"post_id": 79508, "ts": "2026-10-14T11:14:04Z", "hours": 20.3247, "text": "Suspension issues :/ troubleshooting the angle for the spring on the connectors"}, {"post_id": 78909, "ts": "2026-10-12T00:28:59Z", "hours": 12.0008, "text": "Made a screw based suspension, using springs to bounce. Iāve printed and tested it, seems to be wroking fine."}, {"post_id": 62774, "ts": "2026-09-06T09:13:58Z", "hours": 8.4919, "text": "Made version 2, which has spring suspension and sider body base (also looks cooler in general) This is a robot snake, and this is one of the segments, the servo is ontop of another servo which can control the y and z axis of the front segment"}, {"post_id": 59589, "ts": "2026-09-01T14:28:50Z", "hours": 6.7992, "text": "Did the segment to segment connections and updated the gearbox to make it gear down for more torque. Iām making a snake robot mechanical thing any suggestions or name ideas pls leave a comment:)"}, {"post_id": 54356, "ts": "2026-08-25T09:49:09Z", "hours": 1.0231, "text": "Made the f1 aero side cover more connected to the case"}, {"post_id": 53833, "ts": "2026-08-24T15:07:15Z", "hours": 2.9964, "text": "Made more progress on the CAD by adding a longer side gear shaft and cover. The cover is going to be like an f1 car side"}, {"post_id": 52784, "ts": "2026-08-23T03:55:44Z", "hours": 1.3672, "text": "Made the top servo mount to have screws linking to bottom servo mount, made some added progress on the suspsension"}, {"post_id": 52434, "ts": "2026-08-22T15:35:47Z", "hours": 2.4836, "text": "Made the General Body and created mount for servos. Fusion keeps crashing:(("}, {"post_id": 52298, "ts": "2026-08-22T12:38:32Z", "hours": 0.8019, "text": "Made the gearbox to turn the motor shaft sideways, allowing for a narrower body, The lid is screwed by M3 screws"}]...
|
Title: SnakeBot by @leeianiop | Stardance
Devlogs Title: SnakeBot by @leeianiop | Stardance
Devlogs:
Made the gearbox to turn the motor shaft sideways, allowing for a narrower body, The lid is screwed by M3 screws
Made the General Body and created mount for servos. Fusion keeps crashing:((
Made the top servo mount to have screws linking to bottom servo mount, made some added progress on the suspsension
Made more progress on the CAD by adding a longer side gear shaft and cover. The cover is going to be like an f1 car side
Made the f1 aero side cover more connected to the case
Did the segment to segment connections and updated the gearbox to make it gear down for more torque. Iām making a snake robot mechanical thing any suggestions or name ideas pls leave a comment:)
Made version 2, which has spring suspension and sider body base (also looks cooler in general) This is a robot snake, and this is one of the segments, the servo is ontop of another servo which can control the y and z axis of the front segment
Made a screw based suspension, using springs to bounce. Iāve printed and tested it, seems to be wroking fine.
Suspension issues :/ troubleshooting the angle for the spring on the connectors...
|
1792723717.323786
|
1793328517.323786
|
|
69648
|
Basic Console Banking System by @taofeek | Stardan Basic Console Banking System by @taofeek | Stardance...
|
taofeek
|
0
|
1.52
|
0
|
[]
|
[{"post_id": 79510, "ts": "202 [{"post_id": 79510, "ts": "2026-10-14T11:20:44Z", "hours": 1.5225, "text": "Menu Option"}]...
|
Title: Basic Console Banking System by @taofeek | Title: Basic Console Banking System by @taofeek | Stardance
Devlogs:
Menu Option...
|
1792857283.1103067
|
1793462083.1103067
|
|
68937
|
the pad by @Arham_pro | Stardance
|
Arham_pro
|
0
|
1.27
|
0
|
[]
|
[{"post_id": 79511, "ts": "202 [{"post_id": 79511, "ts": "2026-10-14T11:34:44Z", "hours": 1.2669, "text": "makingt the hackpad"}]...
|
Title: the pad by @Arham_pro | Stardance
Devlogs: Title: the pad by @Arham_pro | Stardance
Devlogs:
makingt the hackpad...
|
1793127211.4829693
|
1793732011.4829693
|
|
57022
|
Frictionless by @Aditya_Singh | Stardance
|
Aditya_Singh
|
1
|
8.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T13:25:02Z", "hours": 8.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "PATCHWORK ā Your Personal Productivity Workspace PATCHWORK is a lightweight productivity app designed to help people organize tasks, capture ideas, and keep useful links in one place. Instead of spreading information across multiple apps and tabs, PATCHWORK brings everyday organization into a single, simple workspace. Key features: Task management: Create tasks, set priorities, assign due dates, and track completion. Notes: Capture and organize ideas. Link collection: Keep useful resources together. Quick Capture: Add information without navigating through multiple screens. Search and filtering: Find items more easily. Dashboard: Get an overview of tasks and progress. Persistent storage: Keep saved items after refreshing the page using browser local storage. Built with: React, TypeScript, Vite, and CSS. The problem I wanted to solve: Keeping track of tasks, ideas, and useful resources can become difficult when they are scattered across different places. I built PATCHWORK to bring these everyday productivity tools into one workspace that is straightforward to use. The challenges I faced: One of the biggest challenges was bringing all the different parts of PATCHWORK together into one working application. Getting the React components, TypeScript, styling, and local storage to work together took time, testing, and debugging. Setting up Git, publishing my code on GitHub, and deploying the app were also new experiences that I had to work through. There were moments when things didnāt work as expected, but I learned to troubleshoot problems one step at a time. Another important challenge was making sure that tasks and notes remained saved after refreshing the page. Since PATCHWORK uses browser local storage, I needed to ensure that the app could save data correctly and load it again when reopened. This project taught me that building an application involves much more than just writing code. It requires patience, problem-solving, testing, and a willingness to learn from mistakes. I know that future bugs and challenges may arise, and Iām ready to approach them by investigating the problem, trying solutions, and learning along the way. What makes me proud: Iām most proud of taking PATCHWORK from an idea to a working, publicly accessible application. And Iām proud of that I spent over eight hours working on this project, learning new things, fixing issues, and improving the result along the way. This experience gave me more confidence in my ability to build and publish projects of my own. Things I learned: Building PATCHWORK gave me practical experience with React components, TypeScript, UI styling, browser storage, Git, GitHub, and deploying a web application.", "repo": "https://github.com/zealot-adi/patchwork", "demo": "https://patchwork-gray.vercel.app/"}]...
|
[{"post_id": 79519, "ts": "202 [{"post_id": 79519, "ts": "2026-10-14T12:38:39Z", "hours": 0.9619, "text": "FINALLY!! itās live now"}, {"post_id": 79480, "ts": "2026-10-14T07:16:19Z", "hours": 1.6156, "text": "making the README as professional as I can."}, {"post_id": 79377, "ts": "2026-10-13T18:40:16Z", "hours": 0.6389, "text": "I guess the UI is pretty decent but I found errors while saving a quick capture so Iāll fix that next"}, {"post_id": 79367, "ts": "2026-10-13T17:52:43Z", "hours": 2.565, "text": "just crashing out ..! (gotta add few more lines TvT) and I hope people donāt mind my short devlogs :p"}, {"post_id": 79262, "ts": "2026-10-13T07:39:43Z", "hours": 0.7411, "text": "Itās so mid right now"}, {"post_id": 79253, "ts": "2026-10-13T06:33:48Z", "hours": 1.1675, "text": "gng just completed the typescript thingy gonna do the CSS next xD"}, {"post_id": 79236, "ts": "2026-10-13T04:54:13Z", "hours": 0.3056, "text": "hello chat, Iām making a web app that helps people organize tasks, notes, links, and code snippets in one interactive workspace. Lol and I Just defined the type structures for the items so the interactive board knows how to handle tasks, notes, and links. Imma update yaāll later and I hope I donāt run into bugs againš"}]...
|
Title: Frictionless by @Aditya_Singh | Stardance
Title: Frictionless by @Aditya_Singh | Stardance
Devlogs:
hello chat, Iām making a web app that helps people organize tasks, notes, links, and code snippets in one interactive workspace. Lol and I Just defined the type structures for the items so the interactive board knows how to handle tasks, notes, and links. Imma update yaāll later and I hope I donāt run into bugs againš
gng just completed the typescript thingy gonna do the CSS next xD
Itās so mid right now
just crashing out ..! (gotta add few more lines TvT) and I hope people donāt mind my short devlogs :p
I guess the UI is pretty decent but I found errors while saving a quick capture so Iāll fix that next
making the README as professional as I can.
FINALLY!! itās live now
Ships:
PATCHWORK ā Your Personal Productivity Workspace PATCHWORK is a lightweight productivity app designed to help people organize tasks, capture ideas, and keep useful links in one place. Instead of spreading information across multiple apps and tabs, PATCHWORK brings everyday organization into a single, simple workspace. Key features: Task management: Create tasks, set priorities, assign due dates, and track completion. Notes: Capture and organize ideas. Link collection: Keep useful resources together. Quick Capture: Add information without navigating through multiple screens. Search and filtering: Find items more easily. Dashboard: Get an overview of tasks and progress. Persistent storage: Keep saved items after refreshing the page using browser local storage. Built with: React, TypeScript, Vite, and CSS. The problem I wanted to solve: Keeping track of tasks, ideas, and useful resources can become difficult when they are scattered across different places. I built PATCHWORK to bring these everyday productivity tools into one workspace that is straightforward to use. The challenges I faced: One of the biggest challenges was bringing all the different parts of PATCHWORK together into one working application. Getting the React components, TypeScript, styling, and local storage to work together took time, testing, and debugging. Setting up Git, publishing my code on GitHub, and deploying the app were also new experiences that I had to work through. There were moments when things didnāt work as expected, but I learned to troubleshoot problems one step at a time. Another important challenge was making sure that tasks and notes remained saved after refreshing the page. Since PATCHWORK uses browser local storage, I needed to ensure that the app could save data correctly and load it again when reopened. This project taught me that building an application involves much more than just writing code. It requires patience, problem-solving, testing, and a willingness to learn from mistakes. I know that future bugs and challenges may arise, and Iām ready to approach them by investigating the problem, trying solutions, and learning along the way. What makes me proud: Iām most proud of taking PATCHWORK from an idea to a working, publicly accessible application. And Iām proud of that I spent over eight hours working on this project, learning new things, fixing issues, and improving the result along the way. This experience gave me more confidence in my ability to build and publish projects of my own. Things I learned: Building PATCHWORK gave me practical experience with React components, TypeScript, UI styling, browser storage, Git, GitHub, and deploying a web application....
|
1793048092.9421334
|
1793134492.9421334
|
|
14948
|
My JARVIS by @denistrovas | Stardance
|
denistrovas
|
0
|
2.41
|
0
|
[]
|
[{"post_id": 7952, "ts": "2026 [{"post_id": 7952, "ts": "2026-06-13T08:13:38Z", "hours": 2.4075, "text": "I am working on a ĪĪ chatbot, that can control my smart home and my PC! Now I try to connect it with my smart home app ti open the lights! I am also working to recognise my voice!"}]...
|
Title: My JARVIS by @denistrovas | Stardance
Devl Title: My JARVIS by @denistrovas | Stardance
Devlogs:
I am working on a ĪĪ chatbot, that can control my smart home and my PC! Now I try to connect it with my smart home app ti open the lights! I am also working to recognise my voice!...
|
1792770578.7510853
|
1793375378.7510853
|
|
23222
|
Climate Shield by @HackerDpro | Stardance
|
HackerDpro
|
3
|
55.0
|
452
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T13:30:29Z", "hours": 26.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Dear voters, I made āCLIMATE SHIELDā, an interactive dashboard with real-time natural disasters (focussed mostly on fires) from NASA APIās being shown. Why: I made this project because I was surprised by hearing so much fire incidents on the news, I liked the idea of being able to see all fires and data in one place and easy-to-read. I also liked the idea of using NASA data for my project, as this Stardance challenge is sponsored by NASA. During the process of creating this project, I learn a lot about how to use APIās and merge multiple APIs into one dashboard. The difference between this and the previous ship I got lots of ideas and inspirations from the previous ship. So I did my best to implement them all into this ship, some examples: A canvas tutorial that explains the basics from my page to new users. You can replay it in the TELEMETRY page! Added more sources, this way some areas that werenāt covered before have also data (although I have done my best to only use free APIās, that means that it may not contain ALL the data there currently is). In my previous ship I added another way of seeing the world (if you click on the āRECONā buttons), now it is also a map you can select as standard-view. There was a bug that I canāt explain this short (you can see more info about it in my devlogs), but I mostly fixed it! I hope you have a great day, and thanks for voting!!!", "repo": "https://github.com/HackerDpro/climate-shield", "demo": "https://climate-shield.netlify.app/"}, {"ship_num": 2, "ts": "2026-10-08T20:49:50Z", "hours": 25.0, "multiplier": 15.5, "payout": 385, "blessing": "neutral", "text": "I made a web page with NASA live data (APIās) to track natural problems around the world. CLIMATE SHIELD! I am proud of it being one of my biggest projects. I got the idea of doing this by seeing in the news all the wildfires happening right now, it was perfect timing as I was searching for ideas of what I could make for Startdance. Even though I knew there are already bunch of other sites that do this and may be 100x better than mine I just thought thta I woudl be so proud if I were able to make one myself. To be honest I did use AI, maybe a little bit too much some times. But I tried my best to participate as much as I can on the project, I know that AI shouldnāt be doing this for me. I learnt about all the back end things and APIās (I was frontend dev before but had low experience of back end, so this learnt me much too). So dear reviewer, I hope you like, enjoy and support my project as much as I do, have fun reviewing all the parts of it. If even like this my project would dissapoint you, Iād be glad to be able to get a feedback so I can make it even better! P.S. I appear to sometimes still have problems with the backend, it is hosted on the hack club Nest servers that should run 24/7 but I sometimes have connection errors with it so if the backend data doesnāt show directly after reloading the site please donāt check my project as failed, I am doing my best to make it work! Oh and yeah, I ma sorry for this looking so unstructurised but I didnāt really know how this be represented to you, if I maybe should write this the same layout as a README or a DEVBLOG", "repo": "https://github.com/HackerDpro/climate-shield", "demo": "https://climate-shield.netlify.app/"}, {"ship_num": 3, "ts": "2026-06-21T19:03:22Z", "hours": 4.0, "multiplier": 17.74, "payout": 67, "blessing": "neutral", "text": "I built Climate Shield, an AI-enhanced dashboard for global wildfire prediction. What I made: A high-performance Command Center that tracks 6,000+ real-time wildfire events. It integrates NASA satellite data with Open-Meteo elevation and OpenWeatherMap metrics to predict fire spread behaviors based on terrain and wind vectors. What was challenging: Scaling! Rendering 6k+ fires crashed my browser initially. I solved this by migrating the map engine to HTML5 Canvas for instant performance. I also had to implement an āon-demandā API fetching strategy to bypass rate limits while maintaining deep-dive analytics. What Iām proud of: The āTerrain AI.ā By calculating elevation data in real-time, the dashboard now identifies āCritical Uphill Alignmentā a major factor in wildfire spread, and generates a 24-hour linear projection for dangerous outbreaks. How to test: Visit the Live Dashboard. ( https://climate-shield.netlify.app/ ) Toggle between Tactical (full data), Orbital (map focus), and Telemetry (deep analytics) modes. Click any fire marker to view specific wind, elevation, and hazard score data. Have fun discovering all the data.", "repo": "https://github.com/HackerDpro/climate-shield", "demo": "https://climate-shield.netlify.app/"}]...
|
[{"post_id": 79522, "ts": "202 [{"post_id": 79522, "ts": "2026-10-14T13:05:26Z", "hours": 6.2528, "text": "ALL BUGS SOLVED (I think) This is my last devlog before 3rd ship! It was hard but I think I have done everything my 2nd shipās voters told me to, I am exited to see what my 3rd shipās voters will think of my project. I am happy with how my project turned out (Although I always like people giving me ideas and inspirations for future features and more)!"}, {"post_id": 79467, "ts": "2026-10-14T05:10:56Z", "hours": 8.4911, "text": "8 hours later = BUG FIXED After 8 hours of coding later and some frustrations: I finally fixed the annoying bug that I had (more info of the bug is to be seen in my previous devlogs). I am making my final changes before shipping, fixing a new smaller bug I found recently āNASA FIRMS data not loadingā. After making all these changes: the bug fix, tutorial implementation, adding new sources and merging them, ⦠I expect my 3rd ship to be soon!!!"}, {"post_id": 78883, "ts": "2026-10-11T21:15:19Z", "hours": 5.4208, "text": "More progress with merging Today Iāve mostly made progress with the codes to merge multiple APIās into the same details pup-up. I also did my best on finding a solution for the bug that has been happening when a fire pop-up shows and it touches the top of the page and dissapears. My only solution right now is to minimize the page (āctrlā + ā-ā). Come back to see tomorrowās devlog!"}, {"post_id": 78459, "ts": "2026-10-10T20:51:07Z", "hours": 6.0917, "text": "POST-SHIP PROGRESS Iāve been working on satisfying the reviews I got from my last shipmentās voters. I have been making a tutorial for first-timers on my page, it will show the basics of how to navigate and use my Climate-Shield project, a replay will be availble in the āTELEMETRYā tab. (view picture below). I am doing my best on fixing a very annoying bug that makes the details from a fire show for a split second and dissapear. It has been hard to fix that bug for now⦠I am working on adding more resources so I donāt only rely on 1 API but multiple (some may have more data than others). The difficult part has been trying to merge same fires from different apiās in one fire (to not have duplicates). These are my main issues I am working on right now, tomorrow Iāll continue, have a good day!"}, {"post_id": 77931, "ts": "2026-10-08T20:33:39Z", "hours": 7.9175, "text": "After coming back to Climate Shield I found that the backend (hack club Nest) had stopped, so the dashboard could no longer load its data. I got it running again (with PM2 and systemd), then replaced the map that suddenly was asking for an API key with another one (Esri tiles). When the fires still seemed missing, I checked the live data and found 7,130 valid reports. On the new map, the markers were just too small and hard to see, so I made them bigger and with a dark outline. I then tested the Netlify page with the API and saw that everything worked. I also updated the README and wrote my use of AI assistance (I am not sure if I wouldāve been able to revive the project without it)."}, {"post_id": 22753, "ts": "2026-07-05T10:28:33Z", "hours": 2.4594, "text": "I have been a bit quiet lately, here is what is happening: I am on holidays with my family in Spain, this is what is keeping my time limited. I also donāt have a desktop here so that makes working and coding a bit more difficult (I work on a 14ā schoollaptop). I am working on a very big update, about adding satelite cams and nearby webcams to visualize fires and maybe other things. This is a bit harder than expected but I expect it to be done in some hours, this would be the special update for celebrating my 25 or 30 hours in total coding time. I am also trying to make the feedback recieved from the shipping true, removing some bugs users found, ⦠If you are reading this maybe you would like to try it out, I really appreciate feedback because it helps me improve what I donāt see. https://climate-shield.netlify.app/"}, {"post_id": 16198, "ts": "2026-06-26T10:01:54Z", "hours": 8.3156, "text": "Changing to a real server & a new TACTICAL UI Added a new Dropdown menu to the TACTICAL page to filter threats by layers and fully changed the backend to the Hack Club Nest server! The biggest friction this week was dealing with my old Render backend constantly going to sleep, which made the web app feel broken to new users. I finally set up my FastAPI app with PM2 so it stays awake 24/7. On the frontend, I built a sleek new dropdown to change between Earthquakes, Floods, Storms, and Volcanoes. The hard part was getting the map layers to play nicely together, toggling the new NASA APIās kept overwriting my core 6,000+ wildfire array! I had to rewrite the logic to separate the Leaflet layers so the map can stays fast and doesnāt wipe your data when you switch views. Right now, I am still trying to fix some bugs and improving the CO2 graph, I am also planning on updating my README.md to explain the new features (better). THANK YOU FOR READING! (I am almost at 20 hours of coding omg, I may need to add a special feature for when it happens. Any ideas or improvements are really appreciated!)"}, {"post_id": 15016, "ts": "2026-06-24T12:13:11Z", "hours": 0.7833, "text": "I hit 10 hours of coding! Here is what i lately changed: I just made a clock in the Tactical page (who doesnāt need a clock). I changed the font-family to Roboto. And I also changed the colors and some styling to feel more personal (I got much comments saying that I used AI so I am currently rewriting the most of the css to feel more like me)."}, {"post_id": 14306, "ts": "2026-06-23T11:47:37Z", "hours": 1.7369, "text": "Lastly Iāve remade the whole (first section) of the README.md, no more AI is used in it. I have made some improvement on the Orbital to be able to display the extra sensors too (btw extra sensors is a new feature too, read the README.md to learn more about it). I also made a costum favicon. Right now I am gathering APIās for more data and info comming soon, and also trying to categorize the things better so my site doesnāt look too messy (to new users)."}, {"post_id": 13910, "ts": "2026-06-22T20:14:16Z", "hours": 3.6611, "text": "Here is a summary of what I added on Day 3: Orbital Engine: Implemented a 3D WebGL globe with hardware-accelerated solar shading and physical height-mapped thermal pillars. Predictive āPre-Crimeā Scanning: Created a sector-based scan that analyzes soil moisture and weather data to calculate ignition probability for any empty landmass. Tactical Evacuation Routing: Integrated the Open Source Routing Machine (OSRM) to automatically generate safe civilian escape paths based on wind direction and terrain. Multi-Hazard Sensor Array: Added specialized monitoring layers for Mudslides (soil hydrophobicity), Cyclones (SST anomalies), Volcanic Ash (stratospheric tracking), and Seismic Activity (USGS lithospheric data). Raw Radiometry Engine: Added the ability to ingest NASA MODAPS CSV data to measure physical fire intensity in Megawatts (FRP), rather than just visual location. Performance Engineering: Optimized massive dataset rendering by offloading complex physics calculations to background CPU Web Workers to ensure zero UI lag. More info in https://github.com/HackerDpro/climate-shield"}, {"post_id": 13270, "ts": "2026-06-21T18:44:58Z", "hours": 2.8814, "text": "Read the README.dm for a full resume but here is a shortened version of my day 2: Iāve hit a major milestone in the development of Climate Shield. Scaling a dashboard to handle 6,000+ live wildfire events while maintaining a responsive user interface required a total re-architecture of my data pipeline. Technical Challenges & Solutions: Performance Scaling: To prevent browser crashes, I migrated from standard map markers to an HTML5 Canvas rendering engine. This allows for thousands of data points to load near-instantly without lag. API Intelligence: To handle 6,000+ potential weather requests without triggering rate limits, I implemented an āon-demandā fetching model. Wind vectors and elevation-based terrain analytics now trigger only when a user interacts with a specific fire, ensuring the dashboard remains fast and efficient. Terrain-Aware Analytics: I integrated elevation data to model fire spread. The engine now calculates whether a fire is on a āCritical Uphill Alignmentāāa major factor in real-world wildfire behaviorāproviding a 24-hour linear projection for the most dangerous incidents. Dashboard Evolution: Iāve evolved the UI into a true Command Center with three distinct view modes:Tactical: The default full-dashboard view.Orbital: A map-focused mode for spatial tracking. Telemetry: A high-level data engine featuring carbon flux calculations, predictive risk averages, and hazard distribution matrices. This transition from a simple map to a multi-layered predictive engine has significantly improved the toolās utility. Whether itās tracking global CO2 trajectories or specific uphill fire spread, Climate Shield is now a high-performance asset for wildfire visualization."}, {"post_id": 13006, "ts": "2026-06-21T08:24:12Z", "hours": 0.9553, "text": "Spent our first session setting up the entire architecture for Climate Shield. Instead of just building a static map, we built a live data bridge. We successfully connected a Python backend engine using FastAPI to NASAās live EONET satellite network, pulling in over 6,000 active global wildfires! To bypass cloud firewalls and handle messy data, we engineered a custom data-cleaning filter. Then, we linked the coordinates to the OpenWeatherMap API to calculate real-time wind speed and direction. Right now, the frontend map isnāt just displaying fire locationsāit is actively rendering dynamic Risk Vectors (yellow trajectory lines) showing exactly where the wind is driving the fire spread. Next up: building the AI hazard scoring system!"}]...
|
Title: Climate Shield by @HackerDpro | Stardance
Title: Climate Shield by @HackerDpro | Stardance
Devlogs:
Spent our first session setting up the entire architecture for Climate Shield. Instead of just building a static map, we built a live data bridge. We successfully connected a Python backend engine using FastAPI to NASAās live EONET satellite network, pulling in over 6,000 active global wildfires! To bypass cloud firewalls and handle messy data, we engineered a custom data-cleaning filter. Then, we linked the coordinates to the OpenWeatherMap API to calculate real-time wind speed and direction. Right now, the frontend map isnāt just displaying fire locationsāit is actively rendering dynamic Risk Vectors (yellow trajectory lines) showing exactly where the wind is driving the fire spread. Next up: building the AI hazard scoring system!
Read the README.dm for a full resume but here is a shortened version of my day 2: Iāve hit a major milestone in the development of Climate Shield. Scaling a dashboard to handle 6,000+ live wildfire events while maintaining a responsive user interface required a total re-architecture of my data pipeline. Technical Challenges & Solutions: Performance Scaling: To prevent browser crashes, I migrated from standard map markers to an HTML5 Canvas rendering engine. This allows for thousands of data points to load near-instantly without lag. API Intelligence: To handle 6,000+ potential weather requests without triggering rate limits, I implemented an āon-demandā fetching model. Wind vectors and elevation-based terrain analytics now trigger only when a user interacts with a specific fire, ensuring the dashboard remains fast and efficient. Terrain-Aware Analytics: I integrated elevation data to model fire spread. The engine now calculates whether a fire is on a āCritical Uphill Alignmentāāa major factor in real-world wildfire behaviorāproviding a 24-hour linear projection for the most dangerous incidents. Dashboard Evolution: Iāve evolved the UI into a true Command Center with three distinct view modes:Tactical: The default full-dashboard view.Orbital: A map-focused mode for spatial tracking. Telemetry: A high-level data engine featuring carbon flux calculations, predictive risk averages, and hazard distribution matrices. This transition from a simple map to a multi-layered predictive engine has significantly improved the toolās utility. Whether itās tracking global CO2 trajectories or specific uphill fire spread, Climate Shield is now a high-performance asset for wildfire visualization.
Here is a summary of what I added on Day 3: Orbital Engine: Implemented a 3D WebGL globe with hardware-accelerated solar shading and physical height-mapped thermal pillars. Predictive āPre-Crimeā Scanning: Created a sector-based scan that analyzes soil moisture and weather data to calculate ignition probability for any empty landmass. Tactical Evacuation Routing: Integrated the Open Source Routing Machine (OSRM) to automatically generate safe civilian escape paths based on wind direction and terrain. Multi-Hazard Sensor Array: Added specialized monitoring layers for Mudslides (soil hydrophobicity), Cyclones (SST anomalies), Volcanic Ash (stratospheric tracking), and Seismic Activity (USGS lithospheric data). Raw Radiometry Engine: Added the ability to ingest NASA MODAPS CSV data to measure physical fire intensity in Megawatts (FRP), rather than just visual location. Performance Engineering: Optimized massive dataset rendering by offloading complex physics calculations to background CPU Web Workers to ensure zero UI lag. More info in https://github.com/HackerDpro/climate-shield
Lastly Iāve remade the whole (first section) of the README.md, no more AI is used in it. I have made some improvement on the Orbital to be able to display the extra sensors too (btw extra sensors is a new feature too, read the README.md to learn more about it). I also made a costum favicon. Right now I am gathering APIās for more data and info comming soon, and also trying to categorize the things better so my site doesnāt look too messy (to new users).
I hit 10 hours of coding! Here is what i lately changed: I just made a clock in the Tactical page (who doesnāt need a clock). I changed the font-family to Roboto. And I also changed the colors and some styling to feel more personal (I got much comments saying that I used AI so I am currently rewriting the most of the css to feel more like me).
Changing to a real server & a new TACTICAL UI Added a new Dropdown menu to the TACTICAL page to filter threats by layers and fully changed the backend to the Hack Club Nest server! The biggest friction this week was dealing with my old Render backend constantly going to sleep, which made the web app feel broken to new users. I finally set up my FastAPI app with PM2 so it stays awake 24/7. On the frontend, I built a sleek new dropdown to change between Earthquakes, Floods, Storms, and Volcanoes. The hard part was getting the map layers to play nicely together, toggling the new NASA APIās kept overwriting my core 6,000+ wildfire array! I had to rewrite the logic to separate the Leaflet layers so the map can stays fast and doesnāt wipe your data when you switch views. Right now, I am still trying to fix some bugs and improving the CO2 graph, I am also planning on updating my README.md to explain the new features (better). THANK YOU FOR READING! (I am almost at 20 hours of coding omg, I may need to add a special feature for when it happens. Any ideas or improvements are really appreciated!)
I have been a bit quiet lately, here is what is happening: I am on holidays with my family in Spain, this is what is keeping my time limited. I also donāt have a desktop here so that makes working and coding a bit more difficult (I work on a 14ā schoollaptop). I am working on a very big update, about adding satelite cams and nearby webcams to visualize fires and maybe other things. This is a bit harder than expected but I expect it to be done in some hours, this would be the special update for celebrating my 25 or 30 hours in total coding time. I am also trying to make the feedback recieved from the shipping true, removing some bugs users found, ⦠If you are reading this maybe you would like to try it out, I really appreciate feedback because it helps me improve what I donāt see. https://climate-shield.netlify.app/
After coming back to Climate Shield I found that the backend (hack club Nest) had stopped, so the dashboard could no longer load its data. I got it running again (with PM2 and systemd), then replaced the map that suddenly was asking for an API key with another one (Esri tiles). When the fires still seemed missing, I checked the live data and found 7,130 valid reports. On the new map, the markers were just too small and hard to see, so I made them bigger and with a dark outline. I then tested the Netlify page with the API and saw that everything worked. I also updated the README and wrote my use of AI assistance (I am not sure if I wouldāve been able to revive the project without it).
POST-SHIP PROGRESS Iāve been working on satisfying the reviews I got from my last shipmentās voters. I have been making a tutorial for first-timers on my page, it will show the basics of how to navigate and use my Climate-Shield project, a replay will be availble in the āTELEMETRYā tab. (view picture below). I am doing my best on fixing a very annoying bug that makes the details from a fire show for a split second and dissapear. It has been hard to fix that bug for now⦠I am working on adding more resources so I donāt only rely on 1 API but multiple (some may have more data than others). The difficult part has been trying to merge same fires from different apiās in one fire (to not have duplicates). These are my main issues I am working on right now, tomorrow Iāll continue, have a good day!
More progress with merging Today Iāve mostly made progress with the codes to merge multiple APIās into the same details pup-up. I also did my best on finding a solution for the bug that has been happening when a fire pop-up shows and it touches the top of the page and dissapears. My only solution right now is to minimize the page (āctrlā + ā-ā). Come back to see tomorrowās devlog!
8 hours later = BUG FIXED After 8 hours of coding later and some frustrations: I finally fixed the annoying bug that I had (more info of the bug is to be seen in my previous devlogs). I am making my final changes before shipping, fixing a new smaller bug I found recently āNASA FIRMS data not loadingā. After making all these changes: the bug fix, tutorial implementation, adding new sources and merging them, ⦠I expect my 3rd ship to be soon!!!
ALL BUGS SOLVED (I think) This is my last devlog before 3rd ship! It was hard but I think I have done everything my 2nd shipās voters told me to, I am exited to see what my 3rd shipās voters will think of my project. I am happy with how my project turned out (Although I always like people giving me ideas and inspirations for future features and more)!
Ships:
I built Climate Shield, an AI-enhanced dashboard for global wildfire prediction. What I made: A high-performance Command Center that tracks 6,000+ real-time wildfire events. It integrates NASA satellite data with Open-Meteo elevation and OpenWeatherMap metrics to predict fire spread behaviors based on terrain and wind vectors. What was challenging: Scaling! Rendering 6k+ fires crashed my browser initially. I solved this by migrating the map engine to HTML5 Canvas for instant performance. I also had to implement an āon-demandā API fetching strategy to bypass rate limits while maintaining deep-dive analytics. What Iām proud of: The āTerrain AI.ā By calculating elevation data in real-time, the dashboard now identifies āCritical Uphill Alignmentā a major factor in wildfire spread, and generates a 24-hour linear projection for dangerous outbreaks. How to test: Visit the Live Dashboard. ( https://climate-shield.netlify.app/ ) Toggle between Tactical (full data), Orbital (map focus), and Telemetry (deep analytics) modes. Click any fire marker to view specific wind, elevation, and hazard score data. Have fun discovering all the data.
I made a web page with NASA live data (APIās) to track natural problems around the world. CLIMATE SHIELD! I am proud of it being one of my biggest projects. I got the idea of doing this by seeing in the news all the wildfires happening right now, it was perfect timing as I was searching for ideas of what I could make for Startdance. Even though I knew there are already bunch of other sites that do this and may be 100x better than mine I just thought thta I woudl be so proud if I were able to make one myself. To be honest I did use AI, maybe a little bit too much some times. But I tried my best to participate as much as I can on the project, I know that AI shouldnāt be doing this for me. I learnt about all the back end things and APIās (I was frontend dev before but had low experience of back end, so this learnt me much too). So dear reviewer, I hope you like, enjoy and support my project as much as I do, have fun reviewing all the parts of it. If even like this my project would dissapoint you, Iād be glad to be able to get a feedback so I can make it even better! P.S. I appear to sometimes still have problems with the backend, it is hosted on the hack club Nest servers that should run 24/7 but I sometimes have connection errors with it so if the backend data doesnāt show directly after reloading the site please donāt check my project as failed, I am doing my best to make it work! Oh and yeah, I ma sorry for this looking so unstructurised but I didnāt really know how this be represented to you, if I maybe should write this the same layout as a README or a DEVBLOG
Dear voters, I made āCLIMATE SHIELDā, an interactive dashboard with real-time natural disasters (focussed mostly on fires) from NASA APIās being shown. Why: I made this project because I was surprised by hearing so much fire incidents on the news, I liked the idea of being able to see all fires and data in one place and easy-to-read. I also liked the idea of using NASA data for my project, as this Stardance challenge is sponsored by NASA. During the process of creating this project, I learn a lot about how to use APIās and merge multiple APIs into one dashboard. The difference between this and the previous ship I got lots of ideas and inspirations from the previous ship. So I did my best to implement them all into this ship, some examples: A canvas tutorial that explains the basics from my page to new users. You can replay it in the TELEMETRY page! Added more sources, this way some areas that werenāt covered before have also data (although I have done my best to only use free APIās, that means that it may not contain ALL the data there currently is). In my previous ship I added another way of seeing the world (if you click on the āRECONā buttons), now it is also a map you can select as standard-view. There was a bug that I canāt explain this short (you can see more info about it in my devlogs), but I mostly fixed it! I hope you have a great day, and thanks for voting!!!...
|
1793008365.5155494
|
1793872365.5155494
|
|
4799
|
Evochess by @Sam | Stardance
|
Sam
|
1
|
225.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T04:56:14Z", "hours": 225.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Letās ship š¢ This is a website where people can learn and improve their chess skills by watching courses, solving puzzles and practicing their vision. The website was overall really challenging to build. If I had do pick, it would definitely be making a working chessboard for puzzles. At the beginning of the project I didnāt even know if I was capable of building one but I am really glad I tried as Iāve learned so much. Another challenging thing would definitely be making the website responsive. I donāt like making website responsive and in this project animations added another layer of complexity. Iāve tried my best to keep things responsive though. I am really proud of completing the project and mainly working chessboard as this is my first time building something like this. I am also proud of the animations and the ui of the website. To test my website some knowledge of chess is preferred but even if you have zero knowledge about chess you can test out my project as there are courses which will teach you about chess. Thanks stardance for everything šš. I probably would never have created or completed this project without stardanceš", "repo": "https://github.com/samgod1/Chess-website", "demo": "https://evochess.vercel.app"}]...
|
[{"post_id": 79525, "ts": "202 [{"post_id": 79525, "ts": "2026-10-14T13:11:44Z", "hours": 3.0406, "text": "THIS MIGHT BE THE LAST DEVLOG First I polished the puzzles sidebar. I made the sidebar width to be same as vision page sidebar. Then I changed the level button size as they were too small for larger screens. I also made the level button container scrollable if the level buttons overflow. This took the most time because the whole puzzles sidebar body was overflowing pushing down that start button. I just wanted the sidebar body to not overflow which would make the levels container to be scrollable. The fix at last was using min-height: 0 to the sidebar body. Idk how the min-height: 0 is helping here š . Next I made the visualization section animation (The last section of the home page) to appear quicker. This was a recommendation from my brother as when scrolling previously the section might seem like it contained nothing until you scroll fully. I faced issued mainly with the section not pinning to the top of screen when trying to move the animation timeline starting point. Also I tried to placing text higher on y axis and animate it coming down with the user scroll which produce the result I was expecting. So, I split the timeline into two. The first one reveals the text and the second one shows a person visualizing. The tex revealing animation ends when the section top hits the top of the screen which makes the section pin to the top exactly how I wanted it to be. Then I polished vision page sidebar as follows: Made the sidebar responsive after user has clicked on start Made the sidebar header look better and fix mismatch of padding from body Returned to using flex for the attempts and mad them responsive Tweaked the options and info as they were looking odd in some screen sizes (mainly the tablet one which looked really bad) I then copied some of these changes to the puzzles sidebar for maintaining similarity. Lastly I capped the width of course, puzzles and vision page to 1600px by adding a wrapper element. It acted weird on puzzles and vision page sidebar as there was already a element named wrapper and so I changed the classname to page-wrapper."}, {"post_id": 76969, "ts": "2026-10-05T07:23:36Z", "hours": 1.8433, "text": "Fixing things and some more responsive things Iāve fixed chessboard displaying multiple selected squares. This happened when user selected a piece and then selected another piece by dragging. The fix was really simple. I just added resetSquares function when piece on drag start. Iāve also fixed pieces stacking on top of each other if user drags and drops a piece on another piece quickly before the opponents move happens. This was prevented when pieces are moved only by clicking but I forgot to prevent this if pieces were dragged and dropped. I did two things to prevent this: I reduced the time for opponent piece to move after the first move. I disabled the piece from dragging if it wasnāt the playerās turn. It seems the first fix wasnāt sufficient as it created another bug. So, if user selected a piece by clicking or dragging and then dragged the same piece then the destination squares and captureSquare will just completely disappear. The occurred due to resetSquares function that I had added. I thought for a while and came up with this solution. The resetSquares function only executes if user selects another piece on drag. However the function wonāt execute if the selected Piece is being dragged. The selected piece state null at first so resetSquares() wonāt also execute if selected piece is null. Now, it works as expected until and unless I find some bugs. Now returning back to the responsiveness. I fixed the puzzles button to be equal width and height. I had made the level buttons responsive before but they werenāt the same size. I had tried the aspect ratio last time as well but it was breaking the layout. Basically I used aspect ratio, removed the grid templated rows and changed some clamp values. Also I removed the media query below 1440px and integrated it as default css. After doing that, I started to fix the attempts in in vision sidebar. I thought it would take me two seconds to do it as I just had to apply the puzzle button knowledge here. I thought just doing this will work grid-template-columns: repeat(auto-fit, minmax(40px, 1fr)); I was wrong š This worked fine for level buttons cuz the number of buttons were static. Here the attempts squares increases as the user clicks on the chessboard. If thereās only one attempt square then it will take the whole width. I was stuck after this. I tried different things such as using max-width, trying to add width: fit-content, etc. but nothing worked. At last I thought of reverting back to what the code orginally was which just used flex and flex wrap but coming this far I just used grid and used different values with height to make the attemps square kinda responsive. I still need to use clamp or something to make this look good. Uhhhhhh this is so frustrating⦠. I think Iām overexplaining things. I should just simplify down things"}, {"post_id": 75141, "ts": "2026-09-29T08:47:38Z", "hours": 2.0161, "text": "This devlog is a short one Iāve made the vision page responsive for larger screens. Last time I made the page responsive for mobile screens. I made some small changes in puzzles page while doing this for maintaining similar code . I ran into some issues such as css not working due to incorrect nesting and writing the writing the css on wrong file. Also, I removed media query for 1440px as the default css will work between 1024px and 1440px using clamp css functions and by doing that, above 1440px the css will stay the largest clamp value. I think I will do the same in puzzles page as well. 2hrs wenāt so quickly mainly cuz of my stupidity as I broke things that already was working fine. Also, I donāt think I like the mobile responsiveness that much but i donāt think iāll change it now (or maybe I will). While writing this devlog I just realize that Iāve make the sidebar responsive after vision page has started. Uhhh i hate responsive design"}, {"post_id": 73203, "ts": "2026-09-24T16:25:05Z", "hours": 2.6344, "text": "Changed some puzzles and more responsiveness work Copied the puzzles page and itās componentās media query css So after making puzzles page somewhat responsive last time, the first thing I decided to do after that was copying puzzles page media query css and just paste it in vision page as both of pages are very similar. This made the vision page and itās components a little responsive. Puzzle changes Iāve changed the puzzle from level 12, 23 and 30. The 12 and 23 level had 2 ways to deliver checkmate and only one of them counted as correct. I changed them as user might get frustrated seeing that. My code doesnāt handle that so I just changed them. Level 30 was changed cuz it wasnāt really difficult. I donāt think Iām satisfied with the new level 30 puzzle either. One issue while polishing signup page I didnāt want the form to look squished on devices with small vertical screen size. Due to this last time I generally kept things smaller than what I wanted to make sure it looks okay for those devices. To fix that I added min-height to the form-container. It prevented the form from squishing but the form-container was overflowing as the puzzles page has 100dvh. What I wanted was just the form scrolling using overflow: scroll but this probably took me about 20-30 mins to make it work š . I set overflow to scroll to form-container it didnāt work, added it to form which also didnāt work and then I added it to puzzles page. The scroll part was working when I added it on puzzles page but not what I was looking. Then I created a wrapper div to hold the img container and form container hoping now adding overflow:scroll to form container will do the job. After trying all things things I realized that the min-height was set to form container instead of form. The fix was to adding min-height to form and set overflow scroll to form-container. I removed the wrapper div after that as it was unnecessary and also hid the scrollbar that appears in form-container. Signup and login page polish after that annoying issue After that annoying issue Iād say things went pretty smoothly. I mainly used clamp as always for making things responsive. And as always it took me longer that expected. After polishing up the signup page I copied the code to login page and just changed signup to login. Vision page responsive on mobile devices Making the vision page responsive for mobile device was really similar as polishing signup page. I just used clamp for everything and made sure everything looked good. Now that I think about it i only made the sidebar responsive including the popup menu as only that is displayed on mobile devices and chessboard is hidden. The chessboard is also kinda responsive due to the copy pasting the puzzles page media query css. The making of sidebar responsive was just trying out different sizes and then putting the value into clamp calculator and copy pasting the value. Now, Iāll work on the vision page responsiveness for bigger devices and then if everything looks great after testing then Iāll ship the project"}, {"post_id": 71645, "ts": "2026-09-21T06:52:58Z", "hours": 3.2419, "text": "Made puzzles page responsive and bugs fixes Puzzles page responsive Most the time was spent making the puzzles page responsive. As always it took more time than expected. There were many issue that popped up and slowly but surely I fixed them. One of the issues was in bigger mobile screens the sidebar was being squished because the chessboard was getting really big but puzzles page has height of 100dvh as the chesboard in mobile phones is calculated according to width. To fix it I tried adding min-height to the sidebar for not getting squished and height of auto to puzzles page but this broke the sidebar when puzzles is not started cuz thereās no chessboard. The height of sidebar is 100% so due to the parentās height being auto the sidebar height was about as didnāt fill the whole screen. To fix this I used overflow: scroll to puzzles page and itās height to 100dvh. Another issue came when trying to make chessboard and sidebar look decent in different laptop sizes. I made it somehow work but using clamp, min-height, max-height, min-width and max width. It was kind of a pain to solve all the issues that came while doing this. Thatās why Iāve rushed making the puzzles page responsive. My plan is to come and polish it after Iāve made the course page responsive as well. It shouldnāt be too difficult imo as itās very similar to puzzles page. Fixed user being able to drag and drop opponentās pieces It was a quite dumb bug. I had prevented this for click to move feature but I didnāt think about it in drag and drop. The fix was quite simple as dnd-kit (npm package) provides a disabled property in useDraggble. I disabled it for the pieces for dragging which had the opposite color of chessboard. Fix next puzzle button not working on second last level I didnāt actually know about this bug. A friend of mine told me about this issue while testing the website. After level 29 is completed a state is toggled to true which prevents the next button from not working. The next button is now only supposed to not work after completed the last level. I havenāt used fixed values for fixing this so in future if I decide to add or remove puzzles it shouldnāt break. The fix was a little more complex than I anticipated. 9 days of stardance remain now. So, I have to lock in now. Okay bie"}, {"post_id": 70097, "ts": "2026-09-18T13:33:32Z", "hours": 2.1928, "text": "Weāre close to the end First I fixed the buggy dropping piece. I fixed this when I first worked on drag and drop piece feature but I donāt know how it broke again. When trying different things to fix it I tried to move the setIsDragging(false) lower inside dragEnd function below movePiece and capturePiece function calls. Surprisingly it worked š. I fixed light square being dark and vise versa if user had the black pieces. I found out this issue because the coordinates colors were mismatched. So my first intuition was changing the color of coords.jsx. I got really confused as the changes did nothing in the browser. I am so dumb I was changing the vision page chessboardās coords.jsx instead of puzzles page chessboardās coords.jsx. It worked but then I realized the coordinates color werenāt wrong square colors were. I undid the changes made to coords.jsx. I also seperated the coords.jsx but adding puzzles and vision in the name. Then I fixed the squares color for blackās board. Iāve figured out the mobile design for puzzle section. First the idea was that the chessboard and sidebar would be stacked on top of each other. This was the easy route but if I did that then it would add friction to the mobile players as they would have to scroll all the way down to start the puzzles. Then I looked at chess.com and they were doing it really well where only after clicking start puzzle the chessboard will appear. So I removed the chessboard below 425px first and then made the button text, size and gap smaller. I also removed the aspect ratio of 1/1 from the buttons as the buttons were ruining the gaps between them in certain screen sizes. Now for the first challenge I faced. How do I only make the chessboard appear and disappear when clicking start puzzle only on mobile devices. As I used gsap matchMedia to make the chessboardās container display none or block according to hasPuzzleStarted for mobile screens. The chessboardSize is calculated according to chessboard container so that the chessboard is divisible by 4. When first loading the chessboard if the container has display none then the chessboardSize becomes zero and when setting the container to block will only show empty chessboard container without a board. I tried using the autoAlpha property of gsap hoping that it will do that same job as display none but without remove the element. It was making the container invisible but the container would still retain itās height and width. I was starting to doubt myself here and was thinking to take the easy route but just stacking the board and sidebar vertically. After thinking for a while I came up with a breakthrough I made the position of chessboard container to absolute and visibility to invisible. Now the chessboard container wonāt be visible and wonāt take up any space as it is absolute. When the board used absolute position idk why but the board container got so bigger. It also distorted the pieces when puzzle started. To fix it I ran the gsapMatchMedia code only after chessboardSize is calculated which was a great idea. It fixed the board when the puzzle started but when it was hidden it was still large. I just replaced the absolute and visibility with display: none as it only runs after the chessboardSize is calculated, thatās why there is no issue with display:none. Last change is when sidebarMode is notStarted then only chessboard is hidden. I know that 80% of the things I say wonāt be understood but Iām not a good explainer so you have do deal with it š
. Were really close to the end now I just have to make puzzles page and vision page responsive and just polish the website and then click the ship button"}, {"post_id": 69180, "ts": "2026-09-16T15:22:21Z", "hours": 2.6522, "text": "Omg how does changing the color model solve the issue Before that I fixed the black piece being upside down when dragging. You can see it in my last devlogās video. I was only happening with black pieces because to make the board work when user got the black pieces I just rotated the board 180 degree. This made all the pieces upside down and to fix that I again rotated the pieceās img 180 degree. Ig when dragging using dnd-kit (npm package) the transform value was being overwritten causing this issue. To fix the issue rather the rotating with board using css I changed the order of files and ranks. I used flex-direction column replacing column-reverse for the rank to start from 1 to 8. Then for reversing the files when color is black then I mapped squares from reversed files array using toReversed array method. I thought by doing this Iāll make the code cleaner but I think itās more messy now š . Also I did have hard time understanding my own code when trying to solve the issue š . I fixed the pieces, destSquares and captureSquares being generated on the wrong squares. I realized the piece transition wasnāt working when capturing piece both for userās piece and opponentās piece. The transition only happens if hasPlacedPieces is set to true and isDragging is false. So, my first assumption the hasPlacedPieces was being turned to false only when capturing pieces but I was wrong. I was checked if it had something to do with the value of isDragging. I found the isDragging was never turned false so I fixed it but still the main issue wasnāt resolved. I was console logging things and just trying to figure out what was actually causing the issue. The fix was really simple. To implement the drag and drop feature Iāve broken down piece code into itās own component. There inside the component I have added the key attribute and it was the issue. The key attribute is supposed to be used on the component itself instead of inside the component div. (Eg.) I donāt know why it only broke the capture transition but anyways itās fixed Now to the part where I donāt even understand how does this even happen. Hopefully you understood what I was saying in the video btw please unmute the video as I am talking in that video. So what happened was the piece img bg color changes when itās selected. This was working fine until I added the dragging feature. When the piece is dragged you see the background color comes along with the piece. So I decided that the square should change itās color rather than the img inside the piece. I was going to create squareRefs for holding all the values of sqaures and then select the square using gsap to change the color but I realized a easier way would be to just target the square id. It worked so I also decided to use for changing background color of square when user move was either correct or incorrect. On light squares it worked great and it also fixed the animation as the same animation was working a little weirdly when using pieceRefs. I was happy that it was better but then I found the bug from the video. I tried different things and just couldnāt figure out what was the issue but when I decided to change the color from var(āc-red) to yellow it worked as intended. Then I changed the same hsl color into hex and it also worked but I donāt know whyyyy. If someone knows why this happened please tell me cuz itās ridiculous. Most of the issue had a simple solution but learning what caused the issue what the difficult part."}, {"post_id": 68502, "ts": "2026-09-15T07:18:35Z", "hours": 3.0806, "text": "Worked on the drag and drop feature Although itās not fully complete and polished, itās kinda working. I stopped working on the feature and started writing this devlog cuz It has been 3hrs Iām forgetting what I did while working on it. Firstly I wasnāt even going to implement this on the first place as I thought this was outside my coding capability but someone gave me a feedback that I should add this feature so I decided to give it a shot. I found out about the dnd-kit package for implementing drag and drop. I was skeptical of using it at first. I was reading their docs to figure out the package. My main concern was how would I implement the feature with the already existing click to move feature. They provide a useDraggable hook for making any element draggable. The useDraggable was used to make the piece draggable. I had to convert the piece code into a component for it to work. To drop something into another thing thereās useDropable hook which as the piece I made square, destSquares and captureSquares into components. If I were a good react dev I wouldāve already did those things ig the using the package is some what helping my code to be cleaner. I used the useDroppable hook inside destinationSquares and captureSquares. I was concerned that we couldnāt actually drop the piece as it doesnāt live inside the square rather it lives on top of the board using position absolute. But, I had gotten dnd-kit wrong. I element does need go inside the element if useDroppable is used. Thereās DragDropProvider that connects both draggable and droppable hook. Letās just say DragDropProvider gave me all the function such as dragEnd and values needed to move the piece. Later I changed the useDroppable to be inside all squares cuz after dragging the piece there was some issues when dropping the piece in itās original square if the user wanted to cancel the move. I didnāt really have to write new code for moving, capturing and resettingSquare as the code I wrote previously worked fine with the drag and drop functionality. There were many issues while trying to add this feature. Still there are issues I need to fix such as the highlighting the square bg color instead of the piece bg color when selecting piece and other bugs Iāve found. Also transition when opponent captures pieces doesnāt working also need to fix that. But, Iām really glad I tried to add this feature as Iāve learned alot and the puzzles board now feels more fun because of the feature. Thanks @PAPER_01 for suggesting the feature š Okay, Iāll stop yapping. Have a good time"}, {"post_id": 67307, "ts": "2026-09-13T11:45:38Z", "hours": 2.3678, "text": "Gosh Iām so dumb Last time I thought I had fixed 404 page issue when visiting paths like course directly. I did fix it for local development but not for production which is really dumb, shouldnāt the development environment be the same as deployment when using vercel cli. I tweaked the vercel.json to fix the issue in production now but now in the development the website didnāt work. The fix that Iām now using is leaving the production as it is and in devlopment using the environment created by vercel cli only as backend and running the frontend seperately using pnpm run dev. To connect both backend and frontend I configured the vite.config.js to redirect every /api request to localhost:3000(this is running throught vercel cli) Most of the time was spent on making the signup page responsive. The login page is also now responsive but itās just a copy paste of signup page css. I am quite dissapointed in myself because it took me so long to do this and still I donāt like how it looks on certain screens. As I realized that I was spending too much time on making signup page responsive I panicked and just rushed the process. As a result a have a reponsive signup and login page that Iām not very proud of. I fixed the signup not working. While signing up there it showed user already exist error everytime. The fix was quite simple, I had missed await keyword when checking for user with same email in database. Due to which the userExists variable was always true. Then I did something really dumb. I tried to fix something that was already working. I was worried that if I delete a user from database and then if that user tries to login then it would throw an error so without even checking if that was true I started making changes to the protectRoute.js file. I was thinking after the token is verified then Iāll just check if the user exists or not. In the process I deleted one important line of code because of which I wasnāt able to login now and I didnāt know why. I tried made the code as before not knowing the line is still missing so the error still persisted. After giving up and doing ctrl + z undo the previous code returned I finally realized the missing line of code. Also the feature was already there when fetching user data so none of this was necessary š« ."}, {"post_id": 66353, "ts": "2026-09-12T04:12:13Z", "hours": 4.2436, "text": "Weāve reached 200 hours Itās a big milestone that Iāve finally reached . Iāve made the whole course page responsive. This took me longer than Iāve expected. But before that I was getting 404 not found when visiting locations like /course directly but it was working normally when I was navbar to navigate. Iāve seen this issue before as well so I kinda knew that this was because of react SPA (Single Page Application) thing. To fix this I configured the vercel.json file and now it works as expected. So onto the course page. Firstly I made the accordions responsive on mobile screens using css clamp function. I removed the course info section for mobile devices. I didnāt touch the course card as they were a future problem for me to do. But the basic idea was the image with take up the whole width and the image and the text will be vertically aligned instead of the default horizontal alignment. Between 1024px and 768px one of the issues was the course info was looking crammed on the smaller side. so I reduced the padding and font-sizes with clamp css function so that it still looks good on the bigger screens. I also made the progress bar slimmer and badges smaller. Another issue were the course cards. One the bigger screens they looked find but on smaller screens the text were taking up more height than the image itself. I changed the value of thumbnail image from fixed value to %. Also I reduced the massive 1.75rem padding on the course card container for smaller screens. Also for all screens sizes below768px I made the banner slightly bigger vertically as the previous banner was looking very slim on mobile devices. I scraped the idea of making course cards vertically aligned and stayed with the horizontal alignment. I somehow managed the cards to look decent on smaller screens as well by using clamp(). The things I needed to do were similar but I guess it took me long as I was first checking the min and max values using browser dev tools and then putting that into clamp calculator and then pasting the value into vscode. Basically I had to constantly switch between things. In the end, I went to sleep but couldnāt fall asleep so I decided to complete the course page reponsiveness and do on last thing which was making the loading spinner responsive. Then, I peacefully went to bed ."}, {"post_id": 65437, "ts": "2026-09-10T15:59:36Z", "hours": 3.6533, "text": "This was a rough one One a good note Iāve completed making the home page responsive (for now). After making the hero section more responsive last time I then proceeded with making the courses and puzzles page more responsive. I mainly used the clamp css funciton to make the course and puzzles section responsive. The courses section remained the same as I am quite happy wiht how it turn out but I didnāt like how the puzzles section was looking after testing the website out in my phone. It looked to small for a section so below 768px instead of the text and image being horizontally aligned itās now vertically aligned. The clamp part was similar to the courses section. Finally after completing those two I started working on the visualization section. I was the hardest section to make responsive due to the absolute positioning of the moves. Firstly I only focused on bigger screens as I had no idea how it would look on smaller devices. The moves were positioned before by mapping an array with the move notation and the css of top and right/left with percent values. I tried to remove that and instead of mapping the elements I thought of manually placing them and giving the ids by which I could have greater control over the css. While trying that I couldnāt make it work as in smaller screen heights it still looked terrible. At this point I was losing hope. I was wasting time watching a anime series just so I could avoid working on this. I tried thinking out the solution but nothing came in mind. Later when I was messing around with css throught the developer tools on the browser I realized the I could change the height of the image container to change the positioning of the moves as the moves are postioned on the basis of the image container. Now below 1440px the height of image container is 90% and below 1024px itās 80% and I have a max-height value set for safety. Itās not prefect but itās much better and Iām relieved š . The mobile design uses a image contaning the main image and all the moves as thereās no animation on mobile devices. I made the image in fimga and using clamps and % values I think itās decently responsive. To make the pages responsive I am using the developer tool in browser to first figure out the min and max values and the putting that value into clamp calculator to generate values. I am constantly switching between vscode and browser for this and if you have a better way to do it please lemme know. Okay the devlog has turned very long so bieeā¦"}, {"post_id": 64066, "ts": "2026-09-08T06:38:40Z", "hours": 1.9236, "text": "Worked on hero and puzzles section (Responsiveness) The puzzles section was the easier that hero and courses section for making it responsive cuz puzzles section doesnāt contain any animations or any special thing. After several trials of adjusting the fonts and image I stopped after it looked quite decent. Before working on the visualization section I decided to polish the hero section first. My main goal with polishing the hero sectino was mainly using clamp() css function for smooth responsive text. Although the text are responsive using media queries in hero section, the text look kinda odd in some screens. After using clamp the website feels better that before. Also I changed the width of image with % values which does feel better. I also used clamp for some vertical padding as well cuz it was looking bad for devices with smaller vertical heights. I thought from 425px to 768px was tablet screen size but it seems the tablet screen size starts from 768px. So now upto 768px the website follows the mobile design. Now Iāll polishing courses section and puzzles sections just like the hero section. Wish me luck š. Bye I wanted to add more images but it seems 4 is the limit ."}, {"post_id": 63438, "ts": "2026-09-07T08:57:07Z", "hours": 4.4833, "text": "More website responsive stuff Firstly, I removed the animations from home and courses section below 768px of screen size. I didnāt remove the hero section starting animation cuz itās nice. I used gsap matchMedia to achieve this. While removing the animations a funny thing happened, the matchMedia wasnāt working and then I was reading this a gsap forum hoping to see where did I go wrong. I later found that I was doing things correctly but instead of looking at localhost I was looking at live website. Obviously the changes didnāt appear š¤¦āāļø Then, I made the courses section kinda resposive. Firstly I went to figma to design the mobile version of courses section as I was mainly unsure of what to do with the thumbnail cards. I decided to turn them into carousel which imo was a great idea. First, I turned turned the main courses section text smaller and then started working on the carousel. The making of carousel was rough. Firstly I was reading stuff online on how the sliding thing works. I think I somewhat figured that out but what I couldnāt figure out is the aligning the cards perfectly. The issue was I was going for a style where the first and the last card arenāt centered alight while the rest of them are. The swiping snapped the cards into place and some parts of the left and right cards would also be visible. I couldnāt figure out how to make this and was about to making hamburger menu but coincidentally while scrolling the stardance home page I saw recommended projects section where itās like a carousel without the snapping thing. It was way easier to achieve than what I was thinking so even though I didnāt make what I wanted the carousel isnāt bad. The overall the courses section felt responsive so I started working on the hamburger menu. Working on hamburger menu went pretty smoothly except for some things going wrong here and there. I first roughly designed the the menu in figma and then wrote the code."}, {"post_id": 62042, "ts": "2026-09-05T08:11:51Z", "hours": 3.8953, "text": "Starting making the website responsive Before starting on making the website responsive I saw that when logging in or signing up there is some delay before redirection where people might click the login button several times thinking that it itās working which is bad ux. In development there was almost no delay because I was using local mongodb. To let the user know that the button has been clicked successfully and to prevent multiple login/signup button clicks the buttons are disabled as soon as user clicks any button in login or signup page while turning the buttons color into gray. Now on to the reponsive ui part. I first tried making the navbar responsive but it didnāt look right in small screens. I was also trying to make the hero section responsive but without any design to follow. So realizing that I needed a design first I then hopped onto figma to design the navbar and hero section. I changed the ui of the navbar ig to make it easier to make it responsive but I donāt know if the navbar ui got better or worse. I know one thing and that is the navbar has got simpler. The design on the mobile is pretty simple imo but thatās the best I could do to make it look decent. I used flex property to make all the text align vertically in phones and decided to remove the image in phone screens. Iāve have currently hidden all sections below 1024px except the hero section to focus only on the hero section without other sections interference. Iāve mostly used hardcoded values to make hero section which I will change to clamp css propery for smoother hero section responsiveness. I have just eyeballed the sizes and paddings which is a bad idea but Iām just lazy to create figma design for every layouts. Now, Iāll make the hamburger menu working. Uhh, I hate making website responsive but it has to be done. If youāve any suggestion feel free to leave it down in the comments."}, {"post_id": 61270, "ts": "2026-09-04T03:49:40Z", "hours": 1.9669, "text": "The website is live guys I used vercel to deploy my mern stack project and it was rough . I first tried deploying the the frontend and the backend separately. After reading blogs and trying I ended up deploying the express backend but at that point I had learned that thereās vercel cli with which I donāt have to push commits everytime to find out errors in production. I can just use āvercel devā command to create a production like environment but for development and testing out. I couldnāt figure out how to run frontend and backend seperately using vercel cli. I then tried deploying the whole repo. The issue with this was I couldnāt configure the website with folder structure like this chess-website ----frontend ----backend Maybe thereās a way to make this work (I couldnāt ), I chose the easier path which Iām kinda familiar with. In this approach thereās no frontend and backend directory. The backend is renamed to api which allows vercel to recognize that itās the backend and all the contents of the frontend folder will be moved up to the root directory. Errors came as I changed the folder structure but fixed on after another. The backend wasnāt working which got me really confused. There were many issues in this approach as well but atlast the website is running and backend is working properly . The two days break I took from coding is over and i think I feel better. Hereās the link to the website: https://evochess.vercel.app/"}, {"post_id": 58966, "ts": "2026-08-31T15:18:41Z", "hours": 2.2961, "text": "Many small improvements š Iāve added transition to level btns and added icons and different ui to puzzle sidebar button. I am using an array inside objects to display all buttons. So to customize the buttons I manipulated the array.Some button have only text, some have both text and img and some have only img. Also the main button is wider and other buttons are gray in background color. For this I used the className like in tailwind to add the styling meaning the buttons which need gray color will have the className gray. The size of the buttons is differentiated using different values of flex grow. I think the buttons look way better now. Iāve added reset if user changes from puzzles page to other page. The is to avoid any unnecessary bugs and error. I had already done this in vision page now it was the turn of the puzzles page. I have been avoiding this for so long but finally Iāve done it. I added the videos for professional course (or should I say advance course). I changed the name to advance cuz professional is just the wrong word to use here. I also moved some videos from beginner to intermediate. Now that the courses are in place I can finally write what youāll learn in the information section. Iāve added numbers such as 0 - 1000 representing what I mean by beginner. Iāve tried to match videos to the elo level. The data in courses section in the home page is also change from placeholder data. Looking back at the code they are really bad but Iāll leave it as it is not broken š. Now I think the project is coming to itās final stages I do need to add things but after that ig all I need is to polish the website and make website responsive. Iāve also fixed progress bar animation happening everytime on reload. This was a small thing but it was bugging me so I decided to fix it. Fixing it was annoying as I had expected to fix this easily. After some trial and error I fixed it using a hasCompleted state which is set to true after finish lesson button is click. Only when the hasCompleted is true the animation occurs. Some other changes I did were fixing only displaying highest achieved medal in course page and adding background color transitions to buttons. Enought yapping. I donāt feel like coding and I think I should take some rest for the next two days. Hope the rest reset my feelings and returns me to my prime stardance days š."}, {"post_id": 56525, "ts": "2026-08-28T10:04:18Z", "hours": 2.7708, "text": "Wow! This is the 51th devlog Iāve added the player color indicator in the sidebar. It tells you which color youāre playing. Before coding this I just complicating things in my head by thinking of creating new unnecessary states. I used pen and paper to think and realized why not use the color state already available in chessboard. To access the state I moved it up to the puzzles context file where both sidebar and chessboard could get and change the color. I also moved the hint down as it look clutter both color and hint together in the sidebar. Two quick small fixes. I fixed retry and back button not working and fixed replay button not playing the same level only on last level. Iāve added pawn promotions functionality to the opponentās pawns. In puzzle 17 and 26 there are promotions that happen but without the promotion part it just looks weird to look at. Especially in level 26 where the pawn promotes to a knight and without having that knowledge the user will just get confused. I havenāt added promotion functionality for the user pawns because there is no puzzle that requires it. I will add it if I have the time to but rn i am going to just ignore it. One of the bugs I faced while doing this was the knight promotion worked fine but the queen promotion at level 17 wasnāt. The pawn was just disappearing because the pawn was capturing itself cuz the promotion only work for black pieces which is now fixed. Next I fixed the random color option color menu not working. Idk when and how it broke I thought it was working fine but it seems not. It seems it was not working because the element was being unmounted before running the selectRandomColor function. So, I moved it to vision context and with a useEffect hook it runs every time hasStarted is true. A small change but which I feel great that itās solved. When clicking on accordion or pieces twice sometimes it selects the icon and other things which was just annoying. The fix was just two lines of css which I learned from a random dude on the internet. Really thank that random dude. Iāve now added functionality for adding multiple bestScore for according to the time and color. Before the highest score in vision would be the score scored across any time or color. So if you were to score 5 point in 45 seconds and score 5 points in 30 seconds they were treated as the same thing which imo opinion isnāt fair. To achieve this I used object inside a object unlike the single number representing the bestScore like before. The object looks like this. { white: { 15: 0, 30: 0, 45: 0, }, black: { 15: 0, 30: 0, 45: 0, } } I did have a very hard time figuring out how to update the state like this as I had to change the specific time score within the correct color. One thing I did learn from this is we can use square brackets for using a variableās value as key while manipulating the useState object. I also encountered some errors while trying to implement this functionality. Now everything is working as expected."}, {"post_id": 55374, "ts": "2026-08-27T05:12:03Z", "hours": 2.2717, "text": "Iām so sloppy now Iāve added sounds for piece movement, capturing piece and completed puzzle. I spent more time than I shouldāve finding the sounds. I am still not sure about the sounds that Iāve added expect completed puzzle sound. There was issue with playing sounds during opponent move cuz unlike moving playerās piece where there are seperate function for moving and capturing pieces, the moving and capturing logic is inside the same function. After thinking a while I did solve the issue. It seems mac default recording doesnāt capture sounds so you just have to trust me here š
. Iāve made hint button disabled when pieces are moving (Both player and opponent piece). I did this after figuring out if user click the hint button quickly after the last puzzle move then we get an error. Although this thing happening is very unlikely but itās better to always fix bugs. Also I donāt know what happens if user clicks on hint inbetween moves so I think preventing it is better. A small change, Iāve added better hover transition to logout button. I didnāt add a red background during making it cuz I had issue with chaning the svg color. Iāve learned that if I make the svg inline in the jsx and set fill to currentColor then I can change the svg color through css and add transitions. Also, Iāve added popup animations to time menu and color menu. I was even struggling with this even though Iāve added those kind of animations before. I was using the new Activity element in react to toggle the menus but to for adding the animations Iāve removed the Activity element cuz the menu would disappear before animating. I took some break from coding cuz I got sick. I think Iām really sloppy now. Imo these changes shouldnāt have taken me 2hrs. Hope I will be able to shake off this sloppiness."}, {"post_id": 53935, "ts": "2026-08-24T17:12:15Z", "hours": 2.6236, "text": "A little rest from programming Iāve added hint button in the puzzles sidebar. I had been trying to avoid working on this but I couldnāt avoid it forever. Also the puzzles sidebar looked really empty without the hint button. In chess.com the hint button highlights the correct. I did things a little differently, the hint is communicated via text to user. The text animates during first appearance and Iāve made it so that user gets only one hint. After the hint the button goes gray indicating itās not clickable anymore. I made puzzles sidebar code better to display buttons and also added replay button with functionality on successful puzzle complete. I mainly made the code better cuz I need to add the replay button. The replay button is same as retry button for replaying the puzzle after completion. I made next button do nothing if user reaches the last level. Before when completing the last puzzle level we would reach the next level automatically which is prevented now. Iāve been sick for 2-3 days now and am just writing this devlog. Hopefully from tomorrow I will be working on the project more seriously."}, {"post_id": 51434, "ts": "2026-08-21T04:22:13Z", "hours": 1.9856, "text": "Interesting updates I added back button in puzzles sidebar with functionality. Before there was not way to go to the default sidebar (the notStarted state). Now after messing up or completing a puzzle thereās a back button which sets the board to default postion and set sidebarMode to ānotStartedā. I wanted both buttons to be taking up equal space but later thought the smaller back button is better. Also now, puzzleLevel updates instantly updates after solving a puzzle instead of updating only after clicking next puzzle button. User can now select and play any completed puzzle by clicking level btns in sidebar. Previously user can only start the puzzle Level user has reached which meant no puzzle 1 and 2 resolving puzzle after user has reached level 3. I split the puzzleLevel state into selectedLevel and highestReachedLevel. The puzzle is set to the selectedLevel and the buttons arenāt clickable above the highestReachedLevel. The ui of level buttons is changed. I made the buttons smaller and made the selected level more distinct by adding a inner glow to the button. Weāve upto 30 levels now . I downloaded the lichess puzzles database for this project but whenever I opened the file my laptop will just heat as there were more than 69 millions data š . I did try to use the lichess data but I didnāt actually like the progression of difficulty so I used chatgpt to make puzzles. Iāve played upto 21 levels and I think itās good so far. Thatās all for now, okay bieā¦."}, {"post_id": 50379, "ts": "2026-08-19T15:27:48Z", "hours": 1.1106, "text": "Finally, I present to you a short devlog š I have fixed the issue of pieces moving with transition when pieces are being placed after clicking on retry puzzle. To prevent this I already written code which worked perfectly but when only on retry puzzle it wasnāt working. This solution was simple but figuring out the issue took time. To fix the issue I used a useState hook to set hasPiecesPlaced to true only after pieces state updated. Also, Iāve already written code for handling page change in the middle of vision practice. I think this doesnāt work after I removed Chessboard.jsx and ChessboardContext.jsx. Not sure when this broke . I found better way to do this using the useEffect hook cleanup function. I learned that when adding setState directly in cleanup function it throws at recurring error š . I felt my laptop heating up š š . But thereās no error when adding setState inside the function and then running the function in the cleanup function. Thatās all for today. Couldnāt do as much as would like today cuz a rat bit me š. Byeā¦"}, {"post_id": 49661, "ts": "2026-08-18T15:27:18Z", "hours": 4.6519, "text": "Ayy good progress today I created a separate chessboard component for puzzles page only. Before both puzzles page and vision page were using the same chessboard component making the code complex, hard to read and hard to debug. Firstly I decided to move all the chessboard functions and states into puzzle context but later changed my mind midway. I decided the chessboard functions and states make more sense to be in itās own folder. Everything broke while doing as expected but I fixed them one by one. Now the puzzles chessboard is functional and itās code looks a little less overwhelming to me. Now the vision page also needed a separate a chessboard. It wasnāt as easy as just copying and pasting most of the code into vision chessboard because the data was connected to more components of the sidebar such as progress timer, color Menu, etc. I donāt if I should separate the functions to components that they server of just dump it all into the vision context file. What I did was keep functions into their respective folders cuz I think the vision context file looks really cluttered doing that. Everything broke here as well but as before I fixed things one by one. Now I really believe it will be much easier for me to work on chessboards as theyāve been seperated. Also I deleted the original chessboard component and chessboard context after that. On clicking the sidebar button the reset board function is called and the function came from chessboard context. As there is no chessboard context now you can see that thereās a problem here. The reset board function in now in PuzzlesChessboard.jsx which means we canāt access it from PuzzlesSidebarBody.jsx. To solve this I just made the board reset everytime when hasPuzzleStarted is true. We do have the access to hasPuzzleStarted from puzzle context. Fixing that somehow broke the piece transition though. After that I mostly worked on the small things. Such as fixing no transition during piece, fixing the progress timer staring with 2 seconds less than the time set, adding chessboard size to puzzles chessboard in a better way, etc⦠Now the next puzzle and retry puzzle buttons also work. The next puzzle button works as expected. The retry puzzle button also works but the pieces move to their repective place with animation when the board resets which I donāt wanāt. To prevent this specific thing I have already written some code before and itās working when starting the puzzle, moving to next puzzle, rendering the default pieces on first load. I canāt figure out why itās specifically working for retrying a puzzle. I spend a good amount of time looking but idk. Iāll look into this tomorrow. I think the devlogs are still pretty long. Iāll try to keep the devlogs shorter on future devlogs. Okay bieā¦"}, {"post_id": 48941, "ts": "2026-08-17T14:42:47Z", "hours": 3.0389, "text": "Two steps forward, Four steps backwards š Firstly, Iāve fixed the gsap animations not working. This happened because last time I renamed all the color state into chessboardColor. Due to this the gsap backgroundColor css property turned into backgroundchessboardColor. Ig the lesson here is think before using change all occurences feature in vscode. The sidebar now changes. If puzzle hasnāt started then itās the same old ui. If the puzzle starts the level btns disappear along with start puzzle button. If user makes incorrect move the sidebar show retry puzzle button and if the puzzle is completed successfully then next puzzle button shows up. One thing I learned here is making one button use different className, onClick handler and text easily by storing all data in object. The retry and completed onClick function looks empty. So, I decided to work on the retry puzzle button functionality. To make the functionality work I imported the resetBoard function from chessboard context. Calling the function directly didnāt work because setState function doesnāt apparently update if the value is same. I fixed that by passing {retryLevel: true} or false to the function. After doing this the first opponent move did break and I did fix it but I think with bad code. Looking at the code now Iāve been calling resetting the board and setting default position using the chessboardColor seems wrong. So, then I started cleaning the code. I guess I was correct and things needed to change. I would say these are mostly small changes and donāt need explanation but it seems that the chessboardColor had an actually bug and it took my soul away trying to fix that š . So, the opponent move was capturing itās own piece meaning that the piece which moved at the beginning would automatically disappear. This was happening because the moveOpponentPiece function ran before the chessboardColor could change when the puzzle is first started. To fix this I had used useEffect hook with chessboardColor in the dependency array to reset the board. But only works if I have the black pieces. If I have the white pieces the chessboardColor doesnāt update because useState doesnāt update when the value is same. The value is white at first because of the default position set when puzzle hasnāt started. I donāt even know how to explain the fix i used. I just chained state updates from file to file to have colorUpdated state value updated in chessboard context.jsx. Basically I had a rough time fixing the resetBoard function running before chessboard color was updated. This time even pen and paper also couldnāt help me solve this š š but it did help me to understand the problem on a deeper level. I tried adding next puzzle button functionality. āI triedā š cuz I couldnāt get it to work and on top of that when I tested the retry button it didnāt work. Donāt know how but the retry button also broke. Now, Iām taking a huge decision again. I think some of the problems can be reduced if the chessboard wasnāt a single component that works on both puzzle page and vision page. I think I was too ambitious but now seeing these issues I think itās better for me to have to separate chessboard components. This might not be the best practice, but this will probably make my life easier. I just read the āDevlogs that get noticedā in the resources page and I think I should make my devlogs a little shorter. I said this in one of my previous blocks as well, but it seems that I am explaining too much. So letās see what will happen tomorrow. Okay bieeeeā¦."}, {"post_id": 47257, "ts": "2026-08-15T02:00:48Z", "hours": 3.0875, "text": "Learnt something valuable ⨠Okay now the puzzle buttons have dynamic ui. The puzzle button will have ui according to the puzzle level. I was confused on how to achieive because there were three condition instead of two. If there were only two coniditions then it would have be easy as I would have simply used ternary operator. I couldnāt use if condition inside jsx. After some time I figured that if could call a function and use if conditions inside the function and return the className. Also now the puzzle level is stored and fetched from the backend. After doing that a toast error popped up as you can see below. I didnāt know why this was showing up when the page is first loaded up but instead of fixing that I first moved on to make the start puzzle button work. I think my main problem is I get distracted easily. To make the start puzzles button work firstly I created puzzle context file . I was deciding to make the chesboard context the puzzlecontext as all the data needed for puzzles page was there but I think itās better to seperate those things. So, I placed the puzzle context higher than chessboard context with that thought process. If the puzzle hasnāt started the fen value is set to default starting position. Then I again got distracted and thought why isnāt the vision context also above the chessboard context. So, I moved the vision context and the coordinates broke. The reason was color state so then I created different color states for vision and puzzle context. While writing this I donāt actually know what Iām really doing. I do one thing and jump onto another making writing the devlog very hard. I think I can do better⦠š After learning the lesson, doing thing one at a time. I only focused on making the start button work. So I moved some values inside puzzles context for this to work and everything broke. But, I wasnāt feeling overwhelmed as my focus on only one thing. Slowly but surely I fixed the pieces moving, capturing and the first opponent move. I think my main issue is dealing with useState hook updating in batches. Ig I will just get better with time. Still the backgroundColor animation is broken which I need to fix. Also while doing this I found out why the toast error was occurring. Silly me didnāt add method post to update the puzzle level. Now after the puzzle finishes the puzzle levels value updates and the updated value persists. I should definitely do things one at a time. Getting distracted and doing multiple things will just make me feeling overwhelmed and will make it harder for me to devlog as well."}, {"post_id": 46384, "ts": "2026-08-13T15:40:46Z", "hours": 4.4847, "text": "Making good progress The piece background color now changes color depending upon the correct or incorrect move that the user makes. Last time I was trying to achieve this by just using useState hook. Iāve understood now that it was the wrong approach instead now gsap handles the animation part. The main issue with gsap I was having was I didnāt know how to select the exact piece for animation. Iāve achieved this by using useRef hook named pieceRefs containing an object will all the pieces on the board with their ids as key. I havenāt never used a ref like this before and it feels scary to write code in the unknown territory but ig itās a part learning. Also Iāve removed the code that changed the backgroundColor using useState and used gsap. It was just waste of my time to try to use useState hook to change the backgroundColor . So now, piece toggling the highlighted bg color when a piece is selected or unselected will be handled through gsap. Ahhhhhhh.. Finally after a puzzle is completed successfully the the next puzzle will start. My brain feels like itās melting after making this work. I struggled so much to make the work mainly due to react batching the state updates. Unexpected bugs came while coding this. So, basically a puzzle is considered finished if the moveOpponentPiece function has no moves left. Then, we change the fen state and also reset the board so that the pieces are placed again. After that when player reaches next level the opponent first move needs to take place. For that I have a useEffect hook to check if opponentMoveIndex and userMoveIndex value are default values. The values are set to default through resetBoard function and if the values are the default ones then the opponent pieces moves. One of the main issues I had with this was the moveOpponentPiece function was running twice. Due to which one of the opponent move was being skipped. I wasnāt able to locate why and was making so many unnecessary changes and console logging everywhere to fix this š . The issue was that the useEffect that I talked about earlier had pieces in the dependency array making the moveOpponentPiece function to run twice. Iām really exhausted after doing this⦠Then after some relaxation I made a rough figma design for the puzzles sidebar. It was kinda relaxing to not worry about coding for a while. I had big plans for the sidebar like making candy crush type levels but I donāt think Iāve time for that so just basic buttons will have to do. Iāve tried creating the distuinguishing the levels based on completed levels, current level and locked levels. Back to coding again, I mostly copied the vision sidebar code for puzzles sidebar as the only difference is in the sidebar body. It seems that Iāve forgetten to use css grids. I wanted the buttons layout to be responsive. I took a quick revisit on how grids. Throwed random properties at the grid hoping it will work as I expected š. At last it was the auto-fill property I was looking for with a combination of minmax. Iāve tried created the css for completed, current and locked now I just have to hook them up to the buttons according to puzzle level reached by player. Iāll do that tomorrow, now Iāll stop writing. If youāre reading this, I hope your project is going wellš."}, {"post_id": 45805, "ts": "2026-08-12T14:57:39Z", "hours": 2.5114, "text": "I am stuck Ayy the opponent moves work as expected now. In last devlog I wasnāt able to capture opponentās page because I accidentally didnāt filter the pieces, only moved the piece. Now the capturing system also works as normal. While talking about capturing pieces now the opponent can also capture pieces. If any of the playerās piece is on the destination of opponentās piece then it will be captured. The main lesson learned here is to mostly use the previous data while changing the stateās value to avoid unnecessary bugs. Iāve made the reset board function work. This was the point where I decided to rebuilt the code by removing the use dom manipulation and looking back I think it was a great decision by me. (Context: 2, 3 devlogs ago I found out my code was really trash while creating the reset board function). While writing reset board function I did run into some weird bugs. The board is reset by reconverting the fen to pieces array. The first opponent move happens when the opponentMoveIndex is 0 now. In the reset function the opponentMoveIndex is set to zero. Iāll add a animation to indicate that the userās move is incorrect later. For now I added the animation for the piece moving. Iāve learned that when moving the pieces by updating the state in react, the key of the element is what matters for animation to occur. If the key of the element is same and just the transform style has changed react knows that itās the same piece that jumped from one place to another. Also now, the move transition doesnāt happen when the pieces are being place. Because the pieces are placed using the transfrom property, the same property used to move the piece. I took me a while to fix this. It seems that this was happening because the squareWidth was making the page re render. Iāve fixed it but I still I donāt completely understand it, which shows that Iāve a long way to go. This one is small but crucial. Now the user cannot select the opponentās piece during opponentās turn. Iāve added a 500 ms delay for opponentās move so that it doesnāt feel things are happening really fast. In that timeframe user is not able to select any pieces now. I am now stuck at the part where I am trying to animate the pieces after checking the user input. Whether itās correct or incorrect. I wanted to make the background green if the move was correct and red if it move user made was incorrect. Using states is proving to be tricky for me as theyāre fully synchronous. My brain goes okay this will happen and that will happen but the code wonāt have the updated data because of useState nature. Also I tried to change the background color same way I move the pieces. Now that I think I about it I just wasted time. I will try to do animations with gsap now but idk how to explain I canāt really think of a way to do it with these useStates. Okay this was more that enough yap for 2hr 30 mins of work. Letās see if I figure out a way tomorrow. If youāre reading this love you man š."}, {"post_id": 45236, "ts": "2026-08-11T16:05:21Z", "hours": 6.4983, "text": "Most rebuilding my broken code For context last devlog I took the decision to start rewriting the code to stop accessing dom directly by using states. Now the pieces are mapped from pieces state rather than directly from fen so that I can move the pieces from state instead of manipulating the dom. To achieve this I firstly created to convert the fen to pieces array. The pieces array looks something like this rn. [ {id: 'r-a8', pieceNotation: 'r', square: 'a8', coordOfFile: 0, coordOfRank: 0}, {id: 'r-e8', pieceNotation: 'r', square: 'e8', coordOfFile: 4, coordOfRank: 0} ] From this I learnt that setting the key attribute serves itās own purpose in react. I donāt fully understand it rn but Iāll look into it. Now, the id of the piece serves as the key for the piece element and if Iāve understood correctly that will be vital in animating the piece moving. Yay the rook has been reestablished using react state without any dom manipulation. The reestablishment wasnāt too difficult as I thought due to the already existing code. All the changes now happen in the pieces state which then causes the react to repaint the pieces. Now the rook can move from one square to another and capture opponentās pieces. Also Iāve made the reset squares function as it removes the destination squares, caputure squares, etc . Although thereās no animation during piece movement rn Iāll it add later. After making the rook work I stared making all other pieces work as they used to before. I thought I had to write most of the code to fix all the pieces but after finishing the rook other fix other pieces wasnāt that bad. I reused the code from the rook where I could, fixed some bugs and errors on the way and modified the code where necessary. Sometimes I got stuck due to my own stupidity but thatās nothing new š. The moveOpponentPiece function is rebuilt. Now the first opponent move will happen when the board is first loaded. While fixing this function I found out that I was able to select the opponentās piece as well. This shouldnāt be the case cuz I had already put railguards for preventing this. After fixing the moveOpponentPiece function I checked why this was happenning and the cause was I put railguards only if user click on another piece when a piece was already selected and that code was also wrong. I fixed them both and now they work as expected. Another bug found. When I clicked on the first pawn it only created one destination square instead of two. This was happening because the for loop had only 7 iterations instead of 8 which added the starting pawn squares to the array. Also the userās pawn were able to capture the userās pieces which was a big nono so I quickly fixed that. Even thought the moveOpponentPiece is working for the first move it instantly breaks from the second move. I still fully donāt understand why this is happening. I know it has something to do with using setState and it not being synchronous. The code looks like this let updatedPieces = pieces.map((piece) => { if (piece.square === position) { return { ...piece, square: destination }; } return piece; }); setPieces((prev) => { console.log(\"updated\", updatedPieces);// I don't understand how this value return updatedPieces; // and this are have different values}); Iāve fixed it while writing this devlog removing updatedPieces variable and mapping the value directly inside setPieces(). Now, the second move works but the third move is broken š . Iāll look into this tomorrow. Iāll wrap this up for today. Also Iām changing my devlog style a little bit. Iām not telling you all the problems I ran into like I did before to keep the devlogs a little short."}, {"post_id": 44520, "ts": "2026-08-10T10:34:10Z", "hours": 3.1394, "text": "Taking a BIG decision Updates: Fixed pieces creating only single capture square Added redirection to signup page in puzzle and vision page if user isnāt logged in Made user unable to select piece when opponentās piece is moving Connect oppenentās move to puzzle data, Add check for user moves and Add functionality to make the opponent piece move automatically after user plays the correct move I fixed the pawn not being showing two capture squares last time. After that I found out that the capturing the piece wasnāt removing the piece from the board. I found out a function that I have commented out was being called and causing an error so I removed the function call for now. This was easy to fix but by doing this I found out that the pawn wasnāt the only one who wasnāt able to display mutliple capture squares. All the other pieces werenāt able to display multiple capture squares due to a simple rookie react mistake. The value of captureSquares was being updated with itās own value instead of using the previous value. After sorting that out I figured i should do same with the destination squares. Previously had an array updatedDestinationSquares after pushing all the values to the array then only I updated the destinationSquares value. In short I was doing the correct thing and me thinking that I could save 2 lines of code by adding setDestinationSquares directly to the loop was a bad idea but the state function isnāt synchronous. So I undid all the changes and also added a updatedCaptureSquare to all functions just to be safe. Now user canāt select pieces when itās the opponentās turn. Although the timeframe to select piece is small but still I wanted to be safe. I achieved this with a state named isOpponentPieceMoving. itās toggled on when user clicks on a destination square and toggles back off after the animation finishes. Next I tried to make the opponent piece move work through with the help of the lichess puzzle data. Before the opponent piece could only the first move to play. After connecting the moveOpponentPiece with puzzles data. I created a function to check whether the move made by user is correct or incorrect. This was also being checked with the data in constants.js file. The data is stored like this r3r1k1/p4ppp/2p2n2/1p6/3P1qb1/2NQR3/PPB2PP1/R1B3K1 w - - 5,e3g3 e8e1 g1h2 e1c1 a1c1 f4h6 h2g1 h6c1 The moves part start after the comma. First move is of opponent. It tells from which square to which square the piece is needs to be moved Eg(e3 to g3). The second move seperated by space is what the user need to play to move forward in the puzzle. So if the userās move is correct then I move the opponentās piece. But if itās incorrect then I reset the board. I got lost in the reset part. I learned if the key of a element is changed the element kinda resets. When I started doing this I felt a little uneasy. I was figuring out the code I wrote was manipulating the dom which isnāt the best practice in react. Regardless, I added a fragment to the code that was generating the pieces with a key with the value of boardKey and updated the boardKey when the userās move was incorrect. But in my mind a question was lingering \"Should I redo this in the way how react wants it\" . Seeing the functionality working I pushed off that question. But, when I captured a piece a error popped up. The ss is below. I tried to locate why was that error popping up. Iāve concluded that the bad code has started to show why itās called bad code. Although I might find this solution to this issue I think itās better for me to just rewrite the code. This is painful but it will make me a better developer. Also I found another bug, the error isnāt the only reason Iām making this decision. Iāll push the code upto what Iāve done right now and then Iāll start to fix what Iāve created."}, {"post_id": 44051, "ts": "2026-08-09T15:53:39Z", "hours": 2.9425, "text": "Iām dissapointed in myself Updates: Fixed pawn unable to show two capture squares at once Added function to move opponentās piece automatically Set fen according to puzzleLevel Moved opponent piece after the pieces have been placed and remove css transition into gsap animation while moving pieces Last time I added functionality to pawn to be able to capture pieces. It worked fine I there was only one piece diagonal to the pawn. I there were two pieces diagonally infront of the pawn only one capture square would appear. Now two capture squares appear if there are two pieces in front of the pawn diagonally. Fixing this was simple. Created the function to move the opponentās piece automatically. In puzzles the user only moves their piece, the opponentās piece moves automatically after user plays their move. This was the most frustrating thing I worked on today. I thought the function worked correctly but I was wrong. Iāll tell you in a sec. I added 3 fens with moves from lichess puzzles data in constants.js . Then I made the default fen data to null and made it so that the fen is selected according to the level of the puzzle. I think I was trying to add loading state for this. It was very poor thinking from me. I was just being very ambious and instead of trying to do things step by step I was trying to multiple things at this time. I donāt remember exactly what changes I tried to make ig I was trying to fix the moveOppenentPiece function as well at this time. I undid some of those changes, left others as it was and fixed the fen and commited that. I was already frustrated at that point and then when I tried fixing the moveOpponentPiece function the constant errors and bugs worsened my frustration. I donāt want to explain that part. Just know that after fighting with my code itās working now. Also before I had css transition for trasform property. Meaning that whenever the pieces moved it moved smoothly. But when the chessboard is first rendered all the pieces also animate to their places. I fixed this by removing the transition css and using gsap to move the pieces. Now the first opponent move happens automatically. This was also frustrating to make it working. Basically today was frustrating. I thought I coded longer but seems like not. But anyway, when youāre at the bottom the only was is going up. Saying that I will stop writing this devlog. I feel I could have written an essay today. Okay bieā¦"}, {"post_id": 43708, "ts": "2026-08-09T03:48:45Z", "hours": 3.2064, "text": "Gobble up pieces Updates: Rotated piece img when color is black and made user unable to select opponentās piece Added functionality of capturing pieces with rook Added functionality of capturing pieces to bishop, king and knight Added functionality of capturing pieces with pawn My goal was to make the board work from both sides. I was ready for this goal to be challenging. I was messing with squareid and position of pieces by checking the color of the board. But it seems donāt have to do much for things to work. Before, I have already made the board rotate using css. I was rotating the pieces when color was black and that was causing issue. Instead of rotating the piece I simply rotated the img inside the piece. Till now every is working as expected. Also I made user unable to select the opposite colored piece. Now we can capture pieces . If a piece can be captured, the piece will have four triangles at the corners. This is inspired from lichess as I didnāt really like the circle of chess.com. I made the triangles myself using figma. Also I created the dot in figma to change itās color. Previously the dots were green. It took me some time to pick the colors of triangle and dot cuz I didnāt wanted their colors to ruin the feel of the chessboard. This works by firstly determining if the piece in the way of destination squares is our piece or the opponents. If itās our piece then destination squares will instantly stop generating but if itās the opponentās piece the we first add the sqaure position to capuredSquares array and then stop generating the destination squares. While doing this I learnt about the remove method which allow me to remove the captured piece element from the board. It took time for figuring out how capture pieces with rook. After that it was really easy for me to do the same with other pieces as well except for the pawn. The pawn isnāt the same as other pieces. It moves vertically and captures diagonally. So I had to write code differently for the pawn. I code for the pawn does seem a little messy but i think itās fine. I would say it wasnāt too difficult to make the pawn capture pieces. I did have to think about making the capturing functionality work for both white and black pawns. This much for this devlog. I am being quite lazy nowadays. Time to grind and lock back in. Hit me up if you also want to grind along with me."}, {"post_id": 43022, "ts": "2026-08-08T02:09:50Z", "hours": 3.1258, "text": "Mostly cleaning up my messy code š§¹ Updates: Made bishop not able to pass through pieces Made the code creating rook destination squares much cleaner Made the code creating bishop destination squares much cleaner Fixed rook and bishop not creating destination sqaures at the edges of the board Made code for creating knight destination squares cleaner and fix if statement condition of rook in ChessboardContext.jsx Made code for creating pawn destination squares cleaner and make pawn unable to pass through pieces Fixed bug while clicking on a piece when another piece is already selected In last devlog I made the rook unable to pass through pieces so it was very logical to do the same to bishop. Making the bishop unable to pass through pieces was pretty simple as the code wasnāt much different from the rook one. Idk what clicked in me after doing that I started to thinking about making the rook destionation squares creation code cleaner. The code was very messy and repitetive and I believed it can made cleaner and smaller. I used 4 while loops before which had almost the same code but different values and slightly different calculations. After thinking and trying I turned the 4 while loops in to a single while loop. Now the code looks much better. Seeing the success in rook destination squares creation code I then moved on to the bishopās code. Made similar changes to the code as the rookās code. Also i believe the queen works perfectly as itās mixture of rook and bishop code but I havenāt really tested it on board. After cleaning up both rook and bishop I found a small bug. The bug appeared because of my slight mistake while trying to make the code better. Basically the rooke and bishop werenāt creating any destination square at the edges of the board. The fix was simple so this didnāt take long to fix. I already didnāt like the knightās destination squares creation code. Me cleaning up the rook and bishop code gave me the motivation to make the knights code better. It did take some time for me for cleaning up that messy and tangled code. I was using break keyword for rook and bishop so I also used break for stopping the loop but I didnāt want the loop to stop completely I just needed to skip the loop if there way a piece or if the knight was on the edge of the board. After a quick search I found that continue keyword does the job. The pawn code wasnāt that messy but it could definetely do better. I mainly changed the pawnās code cuz I wanted the pawn to also be unable to pass through pieces. Before there were two loops now I one loop does the job. Then I also made the pawn unable to pass through pieces by breaking the loop. Fixed the annoying bug. If a piece is clicked when another piece is already selected then it looks like both pieces are selected. Desitnation of both pieces are shown and both pieces are hightlighted. So, as clicking on a square reset the selected piece, I reset the previous piece if user selected another piece with a small change. Now Iām trying to making all these things work from the black side as well. Okay this much for this devlog. See you on the next one. Bieeā¦š"}, {"post_id": 42402, "ts": "2026-08-07T02:53:40Z", "hours": 3.7158, "text": "30 day streak letās goo š„ Updates: Added functionality of moving pawn with seperation destination square for white and black Added functionality of moving knight Changed color of chessboard Made rook not able to pass through pieces The pawns now move one square at a time and have the option to move two squares if theyāre on starting squares. Moving pawn one square is easy but I had to think about creating two destination squares infront of the pawn. So I created a array and push all the starting squares of the pawn and if the pawn is on one of the starting squares then two destination squares are created. Itās also seperate for black pawn and white pawn so that white pawn doesnāt get two destination squares when itās on the black pawnās starting squares. I forgot the knight also needed to move lol š. Just remembered in time after finishing the pawn. The knight was tricky to move. As always I used the mighty pen and paper first before coding. Creating the knight took some time due to random bugs here and there. I think I need to revisit the knight code later as itās very messy. Yay, now the back pieces donāt disapper on the dark squares as I have changed the chessboard light and dark square colors. I think the new colors look great. I was lazy to test out colors so I went to chess.com and picked colors from one of their themes. Okay now were moving to the next step. Making the pieces not be able to move through pieces. I started with the rook. The plan was simple. Check for any piece with squareid thatās same of the destination square and if true stop the loop. I couldnāt figure out how to even select the piece. I was frustrated as I need to select the specific piece with the squareid attribute. I found out about ReactDOM.findDOMNode but I couldnāt figure out how to work with it. I felt really frustrated at that time. I was thinking of using document object but I know that is a bad practice in react. It seems I forgot that we can use querySelector in refs. I already had the chessboardRef so I used querySelector to find if a piece was on the way of the rook. Also I had to change the way I calculated the rookās destination squares but letās not talk about that I think the devlog has gotten pretty long. Although the problems are hard for me to solve when I see the results working I genuinely feel happy. I have gotten lazy after getting sick. Although I have not fully recovered yet Iāll try to stop wasting my time. Okay this much for now bieeā¦."}, {"post_id": 40781, "ts": "2026-08-04T15:12:05Z", "hours": 3.8114, "text": "More pieces can move (Iām sick again š) Updates: Added functionality to handle vision page if user changes page during vision practice Added functionality of moving bishop and seperate calculation of rook moves Added functionality of moving queen Added functionality of moving king I told in the last devlog that I was working on hanling vision page if user changed page during vision practice. And now, itās done. I think I have reset the necessary things so that vision page works normal. If any bug related to this appear in the future then Iāll fix it then. Right now everything looks fine after adding this functionality. Creating destination squares for rook was easy and I thought bishop would also be probably easy. I was very wrong. The thing with rook is that there will always be equal number of destination squares but bishop doesnāt. I bishopās destination squares varies according to itās position. I took a long time to figure things out in pen and paper. I even wrote the whole chessboard notation in paper and looked at only one diagonal first to find some sequence ( Iāve attached the img below š). I started coding after kind of figuring out where to start. I had issues during coding as well but we got it boys. Also I was using OR instead of AND in the while loop causing bugs and I needed some time to digest that AND definetely worked there. A silly mistake from my side. For the queen I didnāt have to code much as I wrapped the rook and bishop destination squares code in to a function. Then, I created a new function for creating destination squares of queen which just called both the rook and bishop function. As this was really easy I was pumped to move on creating kingās destination squares as it is also really easy. Took a sip of coffee and continued my coding journey. I was wrong š„. I got stuck adding the kingās destination squares. I was first thinking of combination of rook and bishop but only one out from every side. This was the wrong way of thinking ig. Then I thought I should use two nested for loops for creating the destination squares which firstly worked out badly cuz Iām dumb. The destination squares weāre being created in such odd manner. After fixing that I had to also remove the destination square which was being created on top of the king and also had to handle to not generate some destination squares when the rook is on the edges of the board. I have done nothing today due to my illness. I hate my immune system š. Iāll code for 5 mins now ig for keeping my streak alive. Okay biee.."}, {"post_id": 39546, "ts": "2026-08-02T15:52:07Z", "hours": 3.3606, "text": "The rook got some moves š Updates: Added movement to piece when destSquare is clicked Added mode state for seperation of chessboard in puzzles and vision page Moved states, refs, effects and functions from Chessboard.jsx to VisionContext.jsx Working on handling vision page data if user switches to other page during vision practice Finally I can proudly say that the rook can move now. I am really happy that itās working. To move the rook I had created destSquares(the square with green dots) last time. Now if the user clicks on any of the destSquare with some maths the rook move to that square. Iāve added transition for the movement to look smooth. While doing this the rook did move to the destSquare but when clicked on the rook again the destSquare appered from when the rook was last time. To fix this I grabbed the destSquare location (e4) then set the squareid of piece to the location. The destSquares were calculated based on the squareid so now after moving the rook I can move it again. Also now if the a piece is seleced the background color of the pieces changes. When a piece is selected then destSquares appear but if the piece is selected again or other square is clicked then the destSquares are removed. Small things like this is making the chessboard feel lively and feel that it works correctly. I wanted to do this before but I thought Iāll do it later. I added a mode state in Chessboard.jsx. The mode state is either āpuzzlesā or āvisionā representing the page the chessboard is on. I have made the pieces not appear while Iām in vision page and am trying to make sure nothing is running behind the scences if user decides to move to another page after they click on start. The countdown timer code of vision page was in Chessboard.jsx. I didnāt like that so I decided to move the code to VisionContext.jsx with the timer I move some states , refs and function with it. I had some issues during this migration but it wasnāt too difficult to resolve. I thought I had worked more but seems like Iāve. Iām confused, when I think I have done little work at that time I some how end up will better hours and when I think I have done decent amount of work I end up with less hours. Anyways it feels good watching the rook moves are working correctly. This much for this devlog. Peace āļø"}, {"post_id": 38612, "ts": "2026-08-01T02:55:53Z", "hours": 4.9544, "text": "I got sick š¤§š„ Updates: Make pieces position perfectly to square in chessboard Moved chessboard states and refs to ChessboardContext.jsx Fixed pieces sometimes being group together in one square when chessboard offsetWidth is null Added destSquare element on click for all possible moves of rook Last time I did position the squares but when I changed the background color of pieces there was a slight misalignment. I started searching what was causing that to happen. It was due to the height and width of chessboard being in decimals. I checked to see what lichess were doing and found out the height and width of the chessboard were always divisible by four. I did the same for my website and now itās perfectly aligned and thatās what I love to see. Moved the states and refs from chessboard.jsx to chessboardContext.jsx to make the chessboard code less cluttered. The code relevent to puzzles page is in the chessboardContext while the code revelent to vision page is still in the chessboard page. When the page was loaded for the first time the pieces were being group together at the top left square. It was being fixed automically when the page was reloaded. It also happened while navagating from home page. I found out this was happenning due to chessboardWidth being null at start. To fix this I created a useState for the chessboardWidth so the page rerendered after the value was changed. My goal today was to make the rook move but I could only work up to generating the destSquares when the piece is clicked. I achieved this by creating a useState array and if user now clicks on the rook it calculates all the possible squares that the rook can move to and then that array is mapped using math to place destSquares perfectly on top of squares. The destSquares have a dot insided them which will be replaced by a icon but thatās the reason theyāre not aligned centered currently. I did have a hard time doing this. Letās not talk about it. š Iāve written everything in short so that I donāt hit the 4000 characters limit and also ig itās better for people reading (if any š„). I got sick yesterday and was just able to work on my project for 1 hr. Today I thought didnāt work much but it seems today I did 3 and half hrs. I am happy about today. I really donāt know if I can create the puzzle but Iāll try my best to do so. Everything I try to do seems to come with their own set of challenges and take time to overcome those challenges. Letās see what happens š"}, {"post_id": 37397, "ts": "2026-07-30T02:35:38Z", "hours": 3.0969, "text": "The pieces have been placed. I was so sloppy š Iāve added pieces to the chessboard. Iāve finally started facing my fear and started working on the puzzles section. It seems that creating the chessboard for puzzles will be harder than I have anticipated. Also please donāt mind the black pieces blending in with the background. I didnāt find chess piece set I liked so I downloaded the lichess chess piece set from pinterest. I was trying to crop them in figma and I coundnāt crop them properly. Also it was a tedious job. After downloading two crop pieces from figma I again went to the web to find out if someone already made them. This website came in clutch (greenchess.net). They had the whole chess pieces set of lichess available for download. Then, I started to code with no plan in mind . I donāt know why do I do this to myself. Obviously it was a bad decision. So I decided to use pen and paper to mainly solve one thing and that was how to place the pieces on the board. The writing helped me alot to think better. I was so sloppy while coding. I was mostly outside while coding and I was really distracted. One sec I was coding and another sec I was thinking about something else. I was making so many silly mistakes making the process more frustrating that it already was. I learned about fen while doing this (Forsyth-Edwards Notation). Through this any chess position can be stored and recreated in one line. It looks like this rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 I only needed to loop over the first part divided by slashes for positioning the pieces. Other things will be used later. I feel the code is really poorly written but it works so idk. I also found out about regex while I was trying to write a if condition for seperating strings and string with numbers. Okay this much for today. Bieā¦."}, {"post_id": 36798, "ts": "2026-07-29T02:45:06Z", "hours": 2.2681, "text": "Moving onto something big (Iām scared) Updates: Change ui of popup menus in options.jsx Added sounds for correct and incorrect attempt in chessboard Added countdown and start sound in chessboard.jsx Added puzzles page Renamed sidebar of vision page and itās component with prefix of vision. Most of the updates in this devlog are small changes. But now I am going on to work on the puzzles page. I donāt know how I will figure this out. I hope it goes mostly smoothly.. I had designed the popup menus in the last devlog. I think the newer design is much better than the last one. The popup menus donāt look the same in the figma and the website cuz I tweak some things while coding. The figma design was a rough design Adding the sounds in the vision page has made praticing much more fun. The built in mac recorder doesnāt record sound unfortunately or I just donāt how to.. So, Iāll add a ss of vision page with menu open and a ss of puzzles page. I added chessboard and sidebar to vision page. There were two sidebars now so I decided to rename vision page sidebar to VisionSidebar and puzzles pages sidebar to PuzzlesSidebar. Okay that was all for this time. Give me strength to start making the puzzle by liking and commentin on the devlog. Byee ā„ļø. Also if youāre reading this support @PAPER_01 . AniShuffle has been taken down but sheās been unbanned now š."}, {"post_id": 36163, "ts": "2026-07-28T02:25:06Z", "hours": 3.6781, "text": "Youāve my coordinates now Updates: Added coordinates to chessboard Changed previous to current Fixed user input on chessboard being checked before countdown finished The show coordinates now works Fixed some event bubbling issues in colorMenu and timeMenu Designing the pop up menus Now itās easier to locate squares with the help of coordinates . Now you will also notice the board has fliped while changing colors. ~ A small change, in the sidebar the previous word has been replace with current. I think the current word makes more sense there. ~ I also fixed user being able to click on the squared before the countdown finished. This was a silly mistake from me. ~ The coordinates has made it easier to locate squares. But if you want some challenge then you can toggle show coordinates off now. ~ Thatās all for this devlog. If you wanāt my actual coordinates dm me š."}, {"post_id": 35623, "ts": "2026-07-27T05:20:24Z", "hours": 7.9881, "text": "Weāve reach 100 hours š Changes: Fixed timer not displaying in sidebar Removed the square display after time is over Fixed timer setInterval running multiple times and made countdown timer code cleaner Fix TimeMenu not closing Removed unused imports Designed the sidebar to add new data Added the new design Added animation to make the square notation that appears on the chessboard disappear First of all, we have reached 100 hours letās goooooo. I would like to thank everybody who have followed my project read, liked or commented on my devlogs . My project has recently started getting some traction. Special thanks to @PAPER_01 š. I have done a lot of things this devlog. I will try to cover these in as short as possible. It seems that the setInterval in progress.jsx was running twice. I found out this while I was making the countdown timer code cleaner. So to fix that I reset the hasCountdownCompleted as soon as the timer in progress.jsx runs out. Now, countdown and progress timer work as intended with cleaner code. The random color option in color menu now works. It was a little tricky making that work. Letās just say it wasnāt working as expected but the fix wasnāt that hard. I liked what chess.com were doing. They were displaying the square notation and then the square notation would just disappear. The square rotation will also live in the sidebar so that if user forgets what the square was just displayed, they can easily look at the sidebar. I really like this idea and decided to implement on my project as well. But before I added this to the website, I first designed it on Figma. I also thought of displaying the score and best score on sidebar. Designing it was fun and tricky. I didnāt really like how the previous score and best score were looking and after some trial and error it looked okay. All of these things were fine and enjoyable to do but making the best score work was so frustratingggggg. Itās the reason that I couldnāt devlog yesterday. The issue was score was showing to be zero inside updateTimer function even though the score was greater than zero everywhere else. I thought fixing it wouldnāt be really hard. I tried console log score everywhere to see when the value was being zero but there was no sign of the score turn into zero. Later I found out that due to the updateTimer function being inside a setInterval the value is kind of locked and used useRef hook to solve the issue. Okay, thatās all for this devlog. Now that I have reached 100 hours letās aim for 150 hours as soon as possible. I have taken very long to write this devlog so I like would be heavily appreciated š."}, {"post_id": 34403, "ts": "2026-07-25T02:47:48Z", "hours": 4.5364, "text": "Mostly cleaning up the code and breaking things Changes: Made timer code better and cleaner Added functionality to timeMenu options Added countdown before starting the timer and displaying the squares -Added VisionContext.jsx to make code cleander and broke down vision page into smaller components As I said in the previous dialogue, the timer code was messy. So I decided to clean the code now it looks much better. Also now the time button options work now the timer will have 15, 30 or 45 seconds according to what you choose. So before, after cleaning on start the timer would start right away and the square would also show up. But this might make the user frustrated as they have to click start and right away move their mouse to the chessboard. I saw that chess.com has a countdown timer so I also made one. The code for this countdown timer is also messy so I will probably make it more cleaner next time. This is the main thing I have doing this whole devlog which I cannot show you because itās just making the code cleaner. The vision pays had a chessboard component and then sidebar element to it. The sidebar element had all the code which was making the vision page could a lot messy. So I have broken down components into components and those components in the further components. I think this is making the code much more easy to read and find and debug each component more easily. But in the process of cleaning my messy code, things have broken down. The timer isnāt working, I will fix that later. I donāt have much to show here today so the see the countdown timer working and the broken timer š. I will fix everything in the next devlog. So stay tuned. Bieeeā¦"}, {"post_id": 33853, "ts": "2026-07-24T03:14:59Z", "hours": 4.7681, "text": "Ayy almost 5 hrs today !! Changes: Fixed attempt square and attempts not wrapping as expected Fixed color being stuck in chessboard when same square is clicked rapidly Added color menu popup when click color button in sidebar Added time menu popup when user clicks time button in sidebar Added Progress component in sidebar with working score Made timer in progress.jsx functional Fixing the user attempts in the was pretty easy. I just added a attempts container to wrap the attempts element and then the CSS work as expected. Fixing the red or green colour being stuck in chessboard when clicked rapidly was a headache to fix. I was trying my best and at last I came up to the decision that I needed a timeline for the animation before the animation was played the progress of the animation should be zero. I tried that and obviously that didnāt work but it seems that I was close to the answer. I used Claude to figure out the answer and Claude used killTweenOf gsap function to remove the animation before the animation was even played. It also added a onInterrupt property to the animation which basically reverted the stuck colour after killing the animation. I didnāt want to use Claude, but I just couldnāt figure it out and I think it was better to use Claude as I have never used those functions and properties of gsap. Also Claude made that portion of my much cleaner. Seeing this now, I will be more focused on the cleanliness of the code because claude showed me that my code was repetitive and how it could be made smaller and easy readable. I decided to make the colour menu pop-up and time menu pop-up straight by coding instead of designing it first as I should have. As you can see, the result is very terrible. I am sure definitely fixing it in the next devlog. I was force thinking of making a pop-up menu component and using them in both buttons but I found that it was a hassle and not worth it. Only the white and black button in colour pop-up menu work. They just rotate the board and thatās all I still need to add functionality to them. After learning the lesson that I should definitely design before coding. I started designing the progress component. Although there isnāt much to design there I definitely would have made it as bad as the pop-up menus. While coding this, I also made the score display the total number of correct at attempts which was pretty easy. I just had to add one digit whenever the chose the correct square. Then, I started working on the timer. The timer would have been really easy if I just used setTimeout every second but I like to torture myself so instead of just doing that, I challenged myself using date constructor. I have done this before but it has been sometime and I remember how it worked. The countdown started from 28 which was frustrating. Now, I have just completed that but the code is really messy. I will definitely fix that tomorrow or today as I might post this devlog tomorrow. I think that shorter devlogs do better in terms of views. Iāll try that next time. See you in the next devlog š."}, {"post_id": 33005, "ts": "2026-07-22T15:24:41Z", "hours": 3.3339, "text": "Things are going great Changes: Added chessboard component with ranks and colored squares Added function for generating random squares and displayed them Added feature to display green and req squares to indicate whether the user clicked correctly or incorrectly in the chessboard Displayed attempt made by user in the sidebar with respective colors for correct and incorrect ones I thought doing all of these took me at least four hours but I was wrong. It seems that itās only been about like three hours. This time I have worked on the chessboard itself on the vision page. Before it was just a plain whiteboard but now there are individual squares which was pretty easy to implement. I however needed some time to figure out how to add colours to the squares. But it also wasnāt that difficult. Then I created a function for generating random squares with the help of math.random(). I created an absolute element to display the random squares at the centre of the chessboard. To indicate the user that the square they have clicked is correct or incorrect I played the small animation that changed the colour of the user clicked square into red or green depending upon whether the user input was correct or incorrect. I was stuck here because I didnāt know how to reverse the animation. Of course I could just change the colour to green and then the colour of the square but that didnāt look quite right as I am probably going to change the chessboard colour later. So I wanted the animation to be flexible I was trying to play and reverse a animation timeline but it was so much easier than that later. I just remember there was the repeat and yo-yo property that will easily accomplish this effect Iām looking for. I have found a new bug with this if I spam click a square the square permanently turns into either red or green so definitely I will fix that in the next devlog. Also now the squares that the user clicks will be displayed on the side bar. The colour of this square notation will be red or green depending upon the user selected the square correctly or incorrectly. I have found out that thereās a flex related css bug in attempts element. I will look into that tomorrow. Okay bie.. Hope you have a great day š"}, {"post_id": 32765, "ts": "2026-07-22T04:05:46Z", "hours": 4.1331, "text": "Started working on the vision page Changes Designed the vison page Created the vison page and worked on the sidebar ui I have changed the name from visualisation to a vision. I actually donāt know which one is better. I just changed because chess.com and chesskid.com had vision for practicing the squares on the board. Designing of the vision section was quite fun although I had some issues with auto layout that wasnāt big of a deal. I was thinking what options should I have and thought it would be best to add show coordinates, change the color and select the time. I think the UI turned out pretty great. I will probably change the colour of the chessboard but black and white also looks fine. Coding design wasnāt too difficult. It was just copying the design that I made, but the Figma design looks different. I should check out why the size of the buttons are the same but in Figma they look a lot bigger. It might be because the width of the sidebar is not the same. In conclusion, this was a peaceful devlog. It feels really nice not having to fight with your code and your designs. Hope that the future develops are the same š¤. Until then peaceāļø."}, {"post_id": 32156, "ts": "2026-07-21T03:52:34Z", "hours": 4.9689, "text": "We have followers Changes Designed hollow medals Switched from localStorage to db for storing updating and retrieving completed courses data Added feature to show medals achieved by user Designing the hollow medals (I donāt know what to call that so Iāll just say hollow medal) was really fun. I just started designing the medal for fun in Figma. The result turned out really great even better than what I had expected. I was using circles for the medal itself and was trying to use the rectangles for the below design. Later I figured that it would be wiser to use the pencil instead of creating a rectangle and mapping out the bottom portion of the medal which turned out to be a great idea. In this project, I have started using Figma for creation of some assets and I am loving it so far my intention is to keep on using Figma until and unless I really have to use AI. Switching from localStorage to database for completed courses data was easy in my head but it took me longer than expected mainly because of three reasons. Firstly, I was thinking of creating a separate backend endpoint for course data. After creating the controller and route for course data I thought that it isnāt really necessary to create another endpoint for this as we can store it in the users data itself. Secondly, after deleting the routes and controller, I created API function for fetching and updating the completed course data period I had forgotten that I donāt actually need to have a separate getCompleted function because while fetching the user itself, the data comes with it. I have forgotten to delete the getCompleted.js file which I will do later. Thirdly, I have started to use Postman for testing out api . I am loving to learn things such as Postman and Figma. But this issue I was facing was the postman was working correctly but from my codebase the request body was showing undefined. It was a fetch thing I use axios before and I am figuring out right now why people used axios. It seems that I needed to specify in the header that this request had the content of json. So figuring that out also took some time. Also, I have added the feature to show medals achieved by user. The code isnāt quite clean for this feature. Thanks to the people that followed this project. I genuinely appreciate that š. New followers : @PAPER_01 @sak"}, {"post_id": 31100, "ts": "2026-07-19T07:07:40Z", "hours": 3.5, "text": "When will my devlog get more than 7 views š Changes: Added loading component Added scrollsmoother in home page Fixed course page padding and added toast while redirecting unauthenticated user Added back button to signup and login page Designed the logo for website Added the logo to the website Now whenever the frontend fetches user data from the backend there will be a loading component that will come up. I made the loading spinner myself in figma why not š. Scrolling the home page using a mouse is so much better now now due to scrollsmoother plugin of gsap. I was facing a issue with this though. I was seeing an error while navigating to other pages. After a while I found out a guy with same issue in gsap forum and his solution worked. God bless that guy š. Some small changes were fixing the padding in course page , adding a toast while redirecting unauthenticated user from couse page and adding back button in singup and login page. I think they donāt need much explanation. I tried to design the logo of my website in figma. I tried different things and landed with a design that felt decent (The logo with king in the center). I look nice up close but it didnāt feel the same when shrunk down as a logo. So I started designing another one. I landed on the logo with cyan and dark purple background and !! symbol up front. I really donāt know how I feel about this logo. I looks decent sometimes and other times questionable. Please leave your opinion in the comments š. While adding the icon as a favicon, for some reason the favicon wasnāt display which was confusing. Later I found out that this was a brave issue cuz itās showing up in zen browser. Okay this much for now. Please like so that more people see this devlog š."}, {"post_id": 30508, "ts": "2026-07-18T04:21:03Z", "hours": 5.0097, "text": "Wth itās been 5hrs?? Added toast for login signup and login as guest errors Made the signup data persist even after the value of hasContinued changes Designed the dropdown menu Added dropdown menu Added logout functionality First of all, Iām genuinly confused how this took me 5hrs.. Added toast so that now when thereās any error during the signup or login. For example during signup maybe a user might write a username less than two characters, then the toast pops up telling the user it should be greater than 2 characters. I was stuck during this cuz the trycatch block wasnāt catching the error which was confusing. I used axios previously and it threw an error if the backend response wasnāt ok. But this time I avoided using axios for reasons that you guys probably know š. It seems that fetch didnāt throw any error so I had to manually throw errors in the api functions. The making of signup data persist on hasContinued value change was early. I just set the value attribute of input to be itās respective useState data. As you can see in the image that I designed the dropdown. I first designed the dark one which I really loved but it didnāt match the navbar so I created a light one. After seeing the dark one I really didnāt like the light one. So I tried fixing the design. I asked someone in the slack and they said the previous light dropdown design looked fine. Ig looking at the dropdown for long made it look fine to me as well š. Now I added the dropdown to the website. I had issue with the padding of the logout button during designing phase but I just winged it during coding phase and it worked š. The dropdown now looks fine imo. I however did have a issue while making the dropdown closing work when user clicked outside of the dropdown. I thought of using an overlay in the background but I knew that there was a way of doing this by checking the click event. It seems I had forgetten to do this. After some trial and errors I remember how it was done.. I also added logout functionality which was fairly easy to add cuz Iām storing the jwt in the localStorage. I just removed the token for localStorage, set the user to null, set isDropdownOpen to false and navigated the user to the home page. Ig, iāll try do things faster next time ā”ļø. Donāt want to spend 5hrs on things like these. Okay bieeā¦"}, {"post_id": 29446, "ts": "2026-07-16T12:12:04Z", "hours": 2.0422, "text": "Omg itās finally fixed I finally fixed the bug that I addressed in my last devlog. This was so frustrating. I never expected that this would take me 2hrs and I would write a whole devlog on it š. The bug was that when I was logging in I was being redirected to /signup after signup, login or login as guest. I had made so that after signing up or logging in the user would be redirected to course page. I had also made it so that if the user value is null then the user would be redirected to the sign of page. So now you can see that where this is going. I just couldnāt simply figure out why the user value was null. After doing so much thinking and reading the code and trying to fix the bug, I have finally succeeded.Another issue that I was facing during the working was I was constantly forgetting what I was doing and to see everything visually I used excalidraw as you can see in the picture. So there were three things that was leading to this bug. Firstly, I wasnāt using the await keyword while calling the api functions. Secondly, I didnāt have a loading state while fetching the userās data. Lastly, the function getUser function responsible for fetching the user data wasnāt even being called when redirected to course page. The function was only being called when the user first loaded the website. Right now, my head is aching now I think I should take some rest. I didnāt remember to add loading state which was so silly of me. I only realized that after visiting my old project. Seeing that I felt dumb because ofc you would need a loading state while fetching the user data from backend. I feel a little relieved now š®āšØ. I cannot even remember properly all the things that I tried to solve this. It was just a mess š©. After solving the bug, now looking back, it wasnāt that difficult to solve. It was just a me problem. I could write more on this but Iām too tired for this now. Okay biee..š"}, {"post_id": 28787, "ts": "2026-07-15T09:05:35Z", "hours": 2.67, "text": "Life is frustrating š© ##Changes: Added navigation to /course after successful login Designed navbar when user is logged in Added the user button in navbar when user is logged in Added redirection to signup if user goes to /course without authentication Fixed jwt malformed error in protectRoute.js The navigation to /course after successful was implemented before but I somehow missed to implement that in login page. Designing the navbar for authenticated user was very challenging than I expected. As you can see in the image there are multiple attempts at creating the navbar. Everything I tried was just looking bad. The final design is also questionable. But for now it is what it is. Now unauthenticated user arenāt allowed to visit course page. They will be redirected to signup page if they try. This was supposed to be simple but somehow I made this also hard for myself. I have done this before so this should have been easy for me but nope. The redirecting was working fine but I were to be authenticated and be on course page and then reload, then also I would be redirected to the signup page. After I made up my own solution for this which I donāt think is the best way to do it. Due to my incapability of designing simple things and solving minor bugs I was questioning my ability to solve problems and design. Which at that moment felt sad š. Also there was jwt malformed error popping up in the backend which was also frustrating to solve. Not because it was hard but because it was easy and I wasnāt able to solve it. I wonāt tell you what happened here as the devlog is getting long. No video this time cuz the I canāt show the navigation changes working as they arenāt working properly. The bug is preventing user from redirecting to /course after login or signup. Instead user is redirected to signup. I know that this because of the two redirection changes made in this devlog. So, Iāll go and fix it asap. Hope your coding experience isnāt going as frustrating as mine. Thank you for reading my frustrations. Byeā¦š"}, {"post_id": 28126, "ts": "2026-07-14T06:43:34Z", "hours": 4.0444, "text": "Iām sorry š ##Changes: Use localStorage to store jwt instead of cookies Fix signup page unequal width of img and form container Changed login.css similar to signup.css for consistent code Added login as guest functionality Added navigation to /course after signup or login success Added UserContext.jsx to handle user data Added protectRoute middleware to verify jwt Added ā/api/user/ā endpoint to get user data from backend Too many changes, letās break them down. Iām sorry that I switched to localStorage to store jwt instead of cookies š. The cookie wasnāt working as expected. I was able to store the jwt in the cookie and receive it in the frontend but when I reloaded the cookie would just disappear. I know that thereās a fix for this as I have done this before as well. But, I know that Iāll face the same issue during deployment even if I fix the issue now. Iāll probably deploy this in vercel and last time (in flavortown) I had to change the whole code format due to the cookie issue. So this time Iāll just rely on localStorage for now. If I deploy the website myself then maybe Iāll consider using the cookie. But for now just forgive me š. I fixed the unequal width of img container and form container with again in signup page. This happened because I added padding to the form-container instead of the form. Using flex for this was a headache so I used grid and it worked. Although I didnāt necessarily needed to change the login page css. I did it to maintain a consistent codebase. This is a huge one. I added login as guest functionality. I know that people will be skeptical of entering their email even though they can use any made up email such as [email protected] . I purely added this feature so that people donāt rate me bad just because they assumed that they need their own email to signup. And logging in as guest is easier as well so why not. Now, after the signup, login or login as guest is successful then weāll be redirected to the course page. Later Iāll make it so that users who arenāt logged in wonāt be able to access any other path except for the ā/ā. Also now thereās userContext.jsx for storing and distributing user data. For now thereās getUser function for getting userās data. I have made the backend work to verify the userās token and then only provide the user with their data. Alright no more yapping, the devlog has gotten very long. If anyone has read this devlog, God bless them. ~ Peace āļø."}, {"post_id": 27519, "ts": "2026-07-13T04:42:38Z", "hours": 4.9611, "text": "More progress on signup and login Changes: Designed the username form Created the username form in signup Changed useRef to useState to store signup data Adjusted the backend to receive and store username Add login functionality Fixed required attribute not working in both signup and login form Designing the username form wasnāt that hard as itās just the signup page but will less things. I looked at how chess.com was doing things during signup and thought itās better to split the email and password into one form and username form into another. Thereās also a back button to go to the email and password form. Coding the username form was a little frustrating as I had some issue positioning the back button. Now itās working but now I am facing the old issue of img-container and form container not being the same width. Iāll fix that next. Also the way username form is display is by just toggling a state into true or false in the singup page. After adding the username form there was an error telling that email and password was null. This was because while entering the username I wouldnāt be able to access the email and password input using the useRef hook. The fix was simple, I just changed the useRef into useState and store the data on input change. Now that was extra data (username) that needed to be stored. I sent the username along with email and password to the backend and changed the userSchema to accept username. I worked on the signup functionality last time so this time I worked on the login functionality. In short, now during login the backend verifies the email and password and gives the user a jsonwebtoken as a cookie or an error. I wanted the input to display āfield is requiredā when user tries to login or signup without filling in the form. I just couldnāt get this working and it was so frustrating because the issue was so simple. Later I found out that I was using e.preventDefault on the button instead of the form causing the input to not show āfield is requiredā Okay enough yapping. Gotta go and work on the project. Hope your project is going smoothly. Bieā¦š"}, {"post_id": 26400, "ts": "2026-07-11T05:20:12Z", "hours": 5.6911, "text": "50 hours!! Letās go š Changes Designed signup page and login page Created signup page and login page Divided the codebase into frontend and backend Setup backend Setup signup endpoint to receive formData Designing the signup and long page was really fun. I took some inspirations from pinterest. Iām proud of the design I made š. Turning the design into code was also fun ig. I did face a small bug. The image looked bigger than the form but both had flex-grow of one. The fix was simple I just had to change the flex-basis to 0 so I did flex: 1. Finally Iāve started on the backend. Itās been some time since I havenāt done backend stuff. Coming back to backend felt nice. Although it was frustrating when the data sent to backend was just saying it was undefined. But after some time I just figured out that I forgot add express.json() middleware in my server.js. Iām well now and feel that now Iāve no motive of slowing now. Hope youāre also doing well š¤."}, {"post_id": 25132, "ts": "2026-07-09T04:37:06Z", "hours": 2.7414, "text": "Many small improvements Changes Made the opened cards remain open after finishing a lesson or going back from watch course Saved completed course data in localStorage Added confetti animation after clicking on finish lesson Fixed value of total in course.jsx by making it dynamic Fixed navbar animating when reloading on non home paths This time I have done many small changes but I think that they make a great impact on the website. ~ Firstly I made the card remain open while visiting other pages. I mainly did this as a part of user experience. I thought that itās inconvenient for a user to see the card they opened being closed after they come back from the course watching page. ~ Also, now the data of completed course persists. It is stored in localStorage. Iāll definitely stored the data in database in the future. Also I was facing an annoying bug doing this because I forgot that I needed to stringify the data before storing in localStorageš. ~ Thereās now confetti animation after clicking finish lesson. I think it looks nice. I used a npm package for the animation. ~ Before the total course was a dummy value of 10. Instead of counting the courses manually I just did a sum of length of all courses data from constant.js. Now, when I change the professional course value I wonāt have to think about changing the total value. ~ The navbar animation was meant to run only when user move from home page to other page and vise versa. But, when I was on the course page and if I reloaded the animation would still happen. Fixing this was really painful as the solution was really easy but I just couldnāt figure it out. At last I took the help of Claude to figure out the solution š©. ~ I took two days off because I was sick againš. Why is my immune system so weakkkš.."}, {"post_id": 22223, "ts": "2026-07-04T16:15:12Z", "hours": 2.0581, "text": "Now the completed course has a green tick mark Basically now if you click on finish lesson youāll be redirected back to the course page and the lesson you choose as completed will have a green tick mark inside the course card. ~ Also, if a lesson is completed the navbar wonāt show the finish lesson button. ~ Right now, the data doesnāt persist across reloads. I will store the data in localStorage next and when I implement the backend, then only Iāll store the data in database. ~ The challenging part was seeing the whole picture. How will the feature work, where will the data live and how to know if a lesson is completed, things like that. ~ Also, during development I thought of using useContext hook but I had forgot how to use the hook while following best practices so I just went to my previous project to relearn stuffš
š. ~ I decided to use pen and paper for problem solving and better visualization which worked really great for me šš. I will definitely do this when I encounter problems in the future š. ~ Btw, No bullet points this timeš
. I havenāt completed much as Iām sick. Hopefully I get well tomorrowš¤."}, {"post_id": 20676, "ts": "2026-07-02T10:26:56Z", "hours": 4.2492, "text": "Iām locked in Progress: Changed the dummy data from beginnerCourse and intermediateCourse in constants.js Created WatchCourse page Made courseCard open WatchCourse page with respective course video Made navbar show go back and finish lesson on button if the user is on WatchCourse page Designed a banner for the course page I changed the data of beginnerCourse and intermediateCourse in constants.js file which instantly made the cards inside both beginner and intermediate so much better. The professionalCourse data hasnāt changed and will be changed later. ~ After that I worked on one of the main feature of the website which is being able to watch the course. Now, if user clicks on a course that they want to watch, then will be redirected to WatchCourse page. I achieved by using the YouTube embed link and dynamic routing. ~ The navbar also changes in WatchCourse page as there will be go back and finish lesson button. The go back button currently works but I still have to work on the finish lesson button. ~ I took a break from coding after doing that and started working on the banner. I donāt really know how the banner should look so I just added a gradient, two chess pieces, some text and some chess analysis moves and called it a day. ~ Now Iāll go export that banner and add it to my website. If you have any recommendations please let me know. Biee.."}, {"post_id": 19060, "ts": "2026-06-30T07:56:09Z", "hours": 4.2233, "text": "Mostly designing and coding that design. Progress: Completed the info element Designed the course card inside the accordion Created the course card component Moved accordion, courseCard and progressBar component into components folder within the course page The course page is slowly but surely coming together. I think the info element looks really nice now that itās complete. But yeah the list does contain dummy information. I will change them after I have selected the videos as my courses. ~ CourseCard component seems okay imo. The tick mark is supposed to indicate that the user hasnāt completed that course. After the individual course is completed it will go green. I have mixed feelings for the tick mark being there. The idea seems find but Iām really not sure about the design. ~ But anyways it was fun designing in figma. In the website have made the CourseCard with the ability of each card having different text and image but right now they are only a little different in different levels. ~ Idk how time passes so quickly. Got only this much done in 4hrsš but I think I am now starting to enjoy the process. I am not focused on the time so heavily as I was before š. ~ Okay this time I have decided to keep my devlog shorter. Any opinions will be appreciated ā¤ļø."}, {"post_id": 18099, "ts": "2026-06-29T03:11:34Z", "hours": 5.4111, "text": "Ayy new devlog letās go!! Updates: Designed the info part (the portion with the progress bar) Created working accordion component with animations Started working on the info part Created working progress bar component with animation I like the design of the info element. I have tried using hierarchy to make the design look good. Also I randomly had the idea of earned badges after the user completes the whole course of a certain difficulty. Then, I hoped onto coding the accordion. Firstly I wasnāt making accordion as a component. There were just three div in the course page and I realized that if I donāt make it a component the code is going to look messy so I created the accordion component and now the code looks much cleaner. While making that I stumbled across a funny bug. Clicking on one accordion component was making all component to open. It was because of gsap selecting all the similar classes and animating them. I fixed that by using useRef to select elements. I have also created a progress bar and now Iām working on completing the info element. The progress bar looks good if itās even a little bit full but idk how I feel about the progress bar when itās at 0%. It feels bland and idk what to do. Okay enough rambling. I feel my devlogs should be shorter ig. Anyways if you have any suggestions please let me know. Peace āļøAyy new devlog letās go!!"}, {"post_id": 16777, "ts": "2026-06-27T07:43:36Z", "hours": 3.9072, "text": "Updates Added RootLayout.jsx for reusing a single a navbar across all pages Changed react-router-dom to react-router Added expanding animation to the navbar when the path is ā/ā and shrinking animation on other paths except ā/ā Designed the course part in course page What I wanted Before I added the navbar inside home page but after creating the course page I realized that I would want the navbar to be reusable across all pages. Also I wanted the navbar to expand in other pages expect the home page. Switch to react-router I was using react-router-dom for managing routes. I tried to look up the docs to make the navbar reusable. I couldnāt find anything and saw that react-router-dom just used react-router so I thought itās was not necessary for me to use react-router-dom so I just switch to react-router. Navbar animation issue Animating navbar to expand and shrink was a mess. Itās look really simple and it is simple but not for my brain. I first thought of making the width to 100% and set align items to center. The width part animated as expected but the align items didnāt. Then I thought of using position absolute and centering the nav but now the navbar wasnāt respecting the nav-containerās padding. It was frustrating so I took help of claude and centered it using y property by doing some maths. Time flies I also had issue with the timeline reverse not working but I think I should stop my complains here. I am rambling here because it took too long to do too little š . Designing the course page On the positive side the I have started working on the design of course page. I have only done a small part but itās looking amazing. The part other part that donāt look right were the design which I made during the start of the project. Rn I am just refining that previous design of mine, thatās why the navbar looks different in figma. Hope you have a nice day ā¤ļø"}, {"post_id": 16064, "ts": "2026-06-26T03:14:51Z", "hours": 4.9211, "text": "Visualization section transformation Separated visualization section into text wrapper and body wrapper Added a text with reveal animation in text wrapper Added visualizedMoves with animation around the img-container Deleted the thought component Finally I get to post a devlog with some good. Itās a better time cuz Iām logging both the figma and the coding time for the first time. Previous design I didnāt really like the previous design so I thought for a while and came up with this design. Although it isnāt perfect itās much better than the last one. The figma design and the website donāt look the same because I just did the design roughly in figma and then winged the chess moves position in vscode. I think removing the background of the chess moves was a great decision. New design Firstly I designed the concept in figma before coding. I added a text wrapper within the visualization to break the flow of the website. The previous design which I was going towards started feeling like a generic website (a bad one). Now the thereās text with a reveal animation which looks pretty simple tbh but I think itās better. I might change that in future though or add elements to make it look fuller. The after the text animation the person visualizing image appears and different moves appear indicating that the person is thinking the moves. I was going to use a thought component for this but I did it in a more simpler manner. Time I always underestimate the time required to build things. I feel that I should have completed more in the time that has been recorded but small bugs happen while coding which is really frustrating. In this devlog also I feel I should have completed more. Am I just slow or happens to others as well. I really would like to know (comment)."}, {"post_id": 14231, "ts": "2026-06-23T07:41:29Z", "hours": 1.8261, "text": "Hey, this devlog is a messy one. Changes: Created visualization section Created thought component Designing the visualization section Connected figma to hackatime I just figured out that I can add my connect figma to hackatime and record the time under this project. I have always designed this project before writing the code which a lot of time which could have been tracked is lost. Thatās not a big worry as this project has long way to go. I just figured out that I can add my connect figma to hackatime and record the time under this project. I have always designed this project before writing the code which a lot of time which could have been tracked is lost. Thatās not a big worry as this project has long way to go. Why this devlog is messy/incomplete The main purpose of this devlog is to figure out where I am currently in my project . I havenāt worked on my project like I used to because of my illness. So, instead of working on the project and forgetting what i did I just decided to commit the changes in my vscode write this devlog. I am hoping to work on this project as before as I am feeling better now. So thatās why the images below seem incomplete. Hope you guys are doing well. Btw the figma ss and the website image donāt match cuz i decided to change the figma design just before writing this devlog. I wasnāt happy with the previous design so iām just tweking it to see where i land."}, {"post_id": 9977, "ts": "2026-06-16T14:48:46Z", "hours": 2.8114, "text": "Changes: Split home.jsx into smaller components Installed and applied different font weights Made navbar better Completed puzzle section on a basic level This time instead of jumping on doing something new I started with making the code cleaner first. It was easy as nothing broke. Then, I realized the font in the hero section doesnāt look as bold as in my figma design so after looking into the problem for a while I realized I had just the regular font weight of font downloaded leading to fonts looking different. Also made navbar better by decreasing horizontal padding in the button and adding a box shadow. Adding the box shadow made the navbar visible in the courses section. I also completed puzzle section which is looking good but I want to animate the image (Yoinked from chess.com btw š
). The animation will bring so much life into the section but I really donāt know achieve that. If you can help me or have any suggestion in general please let me know. Thatās all for this time folks. Piece āļø (Itās a pun btw)"}, {"post_id": 9132, "ts": "2026-06-15T08:50:45Z", "hours": 3.4731, "text": "Ayy new devlog!! Changes: Corrected timing of animations in courses section Added level indicator of thumbnail Added temporary images in each thumbnail. Added animation to course title Made animation on work reverse as well Iāve shifted on my macbook for coding which Iāve received from flavortown. Anyways, the courses section looks much better now. I am still not satisfied with the animation of courses info elements. I spend way to long to make that work but in the end I took help of gemini to make it work. Also, timing looks way better than last time. Now, Iām going to split the home page into smaller components to make the code cleaner. Also Iāve to do something of the navbar. Any suggestion will be appreciated."}, {"post_id": 7841, "ts": "2026-06-13T02:27:10Z", "hours": 2.3547, "text": "Changes: Added shrinking animation in hero section Moved courses text to a constants file Added thumbnails in the courses section with animation The courses section animation doesnāt look the way I want it to be. Iāll be fixing that.. Also things are taking more time than expected which is really frustrating. I thought this will take me about an hour but itās still not finished. Iāll surely finish courses section today. Hope your project is going smoothly."}, {"post_id": 6073, "ts": "2026-06-10T06:20:34Z", "hours": 2.8981, "text": "Changes: Added text reveal animation Ahhhh it took three hours only to create this text revealing animation. I stumbled across many css and gsap bugs to make this. I first tried to use the ::before pseudo element which worked really well but later replaced it with span cuz i couldnāt figure out how to animate that with gsap. There are many other things that really annoyed me but lets not make this devlog a whole essay. But I love how it turned out in the end."}, {"post_id": 4195, "ts": "2026-06-07T12:47:02Z", "hours": 2.2108, "text": "Changes: Fixed the page stacking animation Changed the layout of hero section. Made navbar position fixed I was trying to make the navbar sticky which wasnāt working at first and was so annoying, after solving that I found out that it wonāt go outside hero section. I was frustrated that I was messing up something so easy. Also it seems that I was doing the stacking animation the wrong way so I fixed that also. So now I have a clean stacking page animation and a navbar that stays at a fixed position."}, {"post_id": 2749, "ts": "2026-06-05T14:52:59Z", "hours": 0.9686, "text": "Created courses-section with page stacking animation. It took me an hour to figure this out š. I knew that I have to pin the hero-section but couldnāt figure out how to move the courses-section to overlap the hero-section. I watched different videos and even went to some random guy linked in account to find out the answer. But eventually I just figured it out myself. I still have to check if the way I have accomplished it is the correct way or not."}, {"post_id": 2615, "ts": "2026-06-05T07:31:04Z", "hours": 1.5622, "text": "Just worked on adding the animations to the home page. Also I downloaded the font instead of using google fonts cuz it was taking some time to load every time I reloaded the website. The animation of the hero text was a little tricky as it wasnāt working at first but then I found out the culprit was span. I change the span to inline-block and then the animation worked as expected. I have also made the letās go nav button same as the cta button for consistency. You wonāt be able to see the animations sadly cuz Iām attaching a screenshot here."}, {"post_id": 1995, "ts": "2026-06-04T08:13:05Z", "hours": 3.4961, "text": "First devlog I have worked on the hero section. I think it looks pretty good. I have some improvements to do on the nav bar. Also, I have to crop out the hero image. The image is taking alot of space rn. Now Iāll devlog after the hero section is complete and then will start on animating the hero section. Hope youāre project is also going well."}]...
|
Title: Evochess by @Sam | Stardance
Devlogs:
Firs Title: Evochess by @Sam | Stardance
Devlogs:
First devlog I have worked on the hero section. I think it looks pretty good. I have some improvements to do on the nav bar. Also, I have to crop out the hero image. The image is taking alot of space rn. Now Iāll devlog after the hero section is complete and then will start on animating the hero section. Hope youāre project is also going well.
Just worked on adding the animations to the home page. Also I downloaded the font instead of using google fonts cuz it was taking some time to load every time I reloaded the website. The animation of the hero text was a little tricky as it wasnāt working at first but then I found out the culprit was span. I change the span to inline-block and then the animation worked as expected. I have also made the letās go nav button same as the cta button for consistency. You wonāt be able to see the animations sadly cuz Iām attaching a screenshot here.
Created courses-section with page stacking animation. It took me an hour to figure this out š. I knew that I have to pin the hero-section but couldnāt figure out how to move the courses-section to overlap the hero-section. I watched different videos and even went to some random guy linked in account to find out the answer. But eventually I just figured it out myself. I still have to check if the way I have accomplished it is the correct way or not.
Changes: Fixed the page stacking animation Changed the layout of hero section. Made navbar position fixed I was trying to make the navbar sticky which wasnāt working at first and was so annoying, after solving that I found out that it wonāt go outside hero section. I was frustrated that I was messing up something so easy. Also it seems that I was doing the stacking animation the wrong way so I fixed that also. So now I have a clean stacking page animation and a navbar that stays at a fixed position.
Changes: Added text reveal animation Ahhhh it took three hours only to create this text revealing animation. I stumbled across many css and gsap bugs to make this. I first tried to use the ::before pseudo element which worked really well but later replaced it with span cuz i couldnāt figure out how to animate that with gsap. There are many other things that really annoyed me but lets not make this devlog a whole essay. But I love how it turned out in the end.
Changes: Added shrinking animation in hero section Moved courses text to a constants file Added thumbnails in the courses section with animation The courses section animation doesnāt look the way I want it to be. Iāll be fixing that.. Also things are taking more time than expected which is really frustrating. I thought this will take me about an hour but itās still not finished. Iāll surely finish courses section today. Hope your project is going smoothly.
Ayy new devlog!! Changes: Corrected timing of animations in courses section Added level indicator of thumbnail Added temporary images in each thumbnail. Added animation to course title Made animation on work reverse as well Iāve shifted on my macbook for coding which Iāve received from flavortown. Anyways, the courses section looks much better now. I am still not satisfied with the animation of courses info elements. I spend way to long to make that work but in the end I took help of gemini to make it work. Also, timing looks way better than last time. Now, Iām going to split the home page into smaller components to make the code cleaner. Also Iāve to do something of the navbar. Any suggestion will be appreciated.
Changes: Split home.jsx into smaller components Installed and applied different font weights Made navbar better Completed puzzle section on a basic level This time instead of jumping on doing something new I started with making the code cleaner first. It was easy as nothing broke. Then, I realized the font in the hero section doesnāt look as bold as in my figma design so after looking into the problem for a while I realized I had just the regular font weight of font downloaded leading to fonts looking different. Also made navbar better by decreasing horizontal padding in the button and adding a box shadow. Adding the box shadow made the navbar visible in the courses section. I also completed puzzle section which is looking good but I want to animate the image (Yoinked from chess.com btw š
). The animation will bring so much life into the section but I really donāt know achieve that. If you can help me or have any suggestion in general please let me know. Thatās all for this time folks. Piece āļø (Itās a pun btw)
Hey, this devlog is a messy one. Changes: Created visualization section Created thought component Designing the visualization section Connected figma to hackatime I just figured out that I can add my connect figma to hackatime and record the time under this project. I have always designed this project before writing the code which a lot of time which could have been tracked is lost. Thatās not a big worry as this project has long way to go. I just figured out that I can add my connect figma to hackatime and record the time under this project. I have always designed this project before writing the code which a lot of time which could have been tracked is lost. Thatās not a big worry as this project has long way to go. Why this devlog is messy/incomplete The main purpose of this devlog is to figure out where I am currently in my project . I havenāt worked on my project like I used to because of my illness. So, instead of working on the project and forgetting what i did I just decided to commit the changes in my vscode write this devlog. I am hoping to work on this project as before as I am feeling better now. So thatās why the images below seem incomplete. Hope you guys are doing well. Btw the figma ss and the website image donāt match cuz i decided to change the figma design just before writing this devlog. I wasnāt happy with the previous design so iām just tweking it to see where i land.
Visualization section transformation Separated visualization section into text wrapper and body wrapper Added a text with reveal animation in text wrapper Added visualizedMoves with animation around the img-container Deleted the thought component Finally I get to post a devlog with some good. Itās a better time cuz Iām logging both the figma and the coding time for the first time. Previous design I didnāt really like the previous design so I thought for a while and came up with this design. Although it isnāt perfect itās much better than the last one. The figma design and the website donāt look the same because I just did the design roughly in figma and then winged the chess moves position in vscode. I think removing the background of the chess moves was a great decision. New design Firstly I designed the concept in figma before coding. I added a text wrapper within the visualization to break the flow of the website. The previous design which I was going towards started feeling like a generic website (a bad one). Now the thereās text with a reveal animation which looks pretty simple tbh but I think itās better. I might change that in future though or add elements to make it look fuller. The after the text animation the person visualizing image appears and different moves appear indicating that the person is thinking the moves. I was going to use a thought component for this but I did it in a more simpler manner. Time I always underestimate the time required to build things. I feel that I should have completed more in the time that has been recorded but small bugs happen while coding which is really frustrating. In this devlog also I feel I should have completed more. Am I just slow or happens to others as well. I really would like to know (comment).
Updates Added RootLayout.jsx for reusing a single a navbar across all pages Changed react-router-dom to react-router Added expanding animation to the navbar when the path is ā/ā and shrinking animation on other paths except ā/ā Designed the course part in course page What I wanted Before I added the navbar inside home page but after creating the course page I realized that I would want the navbar to be reusable across all pages. Also I wanted the navbar to expand in other pages expect the home page. Switch to react-router I was using react-router-dom for managing routes. I tried to look up the docs to make the navbar reusable. I couldnāt find anything and saw that react-router-dom just used react-router so I thought itās was not necessary for me to use react-router-dom so I just switch to react-router. Navbar animation issue Animating navbar to expand and shrink was a mess. Itās look really simple and it is simple but not for my brain. I first thought of making the width to 100% and set align items to center. The width part animated as expected but the align items didnāt. Then I thought of using position absolute and centering the nav but now the navbar wasnāt respecting the nav-containerās padding. It was frustrating so I took help of claude and centered it using y property by doing some maths. Time flies I also had issue with the timeline reverse not working but I think I should stop my complains here. I am rambling here because it took too long to do too little š . Designing the course page On the positive side the I have started working on the design of course page. I have only done a small part but itās looking amazing. The part other part that donāt look right were the design which I made during the start of the project. Rn I am just refining that previous design of mine, thatās why the navbar looks different in figma. Hope you have a nice day ā¤ļø
Ayy new devlog letās go!! Updates: Designed the info part (the portion with the progress bar) Created working accordion component with animations Started working on the info part Created working progress bar component with animation I like the design of the info element. I have tried using hierarchy to make the design look good. Also I randomly had the idea of earned badges after the user completes the whole course of a certain difficulty. Then, I hoped onto coding the accordion. Firstly I wasnāt making accordion as a component. There were just three div in the course page and I realized that if I donāt make it a component the code is going to look messy so I created the accordion component and now the code looks much cleaner. While making that I stumbled across a funny bug. Clicking on one accordion component was making all component to open. It was because of gsap selecting all the similar classes and animating them. I fixed that by using useRef to select elements. I have also created a progress bar and now Iām working on completing the info element. The progress bar looks good if itās even a little bit full but idk how I feel about the progress bar when itās at 0%. It feels bland and idk what to do. Okay enough rambling. I feel my devlogs should be shorter ig. Anyways if you have any suggestions please let me know. Peace āļøAyy new devlog letās go!!
Mostly designing and coding that design. Progress: Completed the info element Designed the course card inside the accordion Created the course card component Moved accordion, courseCard and progressBar component into components folder within the course page The course page is slowly but surely coming together. I think the info element looks really nice now that itās complete. But yeah the list does contain dummy information. I will change them after I have selected the videos as my courses. ~ CourseCard component seems okay imo. The tick mark is supposed to indicate that the user hasnāt completed that course. After the individual course is completed it will go green. I have mixed feelings for the tick mark being there. The idea seems find but Iām really not sure about the design. ~ But anyways it was fun designing in figma. In the website have made the CourseCard with the ability of each card having different text and image but right now they are only a little different in different levels. ~ Idk how time passes so quickly. Got only this much done in 4hrsš but I think I am now starting to enjoy the process. I am not focused on the time so heavily as I was before š. ~ Okay this time I have decided to keep my devlog shorter. Any opinions will be appreciated ā¤ļø.
Iām locked in Progress: Changed the dummy data from beginnerCourse and intermediateCourse in constants.js Created WatchCourse page Made courseCard open WatchCourse page with respective course video Made navbar show go back and finish lesson on button if the user is on WatchCourse page Designed a banner for the course page I changed the data of beginnerCourse and intermediateCourse in constants.js file which instantly made the cards inside both beginner and intermediate so much better. The professionalCourse data hasnāt changed and will be changed later. ~ After that I worked on one of the main feature of the website which is being able to watch the course. Now, if user clicks on a course that they want to watch, then will be redirected to WatchCourse page. I achieved by using the YouTube embed link and dynamic routing. ~ The navbar also changes in WatchCourse page as there will be go back and finish lesson button. The go back button currently works but I still have to work on the finish lesson button. ~ I took a break from coding after doing that and started working on the banner. I donāt really know how the banner should look so I just added a gradient, two chess pieces, some text and some chess analysis moves and called it a day. ~ Now Iāll go export that banner and add it to my website. If you have any recommendations please let me know. Biee..
Now the completed course has a green tick mark Basically now if you click on finish lesson youāll be redirected back to the course page and the lesson you choose as completed will have a green tick mark inside the course card. ~ Also, if a lesson is completed the navbar wonāt show the finish lesson button. ~ Right now, the data doesnāt persist across reloads. I will store the data in localStorage next and when I implement the backend, then only Iāll store the data in database. ~ The challenging part was seeing the whole picture. How will the feature work, where will the data live and how to know if a lesson is completed, things like that. ~ Also, during development I thought of using useContext hook but I had forgot how to use the hook while following best practices so I just went to my previous project to relearn stuffš
š. ~ I decided to use pen and paper for problem solving and better visualization which worked really great for me šš. I will definitely do this when I encounter problems in the future š. ~ Btw, No bullet points this timeš
. I havenāt completed much as Iām sick. Hopefully I get well tomorrowš¤.
Many small improvements Changes Made the opened cards remain open after finishing a lesson or going back from watch course Saved completed course data in localStorage Added confetti animation after clicking on finish lesson Fixed value of total in course.jsx by making it dynamic Fixed navbar animating when reloading on non home paths This time I have done many small changes but I think that they make a great impact on the website. ~ Firstly I made the card remain open while visiting other pages. I mainly did this as a part of user experience. I thought that itās inconvenient for a user to see the card they opened being closed after they come back from the course watching page. ~ Also, now the data of completed course persists. It is stored in localStorage. Iāll definitely stored the data in database in the future. Also I was facing an annoying bug doing this because I forgot that I needed to stringify the data before storing in localStorageš. ~ Thereās now confetti animation after clicking finish lesson. I think it looks nice. I used a npm package for the animation. ~ Before the total course was a dummy value of 10. Instead of counting the courses manually I just did a sum of length of all courses data from constant.js. Now, when I change the professional course value I wonāt have to think about changing the total value. ~ The navbar animation was meant to run only when user move from home page to other page and vise versa. But, when I was on the course page and if I reloaded the animation would still happen. Fixing this was really painful as the solution was really easy but I just couldnāt figure it out. At last I took the help of Claude to figure out the solution š©. ~ I took two days off because I was sick againš. Why is my immune system so weakkkš..
50 hours!! Letās go š Changes Designed signup page and login page Created signup page and login page Divided the codebase into frontend and backend Setup backend Setup signup endpoint to receive formData Designing the signup and long page was really fun. I took some inspirations from pinterest. Iām proud of the design I made š. Turning the design into code was also fun ig. I did face a small bug. The image looked bigger than the form but both had flex-grow of one. The fix was simple I just had to change the flex-basis to 0 so I did flex: 1. Finally Iāve started on the backend. Itās been some time since I havenāt done backend stuff. Coming back to backend felt nice. Although it was frustrating when the data sent to backend was just saying it was undefined. But after some time I just figured out that I forgot add express.json() middleware in my server.js. Iām well now and feel that now Iāve no motive of slowing now. Hope youāre also doing well š¤.
More progress on signup and login Changes: Designed the username form Created the username form in signup Changed useRef to useState to store signup data Adjusted the backend to receive and store username Add login functionality Fixed required attribute not working in both signup and login form Designing the username form wasnāt that hard as itās just the signup page but will less things. I looked at how chess.com was doing things during signup and thought itās better to split the email and password into one form and username form into another. Thereās also a back button to go to the email and password form. Coding the username form was a little frustrating as I had some issue positioning the back button. Now itās working but now I am facing the old issue of img-container and form container not being the same width. Iāll fix that next. Also the way username form is display is by just toggling a state into true or false in the singup page. After adding the username form there was an error telling that email and password was null. This was because while entering the username I wouldnāt be able to access the email and password input using the useRef hook. The fix was simple, I just changed the useRef into useState and store the data on input change. Now that was extra data (username) that needed to be stored. I sent the username along with email and password to the backend and changed the userSchema to accept username. I worked on the signup functionality last time so this time I worked on the login functionality. In short, now during login the backend verifies the email and password and gives the user a jsonwebtoken as a cookie or an error. I wanted the input to display āfield is requiredā when user tries to login or signup without filling in the form. I just couldnāt get this working and it was so frustrating because the issue was so simple. Later I found out that I was using e.preventDefault on the button instead of the form causing the input to not show āfield is requiredā Okay enough yapping. Gotta go and work on the project. Hope your project is going smoothly. Bieā¦š
Iām sorry š ##Changes: Use localStorage to store jwt instead of cookies Fix signup page unequal width of img and form container Changed login.css similar to signup.css for consistent code Added login as guest functionality Added navigation to /course after signup or login success Added UserContext.jsx to handle user data Added protectRoute middleware to verify jwt Added ā/api/user/ā endpoint to get user data from backend Too many changes, letās break them down. Iām sorry that I switched to localStorage to store jwt instead of cookies š. The cookie wasnāt working as expected. I was able to store the jwt in the cookie and receive it in the frontend but when I reloaded the cookie would just disappear. I know that thereās a fix for this as I have done this before as well. But, I know that Iāll face the same issue during deployment even if I fix the issue now. Iāll probably deploy this in vercel and last time (in flavortown) I had to change the whole code format due to the cookie issue. So this time Iāll just rely on localStorage for now. If I deploy the website myself then maybe Iāll consider using the cookie. But for now just forgive me š. I fixed the unequal width of img container and form container with again in signup page. This happened because I added padding to the form-container instead of the form. Using flex for this was a headache so I used grid and it worked. Although I didnāt necessarily needed to change the login page css. I did it to maintain a consistent codebase. This is a huge one. I added login as guest functionality. I know that people will be skeptical of entering their email even though they can use any made up email such as [email protected] . I purely added this feature so that people donāt rate me bad just because they assumed that they need their own email to signup. And logging in as guest is easier as well so why not. Now, after the signup, login or login as guest is successful then weāll be redirected to the course page. Later Iāll make it so that users who arenāt logged in wonāt be able to access any other path except for the ā/ā. Also now thereās userContext.jsx for storing and distributing user data. For now thereās getUser function for getting userās data. I have made the backend work to verify the userās token and then only provide the user with their data. Alright no more yapping, the devlog has gotten very long. If anyone has read this devlog, God bless them. ~ Peace āļø.
Life is frustrating š© ##Changes: Added navigation to /course after successful login Designed navbar when user is logged in Added the user button in navbar when user is logged in Added redirection to signup if user goes to /course without authentication Fixed jwt malformed error in protectRoute.js The navigation to /course after successful was implemented before but I somehow missed to implement that in login page. Designing the navbar for authenticated user was very challenging than I expected. As you can see in the image there are multiple attempts at creating the navbar. Everything I tried was just looking bad. The final design is also questionable. But for now it is what it is. Now unauthenticated user arenāt allowed to visit course page. They will be redirected to signup page if they try. This was supposed to be simple but somehow I made this also hard for myself. I have done this before so this should have been easy for me but nope. The redirecting was working fine but I were to be authenticated and be on course page and then reload, then also I would be redirected to the signup page. After I made up my own solution for this which I donāt think is the best way to do it. Due to my incapability of designing simple things and solving minor bugs I was questioning my ability to solve problems and design. Which at that moment felt sad š. Also there was jwt malformed error popping up in the backend which was also frustrating to solve. Not because it was hard but because it was easy and I wasnāt able to solve it. I wonāt tell you what happened here as the devlog is getting long. No video this time cuz the I canāt show the navigation changes working as they arenāt working properly. The bug is preventing user from redirecting to /course after login or signup. Instead user is redirected to signup. I know that this because of the two redirection changes made in this devlog. So, Iāll go and fix it asap. Hope your coding experience isnāt going as frustrating as mine. Thank you for reading my frustrations. Byeā¦š
Omg itās finally fixed I finally fixed the bug that I addressed in my last devlog. This was so frustrating. I never expected that this would take me 2hrs and I would write a whole devlog on it š. The bug was that when I was logging in I was being redirected to /signup after signup, login or login as guest. I had made so that after signing up or logging in the user would be redirected to course page. I had also made it so that if the user value is null then the user would be redirected to the sign of page. So now you can see that where this is going. I just couldnāt simply figure out why the user value was null. After doing so much thinking and reading the code and trying to fix the bug, I have finally succeeded.Another issue that I was facing during the working was I was constantly forgetting what I was doing and to see everything visually I used excalidraw as you can see in the picture. So there were three things that was leading to this bug. Firstly, I wasnāt using the await keyword while calling the api functions. Secondly, I didnāt have a loading state while fetching the userās data. Lastly, the function getUser function responsible for fetching the user data wasnāt even being called when redirected to course page. The function was only being called when the user first loaded the website. Right now, my head is aching now I think I should take some rest. I didnāt remember to add loading state which was so silly of me. I only realized that after visiting my old project. Seeing that I felt dumb because ofc you would need a loading state while fetching the user data from backend. I feel a little relieved now š®āšØ. I cannot even remember properly all the things that I tried to solve this. It was just a mess š©. After solving the bug, now looking back, it wasnāt that difficult to solve. It was just a me problem. I could write more on this but Iām too tired for this now. Okay biee..š
Wth itās been 5hrs?? Added toast for login signup and login as guest errors Made the signup data persist even after the value of hasContinued changes Designed the dropdown menu Added dropdown menu Added logout functionality First of all, Iām genuinly confused how this took me 5hrs.. Added toast so that now when thereās any error during the signup or login. For example during signup maybe a user might write a username less than two characters, then the toast pops up telling the user it should be greater than 2 characters. I was stuck during this cuz the trycatch block wasnāt catching the error which was confusing. I used axios previously and it threw an error if the backend response wasnāt ok. But this time I avoided using axios for reasons that you guys probably know š. It seems that fetch didnāt throw any error so I had to manually throw errors in the api functions. The making of signup data persist on hasContinued value change was early. I just set the value attribute of input to be itās respective useState data. As you can see in the image that I designed the dropdown. I first designed the dark one which I really loved but it didnāt match the navbar so I created a light one. After seeing the dark one I really didnāt like the light one. So I tried fixing the design. I asked someone in the slack and they said the previous light dropdown design looked fine. Ig looking at the dropdown for long made it look fine to me as well š. Now I added the dropdown to the website. I had issue with the padding of the logout button during designing phase but I just winged it during coding phase and it worked š. The dropdown now looks fine imo. I however did have a issue while making the dropdown closing work when user clicked outside of the dropdown. I thought of using an overlay in the background but I knew that there was a way of doing this by checking the click event. It seems I had forgetten to do this. After some trial and errors I remember how it was done.. I also added logout functionality which was fairly easy to add cuz Iām storing the jwt in the localStorage. I just removed the token for localStorage, set the user to null, set isDropdownOpen to false and navigated the user to the home page. Ig, iāll try do things faster next time ā”ļø. Donāt want to spend 5hrs on things like these. Okay bieeā¦
When will my devlog get more than 7 views š Changes: Added loading component Added scrollsmoother in home page Fixed course page padding and added toast while redirecting unauthenticated user Added back button to signup and login page Designed the logo for website Added the logo to the website Now whenever the frontend fetches user data from the backend there will be a loading component that will come up. I made the loading spinner myself in figma why not š. Scrolling the home page using a mouse is so much better now now due to scrollsmoother plugin of gsap. I was facing a issue with this though. I was seeing an error while navigating to other pages. After a while I found out a guy with same issue in gsap forum and his solution worked. God bless that guy š. Some small changes were fixing the padding in course page , adding a toast while redirecting unauthenticated user from couse page and adding back button in singup and login page. I think they donāt need much explanation. I tried to design the logo of my website in figma. I tried different things and landed with a design that felt decent (The logo with king in the center). I look nice up close but it didnāt feel the same when shrunk down as a logo. So I started designing another one. I landed on the logo with cyan and dark purple background and !! symbol up front. I really donāt know how I feel about this logo. I looks decent sometimes and other times questionable. Please leave your opinion in the comments š. While adding the icon as a favicon, for some reason the favicon wasnāt display which was confusing. Later I found out that this was a brave issue cuz itās showing up in zen browser. Okay this much for now. Please like so that more people see this devlog š.
We have followers Changes Designed hollow medals Switched from localStorage to db for storing updating and retrieving completed courses data Added feature to show medals achieved by user Designing the hollow medals (I donāt know what to call that so Iāll just say hollow medal) was really fun. I just started designing the medal for fun in Figma. The result turned out really great even better than what I had expected. I was using circles for the medal itself and was trying to use the rectangles for the below design. Later I figured that it would be wiser to use the pencil instead of creating a rectangle and mapping out the bottom portion of the medal which turned out to be a great idea. In this project, I have started using Figma for creation of some assets and I am loving it so far my intention is to keep on using Figma until and unless I really have to use AI. Switching from localStorage to database for completed courses data was easy in my head but it took me longer than expected mainly because of three reasons. Firstly, I was thinking of creating a separate backend endpoint for course data. After creating the controller and route for course data I thought that it isnāt really necessary to create another endpoint for this as we can store it in the users data itself. Secondly, after deleting the routes and controller, I created API function for fetching and updating the completed course data period I had forgotten that I donāt actually need to have a separate getCompleted function because while fetching the user itself, the data comes with it. I have forgotten to delete the getCompleted.js file which I will do later. Thirdly, I have started to use Postman for testing out api . I am loving to learn things such as Postman and Figma. But this issue I was facing was the postman was working correctly but from my codebase the request body was showing undefined. It was a fetch thing I use axios before and I am figuring out right now why people used axios. It seems that I needed to specify in the header that this request had the content of json. So figuring that out also took some time. Also, I have added the feature to show medals achieved by user. The code isnāt quite clean for this feature. Thanks to the people that followed this project. I genuinely appreciate that š. New followers : @PAPER_01 @sak
Started working on the vision page Changes Designed the vison page Created the vison page and worked on the sidebar ui I have changed the name from visualisation to a vision. I actually donāt know which one is better. I just changed because chess.com and chesskid.com had vision for practicing the squares on the board. Designing of the vision section was quite fun although I had some issues with auto layout that wasnāt big of a deal. I was thinking what options should I have and thought it would be best to add show coordinates, change the color and select the time. I think the UI turned out pretty great. I will probably change the colour of the chessboard but black and white also looks fine. Coding design wasnāt too difficult. It was just copying the design that I made, but the Figma design looks different. I should check out why the size of the buttons are the same but in Figma they look a lot bigger. It might be because the width of the sidebar is not the same. In conclusion, this was a peaceful devlog. It feels really nice not having to fight with your code and your designs. Hope that the future develops are the same š¤. Until then peaceāļø.
Things are going great Changes: Added chessboard component with ranks and colored squares Added function for generating random squares and displayed them Added feature to display green and req squares to indicate whether the user clicked correctly or incorrectly in the chessboard Displayed attempt made by user in the sidebar with respective colors for correct and incorrect ones I thought doing all of these took me at least four hours but I was wrong. It seems that itās only been about like three hours. This time I have worked on the chessboard itself on the vision page. Before it was just a plain whiteboard but now there are individual squares which was pretty easy to implement. I however needed some time to figure out how to add colours to the squares. But it also wasnāt that difficult. Then I created a function for generating random squares with the help of math.random(). I created an absolute element to display the random squares at the centre of the chessboard. To indicate the user that the square they have clicked is correct or incorrect I played the small animation that changed the colour of the user clicked square into red or green depending upon whether the user input was correct or incorrect. I was stuck here because I didnāt know how to reverse the animation. Of course I could just change the colour to green and then the colour of the square but that didnāt look quite right as I am probably going to change the chessboard colour later. So I wanted the animation to be flexible I was trying to play and reverse a animation timeline but it was so much easier than that later. I just remember there was the repeat and yo-yo property that will easily accomplish this effect Iām looking for. I have found a new bug with this if I spam click a square the square permanently turns into either red or green so definitely I will fix that in the next devlog. Also now the squares that the user clicks will be displayed on the side bar. The colour of this square notation will be red or green depending upon the user selected the square correctly or incorrectly. I have found out that thereās a flex related css bug in attempts element. I will look into that tomorrow. Okay bie.. Hope you have a great day š
Ayy almost 5 hrs today !! Changes: Fixed attempt square and attempts not wrapping as expected Fixed color being stuck in chessboard when same square is clicked rapidly Added color menu popup when click color button in sidebar Added time menu popup when user clicks time button in sidebar Added Progress component in sidebar with working score Made timer in progress.jsx functional Fixing the user attempts in the was pretty easy. I just added a attempts container to wrap the attempts element and then the CSS work as expected. Fixing the red or green colour being stuck in chessboard when clicked rapidly was a headache to fix. I was trying my best and at last I came up to the decision that I needed a timeline for the animation before the animation was played the progress of the animation should be zero. I tried that and obviously that didnāt work but it seems that I was close to the answer. I used Claude to figure out the answer and Claude used killTweenOf gsap function to remove the animation before the animation was even played. It also added a onInterrupt property to the animation which basically reverted the stuck colour after killing the animation. I didnāt want to use Claude, but I just couldnāt figure it out and I think it was better to use Claude as I have never used those functions and properties of gsap. Also Claude made that portion of my much cleaner. Seeing this now, I will be more focused on the cleanliness of the code because claude showed me that my code was repetitive and how it could be made smaller and easy readable. I decided to make the colour menu pop-up and time menu pop-up straight by coding instead of designing it first as I should have. As you can see, the result is very terrible. I am sure definitely fixing it in the next devlog. I was force thinking of making a pop-up menu component and using them in both buttons but I found that it was a hassle and not worth it. Only the white and black button in colour pop-up menu work. They just rotate the board and thatās all I still need to add functionality to them. After learning the lesson that I should definitely design before coding. I started designing the progress component. Although there isnāt much to design there I definitely would have made it as bad as the pop-up menus. While coding this, I also made the score display the total number of correct at attempts which was pretty easy. I just had to add one digit whenever the chose the correct square. Then, I started working on the timer. The timer would have been really easy if I just used setTimeout every second but I like to torture myself so instead of just doing that, I challenged myself using date constructor. I have done this before but it has been sometime and I remember how it worked. The countdown started from 28 which was frustrating. Now, I have just completed that but the code is really messy. I will definitely fix that tomorrow or today as I might post this devlog tomorrow. I think that shorter devlogs do better in terms of views. Iāll try that next time. See you in the next devlog š.
Mostly cleaning up the code and breaking things Changes: Made timer code better and cleaner Added functionality to timeMenu options Added countdown before starting the timer and displaying the squares -Added VisionContext.jsx to make code cleander and broke down vision page into smaller components As I said in the previous dialogue, the timer code was messy. So I decided to clean the code now it looks much better. Also now the time button options work now the timer will have 15, 30 or 45 seconds according to what you choose. So before, after cleaning on start the timer would start right away and the square would also show up. But this might make the user frustrated as they have to click start and right away move their mouse to the chessboard. I saw that chess.com has a countdown timer so I also made one. The code for this countdown timer is also messy so I will probably make it more cleaner next time. This is the main thing I have doing this whole devlog which I cannot show you because itās just making the code cleaner. The vision pays had a chessboard component and then sidebar element to it. The sidebar element had all the code which was making the vision page could a lot messy. So I have broken down components into components and those components in the further components. I think this is making the code much more easy to read and find and debug each component more easily. But in the process of cleaning my messy code, things have broken down. The timer isnāt working, I will fix that later. I donāt have much to show here today so the see the countdown timer working and the broken timer š. I will fix everything in the next devlog. So stay tuned. Bieeeā¦
Weāve reach 100 hours š Changes: Fixed timer not displaying in sidebar Removed the square display after time is over Fixed timer setInterval running multiple times and made countdown timer code cleaner Fix TimeMenu not closing Removed unused imports Designed the sidebar to add new data Added the new design Added animation to make the square notation that appears on the chessboard disappear First of all, we have reached 100 hours letās goooooo. I would like to thank everybody who have followed my project read, liked or commented on my devlogs . My project has recently started getting some traction. Special thanks to @PAPER_01 š. I have done a lot of things this devlog. I will try to cover these in as short as possible. It seems that the setInterval in progress.jsx was running twice. I found out this while I was making the countdown timer code cleaner. So to fix that I reset the hasCountdownCompleted as soon as the timer in progress.jsx runs out. Now, countdown and progress timer work as intended with cleaner code. The random color option in color menu now works. It was a little tricky making that work. Letās just say it wasnāt working as expected but the fix wasnāt that hard. I liked what chess.com were doing. They were displaying the square notation and then the square notation would just disappear. The square rotation will also live in the sidebar so that if user forgets what the square was just displayed, they can easily look at the sidebar. I really like this idea and decided to implement on my project as well. But before I added this to the website, I first designed it on Figma. I also thought of displaying the score and best score on sidebar. Designing it was fun and tricky. I didnāt really like how the previous score and best score were looking and after some trial and error it looked okay. All of these things were fine and enjoyable to do but making the best score work was so frustratingggggg. Itās the reason that I couldnāt devlog yesterday. The issue was score was showing to be zero inside updateTimer function even though the score was greater than zero everywhere else. I thought fixing it wouldnāt be really hard. I tried console log score everywhere to see when the value was being zero but there was no sign of the score turn into zero. Later I found out that due to the updateTimer function being inside a setInterval the value is kind of locked and used useRef hook to solve the issue. Okay, thatās all for this devlog. Now that I have reached 100 hours letās aim for 150 hours as soon as possible. I have taken very long to write this devlog so I like would be heavily appreciated š.
Youāve my coordinates now Updates: Added coordinates to chessboard Changed previous to current Fixed user input on chessboard being checked before countdown finished The show coordinates now works Fixed some event bubbling issues in colorMenu and timeMenu Designing the pop up menus Now itās easier to locate squares with the help of coordinates . Now you will also notice the board has fliped while changing colors. ~ A small change, in the sidebar the previous word has been replace with current. I think the current word makes more sense there. ~ I also fixed user being able to click on the squared before the countdown finished. This was a silly mistake from me. ~ The coordinates has made it easier to locate squares. But if you want some challenge then you can toggle show coordinates off now. ~ Thatās all for this devlog. If you wanāt my actual coordinates dm me š.
Moving onto something big (Iām scared) Updates: Change ui of popup menus in options.jsx Added sounds for correct and incorrect attempt in chessboard Added countdown and start sound in chessboard.jsx Added puzzles page Renamed sidebar of vision page and itās component with prefix of vision. Most of the updates in this devlog are small changes. But now I am going on to work on the puzzles page. I donāt know how I will figure this out. I hope it goes mostly smoothly.. I had designed the popup menus in the last devlog. I think the newer design is much better than the last one. The popup menus donāt look the same in the figma and the website cuz I tweak some things while coding. The figma design was a rough design Adding the sounds in the vision page has made praticing much more fun. The built in mac recorder doesnāt record sound unfortunately or I just donāt how to.. So, Iāll add a ss of vision page with menu open and a ss of puzzles page. I added chessboard and sidebar to vision page. There were two sidebars now so I decided to rename vision page sidebar to VisionSidebar and puzzles pages sidebar to PuzzlesSidebar. Okay that was all for this time. Give me strength to start making the puzzle by liking and commentin on the devlog. Byee ā„ļø. Also if youāre reading this support @PAPER_01 . AniShuffle has been taken down but sheās been unbanned now š.
The pieces have been placed. I was so sloppy š Iāve added pieces to the chessboard. Iāve finally started facing my fear and started working on the puzzles section. It seems that creating the chessboard for puzzles will be harder than I have anticipated. Also please donāt mind the black pieces blending in with the background. I didnāt find chess piece set I liked so I downloaded the lichess chess piece set from pinterest. I was trying to crop them in figma and I coundnāt crop them properly. Also it was a tedious job. After downloading two crop pieces from figma I again went to the web to find out if someone already made them. This website came in clutch (greenchess.net). They had the whole chess pieces set of lichess available for download. Then, I started to code with no plan in mind . I donāt know why do I do this to myself. Obviously it was a bad decision. So I decided to use pen and paper to mainly solve one thing and that was how to place the pieces on the board. The writing helped me alot to think better. I was so sloppy while coding. I was mostly outside while coding and I was really distracted. One sec I was coding and another sec I was thinking about something else. I was making so many silly mistakes making the process more frustrating that it already was. I learned about fen while doing this (Forsyth-Edwards Notation). Through this any chess position can be stored and recreated in one line. It looks like this rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 I only needed to loop over the first part divided by slashes for positioning the pieces. Other things will be used later. I feel the code is really poorly written but it works so idk. I also found out about regex while I was trying to write a if condition for seperating strings and string with numbers. Okay this much for today. Bieā¦.
I got sick š¤§š„ Updates: Make pieces position perfectly to square in chessboard Moved chessboard states and refs to ChessboardContext.jsx Fixed pieces sometimes being group together in one square when chessboard offsetWidth is null Added destSquare element on click for all possible moves of rook Last time I did position the squares but when I changed the background color of pieces there was a slight misalignment. I started searching what was causing that to happen. It was due to the height and width of chessboard being in decimals. I checked to see what lichess were doing and found out the height and width of the chessboard were always divisible by four. I did the same for my website and now itās perfectly aligned and thatās what I love to see. Moved the states and refs from chessboard.jsx to chessboardContext.jsx to make the chessboard code less cluttered. The code relevent to puzzles page is in the chessboardContext while the code revelent to vision page is still in the chessboard page. When the page was loaded for the first time the pieces were being group together at the top left square. It was being fixed automically when the page was reloaded. It also happened while navagating from home page. I found out this was happenning due to chessboardWidth being null at start. To fix this I created a useState for the chessboardWidth so the page rerendered after the value was changed. My goal today was to make the rook move but I could only work up to generating the destSquares when the piece is clicked. I achieved this by creating a useState array and if user now clicks on the rook it calculates all the possible squares that the rook can move to and then that array is mapped using math to place destSquares perfectly on top of squares. The destSquares have a dot insided them which will be replaced by a icon but thatās the reason theyāre not aligned centered currently. I did have a hard time doing this. Letās not talk about it. š Iāve written everything in short so that I donāt hit the 4000 characters limit and also ig itās better for people reading (if any š„). I got sick yesterday and was just able to work on my project for 1 hr. Today I thought didnāt work much but it seems today I did 3 and half hrs. I am happy about today. I really donāt know if I can create the puzzle but Iāll try my best to do so. Everything I try to do seems to come with their own set of challenges and take time to overcome those challenges. Letās see what happens š
The rook got some moves š Updates: Added movement to piece when destSquare is clicked Added mode state for seperation of chessboard in puzzles and vision page Moved states, refs, effects and functions from Chessboard.jsx to VisionContext.jsx Working on handling vision page data if user switches to other page during vision practice Finally I can proudly say that the rook can move now. I am really happy that itās working. To move the rook I had created destSquares(the square with green dots) last time. Now if the user clicks on any of the destSquare with some maths the rook move to that square. Iāve added transition for the movement to look smooth. While doing this the rook did move to the destSquare but when clicked on the rook again the destSquare appered from when the rook was last time. To fix this I grabbed the destSquare location (e4) then set the squareid of piece to the location. The destSquares were calculated based on the squareid so now after moving the rook I can move it again. Also now if the a piece is seleced the background color of the pieces changes. When a piece is selected then destSquares appear but if the piece is selected again or other square is clicked then the destSquares are removed. Small things like this is making the chessboard feel lively and feel that it works correctly. I wanted to do this before but I thought Iāll do it later. I added a mode state in Chessboard.jsx. The mode state is either āpuzzlesā or āvisionā representing the page the chessboard is on. I have made the pieces not appear while Iām in vision page and am trying to make sure nothing is running behind the scences if user decides to move to another page after they click on start. The countdown timer code of vision page was in Chessboard.jsx. I didnāt like that so I decided to move the code to VisionContext.jsx with the timer I move some states , refs and function with it. I had some issues during this migration but it wasnāt too difficult to resolve. I thought I had worked more but seems like Iāve. Iām confused, when I think I have done little work at that time I some how end up will better hours and when I think I have done decent amount of work I end up with less hours. Anyways it feels good watching the rook moves are working correctly. This much for this devlog. Peace āļø
More pieces can move (Iām sick again š) Updates: Added functionality to handle vision page if user changes page during vision practice Added functionality of moving bishop and seperate calculation of rook moves Added functionality of moving queen Added functionality of moving king I told in the last devlog that I was working on hanling vision page if user changed page during vision practice. And now, itās done. I think I have reset the necessary things so that vision page works normal. If any bug related to this appear in the future then Iāll fix it then. Right now everything looks fine after adding this functionality. Creating destination squares for rook was easy and I thought bishop would also be probably easy. I was very wrong. The thing with rook is that there will always be equal number of destination squares but bishop doesnāt. I bishopās destination squares varies according to itās position. I took a long time to figure things out in pen and paper. I even wrote the whole chessboard notation in paper and looked at only one diagonal first to find some sequence ( Iāve attached the img below š). I started coding after kind of figuring out where to start. I had issues during coding as well but we got it boys. Also I was using OR instead of AND in the while loop causing bugs and I needed some time to digest that AND definetely worked there. A silly mistake from my side. For the queen I didnāt have to code much as I wrapped the rook and bishop destination squares code in to a function. Then, I created a new function for creating destination squares of queen which just called both the rook and bishop function. As this was really easy I was pumped to move on creating kingās destination squares as it is also really easy. Took a sip of coffee and continued my coding journey. I was wrong š„. I got stuck adding the kingās destination squares. I was first thinking of combination of rook and bishop but only one out from every side. This was the wrong way of thinking ig. Then I thought I should use two nested for loops for creating the destination squares which firstly worked out badly cuz Iām dumb. The destination squares weāre being created in such odd manner. After fixing that I had to also remove the destination square which was being created on top of the king and also had to handle to not generate some destination squares when the rook is on the edges of the board. I have done nothing today due to my illness. I hate my immune system š. Iāll code for 5 mins now ig for keeping my streak alive. Okay biee..
30 day streak letās goo š„ Updates: Added functionality of moving pawn with seperation destination square for white and black Added functionality of moving knight Changed color of chessboard Made rook not able to pass through pieces The pawns now move one square at a time and have the option to move two squares if theyāre on starting squares. Moving pawn one square is easy but I had to think about creating two destination squares infront of the pawn. So I created a array and push all the starting squares of the pawn and if the pawn is on one of the starting squares then two destination squares are created. Itās also seperate for black pawn and white pawn so that white pawn doesnāt get two destination squares when itās on the black pawnās starting squares. I forgot the knight also needed to move lol š. Just remembered in time after finishing the pawn. The knight was tricky to move. As always I used the mighty pen and paper first before coding. Creating the knight took some time due to random bugs here and there. I think I need to revisit the knight code later as itās very messy. Yay, now the back pieces donāt disapper on the dark squares as I have changed the chessboard light and dark square colors. I think the new colors look great. I was lazy to test out colors so I went to chess.com and picked colors from one of their themes. Okay now were moving to the next step. Making the pieces not be able to move through pieces. I started with the rook. The plan was simple. Check for any piece with squareid thatās same of the destination square and if true stop the loop. I couldnāt figure out how to even select the piece. I was frustrated as I need to select the specific piece with the squareid attribute. I found out about ReactDOM.findDOMNode but I couldnāt figure out how to work with it. I felt really frustrated at that time. I was thinking of using document object but I know that is a bad practice in react. It seems I forgot that we can use querySelector in refs. I already had the chessboardRef so I used querySelector to find if a piece was on the way of the rook. Also I had to change the way I calculated the rookās destination squares but letās not talk about that I think the devlog has gotten pretty long. Although the problems are hard for me to solve when I see the results working I genuinely feel happy. I have gotten lazy after getting sick. Although I have not fully recovered yet Iāll try to stop wasting my time. Okay this much for now bieeā¦.
Mostly cleaning up my messy code š§¹ Updates: Made bishop not able to pass through pieces Made the code creating rook destination squares much cleaner Made the code creating bishop destination squares much cleaner Fixed rook and bishop not creating destination sqaures at the edges of the board Made code for creating knight destination squares cleaner and fix if statement condition of rook in ChessboardContext.jsx Made code for creating pawn destination squares cleaner and make pawn unable to pass through pieces Fixed bug while clicking on a piece when another piece is already selected In last devlog I made the rook unable to pass through pieces so it was very logical to do the same to bishop. Making the bishop unable to pass through pieces was pretty simple as the code wasnāt much different from the rook one. Idk what clicked in me after doing that I started to thinking about making the rook destionation squares creation code cleaner. The code was very messy and repitetive and I believed it can made cleaner and smaller. I used 4 while loops before which had almost the same code but different values and slightly different calculations. After thinking and trying I turned the 4 while loops in to a single while loop. Now the code looks much better. Seeing the success in rook destination squares creation code I then moved on to the bishopās code. Made similar changes to the code as the rookās code. Also i believe the queen works perfectly as itās mixture of rook and bishop code but I havenāt really tested it on board. After cleaning up both rook and bishop I found a small bug. The bug appeared because of my slight mistake while trying to make the code better. Basically the rooke and bishop werenāt creating any destination square at the edges of the board. The fix was simple so this didnāt take long to fix. I already didnāt like the knightās destination squares creation code. Me cleaning up the rook and bishop code gave me the motivation to make the knights code better. It did take some time for me for cleaning up that messy and tangled code. I was using break keyword for rook and bishop so I also used break for stopping the loop but I didnāt want the loop to stop completely I just needed to skip the loop if there way a piece or if the knight was on the edge of the board. After a quick search I found that continue keyword does the job. The pawn code wasnāt that messy but it could definetely do better. I mainly changed the pawnās code cuz I wanted the pawn to also be unable to pass through pieces. Before there were two loops now I one loop does the job. Then I also made the pawn unable to pass through pieces by breaking the loop. Fixed the annoying bug. If a piece is clicked when another piece is already selected then it looks like both pieces are selected. Desitnation of both pieces are shown and both pieces are hightlighted. So, as clicking on a square reset the selected piece, I reset the previous piece if user selected another piece with a small change. Now Iām trying to making all these things work from the black side as well. Okay this much for this devlog. See you on the next one. Bieeā¦š
Gobble up pieces Updates: Rotated piece img when color is black and made user unable to select opponentās piece Added functionality of capturing pieces with rook Added functionality of capturing pieces to bishop, king and knight Added functionality of capturing pieces with pawn My goal was to make the board work from both sides. I was ready for this goal to be challenging. I was messing with squareid and position of pieces by checking the color of the board. But it seems donāt have to do much for things to work. Before, I have already made the board rotate using css. I was rotating the pieces when color was black and that was causing issue. Instead of rotating the piece I simply rotated the img inside the piece. Till now every is working as expected. Also I made user unable to select the opposite colored piece. Now we can capture pieces . If a piece can be captured, the piece will have four triangles at the corners. This is inspired from lichess as I didnāt really like the circle of chess.com. I made the triangles myself using figma. Also I created the dot in figma to change itās color. Previously the dots were green. It took me some time to pick the colors of triangle and dot cuz I didnāt wanted their colors to ruin the feel of the chessboard. This works by firstly determining if the piece in the way of destination squares is our piece or the opponents. If itās our piece then destination squares will instantly stop generating but if itās the opponentās piece the we first add the sqaure position to capuredSquares array and then stop generating the destination squares. While doing this I learnt about the remove method which allow me to remove the captured piece element from the board. It took time for figuring out how capture pieces with rook. After that it was really easy for me to do the same with other pieces as well except for the pawn. The pawn isnāt the same as other pieces. It moves vertically and captures diagonally. So I had to write code differently for the pawn. I code for the pawn does seem a little messy but i think itās fine. I would say it wasnāt too difficult to make the pawn capture pieces. I did have to think about making the capturing functionality work for both white and black pawns. This much for this devlog. I am being quite lazy nowadays. Time to grind and lock back in. Hit me up if you also want to grind along with me.
Iām dissapointed in myself Updates: Fixed pawn unable to show two capture squares at once Added function to move opponentās piece automatically Set fen according to puzzleLevel Moved opponent piece after the pieces have been placed and remove css transition into gsap animation while moving pieces Last time I added functionality to pawn to be able to capture pieces. It worked fine I there was only one piece diagonal to the pawn. I there were two pieces diagonally infront of the pawn only one capture square would appear. Now two capture squares appear if there are two pieces in front of the pawn diagonally. Fixing this was simple. Created the function to move the opponentās piece automatically. In puzzles the user only moves their piece, the opponentās piece moves automatically after user plays their move. This was the most frustrating thing I worked on today. I thought the function worked correctly but I was wrong. Iāll tell you in a sec. I added 3 fens with moves from lichess puzzles data in constants.js . Then I made the default fen data to null and made it so that the fen is selected according to the level of the puzzle. I think I was trying to add loading state for this. It was very poor thinking from me. I was just being very ambious and instead of trying to do things step by step I was trying to multiple things at this time. I donāt remember exactly what changes I tried to make ig I was trying to fix the moveOppenentPiece function as well at this time. I undid some of those changes, left others as it was and fixed the fen and commited that. I was already frustrated at that point and then when I tried fixing the moveOpponentPiece function the constant errors and bugs worsened my frustration. I donāt want to explain that part. Just know that after fighting with my code itās working now. Also before I had css transition for trasform property. Meaning that whenever the pieces moved it moved smoothly. But when the chessboard is first rendered all the pieces also animate to their places. I fixed this by removing the transition css and using gsap to move the pieces. Now the first opponent move happens automatically. This was also frustrating to make it working. Basically today was frustrating. I thought I coded longer but seems like not. But anyway, when youāre at the bottom the only was is going up. Saying that I will stop writing this devlog. I feel I could have written an essay today. Okay bieā¦
Taking a BIG decision Updates: Fixed pieces creating only single capture square Added redirection to signup page in puzzle and vision page if user isnāt logged in Made user unable to select piece when opponentās piece is moving Connect oppenentās move to puzzle data, Add check for user moves and Add functionality to make the opponent piece move automatically after user plays the correct move I fixed the pawn not being showing two capture squares last time. After that I found out that the capturing the piece wasnāt removing the piece from the board. I found out a function that I have commented out was being called and causing an error so I removed the function call for now. This was easy to fix but by doing this I found out that the pawn wasnāt the only one who wasnāt able to display mutliple capture squares. All the other pieces werenāt able to display multiple capture squares due to a simple rookie react mistake. The value of captureSquares was being updated with itās own value instead of using the previous value. After sorting that out I figured i should do same with the destination squares. Previously had an array updatedDestinationSquares after pushing all the values to the array then only I updated the destinationSquares value. In short I was doing the correct thing and me thinking that I could save 2 lines of code by adding setDestinationSquares directly to the loop was a bad idea but the state function isnāt synchronous. So I undid all the changes and also added a updatedCaptureSquare to all functions just to be safe. Now user canāt select pieces when itās the opponentās turn. Although the timeframe to select piece is small but still I wanted to be safe. I achieved this with a state named isOpponentPieceMoving. itās toggled on when user clicks on a destination square and toggles back off after the animation finishes. Next I tried to make the opponent piece move work through with the help of the lichess puzzle data. Before the opponent piece could only the first move to play. After connecting the moveOpponentPiece with puzzles data. I created a function to check whether the move made by user is correct or incorrect. This was also being checked with the data in constants.js file. The data is stored like this r3r1k1/p4ppp/2p2n2/1p6/3P1qb1/2NQR3/PPB2PP1/R1B3K1 w - - 5,e3g3 e8e1 g1h2 e1c1 a1c1 f4h6 h2g1 h6c1 The moves part start after the comma. First move is of opponent. It tells from which square to which square the piece is needs to be moved Eg(e3 to g3). The second move seperated by space is what the user need to play to move forward in the puzzle. So if the userās move is correct then I move the opponentās piece. But if itās incorrect then I reset the board. I got lost in the reset part. I learned if the key of a element is changed the element kinda resets. When I started doing this I felt a little uneasy. I was figuring out the code I wrote was manipulating the dom which isnāt the best practice in react. Regardless, I added a fragment to the code that was generating the pieces with a key with the value of boardKey and updated the boardKey when the userās move was incorrect. But in my mind a question was lingering "Should I redo this in the way how react wants it" . Seeing the functionality working I pushed off that question. But, when I captured a piece a error popped up. The ss is below. I tried to locate why was that error popping up. Iāve concluded that the bad code has started to show why itās called bad code. Although I might find this solution to this issue I think itās better for me to just rewrite the code. This is painful but it will make me a better developer. Also I found another bug, the error isnāt the only reason Iām making this decision. Iāll push the code upto what Iāve done right now and then Iāll start to fix what Iāve created.
Most rebuilding my broken code For context last devlog I took the decision to start rewriting the code to stop accessing dom directly by using states. Now the pieces are mapped from pieces state rather than directly from fen so that I can move the pieces from state instead of manipulating the dom. To achieve this I firstly created to convert the fen to pieces array. The pieces array looks something like this rn. [ {id: 'r-a8', pieceNotation: 'r', square: 'a8', coordOfFile: 0, coordOfRank: 0}, {id: 'r-e8', pieceNotation: 'r', square: 'e8', coordOfFile: 4, coordOfRank: 0} ] From this I learnt that setting the key attribute serves itās own purpose in react. I donāt fully understand it rn but Iāll look into it. Now, the id of the piece serves as the key for the piece element and if Iāve understood correctly that will be vital in animating the piece moving. Yay the rook has been reestablished using react state without any dom manipulation. The reestablishment wasnāt too difficult as I thought due to the already existing code. All the changes now happen in the pieces state which then causes the react to repaint the pieces. Now the rook can move from one square to another and capture opponentās pieces. Also Iāve made the reset squares function as it removes the destination squares, caputure squares, etc . Although thereās no animation during piece movement rn Iāll it add later. After making the rook work I stared making all other pieces work as they used to before. I thought I had to write most of the code to fix all the pieces but after finishing the rook other fix other pieces wasnāt that bad. I reused the code from the rook where I could, fixed some bugs and errors on the way and modified the code where necessary. Sometimes I got stuck due to my own stupidity but thatās nothing new š. The moveOpponentPiece function is rebuilt. Now the first opponent move will happen when the board is first loaded. While fixing this function I found out that I was able to select the opponentās piece as well. This shouldnāt be the case cuz I had already put railguards for preventing this. After fixing the moveOpponentPiece function I checked why this was happenning and the cause was I put railguards only if user click on another piece when a piece was already selected and that code was also wrong. I fixed them both and now they work as expected. Another bug found. When I clicked on the first pawn it only created one destination square instead of two. This was happening because the for loop had only 7 iterations instead of 8 which added the starting pawn squares to the array. Also the userās pawn were able to capture the userās pieces which was a big nono so I quickly fixed that. Even thought the moveOpponentPiece is working for the first move it instantly breaks from the second move. I still fully donāt understand why this is happening. I know it has something to do with using setState and it not being synchronous. The code looks like this let updatedPieces = pieces.map((piece) => { if (piece.square === position) { return { ...piece, square: destination }; } return piece; }); setPieces((prev) => { console.log("updated", updatedPieces);// I don't understand how this value return updatedPieces; // and this are have different values}); Iāve fixed it while writing this devlog removing updatedPieces variable and mapping the value directly inside setPieces(). Now, the second move works but the third move is broken š . Iāll look into this tomorrow. Iāll wrap this up for today. Also Iām changing my devlog style a little bit. Iām not telling you all the problems I ran into like I did before to keep the devlogs a little short.
I am stuck Ayy the opponent moves work as expected now. In last devlog I wasnāt able to capture opponentās page because I accidentally didnāt filter the pieces, only moved the piece. Now the capturing system also works as normal. While talking about capturing pieces now the opponent can also capture pieces. If any of the playerās piece is on the destination of opponentās piece then it will be captured. The main lesson learned here is to mostly use the previous data while changing the stateās value to avoid unnecessary bugs. Iāve made the reset board function work. This was the point where I decided to rebuilt the code by removing the use dom manipulation and looking back I think it was a great decision by me. (Context: 2, 3 devlogs ago I found out my code was really trash while creating the reset board function). While writing reset board function I did run into some weird bugs. The board is reset by reconverting the fen to pieces array. The first opponent move happens when the opponentMoveIndex is 0 now. In the reset function the opponentMoveIndex is set to zero. Iāll add a animation to indicate that the userās move is incorrect later. For now I added the animation for the piece moving. Iāve learned that when moving the pieces by updating the state in react, the key of the element is what matters for animation to occur. If the key of the element is same and just the transform style has changed react knows that itās the same piece that jumped from one place to another. Also now, the move transition doesnāt happen when the pieces are being place. Because the pieces are placed using the transfrom property, the same property used to move the piece. I took me a while to fix this. It seems that this was happening because the squareWidth was making the page re render. Iāve fixed it but I still I donāt completely understand it, which shows that Iāve a long way to go. This one is small but crucial. Now the user cannot select the opponentās piece during opponentās turn. Iāve added a 500 ms delay for opponentās move so that it doesnāt feel things are happening really fast. In that timeframe user is not able to select any pieces now. I am now stuck at the part where I am trying to animate the pieces after checking the user input. Whether itās correct or incorrect. I wanted to make the background green if the move was correct and red if it move user made was incorrect. Using states is proving to be tricky for me as theyāre fully synchronous. My brain goes okay this will happen and that will happen but the code wonāt have the updated data because of useState nature. Also I tried to change the background color same way I move the pieces. Now that I think I about it I just wasted time. I will try to do animations with gsap now but idk how to explain I canāt really think of a way to do it with these useStates. Okay this was more that enough yap for 2hr 30 mins of work. Letās see if I figure out a way tomorrow. If youāre reading this love you man š.
Making good progress The piece background color now changes color depending upon the correct or incorrect move that the user makes. Last time I was trying to achieve this by just using useState hook. Iāve understood now that it was the wrong approach instead now gsap handles the animation part. The main issue with gsap I was having was I didnāt know how to select the exact piece for animation. Iāve achieved this by using useRef hook named pieceRefs containing an object will all the pieces on the board with their ids as key. I havenāt never used a ref like this before and it feels scary to write code in the unknown territory but ig itās a part learning. Also Iāve removed the code that changed the backgroundColor using useState and used gsap. It was just waste of my time to try to use useState hook to change the backgroundColor . So now, piece toggling the highlighted bg color when a piece is selected or unselected will be handled through gsap. Ahhhhhhh.. Finally after a puzzle is completed successfully the the next puzzle will start. My brain feels like itās melting after making this work. I struggled so much to make the work mainly due to react batching the state updates. Unexpected bugs came while coding this. So, basically a puzzle is considered finished if the moveOpponentPiece function has no moves left. Then, we change the fen state and also reset the board so that the pieces are placed again. After that when player reaches next level the opponent first move needs to take place. For that I have a useEffect hook to check if opponentMoveIndex and userMoveIndex value are default values. The values are set to default through resetBoard function and if the values are the default ones then the opponent pieces moves. One of the main issues I had with this was the moveOpponentPiece function was running twice. Due to which one of the opponent move was being skipped. I wasnāt able to locate why and was making so many unnecessary changes and console logging everywhere to fix this š . The issue was that the useEffect that I talked about earlier had pieces in the dependency array making the moveOpponentPiece function to run twice. Iām really exhausted after doing this⦠Then after some relaxation I made a rough figma design for the puzzles sidebar. It was kinda relaxing to not worry about coding for a while. I had big plans for the sidebar like making candy crush type levels but I donāt think Iāve time for that so just basic buttons will have to do. Iāve tried creating the distuinguishing the levels based on completed levels, current level and locked levels. Back to coding again, I mostly copied the vision sidebar code for puzzles sidebar as the only difference is in the sidebar body. It seems that Iāve forgetten to use css grids. I wanted the buttons layout to be responsive. I took a quick revisit on how grids. Throwed random properties at the grid hoping it will work as I expected š. At last it was the auto-fill property I was looking for with a combination of minmax. Iāve tried created the css for completed, current and locked now I just have to hook them up to the buttons according to puzzle level reached by player. Iāll do that tomorrow, now Iāll stop writing. If youāre reading this, I hope your project is going wellš.
Learnt something valuable ⨠Okay now the puzzle buttons have dynamic ui. The puzzle button will have ui according to the puzzle level. I was confused on how to achieive because there were three condition instead of two. If there were only two coniditions then it would have be easy as I would have simply used ternary operator. I couldnāt use if condition inside jsx. After some time I figured that if could call a function and use if conditions inside the function and return the className. Also now the puzzle level is stored and fetched from the backend. After doing that a toast error popped up as you can see below. I didnāt know why this was showing up when the page is first loaded up but instead of fixing that I first moved on to make the start puzzle button work. I think my main problem is I get distracted easily. To make the start puzzles button work firstly I created puzzle context file . I was deciding to make the chesboard context the puzzlecontext as all the data needed for puzzles page was there but I think itās better to seperate those things. So, I placed the puzzle context higher than chessboard context with that thought process. If the puzzle hasnāt started the fen value is set to default starting position. Then I again got distracted and thought why isnāt the vision context also above the chessboard context. So, I moved the vision context and the coordinates broke. The reason was color state so then I created different color states for vision and puzzle context. While writing this I donāt actually know what Iām really doing. I do one thing and jump onto another making writing the devlog very hard. I think I can do better⦠š After learning the lesson, doing thing one at a time. I only focused on making the start button work. So I moved some values inside puzzles context for this to work and everything broke. But, I wasnāt feeling overwhelmed as my focus on only one thing. Slowly but surely I fixed the pieces moving, capturing and the first opponent move. I think my main issue is dealing with useState hook updating in batches. Ig I will just get better with time. Still the backgroundColor animation is broken which I need to fix. Also while doing this I found out why the toast error was occurring. Silly me didnāt add method post to update the puzzle level. Now after the puzzle finishes the puzzle levels value updates and the updated value persists. I should definitely do things one at a time. Getting distracted and doing multiple things will just make me feeling overwhelmed and will make it harder for me to devlog as well.
Two steps forward, Four steps backwards š Firstly, Iāve fixed the gsap animations not working. This happened because last time I renamed all the color state into chessboardColor. Due to this the gsap backgroundColor css property turned into backgroundchessboardColor. Ig the lesson here is think before using change all occurences feature in vscode. The sidebar now changes. If puzzle hasnāt started then itās the same old ui. If the puzzle starts the level btns disappear along with start puzzle button. If user makes incorrect move the sidebar show retry puzzle button and if the puzzle is completed successfully then next puzzle button shows up. One thing I learned here is making one button use different className, onClick handler and text easily by storing all data in object. The retry and completed onClick function looks empty. So, I decided to work on the retry puzzle button functionality. To make the functionality work I imported the resetBoard function from chessboard context. Calling the function directly didnāt work because setState function doesnāt apparently update if the value is same. I fixed that by passing {retryLevel: true} or false to the function. After doing this the first opponent move did break and I did fix it but I think with bad code. Looking at the code now Iāve been calling resetting the board and setting default position using the chessboardColor seems wrong. So, then I started cleaning the code. I guess I was correct and things needed to change. I would say these are mostly small changes and donāt need explanation but it seems that the chessboardColor had an actually bug and it took my soul away trying to fix that š . So, the opponent move was capturing itās own piece meaning that the piece which moved at the beginning would automatically disappear. This was happening because the moveOpponentPiece function ran before the chessboardColor could change when the puzzle is first started. To fix this I had used useEffect hook with chessboardColor in the dependency array to reset the board. But only works if I have the black pieces. If I have the white pieces the chessboardColor doesnāt update because useState doesnāt update when the value is same. The value is white at first because of the default position set when puzzle hasnāt started. I donāt even know how to explain the fix i used. I just chained state updates from file to file to have colorUpdated state value updated in chessboard context.jsx. Basically I had a rough time fixing the resetBoard function running before chessboard color was updated. This time even pen and paper also couldnāt help me solve this š š but it did help me to understand the problem on a deeper level. I tried adding next puzzle button functionality. āI triedā š cuz I couldnāt get it to work and on top of that when I tested the retry button it didnāt work. Donāt know how but the retry button also broke. Now, Iām taking a huge decision again. I think some of the problems can be reduced if the chessboard wasnāt a single component that works on both puzzle page and vision page. I think I was too ambitious but now seeing these issues I think itās better for me to have to separate chessboard components. This might not be the best practice, but this will probably make my life easier. I just read the āDevlogs that get noticedā in the resources page and I think I should make my devlogs a little shorter. I said this in one of my previous blocks as well, but it seems that I am explaining too much. So letās see what will happen tomorrow. Okay bieeeeā¦.
Ayy good progress today I created a separate chessboard component for puzzles page only. Before both puzzles page and vision page were using the same chessboard component making the code complex, hard to read and hard to debug. Firstly I decided to move all the chessboard functions and states into puzzle context but later changed my mind midway. I decided the chessboard functions and states make more sense to be in itās own folder. Everything broke while doing as expected but I fixed them one by one. Now the puzzles chessboard is functional and itās code looks a little less overwhelming to me. Now the vision page also needed a separate a chessboard. It wasnāt as easy as just copying and pasting most of the code into vision chessboard because the data was connected to more components of the sidebar such as progress timer, color Menu, etc. I donāt if I should separate the functions to components that they server of just dump it all into the vision context file. What I did was keep functions into their respective folders cuz I think the vision context file looks really cluttered doing that. Everything broke here as well but as before I fixed things one by one. Now I really believe it will be much easier for me to work on chessboards as theyāve been seperated. Also I deleted the original chessboard component and chessboard context after that. On clicking the sidebar button the reset board function is called and the function came from chessboard context. As there is no chessboard context now you can see that thereās a problem here. The reset board function in now in PuzzlesChessboard.jsx which means we canāt access it from PuzzlesSidebarBody.jsx. To solve this I just made the board reset everytime when hasPuzzleStarted is true. We do have the access to hasPuzzleStarted from puzzle context. Fixing that somehow broke the piece transition though. After that I mostly worked on the small things. Such as fixing no transition during piece, fixing the progress timer staring with 2 seconds less than the time set, adding chessboard size to puzzles chessboard in a better way, etc⦠Now the next puzzle and retry puzzle buttons also work. The next puzzle button works as expected. The retry puzzle button also works but the pieces move to their repective place with animation when the board resets which I donāt wanāt. To prevent this specific thing I have already written some code before and itās working when starting the puzzle, moving to next puzzle, rendering the default pieces on first load. I canāt figure out why itās specifically working for retrying a puzzle. I spend a good amount of time looking but idk. Iāll look into this tomorrow. I think the devlogs are still pretty long. Iāll try to keep the devlogs shorter on future devlogs. Okay bieā¦
Finally, I present to you a short devlog š I have fixed the issue of pieces moving with transition when pieces are being placed after clicking on retry puzzle. To prevent this I already written code which worked perfectly but when only on retry puzzle it wasnāt working. This solution was simple but figuring out the issue took time. To fix the issue I used a useState hook to set hasPiecesPlaced to true only after pieces state updated. Also, Iāve already written code for handling page change in the middle of vision practice. I think this doesnāt work after I removed Chessboard.jsx and ChessboardContext.jsx. Not sure when this broke . I found better way to do this using the useEffect hook cleanup function. I learned that when adding setState directly in cleanup function it throws at recurring error š . I felt my laptop heating up š š . But thereās no error when adding setState inside the function and then running the function in the cleanup function. Thatās all for today. Couldnāt do as much as would like today cuz a rat bit me š. Byeā¦
Interesting updates I added back button in puzzles sidebar with functionality. Before there was not way to go to the default sidebar (the notStarted state). Now after messing up or completing a puzzle thereās a back button which sets the board to default postion and set sidebarMode to ānotStartedā. I wanted both buttons to be taking up equal space but later thought the smaller back button is better. Also now, puzzleLevel updates instantly updates after solving a puzzle instead of updating only after clicking next puzzle button. User can now select and play any completed puzzle by clicking level btns in sidebar. Previously user can only start the puzzle Level user has reached which meant no puzzle 1 and 2 resolving puzzle after user has reached level 3. I split the puzzleLevel state into selectedLevel and highestReachedLevel. The puzzle is set to the selectedLevel and the buttons arenāt clickable above the highestReachedLevel. The ui of level buttons is changed. I made the buttons smaller and made the selected level more distinct by adding a inner glow to the button. Weāve upto 30 levels now . I downloaded the lichess puzzles database for this project but whenever I opened the file my laptop will just heat as there were more than 69 millions data š . I did try to use the lichess data but I didnāt actually like the progression of difficulty so I used chatgpt to make puzzles. Iāve played upto 21 levels and I think itās good so far. Thatās all for now, okay bieā¦.
A little rest from programming Iāve added hint button in the puzzles sidebar. I had been trying to avoid working on this but I couldnāt avoid it forever. Also the puzzles sidebar looked really empty without the hint button. In chess.com the hint button highlights the correct. I did things a little differently, the hint is communicated via text to user. The text animates during first appearance and Iāve made it so that user gets only one hint. After the hint the button goes gray indicating itās not clickable anymore. I made puzzles sidebar code better to display buttons and also added replay button with functionality on successful puzzle complete. I mainly made the code better cuz I need to add the replay button. The replay button is same as retry button for replaying the puzzle after completion. I made next button do nothing if user reaches the last level. Before when completing the last puzzle level we would reach the next level automatically which is prevented now. Iāve been sick for 2-3 days now and am just writing this devlog. Hopefully from tomorrow I will be working on the project more seriously.
Iām so sloppy now Iāve added sounds for piece movement, capturing piece and completed puzzle. I spent more time than I shouldāve finding the sounds. I am still not sure about the sounds that Iāve added expect completed puzzle sound. There was issue with playing sounds during opponent move cuz unlike moving playerās piece where there are seperate function for moving and capturing pieces, the moving and capturing logic is inside the same function. After thinking a while I did solve the issue. It seems mac default recording doesnāt capture sounds so you just have to trust me here š
. Iāve made hint button disabled when pieces are moving (Both player and opponent piece). I did this after figuring out if user click the hint button quickly after the last puzzle move then we get an error. Although this thing happening is very unlikely but itās better to always fix bugs. Also I donāt know what happens if user clicks on hint inbetween moves so I think preventing it is better. A small change, Iāve added better hover transition to logout button. I didnāt add a red background during making it cuz I had issue with chaning the svg color. Iāve learned that if I make the svg inline in the jsx and set fill to currentColor then I can change the svg color through css and add transitions. Also, Iāve added popup animations to time menu and color menu. I was even struggling with this even though Iāve added those kind of animations before. I was using the new Activity element in react to toggle the menus but to for adding the animations Iāve removed the Activity element cuz the menu would disappear before animating. I took some break from coding cuz I got sick. I think Iām really sloppy now. Imo these changes shouldnāt have taken me 2hrs. Hope I will be able to shake off this sloppiness.
Wow! This is the 51th devlog Iāve added the player color indicator in the sidebar. It tells you which color youāre playing. Before coding this I just complicating things in my head by thinking of creating new unnecessary states. I used pen and paper to think and realized why not use the color state already available in chessboard. To access the state I moved it up to the puzzles context file where both sidebar and chessboard could get and change the color. I also moved the hint down as it look clutter both color and hint together in the sidebar. Two quick small fixes. I fixed retry and back button not working and fixed replay button not playing the same level only on last level. Iāve added pawn promotions functionality to the opponentās pawns. In puzzle 17 and 26 there are promotions that happen but without the promotion part it just looks weird to look at. Especially in level 26 where the pawn promotes to a knight and without having that knowledge the user will just get confused. I havenāt added promotion functionality for the user pawns because there is no puzzle that requires it. I will add it if I have the time to but rn i am going to just ignore it. One of the bugs I faced while doing this was the knight promotion worked fine but the queen promotion at level 17 wasnāt. The pawn was just disappearing because the pawn was capturing itself cuz the promotion only work for black pieces which is now fixed. Next I fixed the random color option color menu not working. Idk when and how it broke I thought it was working fine but it seems not. It seems it was not working because the element was being unmounted before running the selectRandomColor function. So, I moved it to vision context and with a useEffect hook it runs every time hasStarted is true. A small change but which I feel great that itās solved. When clicking on accordion or pieces twice sometimes it selects the icon and other things which was just annoying. The fix was just two lines of css which I learned from a random dude on the internet. Really thank that random dude. Iāve now added functionality for adding multiple bestScore for according to the time and color. Before the highest score in vision would be the score scored across any time or color. So if you were to score 5 point in 45 seconds and score 5 points in 30 seconds they were treated as the same thing which imo opinion isnāt fair. To achieve this I used object inside a object unlike the single number representing the bestScore like before. The object looks like this. { white: { 15: 0, 30: 0, 45: 0, }, black: { 15: 0, 30: 0, 45: 0, } } I did have a very hard time figuring out how to update the state like this as I had to change the specific time score within the correct color. One thing I did learn from this is we can use square brackets for using a variableās value as key while manipulating the useState object. I also encountered some errors while trying to implement this functionality. Now everything is working as expected.
Many small improvements š Iāve added transition to level btns and added icons and different ui to puzzle sidebar button. I am using an array inside objects to display all buttons. So to customize the buttons I manipulated the array.Some button have only text, some have both text and img and some have only img. Also the main button is wider and other buttons are gray in background color. For this I used the className like in tailwind to add the styling meaning the buttons which need gray color will have the className gray. The size of the buttons is differentiated using different values of flex grow. I think the buttons look way better now. Iāve added reset if user changes from puzzles page to other page. The is to avoid any unnecessary bugs and error. I had already done this in vision page now it was the turn of the puzzles page. I have been avoiding this for so long but finally Iāve done it. I added the videos for professional course (or should I say advance course). I changed the name to advance cuz professional is just the wrong word to use here. I also moved some videos from beginner to intermediate. Now that the courses are in place I can finally write what youāll learn in the information section. Iāve added numbers such as 0 - 1000 representing what I mean by beginner. Iāve tried to match videos to the elo level. The data in courses section in the home page is also change from placeholder data. Looking back at the code they are really bad but Iāll leave it as it is not broken š. Now I think the project is coming to itās final stages I do need to add things but after that ig all I need is to polish the website and make website responsive. Iāve also fixed progress bar animation happening everytime on reload. This was a small thing but it was bugging me so I decided to fix it. Fixing it was annoying as I had expected to fix this easily. After some trial and error I fixed it using a hasCompleted state which is set to true after finish lesson button is click. Only when the hasCompleted is true the animation occurs. Some other changes I did were fixing only displaying highest achieved medal in course page and adding background color transitions to buttons. Enought yapping. I donāt feel like coding and I think I should take some rest for the next two days. Hope the rest reset my feelings and returns me to my prime stardance days š.
The website is live guys I used vercel to deploy my mern stack project and it was rough . I first tried deploying the the frontend and the backend separately. After reading blogs and trying I ended up deploying the express backend but at that point I had learned that thereās vercel cli with which I donāt have to push commits everytime to find out errors in production. I can just use āvercel devā command to create a production like environment but for development and testing out. I couldnāt figure out how to run frontend and backend seperately using vercel cli. I then tried deploying the whole repo. The issue with this was I couldnāt configure the website with folder structure like this chess-website ----frontend ----backend Maybe thereās a way to make this work (I couldnāt ), I chose the easier path which Iām kinda familiar with. In this approach thereās no frontend and backend directory. The backend is renamed to api which allows vercel to recognize that itās the backend and all the contents of the frontend folder will be moved up to the root directory. Errors came as I changed the folder structure but fixed on after another. The backend wasnāt working which got me really confused. There were many issues in this approach as well but atlast the website is running and backend is working properly . The two days break I took from coding is over and i think I feel better. Hereās the link to the website: https://evochess.vercel.app/
Starting making the website responsive Before starting on making the website responsive I saw that when logging in or signing up there is some delay before redirection where people might click the login button several times thinking that it itās working which is bad ux. In development there was almost no delay because I was using local mongodb. To let the user know that the button has been clicked successfully and to prevent multiple login/signup button clicks the buttons are disabled as soon as user clicks any button in login or signup page while turning the buttons color into gray. Now on to the reponsive ui part. I first tried making the navbar responsive but it didnāt look right in small screens. I was also trying to make the hero section responsive but without any design to follow. So realizing that I needed a design first I then hopped onto figma to design the navbar and hero section. I changed the ui of the navbar ig to make it easier to make it responsive but I donāt know if the navbar ui got better or worse. I know one thing and that is the navbar has got simpler. The design on the mobile is pretty simple imo but thatās the best I could do to make it look decent. I used flex property to make all the text align vertically in phones and decided to remove the image in phone screens. Iāve have currently hidden all sections below 1024px except the hero section to focus only on the hero section without other sections interference. Iāve mostly used hardcoded values to make hero section which I will change to clamp css propery for smoother hero section responsiveness. I have just eyeballed the sizes and paddings which is a bad idea but Iām just lazy to create figma design for every layouts. Now, Iāll make the hamburger menu working. Uhh, I hate making website responsive but it has to be done. If youāve any suggestion feel free to leave it down in the comments.
More website responsive stuff Firstly, I removed the animations from home and courses section below 768px of screen size. I didnāt remove the hero section starting animation cuz itās nice. I used gsap matchMedia to achieve this. While removing the animations a funny thing happened, the matchMedia wasnāt working and then I was reading this a gsap forum hoping to see where did I go wrong. I later found that I was doing things correctly but instead of looking at localhost I was looking at live website. Obviously the changes didnāt appear š¤¦āāļø Then, I made the courses section kinda resposive. Firstly I went to figma to design the mobile version of courses section as I was mainly unsure of what to do with the thumbnail cards. I decided to turn them into carousel which imo was a great idea. First, I turned turned the main courses section text smaller and then started working on the carousel. The making of carousel was rough. Firstly I was reading stuff online on how the sliding thing works. I think I somewhat figured that out but what I couldnāt figure out is the aligning the cards perfectly. The issue was I was going for a style where the first and the last card arenāt centered alight while the rest of them are. The swiping snapped the cards into place and some parts of the left and right cards would also be visible. I couldnāt figure out how to make this and was about to making hamburger menu but coincidentally while scrolling the stardance home page I saw recommended projects section where itās like a carousel without the snapping thing. It was way easier to achieve than what I was thinking so even though I didnāt make what I wanted the carousel isnāt bad. The overall the courses section felt responsive so I started working on the hamburger menu. Working on hamburger menu went pretty smoothly except for some things going wrong here and there. I first roughly designed the the menu in figma and then wrote the code.
Worked on hero and puzzles section (Responsiveness) The puzzles section was the easier that hero and courses section for making it responsive cuz puzzles section doesnāt contain any animations or any special thing. After several trials of adjusting the fonts and image I stopped after it looked quite decent. Before working on the visualization section I decided to polish the hero section first. My main goal with polishing the hero sectino was mainly using clamp() css function for smooth responsive text. Although the text are responsive using media queries in hero section, the text look kinda odd in some screens. After using clamp the website feels better that before. Also I changed the width of image with % values which does feel better. I also used clamp for some vertical padding as well cuz it was looking bad for devices with smaller vertical heights. I thought from 425px to 768px was tablet screen size but it seems the tablet screen size starts from 768px. So now upto 768px the website follows the mobile design. Now Iāll polishing courses section and puzzles sections just like the hero section. Wish me luck š. Bye I wanted to add more images but it seems 4 is the limit .
This was a rough one One a good note Iāve completed making the home page responsive (for now). After making the hero section more responsive last time I then proceeded with making the courses and puzzles page more responsive. I mainly used the clamp css funciton to make the course and puzzles section responsive. The courses section remained the same as I am quite happy wiht how it turn out but I didnāt like how the puzzles section was looking after testing the website out in my phone. It looked to small for a section so below 768px instead of the text and image being horizontally aligned itās now vertically aligned. The clamp part was similar to the courses section. Finally after completing those two I started working on the visualization section. I was the hardest section to make responsive due to the absolute positioning of the moves. Firstly I only focused on bigger screens as I had no idea how it would look on smaller devices. The moves were positioned before by mapping an array with the move notation and the css of top and right/left with percent values. I tried to remove that and instead of mapping the elements I thought of manually placing them and giving the ids by which I could have greater control over the css. While trying that I couldnāt make it work as in smaller screen heights it still looked terrible. At this point I was losing hope. I was wasting time watching a anime series just so I could avoid working on this. I tried thinking out the solution but nothing came in mind. Later when I was messing around with css throught the developer tools on the browser I realized the I could change the height of the image container to change the positioning of the moves as the moves are postioned on the basis of the image container. Now below 1440px the height of image container is 90% and below 1024px itās 80% and I have a max-height value set for safety. Itās not prefect but itās much better and Iām relieved š . The mobile design uses a image contaning the main image and all the moves as thereās no animation on mobile devices. I made the image in fimga and using clamps and % values I think itās decently responsive. To make the pages responsive I am using the developer tool in browser to first figure out the min and max values and the putting that value into clamp calculator to generate values. I am constantly switching between vscode and browser for this and if you have a better way to do it please lemme know. Okay the devlog has turned very long so bieeā¦
Weāve reached 200 hours Itās a big milestone that Iāve finally reached . Iāve made the whole course page responsive. This took me longer than Iāve expected. But before that I was getting 404 not found when visiting locations like /course directly but it was working normally when I was navbar to navigate. Iāve seen this issue before as well so I kinda knew that this was because of react SPA (Single Page Application) thing. To fix this I configured the vercel.json file and now it works as expected. So onto the course page. Firstly I made the accordions responsive on mobile screens using css clamp function. I removed the course info section for mobile devices. I didnāt touch the course card as they were a future problem for me to do. But the basic idea was the image with take up the whole width and the image and the text will be vertically aligned instead of the default horizontal alignment. Between 1024px and 768px one of the issues was the course info was looking crammed on the smaller side. so I reduced the padding and font-sizes with clamp css function so that it still looks good on the bigger screens. I also made the progress bar slimmer and badges smaller. Another issue were the course cards. One the bigger screens they looked find but on smaller screens the text were taking up more height than the image itself. I changed the value of thumbnail image from fixed value to %. Also I reduced the massive 1.75rem padding on the course card container for smaller screens. Also for all screens sizes below768px I made the banner slightly bigger vertically as the previous banner was looking very slim on mobile devices. I scraped the idea of making course cards vertically aligned and stayed with the horizontal alignment. I somehow managed the cards to look decent on smaller screens as well by using clamp(). The things I needed to do were similar but I guess it took me long as I was first checking the min and max values using browser dev tools and then putting that into clamp calculator and then pasting the value into vscode. Basically I had to constantly switch between things. In the end, I went to sleep but couldnāt fall asleep so I decided to complete the course page reponsiveness and do on last thing which was making the loading spinner responsive. Then, I peacefully went to bed .
Gosh Iām so dumb Last time I thought I had fixed 404 page issue when visiting paths like course directly. I did fix it for local development but not for production which is really dumb, shouldnāt the development environment be the same as deployment when using vercel cli. I tweaked the vercel.json to fix the issue in production now but now in the development the website didnāt work. The fix that Iām now using is leaving the production as it is and in devlopment using the environment created by vercel cli only as backend and running the frontend seperately using pnpm run dev. To connect both backend and frontend I configured the vite.config.js to redirect every /api request to localhost:3000(this is running throught vercel cli) Most of the time was spent on making the signup page responsive. The login page is also now responsive but itās just a copy paste of signup page css. I am quite dissapointed in myself because it took me so long to do this and still I donāt like how it looks on certain screens. As I realized that I was spending too much time on making signup page responsive I panicked and just rushed the process. As a result a have a reponsive signup and login page that Iām not very proud of. I fixed the signup not working. While signing up there it showed user already exist error everytime. The fix was quite simple, I had missed await keyword when checking for user with same email in database. Due to which the userExists variable was always true. Then I did something really dumb. I tried to fix something that was already working. I was worried that if I delete a user from database and then if that user tries to login then it would throw an error so without even checking if that was true I started making changes to the protectRoute.js file. I was thinking after the token is verified then Iāll just check if the user exists or not. In the process I deleted one important line of code because of which I wasnāt able to login now and I didnāt know why. I tried made the code as before not knowing the line is still missing so the error still persisted. After giving up and doing ctrl + z undo the previous code returned I finally realized the missing line of code. Also the feature was already there when fetching user data so none of this was necessary š« .
Worked on the drag and drop feature Although itās not fully complete and polished, itās kinda working. I stopped working on the feature and started writing this devlog cuz It has been 3hrs Iām forgetting what I did while working on it. Firstly I wasnāt even going to implement this on the first place as I thought this was outside my coding capability but someone gave me a feedback that I should add this feature so I decided to give it a shot. I found out about the dnd-kit package for implementing drag and drop. I was skeptical of using it at first. I was reading their docs to figure out the package. My main concern was how would I implement the feature with the already existing click to move feature. They provide a useDraggable hook for making any element draggable. The useDraggable was used to make the piece draggable. I had to convert the piece code into a component for it to work. To drop something into another thing thereās useDropable hook which as the piece I made square, destSquares and captureSquares into components. If I were a good react dev I wouldāve already did those things ig the using the package is some what helping my code to be cleaner. I used the useDroppable hook inside destinationSquares and captureSquares. I was concerned that we couldnāt actually drop the piece as it doesnāt live inside the square rather it lives on top of the board using position absolute. But, I had gotten dnd-kit wrong. I element does need go inside the element if useDroppable is used. Thereās DragDropProvider that connects both draggable and droppable hook. Letās just say DragDropProvider gave me all the function such as dragEnd and values needed to move the piece. Later I changed the useDroppable to be inside all squares cuz after dragging the piece there was some issues when dropping the piece in itās original square if the user wanted to cancel the move. I didnāt really have to write new code for moving, capturing and resettingSquare as the code I wrote previously worked fine with the drag and drop functionality. There were many issues while trying to add this feature. Still there are issues I need to fix such as the highlighting the square bg color instead of the piece bg color when selecting piece and other bugs Iāve found. Also transition when opponent captures pieces doesnāt working also need to fix that. But, Iām really glad I tried to add this feature as Iāve learned alot and the puzzles board now feels more fun because of the feature. Thanks @PAPER_01 for suggesting the feature š Okay, Iāll stop yapping. Have a good time
Omg how does changing the color model solve the issue Before that I fixed the black piece being upside down when dragging. You can see it in my last devlogās video. I was only happening with black pieces because to make the board work when user got the black pieces I just rotated the board 180 degree. This made all the pieces upside down and to fix that I again rotated the pieceās img 180 degree. Ig when dragging using dnd-kit (npm package) the transform value was being overwritten causing this issue. To fix the issue rather the rotating with board using css I changed the order of files and ranks. I used flex-direction column replacing column-reverse for the rank to start from 1 to 8. Then for reversing the files when color is black then I mapped squares from reversed files array using toReversed array method. I thought by doing this Iāll make the code cleaner but I think itās more messy now š . Also I did have hard time understanding my own code when trying to solve the issue š . I fixed the pieces, destSquares and captureSquares being generated on the wrong squares. I realized the piece transition wasnāt working when capturing piece both for userās piece and opponentās piece. The transition only happens if hasPlacedPieces is set to true and isDragging is false. So, my first assumption the hasPlacedPieces was being turned to false only when capturing pieces but I was wrong. I was checked if it had something to do with the value of isDragging. I found the isDragging was never turned false so I fixed it but still the main issue wasnāt resolved. I was console logging things and just trying to figure out what was actually causing the issue. The fix was really simple. To implement the drag and drop feature Iāve broken down piece code into itās own component. There inside the component I have added the key attribute and it was the issue. The key attribute is supposed to be used on the component itself instead of inside the component div. (Eg.) I donāt know why it only broke the capture transition but anyways itās fixed Now to the part where I donāt even understand how does this even happen. Hopefully you understood what I was saying in the video btw please unmute the video as I am talking in that video. So what happened was the piece img bg color changes when itās selected. This was working fine until I added the dragging feature. When the piece is dragged you see the background color comes along with the piece. So I decided that the square should change itās color rather than the img inside the piece. I was going to create squareRefs for holding all the values of sqaures and then select the square using gsap to change the color but I realized a easier way would be to just target the square id. It worked so I also decided to use for changing background color of square when user move was either correct or incorrect. On light squares it worked great and it also fixed the animation as the same animation was working a little weirdly when using pieceRefs. I was happy that it was better but then I found the bug from the video. I tried different things and just couldnāt figure out what was the issue but when I decided to change the color from var(āc-red) to yellow it worked as intended. Then I changed the same hsl color into hex and it also worked but I donāt know whyyyy. If someone knows why this happened please tell me cuz itās ridiculous. Most of the issue had a simple solution but learning what caused the issue what the difficult part.
Weāre close to the end First I fixed the buggy dropping piece. I fixed this when I first worked on drag and drop piece feature but I donāt know how it broke again. When trying different things to fix it I tried to move the setIsDragging(false) lower inside dragEnd function below movePiece and capturePiece function calls. Surprisingly it worked š. I fixed light square being dark and vise versa if user had the black pieces. I found out this issue because the coordinates colors were mismatched. So my first intuition was changing the color of coords.jsx. I got really confused as the changes did nothing in the browser. I am so dumb I was changing the vision page chessboardās coords.jsx instead of puzzles page chessboardās coords.jsx. It worked but then I realized the coordinates color werenāt wrong square colors were. I undid the changes made to coords.jsx. I also seperated the coords.jsx but adding puzzles and vision in the name. Then I fixed the squares color for blackās board. Iāve figured out the mobile design for puzzle section. First the idea was that the chessboard and sidebar would be stacked on top of each other. This was the easy route but if I did that then it would add friction to the mobile players as they would have to scroll all the way down to start the puzzles. Then I looked at chess.com and they were doing it really well where only after clicking start puzzle the chessboard will appear. So I removed the chessboard below 425px first and then made the button text, size and gap smaller. I also removed the aspect ratio of 1/1 from the buttons as the buttons were ruining the gaps between them in certain screen sizes. Now for the first challenge I faced. How do I only make the chessboard appear and disappear when clicking start puzzle only on mobile devices. As I used gsap matchMedia to make the chessboardās container display none or block according to hasPuzzleStarted for mobile screens. The chessboardSize is calculated according to chessboard container so that the chessboard is divisible by 4. When first loading the chessboard if the container has display none then the chessboardSize becomes zero and when setting the container to block will only show empty chessboard container without a board. I tried using the autoAlpha property of gsap hoping that it will do that same job as display none but without remove the element. It was making the container invisible but the container would still retain itās height and width. I was starting to doubt myself here and was thinking to take the easy route but just stacking the board and sidebar vertically. After thinking for a while I came up with a breakthrough I made the position of chessboard container to absolute and visibility to invisible. Now the chessboard container wonāt be visible and wonāt take up any space as it is absolute. When the board used absolute position idk why but the board container got so bigger. It also distorted the pieces when puzzle started. To fix it I ran the gsapMatchMedia code only after chessboardSize is calculated which was a great idea. It fixed the board when the puzzle started but when it was hidden it was still large. I just replaced the absolute and visibility with display: none as it only runs after the chessboardSize is calculated, thatās why there is no issue with display:none. Last change is when sidebarMode is notStarted then only chessboard is hidden. I know that 80% of the things I say wonāt be understood but Iām not a good explainer so you have do deal with it š
. Were really close to the end now I just have to make puzzles page and vision page responsive and just polish the website and then click the ship button
Made puzzles page responsive and bugs fixes Puzzles page responsive Most the time was spent making the puzzles page responsive. As always it took more time than expected. There were many issue that popped up and slowly but surely I fixed them. One of the issues was in bigger mobile screens the sidebar was being squished because the chessboard was getting really big but puzzles page has height of 100dvh as the chesboard in mobile phones is calculated according to width. To fix it I tried adding min-height to the sidebar for not getting squished and height of auto to puzzles page but this broke the sidebar when puzzles is not started cuz thereās no chessboard. The height of sidebar is 100% so due to the parentās height being auto the sidebar height was about as didnāt fill the whole screen. To fix this I used overflow: scroll to puzzles page and itās height to 100dvh. Another issue came when trying to make chessboard and sidebar look decent in different laptop sizes. I made it somehow work but using clamp, min-height, max-height, min-width and max width. It was kind of a pain to solve all the issues that came while doing this. Thatās why Iāve rushed making the puzzles page responsive. My plan is to come and polish it after Iāve made the course page responsive as well. It shouldnāt be too difficult imo as itās very similar to puzzles page. Fixed user being able to drag and drop opponentās pieces It was a quite dumb bug. I had prevented this for click to move feature but I didnāt think about it in drag and drop. The fix was quite simple as dnd-kit (npm package) provides a disabled property in useDraggble. I disabled it for the pieces for dragging which had the opposite color of chessboard. Fix next puzzle button not working on second last level I didnāt actually know about this bug. A friend of mine told me about this issue while testing the website. After level 29 is completed a state is toggled to true which prevents the next button from not working. The next button is now only supposed to not work after completed the last level. I havenāt used fixed values for fixing this so in future if I decide to add or remove puzzles it shouldnāt break. The fix was a little more complex than I anticipated. 9 days of stardance remain now. So, I have to lock in now. Okay bie
Changed some puzzles and more responsiveness work Copied the puzzles page and itās componentās media query css So after making puzzles page somewhat responsive last time, the first thing I decided to do after that was copying puzzles page media query css and just paste it in vision page as both of pages are very similar. This made the vision page and itās components a little responsive. Puzzle changes Iāve changed the puzzle from level 12, 23 and 30. The 12 and 23 level had 2 ways to deliver checkmate and only one of them counted as correct. I changed them as user might get frustrated seeing that. My code doesnāt handle that so I just changed them. Level 30 was changed cuz it wasnāt really difficult. I donāt think Iām satisfied with the new level 30 puzzle either. One issue while polishing signup page I didnāt want the form to look squished on devices with small vertical screen size. Due to this last time I generally kept things smaller than what I wanted to make sure it looks okay for those devices. To fix that I added min-height to the form-container. It prevented the form from squishing but the form-container was overflowing as the puzzles page has 100dvh. What I wanted was just the form scrolling using overflow: scroll but this probably took me about 20-30 mins to make it work š . I set overflow to scroll to form-container it didnāt work, added it to form which also didnāt work and then I added it to puzzles page. The scroll part was working when I added it on puzzles page but not what I was looking. Then I created a wrapper div to hold the img container and form container hoping now adding overflow:scroll to form container will do the job. After trying all things things I realized that the min-height was set to form container instead of form. The fix was to adding min-height to form and set overflow scroll to form-container. I removed the wrapper div after that as it was unnecessary and also hid the scrollbar that appears in form-container. Signup and login page polish after that annoying issue After that annoying issue Iād say things went pretty smoothly. I mainly used clamp as always for making things responsive. And as always it took me longer that expected. After polishing up the signup page I copied the code to login page and just changed signup to login. Vision page responsive on mobile devices Making the vision page responsive for mobile device was really similar as polishing signup page. I just used clamp for everything and made sure everything looked good. Now that I think about it i only made the sidebar responsive including the popup menu as only that is displayed on mobile devices and chessboard is hidden. The chessboard is also kinda responsive due to the copy pasting the puzzles page media query css. The making of sidebar responsive was just trying out different sizes and then putting the value into clamp calculator and copy pasting the value. Now, Iāll work on the vision page responsiveness for bigger devices and then if everything looks great after testing then Iāll ship the project
This devlog is a short one Iāve made the vision page responsive for larger screens. Last time I made the page responsive for mobile screens. I made some small changes in puzzles page while doing this for maintaining similar code . I ran into some issues such as css not working due to incorrect nesting and writing the writing the css on wrong file. Also, I removed media query for 1440px as the default css will work between 1024px and 1440px using clamp css functions and by doing that, above 1440px the css will stay the largest clamp value. I think I will do the same in puzzles page as well. 2hrs wenāt so quickly mainly cuz of my stupidity as I broke things that already was working fine. Also, I donāt think I like the mobile responsiveness that much but i donāt think iāll change it now (or maybe I will). While writing this devlog I just realize that Iāve make the sidebar responsive after vision page has started. Uhhh i hate responsive design
Fixing things and some more responsive things Iāve fixed chessboard displaying multiple selected squares. This happened when user selected a piece and then selected another piece by dragging. The fix was really simple. I just added resetSquares function when piece on drag start. Iāve also fixed pieces stacking on top of each other if user drags and drops a piece on another piece quickly before the opponents move happens. This was prevented when pieces are moved only by clicking but I forgot to prevent this if pieces were dragged and dropped. I did two things to prevent this: I reduced the time for opponent piece to move after the first move. I disabled the piece from dragging if it wasnāt the playerās turn. It seems the first fix wasnāt sufficient as it created another bug. So, if user selected a piece by clicking or dragging and then dragged the same piece then the destination squares and captureSquare will just completely disappear. The occurred due to resetSquares function that I had added. I thought for a while and came up with this solution. The resetSquares function only executes if user selects another piece on drag. However the function wonāt execute if the selected Piece is being dragged. The selected piece state null at first so resetSquares() wonāt also execute if selected piece is null. Now, it works as expected until and unless I find some bugs. Now returning back to the responsiveness. I fixed the puzzles button to be equal width and height. I had made the level buttons responsive before but they werenāt the same size. I had tried the aspect ratio last time as well but it was breaking the layout. Basically I used aspect ratio, removed the grid templated rows and changed some clamp values. Also I removed the media query below 1440px and integrated it as default css. After doing that, I started to fix the attempts in in vision sidebar. I thought it would take me two seconds to do it as I just had to apply the puzzle button knowledge here. I thought just doing this will work grid-template-columns: repeat(auto-fit, minmax(40px, 1fr)); I was wrong š This worked fine for level buttons cuz the number of buttons were static. Here the attempts squares increases as the user clicks on the chessboard. If thereās only one attempt square then it will take the whole width. I was stuck after this. I tried different things such as using max-width, trying to add width: fit-content, etc. but nothing worked. At last I thought of reverting back to what the code orginally was which just used flex and flex wrap but coming this far I just used grid and used different values with height to make the attemps square kinda responsive. I still need to use clamp or something to make this look good. Uhhhhhh this is so frustrating⦠. I think Iām overexplaining things. I should just simplify down things
THIS MIGHT BE THE LAST DEVLOG First I polished the puzzles sidebar. I made the sidebar width to be same as vision page sidebar. Then I changed the level button size as they were too small for larger screens. I also made the level button container scrollable if the level buttons overflow. This took the most time because the whole puzzles sidebar body was overflowing pushing down that start button. I just wanted the sidebar body to not overflow which would make the levels container to be scrollable. The fix at last was using min-height: 0 to the sidebar body. Idk how the min-height: 0 is helping here š . Next I made the visualization section animation (The last section of the home page) to appear quicker. This was a recommendation from my brother as when scrolling previously the section might seem like it contained nothing until you scroll fully. I faced issued mainly with the section not pinning to the top of screen when trying to move the animation timeline starting point. Also I tried to placing text higher on y axis and animate it coming down with the user scroll which produce the result I was expecting. So, I split the timeline into two. The first one reveals the text and the second one shows a person visualizing. The tex revealing animation ends when the section top hits the top of the screen which makes the section pin to the top exactly how I wanted it to be. Then I polished vision page sidebar as follows: Made the sidebar responsive after user has clicked on start Made the sidebar header look better and fix mismatch of padding from body Returned to using flex for the attempts and mad them responsive Tweaked the options and info as they were looking odd in some screen sizes (mainly the tablet one which looked really bad) I then copied some of these changes to the puzzles sidebar for maintaining similarity. Lastly I capped the width of course, puzzles and vision page to 1600px by adding a wrapper element. It acted weird on puzzles and vision page sidebar as there was already a element named wrapper and so I changed the classname to page-wrapper.
Ships:
Letās ship š¢ This is a website where people can learn and improve their chess skills by watching courses, solving puzzles and practicing their vision. The website was overall really challenging to build. If I had do pick, it would definitely be making a working chessboard for puzzles. At the beginning of the project I didnāt even know if I was capable of building one but I am really glad I tried as Iāve learned so much. Another challenging thing would definitely be making the website responsive. I donāt like making website responsive and in this project animations added another layer of complexity. Iāve tried my best to keep things responsive though. I am really proud of completing the project and mainly working chessboard as this is my first time building something like this. I am also proud of the animations and the ui of the website. To test my website some knowledge of chess is preferred but even if you have zero knowledge about chess you can test out my project as there are courses which will teach you about chess. Thanks stardance for everything šš. I probably would never have created or completed this project without stardanceš...
|
1793047914.9301367
|
1793134314.9301367
|
|
58878
|
personal dashboard by @kenji | Stardance
|
kenji
|
0
|
5.06
|
0
|
[]
|
[{"post_id": 79526, "ts": "202 [{"post_id": 79526, "ts": "2026-10-14T13:23:57Z", "hours": 1.2889, "text": "YOOOOOOOOOO alot have been adding nowwww!! lesgooooo, first of all the window is finnallly grabable and it can be closedd. second i added smooth cursor, i got the idea from @Hexaa !!!. for now thatās all of it!!"}, {"post_id": 78055, "ts": "2026-10-09T12:10:00Z", "hours": 1.1928, "text": "cool huh? so yeah i use tailwind too bcs i want to and uhh i love the glassmorphism <3"}, {"post_id": 76980, "ts": "2026-10-05T08:05:45Z", "hours": 0.8889, "text": "have to changed to vite gng. for component"}, {"post_id": 73893, "ts": "2026-09-26T08:42:18Z", "hours": 1.1392, "text": "YO GNGGGGGG ITS FINNALLYYYY, its pretty cool actually. iād loved it so so so so muchh. btw the asset is pretty much i stole it from the internet hehe. but its legal yk. iāll come back when it have more pprrooggrresss"}, {"post_id": 67206, "ts": "2026-09-13T08:13:52Z", "hours": 0.5481, "text": "yooo im inspired from macos 27 golden gate, so i will makin it similar to that. hope there isnāt a bug :)"}]...
|
Title: personal dashboard by @kenji | Stardance
D Title: personal dashboard by @kenji | Stardance
Devlogs:
yooo im inspired from macos 27 golden gate, so i will makin it similar to that. hope there isnāt a bug :)
YO GNGGGGGG ITS FINNALLYYYY, its pretty cool actually. iād loved it so so so so muchh. btw the asset is pretty much i stole it from the internet hehe. but its legal yk. iāll come back when it have more pprrooggrresss
have to changed to vite gng. for component
cool huh? so yeah i use tailwind too bcs i want to and uhh i love the glassmorphism <3
YOOOOOOOOOO alot have been adding nowwww!! lesgooooo, first of all the window is finnallly grabable and it can be closedd. second i added smooth cursor, i got the idea from @Hexaa !!!. for now thatās all of it!!...
|
1792774055.6849623
|
1793378855.6849623
|
|
69649
|
ArsyWatch by @arsyad | Stardance
|
arsyad
|
1
|
2.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T14:30:35Z", "hours": 2.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Day one on ArsyWatch. The idea: an ESP8266 sits in my house and scans the WiFi around it, plus counts how many devices are in the air. Every 30 seconds it sends that to my VPS. Then I get a dashboard that shows which channels are crowded and how many networks sit on each one. Mainly I want it to tell me when to switch my routerās channel. Barely wrote any code today. Most of it went into getting the server ready. Installed cloudflared so I can tunnel in without opening ports, then apt started complaining about a pending kernel upgrade. Running kernel is 7.0.0-1006-aws, the installed one is 7.0.0-1014-aws, so nothing new loads until I reboot. I wanted the ingest endpoint running tonight and now I have to reboot first. Not a big deal, just annoying. One decision I did make: VPS instead of serverless. The ESP sends data every 30 seconds and the dashboard keeps an SSE connection open the whole time. Both want a process that stays alive, and serverless would fight me on it. Tomorrow: database schema, then the ingest endpoint.", "repo": "https://github.com/AmirSys-dev/ArsyWatch", "demo": "https://arsywatch.arsyads.dev/"}]...
|
[{"post_id": 79531, "ts": "202 [{"post_id": 79531, "ts": "2026-10-14T14:04:50Z", "hours": 2.0028, "text": "Day one on ArsyWatch. The idea: an ESP8266 sits in my house and scans the WiFi around it, plus counts how many devices are in the air. Every 30 seconds it sends that to my VPS. Then I get a dashboard that shows which channels are crowded and how many networks sit on each one. Mainly I want it to tell me when to switch my routerās channel. Barely wrote any code today. Most of it went into getting the server ready. Installed cloudflared so I can tunnel in without opening ports, then apt started complaining about a pending kernel upgrade. Running kernel is 7.0.0-1006-aws, the installed one is 7.0.0-1014-aws, so nothing new loads until I reboot. I wanted the ingest endpoint running tonight and now I have to reboot first. Not a big deal, just annoying. One decision I did make: VPS instead of serverless. The ESP sends data every 30 seconds and the dashboard keeps an SSE connection open the whole time. Both want a process that stays alive, and serverless would fight me on it. Tomorrow: database schema, then the ingest endpoint."}]...
|
Title: ArsyWatch by @arsyad | Stardance
Devlogs:
Title: ArsyWatch by @arsyad | Stardance
Devlogs:
Day one on ArsyWatch. The idea: an ESP8266 sits in my house and scans the WiFi around it, plus counts how many devices are in the air. Every 30 seconds it sends that to my VPS. Then I get a dashboard that shows which channels are crowded and how many networks sit on each one. Mainly I want it to tell me when to switch my routerās channel. Barely wrote any code today. Most of it went into getting the server ready. Installed cloudflared so I can tunnel in without opening ports, then apt started complaining about a pending kernel upgrade. Running kernel is 7.0.0-1006-aws, the installed one is 7.0.0-1014-aws, so nothing new loads until I reboot. I wanted the ingest endpoint running tonight and now I have to reboot first. Not a big deal, just annoying. One decision I did make: VPS instead of serverless. The ESP sends data every 30 seconds and the dashboard keeps an SSE connection open the whole time. Both want a process that stays alive, and serverless would fight me on it. Tomorrow: database schema, then the ingest endpoint.
Ships:
Day one on ArsyWatch. The idea: an ESP8266 sits in my house and scans the WiFi around it, plus counts how many devices are in the air. Every 30 seconds it sends that to my VPS. Then I get a dashboard that shows which channels are crowded and how many networks sit on each one. Mainly I want it to tell me when to switch my routerās channel. Barely wrote any code today. Most of it went into getting the server ready. Installed cloudflared so I can tunnel in without opening ports, then apt started complaining about a pending kernel upgrade. Running kernel is 7.0.0-1006-aws, the installed one is 7.0.0-1014-aws, so nothing new loads until I reboot. I wanted the ingest endpoint running tonight and now I have to reboot first. Not a big deal, just annoying. One decision I did make: VPS instead of serverless. The ESP sends data every 30 seconds and the dashboard keeps an SSE connection open the whole time. Both want a process that stays alive, and serverless would fight me on it. Tomorrow: database schema, then the ingest endpoint....
|
1793155946.5997777
|
1793242346.5997777
|
|
6590
|
Flower by @IvyMycelia | Stardance
|
IvyMycelia
|
2
|
104.2
|
1193
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-07-07T02:27:02Z", "hours": 27.0, "multiplier": 19.07, "payout": 503, "blessing": "neutral", "text": "The compiler is written in Flower itself and currently targets C, so this release was mostly geared towards making the type system have actual Flower semantics instead of a thin little blanket over whatever the backend happened to be doing. The big additions in v1.4 were: transparent type aliases real null nullable types as ?T == T | null semantic unions like int | string explicit narrowing with is explicit extraction with as That support now works across locals, parameters, return types, struct fields, and stable field-expression chains. The work had to touch parser logic, typecheck, narrowing, lowering, codegen, bootstrap, and then all the weird regressions those changes politely dragged into the room. It was.. a process for sure What Iām most proud of is that v1.4 pushed Flower toward a clearer identity that wasnāt defined by C as much anymore. This release also brought the docs back in line with the compiler, which was LONGGGGG overdue. If you want to test it, the main things to look at are the Better Types examples and the self-hosting flow. The compiler should bootstrap cleanly, the test suite should pass, and the examples now cover aliases, nullable values, semantic unions, inference, and struct/field narrowing behavior. For those who will be testing it, DO NOTE that I develop exclusively on my MacBook which is a UNIX system! I do not have the ability to properly develop and provide releases for Linux-specificalities or non-POSIX systems. Iām extremely sorry for this, but alternatively watch the provided video to see Flower in action :) If youāre not able to test it, watch this short (crappy) video instead: https://youtube.com/shorts/DyPtIru6cjY?feature=share", "repo": "https://github.com/IvyMycelia/flower", "demo": "https://github.com/IvyMycelia/flower/releases"}, {"ship_num": 2, "ts": "2026-06-18T16:00:30Z", "hours": 38.0, "multiplier": 18.19, "payout": 690, "blessing": "neutral", "text": "Flower is a self-hosted programming language for writing simple, explicit systems code without the abstraction bloat and OOP-heavy direction a lot of modern languages have. The compiler is written in Flower itself, currently targets C, and follows a straightforward pipeline: lexing, parsing, module loading, typechecking, and code generation. Over the past few months, Flower grew from a small lexer/parser/codegen experiment in C into a way bigger language project than I couldvāe imagined. This wasnāt my first attempt at a language, but it has been my favorite! I implemented compiler-enforced module semantics, stronger type-aware codegen, real boolean support, real string support, and a small standard library foundation. Strings now have equality, .length, indexing, and explicit casts to and from @char , while modules support exported prop declarations, aliases as namespaces, and private-by-default top-level declarations. The hardest part was bootstrap stability. I ran into idempotency failures, parser edge cases, compiler corruption scares, and plenty of my own bad logic. A lot of the challenge was getting new features to work not just once, but consistently enough for the compiler to rebuild itself cleanly. One bootstrap it succeeds, and then the next Iām scrambling to figure out why the new binary executable has a corrupted parser despite just working (Still havenāt fixed that yet! It.. was really confusing and Iāve got no clue why it happened lol). Iām proud that I kept pushing through that and ended up with something much more fun to use than where I started ā I mean, I donāt even have to write that much C anymore!! If people want to test Flower, the important thing to know is that it is self-hosted and still experimental, but it does work. The repo includes a bootstrap path, a test suite, and example programs covering types, control flow, memory, imports, strings, and bools. The current release is focused on making the core language feel real and usable before moving on to a larger standard library and a future non-C backend, so donāt be surprised if a C file is shoved in your face!", "repo": "https://github.com/IvyMycelia/flower", "demo": "https://github.com/IvyMycelia/flower/releases"}]...
|
[{"post_id": 79537, "ts": "202 [{"post_id": 79537, "ts": "2026-10-14T14:44:10Z", "hours": 10.3042, "text": "Integers, Integers, Integers Hello!! Been a while :) Lately I have been working on v1.6. I call it the āUsefullnessā update ā rhymes with Grug ā because it adds a ton of long awaited features and various convenience implementations Flower DESPERATELY needs. For example, currently the progress has to do with v1.6.1, or Fixed-Width Integers . When it comes to systems programming and in-general efficiency, having various integer sizes is important as it provides an additional layer of manual control over memory and sizes. I know I would have to add them eventualy, so why not put them at the start of the Usefulness update?? Iām sure theyāll come in handy later on. What Actually Changed? Well, for starters, thereās now fixed-width integers (yay)! Theyāre built in types, so you declare them as you would with any other atom / primitive: type Byte = u8 type Choice = Byte | u16 type OptionalByte = ?Byte struct Packet { pair: Byte[2], size: Choice, owner: OptionalByte } A whole bunch of commits and integer-specific changes regarding indices, arity, unions, nullables, etc etc etc have been made, and they all wonāt fit here so instead, take a look at the current branch ! Whatās In Store? Plenty more features, you can assure yourself! Thereās maybe 6 or 7 ā I swear ā or so commits left for this specific addition, and after that a lot more features laid out in the roadmap for 1.6! As always, thanks for sticking around and watching the fiasco that is this project become more and more estranged with every hour. Love yāall!! Ivy <3"}, {"post_id": 75225, "ts": "2026-09-29T15:04:00Z", "hours": 9.9331, "text": "Integer Types, Parser Fixes, and Segfaults! Phew ā this one was biiiiiggg. Flower is pretty much just a glorified C transpiler, which is NOT what I want for it! In order to move on, the data has to be handled explicitly by the FloC. So essentially, I implemented i8 , u8 , i16 , u16 , i32 , u32 , i64 , and u64 . For now, int canonically refers to an i32 value. A New Era? With these new literals, the old hoist-sized representation had to go. The decimal source text is preserved, meaning values such as 18446744073709551615 remain after parsing without causing any overflow. Types are picked up from declarations, assignments, function arguments, return values, field writes, array-element writes, * breath in * and binary expressions! Oof, that was a mouthful. That, of course, resulted in proper errors for things like: 256 assigned to u8 ā1 assigned to an unsigned type values beyond u64 unconstrained literals outside the default i32 range I Hate Memory During printing, every width is handled. Integer conditions retain existing zero / nonzero behavior, and literal types print their values rather than a character. Halfway through, I ran into sudden segfaults and memory leaks. I was taken aback, because I didnāt even change anything parser related yet. Turns out, I forgot an assignment in a declaration, which apparently the parser wasnāt able to handle (whoops!). Anyways, I fixed it by propagating errors through the compilation process, so the compiler doesnāt try to typecheck or code gen if the parser reports back errors, and instead will print them out. And thatās it! Not thatās it, but thatās all Iām going to explain for now. More specifics available on the GitHub, of course. Speaking of GitHub thank you so much to S1monr3dst0ne07 on GitHub for fixing some memory leaks in the previous version of Flower ā I forgot to prune allocations before returning from a function :p Love yāall!! <3 P.S.: So glad I gave up on documentation, I was genuinely dreading workong on the project and thatās why Iāve been ianctive for a long time :c"}, {"post_id": 53525, "ts": "2026-08-24T03:18:35Z", "hours": 9.7706, "text": "Hey, itās been a while! Iāve been finding it difficult to stay motivated for this project, especially with how the new payout system works and just my in-general inability to keep commitment despite having a lot of passion. That said, I am going back to working on this diligently, and I think to start Iām going to cut down on the documentation by making perhaps one or two changes, and then going right back to the compiler work. Documentation writing has not been the most fun for me, especially with how long it takes and how itās so difficult to not only write language reference that works, but also keeping the same whimsy Flower should have. Thank you to everyone whoās been following this journey, and I canāt wait to see yāall later!!! With Love, - Ivy <3"}, {"post_id": 26743, "ts": "2026-07-11T18:25:46Z", "hours": 9.1964, "text": "Devlog: v1.5.1 ā v1.5.5 Following all of the changes Flower has undergone, I felt it was time for some much-needed documentation. On paper this was supposed to be fairly quick, simple, and not require much brain power. Unfortunately for me I got a bit too over-zealous, and included things I thought should work, but in reality hadnāt. For example, in a lot of the code snippets Iād have something like: for i in range 0..10: print(i) end Printing non-string values was not yet supported in Flower. To fix this, I took a small detour back to v1.4 and implemented support for it ā mostly in a single codegen case: if ast.data._print.value_type.base == TOKEN_FLOAT or ast.data._print.value_type.base == TOKEN_DOUBLE: fprintf(out, \"printf(\\\"%%f\\\", \") gen_expr(ast.data._print.value, out, src) fprintf(out, \");\\n\") end Afterwards I added more smoke-tests in examples/io/print.flo . Every few runs, however, Iād get a segfault. This was especially odd because it wasnāt simply an error but rather a silent memory bug. Eventually I found out where it was originating ā thanks, ASan! Turns out after the new type system changes, I had forgotten to initialize some values to null / 0 in for loop handlers and a few other places. I just added typeInfo.data = null / 0 where applicable and it fixed the issue! What is v1.5, and why is this devlog so long? To answer the latter first.. I lowkey just forgot to post a devlog for the first two docs I made. Thatās it. For the former question, v1.5 is supposed to be explicitly a documentation pass. First thing I worked on was structure. I cleaned up the docs layout, moved things toward a more consistent lowercase docs/ tree ā I had been trying for so long to do that and I just finally got it to work ā and wrote down the documentation process itself so new pages arenāt just floating about. The point was to try and make the docs feel like a book instead of a folder full of unrelated notes. I wrote and checked the language pages for types, functions, and control flow by reading the compiler itself, not by trusting my (poor) memory. That meant checking parser rules, typecheck behavior, codegen boundaries, and example files before writing anything solid. Types especially needed this, given how Flower now has enough real type machinery that the docs can quickly go from being coherent to completely incorrect: nullable sugar, semantic unions, explicit casts after narrowing, alias behavior, current member limits, and the difference between what the language wants to become and what the compiler supports currently. Functions and control flow had a similar issue. I had to document prop , return rules, direct call forms, logical conditions, range-based for , and the rough edges like break and continue not yet being enforced cleanly as loop-only. That kind of thing is small until someone learns the language from the docs and hits the edge head-first (been there, done that). What Now? Iām just going to keep writing docs. Maybe do one devlog for every new doc, or a batch of docs, who knows! I certainly donāt :p"}, {"post_id": 23761, "ts": "2026-07-06T21:49:25Z", "hours": 0.6008, "text": "Devlog: Syncing Flowerās Docs Back to Reality Just a doc cleanup lol. No code change or compiler updates. Probably did more than needed for now but oh well! The mismatch was REALLY bad. The old docs preserve old assumptions, and someone reading them could walk away with a version of Flower that no longer really exists (or, in some cases, doesnāt exist yet or never ever existed)! What changed I updated the docs that had drifted the most from reality (relatable): README.md now reflects the current type-system shape ROADMAP.md treats v1.4 as accomplished the v1.4.0 milestone doc now includes more of the outcome, not just the original plan contributor docs no longer have stale semantics structure.md is more accurate to what Flower currently is, and what still needs a fuller rewrite later Yea, thatās it."}, {"post_id": 23618, "ts": "2026-07-06T18:01:45Z", "hours": 1.6556, "text": "Devlog: Finishing Nullable Field Narrowing At this point, Flower could already narrow semantic unions through field access in the is / as case, and nullable field checks were supposed to be the obvious follow-through: if maybe_box.value != null: label: string = maybe_box.value as string end Instead, I had forgotten to remove a LOT of stale code, and thus part of it was still behaving like only plain local variables could ever be narrowed. There was also a second, smaller mismatch hiding, where null in type position was not lining up with the compilerās actual internal null representation. ?string and string | null werenāt leading to a congruent output and at times were wobblier than they should be. So the fix was mostly cleanup, but the meaningful kind: make null in type syntax lower the same way the compiler expects remove the stale var-only branches in nullable narrowing let stable field paths like maybe_box.value and holder.box.value narrow properly The funny part is that this felt bigger initially than it actually was once fixed. Nothing fundamentally new had to be invented, I just had to stop the old code from interfering with the newer code, which once I figured out how to do so it was quite quick. I spent an embarrassingly long time figuring it outā¦"}, {"post_id": 22284, "ts": "2026-07-04T17:48:44Z", "hours": 1.8161, "text": "Devlog: Letting Union Narrowing Follow Field Access Before v1.4.13 , union narrowing only really worked when the thing being narrowed had a variable name due to almost every similarity check relying on name_start and name_length . This was dumb, because semantic unions already knew how to test tags and extract members. Codegen was not the issue, but rather the annoying part was that the typechecker could remember this: if value is int: n: int = value as int end but not this: if box.value is int: n: int = box.value as int end So I still had to do a little temp-variable ritual: tmp: Value = box.value if tmp is int: n: int = tmp as int end Which was gross. Not necessarily catastrophic, just gross and annoying. I wanted needed convenience What changed The compiler was remembering narrowings by variable name, not by expression shape, so box.value looked obvious in source (to me, at least), but to the typechecker it was basically some random expression and not something it could reliably recognize again later. A variable name already had a stable identity, whereas field access chain did not. So the change was to let narrowable expressions represent more than just AST_VAR_REF . For now, that only means stable dot-access chains. The typechecker can record a narrowing for an expression like: box.value and then recognize the same expression later when a cast shows up. So this works directly now: if box.value is int: n: int = box.value as int end Same for the other union members, like string . The detour My first example accidentally wandered into a different feature: if maybe_box.value != null: That exposed a real nullable-field-guard gap, but that is not what this was supposed to be about. Very rude of the test case to have ambition hmph >:( Where this leaves it Semantic union narrowing now persists past field access ā at least for stable dot-access chains ā and the temp-local is no longer needed. Butttt now I gotta work on nullable-field-guards, ugh (hehe)"}, {"post_id": 21926, "ts": "2026-07-04T03:34:19Z", "hours": 0.4592, "text": "Devlog: Direct Semantic Union Parameters Now instead of having to do this workaround: type Value = int | string func accept(value: Value): bool You can just pass semantic unions directly: func accept(value: int | string): bool That was it. All I had to do was remove a stale type_error clause in register_params and allow binding variables. Then I updated the two relevant accept functions in /examples."}, {"post_id": 21751, "ts": "2026-07-03T20:51:30Z", "hours": 4.9086, "text": "Devlog: Making ?T Actually Mean T | null Before v1.4.10 , ?T was treated as its own nullable system and not really integrated with the rest of the semantic unions. This was unideal, because it created a separation of logic which was cumbersome to maintain. The idea was to make the following be the default: ?int == int | null ?string == string | null ?@int == @int | null Prior to the refactor, nullable types were still mostly pointer-oriented. That worked when ?T basically meant āmaybe this pointer is null,ā but it did not really fit anymore once semantic unions became actual runtime values. If Flower has T | null , then ?T should use that instead of being its own special thing. This is a more pragmatic choice, as it keeps the compiler easier to manage and update later on. What changed Typecheck now lowers ?T into the same semantic-union machinery used by normal unions. That means nullable values now go through the same general path as union values: null checks use union-aware narrowing narrowed nullable values can be extracted with as codegen emits tagged union storage assignments pack into the right union member So this now works as an actual nullable flow: maybe: ?@int = raw if maybe == null: return false end real: @int = maybe as @int The annoying part is that Flower has to track two things at once: the type the programmer is allowed to see after narrowing, and the actual union shape that remains underneath it. After the guard, maybe behaves like an @int . But codegen still has to remember it came from @int | null , because apparently the compiler cannot simply āvibeā its way through storage layout. Tragic! The bugs that annoyed the heck out of me Most of the work was not surface syntax. The syntax was just standing nearby looking innocent. The actual bugs were in the places where Flower knew āthis is non-null now,ā but then forgot how to lower, such as: narrowed nullable values falling back to raw C casts like (int*)(maybe) false branches of == null / != null narrowing to the wrong side (this was my fault lol) null getting packed into the wrong union member That last one was the rude one. For ?@int , generated C could end up doing something like: . tag = 1 , . m0 = NULL instead of packing into the actual null member. So the value looked almost right, but the tag/member pairing was wrong. Then later null checks would fail, because the compiler had technically put null somewhere. Just not the correct somewhere. Very helpful. The fix was separating two questions I had accidentally merged: is this type compatible with this union? which exact union member should this value occupy? Those look related, but they are not the same question. Flower was using the first answer for the second problem, and then acting surprised when everything became soup. Where this leaves Better Types ?T now lowers through the same path as T | null , which means null checks, narrowing, extraction, and storage all line up with the semantic union model. This should make later work cleaner, such as nullable inference, nicer union ergonomics, maybe pattern-like narrowing eventually. Not easy. I am not saying easy near a compiler. That is how they hear you. You do not want them to hear you .."}, {"post_id": 19626, "ts": "2026-07-01T00:18:08Z", "hours": 0.4472, "text": "Devlog: Teaching Flower to Understand Guard Clauses gave Flower branch-local inference. Last update, I added support for branch-local inference, so the compiler could understand things like: if maybe == null: return false else: real: @int = maybe end and: if value is int: return false else: s: string = value as string end That was an improvement, but it still meant narrowing stopped at the end of the branch. That meant stuff like returninging in some conditions still did not really work as naturally as it should: if maybe == null: return false end real: @int = maybe or: if value is string: return false end n: int = value as int In v1.4.9 I fixed that. What changed Now narrowing propagates past very obvious guard clauses. If one branch definitely returns and the other falls through, the compiler now carries the interpretation forward after the if . This means that the compiler can now understand: after if x == null: return ... , x is non-null after if x is string: return ... , a two-member semantic union can narrow to its remaining member I kept this intentionally conservative for now. The compiler is not doing full control-flow analysis yet. It is only recognizing the simplest and most explicit early-exit shape. How it works The main addition was a small semantic check for ādoes this branch definitely return?ā Right now that means: direct return if where both branches definitely return Once the compiler knows one side exits and the other survives, it applies the branchās narrowing to the following statements. Yea.. thatās it lol."}, {"post_id": 19014, "ts": "2026-06-30T05:39:45Z", "hours": 1.2028, "text": "Devlog: Adding Obvious Branch-Local Inference to Flower Before this, narrowing mostly worked in the obvious ātrue branchā cases: if maybe != null: real: @int = maybe end and: if value is string: s: string = value as string end But the else branch was still kind of standing there empty-headed, even when the meaning was extremely obvious. Like, if this happens: if maybe == null: return false else: real: @int = maybe end then inside the else , maybe is clearly not null. So now it doesnāt!! What changed Flower now does branch-local narrowing in else for small, explicit cases. That means these now work: if maybe == null: return false else: real: @int = maybe end and: if value is int: return false else: s: string = value as string end It is only applying inference when the condition says something directly and the opposite branch has one obvious meaning. Nullable narrowing For nullable pointer-like values, Flower now understands both sides of simple null checks: if x != null narrows x to non-null in the if body if x == null narrows x to non-null in the else body the opposite side can narrow to null when that is the only meaning left Semantic union narrowing The same idea applies to semantic unions, but a bit more āheld back.ā Essentially, if Flower sees: if value is int: then the if branch narrows to int , like before. Now, if the union only has one other possible member, the else branch can narrow too. So for: int | string the else after if value is int can be treated as string . This is not full control-flow wizardry, since it doesnāt reason across deep boolean chains, early-returns, or giant branches yet. It is deliberately small and local, because I do not want Flower āhelpingā so much that I need a detective board to figure out what type something is."}, {"post_id": 18478, "ts": "2026-06-29T17:18:49Z", "hours": 0.8039, "text": "Devlog: Letting Semantic Unions Work In Functions After getting semantic unions working in local declarations, the next problem was fairly obvious (and in my roadmap hehe). This did not work before: func make_value(): int | string return 7 end func accept_value(value: int | string): bool return value is int end Which was annoying, because int | string was already a real union type at this point. Flower could use it in locals, it could pack assigned values, it could check variants. But if I returned 7 from a function declared as int | string , or passed 7 into a parameter expecting int | string , the compiler did not know how to carry that union-lowering information across the boundary. This has been one of the easier changes Iāve made in a long while. It compiled properly first try (if you ignore a tiny misspell I made which I fixed really quickly), and there were no prior hidden bugs that surfaced. This.. is too suspicious. What changed The compiler now carries semantic union info through: function parameters function returns imported alias calls If a function expects: int | string and I call: accept_value(7) typecheck records that 7 needs to be packed as the int member of that union. Same for returns: func make_value(): int | string return 7 end That matters because codegen cannot guess later due to the separation of responsibilities Iāve laid out. By the time Flower is emitting C, it needs to know which tag to set and which member to write. Lowering it properly Codegen already knew how to pack union values for declarations and assignments. The missing part was doing the same thing for call arguments and return statements. So now a value can be packed into a tagged union when it is: stored locally passed into a function returned from a function Alias calls got handled too, so things like: remote.accept(11) remote.make_string() do not become their own weird little cursed island. Why this mattered Without this, semantic unions only worked as long as I never organized my code. They worked in local tests, but not in helper functions, imported providers, or normal inputs and outputs. Now union values can actually move around the program instead of being trapped in the one scope where they were declared ā and for me, forgotten! Very exciting, the union can leave the house. They grow up so fast āāĢ“Ģ ā āĢ“Ģā"}, {"post_id": 18151, "ts": "2026-06-29T05:17:03Z", "hours": 3.3186, "text": "Devlog: Semantic Unions Become Actual Values (Part I) In v1.4.6 , I made semantic unions actual runtime values instead of just parsed/typechecked shapes. Before this, Flower could understand: type Value = int | string as a type. It could point at it and say, āyes, that is a union,ā but that was mostly theoretical. The goal was to make this work-work for realsies: type Value = int | string value: Value = 7 if value is int: n: int = value as int end value = \"Ivy\" if value is string: s: string = value as string end That meant Flower needed more than TypeInfo.is_union = true . It needed a full path from syntax, to type proof, to lowered storage, to runtime extraction. Otherwise unions would just be fancy typechecker thingy-ma-bobbies, which is not very useful when the backend still emits C. What changed Instead of treating a union as a vague āone of these types, probably,ā Flower now lowers it into a tagged structure. Conceptually, this: type Value = int | string becomes something like: struct Value { int tag ; union { int as_int ; flower_string as_string ; } data ; }; Not the final sacred form forever, but that is the shape of it: a tag saying which variant is active, plus storage for the possible members. Since Flower emits C right now, the lowering is C-shaped. I am not fully sure how I want this to look in ASM yet, but I do know it would be way more technical, and uglier. This required a few things to play nicely with one another: if value is int creates a union proof the guarded branch stores narrowing information value as int is only allowed after proof assignments pack values into the right tagged member explicit casts extract the right member from storage Otherwise the compiler is just writing checks its own backend cannot cash. The part that makes it ACTUALLY semantic For pointer narrowing, if value is T mostly refines how the compiler treats an existing value. For semantic unions, the check also becomes a runtime tag test. So this: if value is int: means: check the active tag of value , then inside this branch, treat it as the int variant. Then this becomes valid: n: int = value as int because the branch already proved the active variant. Without that proof, value as int should not be casually allowed. Flower is supposed to be explicit, not psychic, and I am not confident enough yet to implement a proper intuitive implicit checker without summoning something cursed. Assignment and extraction This: value: Value = 7 now packs 7 into the int member and sets the tag to the int variant. Then this: value = \"Ivy\" does the same thing, but for the string member. So a semantic union is not just some bytes, but rather a tagged runtime object where Flower knows which member is active. Then explicit casts like: value as string can lower into extracting the string member, but only when the typechecker has accepted that the operation is safe in that control-flow path. Why this checkpoint matters Flower can now store variant values, prove which variant is active, and require explicit extraction instead of relying on random magic I threw together. The flower has grown another concerning little organ."}, {"post_id": 16395, "ts": "2026-06-26T17:55:41Z", "hours": 2.0825, "text": "Devlog: is Checks v1.4.5 added is checks, mostly so code like this can work: if maybe_ptr is @int: real_ptr: @int = maybe_ptr end The idea is (fairly) simple: if the condition proves maybe_ptr is an @int , the inside of the branch should be allowed to treat it like one. Flower did not know how to do that before. It knew what a variable was declared as, but it did not really learn anything from control flow yet. Now it can, at least for the pointer/nullable-ish cases I care about first. This touched the parser, AST, typechecker, narrowing logic, and codegen. So, naturally, the āsmall featureā went everywhere. Iād actually consider this one of the bigger refactors so far, mostly because it added a new TypeAtom structure. Before this, types were still a bit too attached to the places they appeared, and all fell under the TypeInfo . That worked for simpler declarations, but is checks needed type syntax to have something the compiler could pass around to use for comparisons, validations, and narrowing. The parser had to recognize the new expression shape. The AST had to store the left side and the tested type. The typechecker had to make sure the test was allowed and not totally garbage. Then the narrowing logic had to say, āinside this branch, this variable has the proven type of x and therefore we wonāt flag you for being an idiot.ā That last part was where the bug goblin lived. Iām calling them a goblin because they were sneaky (and I also think itās quite a funny and cute name). For a while, Flower had applied narrowing from the if body instead of the if condition, which meant the compiler saw this: if maybe_ptr is @int: real_ptr: @int = maybe_ptr end and somehow still failed on the assignment inside the branch. Very helpful. Thank you, compiler. EVen though itās obviously 100% my fault, I made the compiler, but oh well!! Once I changed the narrowing step to inspect the actual condition expression, it started behaving like it should. The typechecker could see maybe_ptr is @int , attach that narrowed type to the branch scope, and allow maybe_ptr to be used as @int inside the guarded block. For now this explicitness is how I want it. There may come a time in the near future where I decide some implicity is ok, but weāll see ;) is checks are the first real step towards control-flow-aware typing in Flower. Not full union support yet, but definitely the beginning of that road soon to come. Right now it mostly helps with nullable and pointer-like cases. Later, the same idea can support richer unions, better narrowing, and more type-driven control flow without making the programmer manually restate everything the compiler should already know. Also, it bootstrapped cleanly twice ā which.. is obviously the bare minimum, but still!!"}, {"post_id": 15458, "ts": "2026-06-25T04:05:50Z", "hours": 2.4619, "text": "v1.4.4 Devlog: Giving Flower Real Semantic Union Types I made it so that semantic unions are now in Flowerās parser and type system ā but not yet its codegen. The goal was to support types like: value: int | string next: @Node | null type Result = int | string Whatās new The parser now understands | inside type positions and builds semantic union type information instead of relying on those old plain aliases or backend-shaped hacks. On the typecheck side, unions are now carried through normal type copying and alias resolution. That means named aliases like: type MaybeName = string | null make sense after resolution, instead of collapsing into nonsense. The typechecker also now accepts union-compatible usage in the places that matter for a foundation: variable initialization assignment parameter passing return checking alias resolution So if a value matches one union member, it is accepted. This is sorta implicit behavior, but I think it gets a pass due to its somewhat explicit nature? What it does not do yet This version was intentionally strict about using unions as values. You cannot yet directly: index a semantic union access a field on a semantic union use arithmetic / comparison operators on one print one directly Instead, Flower now requires an explicit cast before using a union value that way. That may sound harsh, but it is the right restriction.. for now. There is not any narrowing yet, so pretending unions were fully usable would just make the language lie and spit out 2,000 errors. Where this leaves v1.4 Flower now has: transparent type aliases null as a real type-system concept pointer-first nullable types semantic union type representation The next step is the part that will make unions actually usable rather than merely legal: narrowing with is better explicit extraction with as eventually making ?T truly become T | null instead of remaining pointer-first for now No fun screenshot this time :p just frontend work for now⦠Ivy, signing off <3"}, {"post_id": 14511, "ts": "2026-06-23T17:31:39Z", "hours": 1.8206, "text": "Devlog: Adding Pointer-First Nullable Types to Flower I worked on giving Flower its first real nullable type surface without being overambitious and pretending the compiler is ready for full optional-everything semantics yet. The new syntax now works like this: ptr: ?@int = null text: ?@char = null That means there is now an explicit way to say āthis pointer-like value may be absent,ā instead of relying entirely on raw pointer habits from C (If you couldnāt tell by now, I despise C). What changed The main work was split across lexer, parser, and typecheck. I added: ? as a type marker in type positions is_nullable tracking in TypeInfo type rules for nullable pointer/reference values explicit compatibility for: assigning null into nullable pointer-like types comparing nullable values against null casting between @T and ?@T I also kept the scope intentionally narrow: this implementation is pointer-first nullable support , not full nullable scalars. So ?@int makes sense right now, but ?int is still deferred until I make a better semantic union / optional representation for plain values. Why this matters It would have been easy to overreach here and claim ānullable types are done,ā but that would have been a big phat lie. Pointer-like nullability lowers naturally enough with the current backend and current compiler model. Scalar nullability, however, does not. Once you let int or bool become nullable, you need a more real representation for āhas value / no value,ā and that belongs in the later union work, not here. Result explicit absence compiler-owned semantics better future unions stronger type meaning without hidden magic The next real step after this is not more patching around null ā I consider that done for now ā but instead giving Flower the deeper machinery needed for nullable non-pointer values and semantic unions later in v1.4 so it doesnāt come back to bite me in my butt."}, {"post_id": 13935, "ts": "2026-06-22T21:20:58Z", "hours": 0.355, "text": "Devlog: Formalizing Flowerās Null Foundation Flower already had some of the pieces for null , but they were a bit scattered. The goal here was to make it explicit, consistent, and safe before moving on to nullable syntax like ?T or full union-based nullability later in v1.4 . Another shorter devlog, but still important and distinct enough for me to think āHmm devlog time? Yes, devlog time!ā What changed The main work was in typechecking. I added to the compilerās idea of what null is, how it is represented internally, and what kinds of values are actually allowed to accept it. Rather than letting null-related behavior stay implicit across a few checks, null now follows a clearer rule set: null has one centralized internal type representation pointer-like values can explicitly accept null null comparisons and assignments now go through the same semantic path Why this matters This isnāt all that important on its own, but it matters a lot for where Flower is going next. If null is not defined well, then later features like: ?T better unions smarter narrowing more expressive type flow all become more error-prone (or so I assume given my track record) than I want need them to be. Validation I also expanded the example coverage so null : it now has dedicated behavior checks around assignment, passing values around, and comparison behavior."}, {"post_id": 13918, "ts": "2026-06-22T20:30:15Z", "hours": 1.0089, "text": "Devlog: Fixing Flowerās Compiler Process So It Stops Fighting the Host This wasnāt really about language design at all buttttt it is much more embarrassing , AND more important: Flowerās compiler process itself was too fragile. The immediate issue showed up on Linux, specifically NixOS (thanks shipwrights <3). The build flow was assuming too much: a previously existing bin/Flower could be reused safely bash would exist at the expected path clang would always be available the checked-in compiler binary would be runnable on whatever machine the repo landed on That worked well enough on my machine until it didnāt. On NixOS ā and by extension probably any other machine without the prexisting binaries I had ā it broke: make targets were inconsistent, the shell script failed on interpreter assumptions, and the compiler binary itself could be the wrong format for the host. What changed The fix was to separate āthe compiler source existsā from āthe current compiler binary is usable on this machine.ā The build process now starts by compiling a fresh host-native bootstrap compiler from bin/Flower.c , instead of trusting whatever happens to already exist in bin/Flower . That means the flow is now: bin/Flower.c -> host-native bootstrap compiler -> new Flower compiler -> self-check instead of: maybe existing bin/Flower -> hopefully works -> maybe bootstrap Ok well thatās kinda a lie; it still relies on hopes and dreams to bootstrap sometimes. BUT itās MUCH safer! And now everyone gets to experience crippling bootstrap anxiety, instead of being met with a failure before the actual compiler gets to.. well, do its thign! I also cleaned up the surrounding tooling: switched the bootstrap script to portable sh restored a clearer build / bootstrap / rebuild / test / clean structure made the compiler use CC and CFLAGS from the environment instead of hardcoding clang What this actually improves Flower is still not universally cross-platform yet. The compiler driver still has POSIX-shaped assumptions in places, and the emitted C can still depend on host APIs depending on what the program uses. Iām not yet at the point of wanting to make it completely universal, especially given how Iām only one person and with v2.0 coming up soon itād ā in my humblest of opinions ā be a waste of time. I am honestly grateful for people reviewing my code and otherwise viewing it catching onto details I have overlooked. My goal is to not make a ājust-barely working on my machineā project; I enjoy sharing development with others, and it hurts knowing people canāt appreciate code, whether it be mine or othersā, due to something as simple as hard-coded sh flags."}, {"post_id": 13822, "ts": "2026-06-22T17:23:16Z", "hours": 3.7814, "text": "Devlog: Making Flowerās Type Aliases Transparent This version was simple to develop on paper (and even in practice it wasnāt too bad, only around 4 or so hours!): type Count = int type Total = Count type Name = string and then have those aliases behave like the real type everywhere: n: Count = 12 total: Total = identity(n) name: Name = \"Ivy\" if name != \"Ivy\": return false end if name.length != 3: return false end That meant aliases could not just be parsed and stored, but rather had to be transparent to the compilerās semantic checks. What changed I added type alias declarations to the AST, parser, and type environment, then added the ability to resolve aliases in typechecking before comparing types. That included: return type checks variable initializers function call arguments binary comparisons string-specific comparison logic struct field access The important rule here is that aliases are semantic, not codegen-facing. Count should behave as int , Name should behave as string , and chained aliases like Total -> Count -> int should collapse correctly. In the future, especially post v2.0 , this could change and custom types might become real ā but for now, theyāre just aliases. The bug that exploded bootstrap The first real failure was not in aliases themselves, but in function argument checking. Inside check_call_args(...) , the compiler was resolving the argument expression into expected_type instead of arg_type . That overwrote the parameter type, left the actual argument type uninitialized, and caused the second bootstrap stage to explode into over a thousand misleading errors. This was not a pre-existing issue, it was instead from human error (my error) during the initial implementation where I accidentally put the wrong variable. Once that was fixed, the remaining failures were much more helpful than the bright flash of red and āTypecheck failed with 1224 error(s)ā message! Where this leaves v1.4 With the first step toward ābetter typesā done, aliases are no longer just syntax. That gives v1.4 a solid base for whatever comes next in the type system without having to fake around raw names. During this whole dev session, I did discover that a whole lot more of the source code was left using legacy work-arounds: int instead of bool , name_start; name_length and @char instead of string . In all fairness, some of these arenāt exactly the easiest to refactor. However, I will probably hold off on refactoring the codebase until either right before v2.0 , or right after. Just know itās on my radar ;)"}, {"post_id": 11351, "ts": "2026-06-18T15:46:42Z", "hours": 1.4231, "text": "Devlog: Cleaning Up v1.3 For Release After many hours of work, bool and `string finally became real, and it was time to cleanup the mess I left behind from the versionās development. Mainly the only thing worked on was some cleanup: roadmap now reflects actual v1.3 features and implementations updated README and contribution documents to match the current compiler pipeline cleaned up string examples so they have the full intended v1.3 style instead of some leftover testing usage pushed the compilerās version to 1.3.0 updated help / usage text so it matches the new output-path and auto-run behavior Prior to this, if I had just merged and shipped, the release wouldvāe been messy: README, Contributing, example files, and guidance commands were all mixing older details which made it confusing ā even for me ā when trying to explore the language and what it has to offer. For a bootstrapped compiler especially, making sure everything is cleaned up and polished is something that should not be ignored. Iām definitely guilty of overlooking this, but Iāve outlayed a whole plan for v1.3 unlike past versions, and part of it was setting up a proper versioning system and polishing its release as it goes. This format will be adopted in future versions, since itās just way cleaner and nicer to look at. Future work At this point, v1.3 is done and has implemented, at minimum, a concrete foundation for post-v2 bools and strings. Next will likely be more subtle improvements, and features that are currently reliant explicitly on C rather than Flower-hosted code. In order for v2.0 , Flower will have to be effectively independent from C if it wants to emit machine code. Currently I am planning on adding features such as Type Aliases and maybe a stdlib prior to that, but anything can change!! Thanks for being here for all of v1.3 <3"}, {"post_id": 11116, "ts": "2026-06-18T05:51:28Z", "hours": 1.7269, "text": "Devlog: Giving Flower an Internal cstr Foundation Even after Flower got a real string type, the compiler itself was still leaning directly on C-style string helpers for its own internal work. That meant a lot of Flower source was still semantically depending on libc behavior: !strncmp(...) strcmp(...) strlen(...) strcpy(...) strncpy(...) strdup(...) strrchr(...) That is not where I want the language to stay. What changed I added a new internal module: import \"src/stdlib/cstr.flo\" as cstr and gave it compiler-facing helpers like: prop func len(s: @char): int prop func eq(a: @char, b: @char): bool prop func eq_n(a: @char, b: @char, n: int): bool prop func copy(dst: @char, src: @char): @char prop func copy_n(dst: @char, src: @char, n: int): @char prop func dup(src: @char): @char prop func find_last(src: @char, ch: char): @char This helper module is essentially the precursor to a future strings.flo library that can be distributed. But for now, it uses a basic API layer purely meant for in-house usage. Then I migrated compiler internals over to that module across: src/parser.flo src/module.flo src/lexer.flo src/typecheck.flo src/codegen.flo src/globals.flo src/main.flo So instead of using C-string behavior directly everywhere, the compiler now goes through Flower-owned helpers first. The Compiler Strikes Back This was one of those changes that sounds mechanical until it absolutely is not. A big trap was that old code often relied on C comparison functions returning 0 on equality, so patterns looked like this: not strncmp(...) But cstr.eq_n(...) returns an actual bool , which means blindly rewriting those calls gives inverted logic. So this: if ps.alias_lengths[i] == tok.length and not cstr.eq_n(...): was completely wrong. It had to become: if ps.alias_lengths[i] == tok.length and cstr.eq_n(...): That bug showed up in alias parsing first, which made it especially cursed, because it caused normal namespace-style calls like cstr.eq(...) to stop parsing correctly and crash the bootstrap path in confusing ways. I spent way longer than I wish to admit on trying to figure out why it wasnāt playing nice. But, once I figured it out, it was a really quick fix (I literally just cmd + f ād not cstr and replaced it with cstr lol). Are we done yet..? This does not mean Flower is free from the C backend yet. It does mean something important, though: compiler logic is starting to depend on Flower-defined helper semantics instead of scattered raw libc calls. That is a much better stage for the future backend story, because when C eventually stops being the primary lowering target, the compiler will already have more of its own vocabulary. In other words, this was less about āremove Cā and more about āstop letting C define the languageās internal habits.ā Nah just kidding, I really wanted that bloated ābuiltin_c_callā stuff gone. Unfortunately I only managed to skim it, but thatās closer than before! Result After fixing the migration mistakes and the alias/parser fallout, the compiler bootstrapped successfully again. Flower now has an internal cstr layer, and compiler string handling is a little more its own."}, {"post_id": 11068, "ts": "2026-06-18T03:16:30Z", "hours": 1.2611, "text": "Devlog: Fixing Flowerās Output Driver and Starting the String Stdlib This checkpoint was really two different kinds of progress that ended up helping each other a lot. The first part was not glamorous, but it was necessary: Flowerās compile driver was tripping over its own default output naming. This was a known issue that I had been putting off, but for some reason it really annoyed me this time so I decided enough and to fix it. If no explicit output path was provided, the compiler would generate output.c , then strip the .c and try to emit a binary named output . That worked fine right up until the repo itself already had an output/ directory. At that point, linking failed because the compiler was trying to create a file where a directory already existed. Worse ā because it annoyed me more ā the driver logic was also mixing up āthe generated program exited non-zeroā with ācompilation failed.ā That became especially annoying during bootstrap, because the generated compiler binary would run without CLI arguments, print its own usage error, and then cause bootstrap to report failure even though codegen and C compilation had both succeeded. So I finally got off my butt and cleaned that up. Driver Cleanup The default output path now goes to: output/out.c which naturally produces: output/out as the binary. That avoids the old output filename collision. I also separated compile success from auto-run behavior: explicit output path: compile only default output path: compile, then auto-run if appropriate That means bootstrap no longer āfailsā just because the compiled compiler exits non-zero with missing arguments, and demo/test files can still run automatically when that is actually useful. This sounds like a small driver fix, but honestly it removed a lot of noise from string work ā and more ā immediately. String Stdlib Beginnings Once that output weirdness was under control, I could finish doing what I just started and actually wanted: making string behavior live in Flower instead of endlessly leaning on ad hoc C calls (Call back to last devlog, absolute ball knowledge!!). So I added the first real reusable helpers in src/stdlib/string.flo : is_empty(s) starts_with(s, prefix) ends_with(s, suffix) find_char(s, ch) These are intentionally simple. They mostly exist to prove that the current string support is now strong enough for normal library code to be written on top of it. Not incredibly useful, at least at the level the compiler needs, but at least I could translate some AP Comp Sci A into Flower hehe A string feature does not really feel ārealā until I can build helpers with the language itself instead of only teaching the compiler more special cases. The day I remove the builtin C handlers is the day Iām at peace⦠Validation To exercise that new library surface, I changed string_pass.flo to now act as a small pass file for the experimental library. Its job is not to be impressive. Its job is to answer a more important question: can I import string helpers, call them from normal Flower code, and get expected results through the full compile pipeline? At this point, yes. Where this leaves things This checkpoint did not remove all C string dependencies from the compiler. In fact, it removed essentially none! That is still a separate step, one that may even be in v1.3.7 ;) But it did establish two important things: Flowerās output/driver behavior is now much less annoying. We can start growing a real string library in Flower itself. That is a good place to be, because the next string work can build outward from a stable driver and an actual library surface instead of piling more special behavior into the compiler."}, {"post_id": 11013, "ts": "2026-06-18T01:18:51Z", "hours": 1.0825, "text": "Devlog: Adding String Indexing to Flower This one was fairly quick, and was about making one very normal-looking thing actually work: name: string = \"Ivy\" as string first: char = name[0] That sounds small, but once string became a real Flower type, indexing could no longer piggyback on the old āarrays and pointers onlyā behavior. The compiler needed to understand that string[index] is its own case. What changed I taught the typechecker to treat string subscripts as char . That means: string[index] now resolves to char the index expression must be an integer string indexing is readonly for now So this is valid: first: char = name[0] but this is not: name[0] = 'X' I wanted reads first, writes later. That keeps the rules simple while the string representation is still compiler-owned. Iām not sure how writes would work with a C backend, due to how āstringsā are allocated. Perhaps a feature for post-v2.0? Lowering it to C Since Flower strings currently lower to a struct with .data and .length , codegen needed a special path for string subscripts. Normal arrays and pointers still lower like: arr [ index ] but strings now lower like: name . data [ index ] That keeps the generated C valid without changing how regular subscripts work elsewhere in the language. So something conceptually like: This checkpoint also forced one strict-but-correct rule that required me to update a WHOLE SINGLE LINE (hehe): arg[i] = tolower(arg[i] as char) to arg[i] = tolower(arg[i] as char) as char Because tolower(...) is effectively treated as returning int , assigning it back into a char subscript needs an explicit cast. I kept that strictness on purpose. I do not want Flower silently narrowing values just because C would let it. Validation I expanded the string example coverage to check: string indexing returns the expected chars string[index] works alongside string <-> @char casts bootstrap still succeeds repeated bootstrap succeeds tests still pass Which, after all the recent bootstrap chaos, was very nice to see. Where this leaves v1.3 Now we can: store strings compare strings print strings inspect length index into them as char This should make it much easier to replace the builtin C functions with a Flower library in the near-near future."}, {"post_id": 10953, "ts": "2026-06-17T23:26:21Z", "hours": 3.3353, "text": "Devlog: Finishing Flowerās String Interop Bridge The last round got string into Flower as a real type. This round was about making that foundation actually work lol. The big problem was that once string became real, plain string literals started living in an in-between state: Flower wanted them to mean āFlower string,ā but the compilerās own source still has plenty of places that really mean āraw C string,ā like: RED: @char = \"\\033[0;31m\" if not strcmp(arg, \"help\") or not strcmp(arg, \"h\"): ... end Those cases worked before only because everything was basically pretending string literals were already @char . Once that stopped being true, bootstrap started throwing a fit (my spoiled child). What changed The main fix was to make string literal lowering contextual instead of all-or-nothing. If a literal is being used as a real Flower string , it stays a string . If a literal is being used in a C interop position, it gets lowered as a C string instead. That meant tightening a few compiler rules so this kind of thing works cleanly again: name: string = \"Ivy\" as string raw: @char = name as @char if strcmp(raw, \"Ivy\") == 0: print(name) end I also fixed top-level declarations so globals like: RED: @char = \"\\033[0;31m\" no longer generate nonsense like: char * RED = (( flower_string ){ ... }); which, unsurprisingly, C does not appreciate. The subtle compiler bug The nastiest issue wasnāt even the globals. It was that builtin C calls like strcmp , strncmp , printf , snprintf , and friends are not real Flower functions. That meant the typechecker could hit one of them inside a larger expression, fail early, and stop walking the rest of the tree. So something like: if not strcmp(arg, \"help\") or not strcmp(arg, \"h\"): could partially resolve one side, then leave the other side unprocessed. Very cool. Very stable. Definitely what I wanted. The fix was to add a temporary builtin C-call bridge so the compiler can recognize these calls well enough to keep type resolution and literal lowering consistent during bootstrap. Iām not happy with this fix by any means, but due to the limitations of emitting C, it was the only solution I found that made sense at the time. Tests and examples Once that stopped exploding, I finally wired string testing into the normal types suite instead of leaving it commented out and pretending Iād āget back to it later.ā The string tests now cover: string <-> @char casts string equality / inequality .length empty strings printing strings literal use in current interop cases And the full test suite passed with string included as a first-class part of Types on its first try . Now thatās what I like to see :D What this means This does not mean Flowerās long-term answer is āhardcode libc into the compiler forever.ā It means Flower now has a temporary interop bridge that keeps self-hosting stable while string is worked on. The actual language semantics stay in Flower; the backend-specific weirdness is just being tolerated for now so progress does not stall. In the near, Iāll probably replace all of the necessary C libs with minimal Flower-equivalents. Where this leaves v1.3 At this point, the string foundation feels much sturdier. Not ādone forever,ā not backend-agnostic, and definitely not free of cursed bootstrap energy ā but it works. The next work is no longer rescue work. It is actual forward work: string operations, stdlib basics, and eventually replacing this temporary C bridge with something cleaner when Flower grows past the C backend."}, {"post_id": 9012, "ts": "2026-06-15T01:03:21Z", "hours": 2.7858, "text": "Devlog: Building Flowerās String Type Foundation The core goal was to make this work in a meaningful, compiler-owned way: name: string = \"Ivy\" as string raw: @char = name as @char other: string = raw as string if name == other: print(\"same\\n\") end print(name.length) That meant Flower needed more than a typedef in generated C. It needed actual type rules, actual lowering rules, and I needed enough hairs on my head to not be bald after the amount of scares that occurred. What changed The first step was giving string real compiler support without going too far too fast. I added support for: explicit casts between string and @char string equality / inequality string.length runtime helpers in generated C for: flower_string_from_cstr(...) flower_string_eq(...) flower_print_string(...) That gave Flower a usable string foundation while still keeping literals conservative for self-hosting. Right now, string literals are not fully ānative string values everywhereā yet; the compiler still uses explicit casts like \"Ivy\" as string as the safe bridge. The reason for this āsafe bridgeā is because when I got too ambitious, the compiler would break since everywhere @char was used with a string literal itād break due to no implicity being allowed. I had to comment out the following new changes and keep the legacy support so itād compile: else if ast.kind == AST_STRING_LIT: // fprintf(out, \"flowe_string_from_cst(\") // fprintf(out, \"%.*s\", ast.data._string.str_length, src + ast.data._string.str_start) // fprintf(out, \")\") // LEGACY CODE HERE and else if expr.kind == AST_STRING_LIT: // set_plain_type(out, TOKEN_STRING) // LEGACY CODE HERE return 1 The part that broke The most annoying issue was not string equality or .length . It was print . Originally, non-string print(...) was basically lowered like this: printf ( expr ); That only works when expr is already a C format string. So something like: print(name.length) generated invalid C: printf ( name . length ); The fix was to make print(...) type-aware. Typecheck now records the operand type, and codegen lowers print differently for string , @char , char , floats/doubles, and integer-like values. That sounds small, but it matters a lot: once string became real, print could no longer get away with pretending every printable value was already a C string. An Unsolved Bootstrap Mystery Somehow Flowerās bootstrap process was breaking, and it will probably break again. Despite the bootstrap requiring it to compile itself, somehow afterwords the binary could become corrupted. l-2: ~/Documents/GitHub/FloC % make bootstrap === Building new version === Compiled ./bin/Flower_new.c ā ./bin/Flower_new === Testing new compiler === Compiled ./bin/Flower_test.c ā ./bin/Flower_test Verified bootstrap build complete l-2: ~/Documents/GitHub/FloC % make bootstrap === Building new version === Luckily, I always make sure to keep a backup Flower bin stored under /bin/Flower_backup so I used that to compile the new binary and then it worked. Where this leaves v1.3 What still remains is the bigger ergonomic question: how fully native string literals should behave, and how to migrate the compilerās own source to that world without setting bootstrap on fire again. Iām not sure yet how I want to approach this question, or what the goals for it should even be, but I guess Iāll have to find out soon enough! That is the next fight. But at least now, it is a fight on solid ground."}, {"post_id": 8529, "ts": "2026-06-14T05:55:45Z", "hours": 3.8414, "text": "Devlog: Making Bool Real Without Breaking Bootstrap The original goal, asper usual, was straightforward: before moving on to string , Flower needed bool to actually mean something semantically. Up to this point, boolean-ish behavior mostly worked by accident. Comparisons, conditions, returns, and general expression checking were still loose enough that the compiler could get away with treating a lot of things as āclose enough,ā especially since the C backend ultimately lowers bool to int anyway. That was not going to hold once v1.3 started leaning on richer typing. So this was about drawing a clean line between Flower semantics and C lowering. The Goal In Flower: bool should be its own real type comparisons and logical operators should produce bool arithmetic should not quietly accept bool implicit conversion should stay narrow and predictable explicit casting should remain available through as In C: bool can still lower to int That distinction ended up being the easy part. What Changed The typechecker now treats bool as a proper language type instead of an int-shaped placeholder. Condition checks were tightened so if , while , and not use condition-compatible rules. Arithmetic paths now reject boolean operands, and return / initializer / argument checking now runs through more explicit conversion rules. I also kept implicit widening one-directional: int -> float -> double while leaving narrowing conversions as explicit casts. The actual implementation of booleans and their typing, enforcement, and semantics was a breeze. Itās what came after that got me. What Actually Broke As usual, bootstrap had opinions. The stricter type work exposed older weaknesses that were easy to miss before (This is my coping): function argument checks needed array-to-pointer decay alias and module call lookup paths were too narrow unresolved calls could prevent nested expressions from being fully type-resolved that, in turn, broke some dot-access lowering and caused bad . vs -> emission in generated C So part of this checkpoint turned into compiler stabilization work rather than just bool semantics due to my crappy ātemporaryā logic, error handling ā or lack thereof, and impeccable ability to miss very important details. Iām an amazing programmer, if you couldnāt tell :p Result Flower now has a much firmer semantic base for bool, and the compiler is back to bootstrapping cleanly with those rules in place. That matters because this was really the floor for the next part of v1.3: string . And.. maybe Iāll fix the bootstrap process so it doesnāt blow up in my face again. Oh yea, forgot to mention that. The bootstrapper bootstrapped itself into this very broken parser state that refused to go away so I had to stash my changes, checkout the prior merge (detached), and then recompile manually and fix the parser. Toodles!"}, {"post_id": 6924, "ts": "2026-06-11T16:28:33Z", "hours": 1.3047, "text": "Devlog: Fixing the Typechecker After Bool Enforcement Getting bool into Flower exposed a reallyyyy annoying problem: the typechecker had a couple of tiny logic mistakes (Iām so good at this) which caused the bootstrap to blow up in my face and I ahd no idea why. At first the errors looked unrelated. The compiler started reporting huge numbers of mismatches across main.flo , lexer.flo , module.flo , typecheck.flo , and codegen.flo . I was so confused as to why out of nowhere 903 lines were reporting various typechecking errors when they shouldnāt be. As it turns out, types_match() was the culprit. The function had been inverted in a few places: Mismatched base types and pointer depths were returning success, while normal matching primitive types were falling through to failure. That made the new compiler think ordinary initializers, assignments, comparisons, and returns were all invalid. Once that was fixed, the remaining failures turned out to be a second real compiler bug: pointer arithmetic over arrays was decaying in the wrong direction. Expressions like: mods.modules + j env.structs + env.struct_count arr + 1 should produce pointer types. Instead, the typechecker was reducing pointer depth when arrays decayed, which made perfectly normal indexed access and table walking look type-invalid. So this dev session ended up doing three important things: fixed types_match(...) so actual matches succeed and actual mismatches fail preserved decimal compatibility for float / double matching fixed array-to-pointer decay in pointer arithmetic so compiler internals and examples resolve correctly again What made this especially annoying is that the symptoms looked much larger than the cause. A couple of bad returns in the typechecker created hundreds of downstream errors, and because Flower is self-hosting, that meant the compiler started rejecting its own source. After correcting those core issues, both bootstrap and the example test suite started working again. That is the real value of issues like this: not just āfewer errors,ā but restoring (MY) trust in the compiler and its ability to enforce Flowerās rules and report issues. With that stable again, the path forward is much clearer: continue bool work from a solid base, then move on to the remaining numeric and string improvements without the whole compiler collapsing under one bad predicate."}, {"post_id": 6207, "ts": "2026-06-10T12:52:51Z", "hours": 4.0928, "text": "Devlog: Making Flowerās Bool Support Real Enough to Survive Bootstrap The goal sounded small at first: add proper boolean support, while still lowering booleans to integers in C. In practice, this turned into an overarching type-system problem (typical!). Flower had reached a point where bool could not just be a naming trick over 1 and 0 . The compiler itself needed to understand when an expression was semantically boolean, when it was integer, and when older bootstrap-era shortcuts were no longer valid. A lot of those shortcuts had survived because the backend lowers bool to int anyway. But self-hosting exposed a major issue: source-level typing and C lowering are not the same thing. Things like these started breaking: val: int = parser_peek(ps).kind == TOKEN_TRUE and helper predicates that returned comparison expressions from int -typed functions. So the checkpoint became: keep C lowering simple, but make Flowerās typechecker treat booleans as a real source-level type. The main changes were: parser -> typecheck -> codegen true / false now parse into AST_BOOL_LIT bool literals are still emitted as 0 / 1 in C logical and comparison expressions now resolve to bool arithmetic rejects bool operands if , while , and not now validate condition-compatible expressions variable initializers, assignments, and returns now check types more strictly One of the more annoying bugs turned out not to be āabout boolsā at all. When code like this failed inside the compiler: defined_structs[i].length emitted_imports[i].path the real problem was that for i in 0..count was never registering i in the type environment, so indexed access looked broken when really the loop variable itself had no known type. Once loop indices were typed as int , those field-access failures disappeared (yay!!). The result is a much better place to build from: bool is now semantically distinct in Flower it still lowers cleanly to integer values in generated C bootstrap works again the compiler is stricter without collapsing under its own source That makes the next step much easier: real string support, instead of trying to build strings on top of a type system that still half-thinks everything is an int ."}, {"post_id": 5369, "ts": "2026-06-09T03:37:15Z", "hours": 5.4503, "text": "Devlog: Giving Flower Real Module Support v1.2.x was the point where Flowerās impors had to stop being āyou can import stuff.. and thereās a fake layer of securityā to a prop er (get it?) module system. Before this work, imports and aliases mostly behaved like naming conveniences. You could write: import \"math.flo\" as math math.add(1, 2) but the compiler was still too loose about what that really meant . Alias names were in emitted C symbol names, top-level declarations were not private, and prop existed more as syntax than as a real feature. That was fine for early bootstrap work, but it was not strong enough for the next stage of the language. So the main goal of v1.2.x became: make imported aliases act like real namespaces make prop define the public interface of a module make top-level declarations private by default lay groundwork for field visibility rules like hidden and readonly Module Semantics Instead of Alias Tricks One of the biggest changes was separating Flower semantics from C lowering. Previously, imported aliases were drifting toward becoming part of emitted symbol identity. A local alias should just be a source-level name bound to a module, not the backend symbol. So now each module has its own lowered symbol prefix, and alias lookup happens semantically during compilation. That means: import \"math.flo\" as math math.add(1, 2) is resolved as ālook up exported add in module math.flo ,ā not āinvent a C symbol from the local alias text as math_add() .ā That change also forced a cleanup of emitted names so they stopped leaking absolute filesystem paths. Generated symbols now use project-relative module prefixes instead of machine-specific paths. prop Became Real Another major part of this was making prop actually do something. Instead of treating it as a thin wrapper around only functions, the compiler now recognizes prop as a real top-level export marker. That means the moduleās public interface is defined by what it explicitly exports, while non- prop declarations remain internal. This moved Flower closer to the model I wanted all along: explicit modules, explicit public APIs, no heavy object system (OOP), no fake privacy delegated to the C backend. Dot Access, Pointers, and the Annoying Middle Part This work also exposed a weakness in the compilerās dot-access resolution. Flower source always uses . , while the C backend must decide whether a given access becomes . or -> . That mostly worked already, but nested pointer-heavy field chains exposed cases where the type tracker was not propagating enough information, which caused bad fallback behavior during self-hosting. So before field visibility could be trusted, I had to harden nested dot-access resolution. Not fun, but necessary. As it turns out, I was missing several AST kinds which caused the logic to fall through. Very tedious work, but it was well-worth it in the end! Field Flags Groundwork With module ownership and access resolution in better shape, I added the first field visibility modifiers: hidden readonly frozen Originally I debated having these as bitwise operations, but I decided itād be best to stay within the current updateās scope, so sometime in the future Iāll refactor. Right now, hidden and readonly are the meaningful additions: hidden blocks external field access readonly blocks external assignment frozen is groundwork for later. It is parsed, stored, and carried through the compiler, but full assignment-once enforcement is still deferred. Unsure how Iāll go about it, but thatās an issue for future me :p"}, {"post_id": 4525, "ts": "2026-06-07T21:22:43Z", "hours": 3.6428, "text": "Devlog: Replacing Flowerās Old Function Syntax with func name(...): type This feature started out as what I thought would be a straightforward syntax cleanup. Flowerās old function syntax looked like this: int add(a: int, b: int): return a + b end and exported functions looked like this: prop int test(): return 1 end It worked, technically, but it had started to annoy me more. The biggest issue was that function declarations did not visually match the direction Flower was already heading in, and instead felt much more C-like than I wanted. prop func create(...): Person func main(): int This style says āthis is a functionā up front, gives a clean place for modifiers like prop , and keeps the return type attached to the signature rather than awkwardly leading it. The goal was simple: func name(...): type instead of: type name(...): Simple in theory. not so much when the compiler is written in the language being refactored. The Problem Flowerās parser assumes top-level function definitions start with a type. Old parser logic was built around that: int main(): means: parse a type, an identifier, params, and a body That assumption was scattered through a few different places: normal function definitions prop function declarations forward declarations examples and docs the compilerās own source Now, in retrospect, this was actually one of the easier changes. It didnāt take a whole lot of planning nor brain power, and I was able to change it pretty quickly. Luckily for me, Iāve built codegen to rely purely on ast values rather than shaping. The New Shape The new syntax is: func add(a: int, b: int): int return a + b end and exported functions now look like: prop func test(): int return 1 end This is nicer because: func makes declarations immediately recognizable prop composes more cleanly with func return types now live where people expect them to future syntax has more room to grow without feeling backwards It also feels more in line with Flowerās broader goals: explicit, readable, and not complex. The Refactor Previously, parse_func_def looked for a return type first: type name(...): Now it expects: func name(...): type So the order changed to: expect func parse function name parse parameter list expect : parse return type parse body until end That part was conceptually easy. The more annoying part was updating all the places that assumed if it isnāt a var decl and it looks like a func, itās a func. That fallback had to go (Good riddance!). Instead, top-level parsing needed to become more explicit: prop func ā exported function func ā normal function forward func ā forward declaration The old one worked, but it relied on vague āanything else is probably a functionā rules. The Bootstrap Mistake At one point, I made a bootstrap build so I could use a Flower_new binary to compile the refactored compiler. Unfortunately, I had made a mistake in parse_forward : advancing before peek checks. Feel free to check out the bootstrapper to see why this was an issue ;) This meant my ānew compiler to compile the new compilerā was built from a broken parser. The workaround was cursed, but it worked : check out the commit before the refactor fix the bug compile a new binary switch to the refactor branch use the binary to compile the new version Since the compiled binary was ignored by Git, this was actually fairly simple. Not the most elegant bootstrap story, but it got the compiler to, well, compile."}, {"post_id": 3962, "ts": "2026-06-07T03:08:31Z", "hours": 8.2967, "text": "Devlog: Making Flowerās Type Tracking āEnoughā for Stdlib / String Work The original motivation was simple and ā supposedly ā quick; I wanted to move on to v1.1.1 , āstdlib basics,ā especially string utilities. But Flowerās current compiler did not really know what types expressions had. It mostly had pointer_depth on declarations, which was enough to generate * in C types and sometimes guess whether field access should become . or -> . That worked for very simple cases: p: @Vector2 = new Vector2 p.x = 5 But it broke down for nested access: outer.inner.value outer.inner_ptr.value The compiler could see the syntax chain, but it did not know whether inner was a value field or pointer field. Since Flower source only uses . , the C backend needs to decide whether each hop becomes . or -> . That meant stdlib work was blocked. If I want something like: if strings.equal(string_a, string_b): print(\"same\\n\") end then Flower needs to understand that string_a.length , string_a.data , etc. are real typed fields, not just random syntax to dump into C. Originally I thought I could just simply create a Symbol Table to get that to work. Unfortunately, that plan soon failed as it introduced a mariad of issues relating to the import system. At the time, this frustrated me because I knew the import system sucked, but I didnāt want to fix it until a later version. Eventually, I settled on a specific plan which did actually end up changing how imports are handled.. kinda. The Plan The design I landed on was to add a typecheck/type-tracking stage between parsing and codegen: lexer -> parser -> typecheck -> codegen The parser should stay mostly syntax-only. It builds AST nodes like ādot access,ā so I didnāt really change it. The typecheck pass now collects declarations into a TypeEnv : struct TypeEnv { structs: StructInfo[1024], struct_count: int, vars: VarInfo[8192], var_count: int, funcs: FuncInfo[8192], func_count: int, error_count: int } Then it walks expressions and annotates dot access nodes with an access kind: ACCESS_UNKNOWN: int = 0 ACCESS_DOT: int = 1 ACCESS_ARROW: int = 2 So codegen no longer has to fully guess. It can do: if ast.data._dot_access.access_kind == ACCESS_ARROW: fprintf(out, \"->%.*s\", ...) else if ast.data._dot_access.access_kind == ACCESS_DOT: fprintf(out, \".%.*s\", ...) else: // fallback end That fallback is important because Flower is self-hosted-ish right now. The compiler is written in Flower, and the compilerās own source code is full of field access. If the new typechecker is too strict too early, it breaks the compiler while trying to compile the compiler. Very elegant. Very cursed. Just how I like it ;) Import-Aware Type Tracking At first, typechecking only saw the main file, so I added a module loading pass. Instead of codegen discovering and parsing imports late, the compiler now loads modules earlier: load main module load imports recursively collect declarations from all modules typecheck all modules codegen all modules That required a new module structure: struct Module { path: @char, src: @char, tokens: @TokenStream, ast: @AST } struct ModuleSet { modules: Module[128], count: int } Unfortunately, it didnāt go as smoothly as I wanted. Near the end when I was sure everything would work, I ran into an Idempotency failure due to the new handling of system imports. I.. just manually passed it :p"}]...
|
Title: Flower by @IvyMycelia | Stardance
Devlogs: Title: Flower by @IvyMycelia | Stardance
Devlogs:
Devlog: Making Flowerās Type Tracking āEnoughā for Stdlib / String Work The original motivation was simple and ā supposedly ā quick; I wanted to move on to v1.1.1 , āstdlib basics,ā especially string utilities. But Flowerās current compiler did not really know what types expressions had. It mostly had pointer_depth on declarations, which was enough to generate * in C types and sometimes guess whether field access should become . or -> . That worked for very simple cases: p: @Vector2 = new Vector2 p.x = 5 But it broke down for nested access: outer.inner.value outer.inner_ptr.value The compiler could see the syntax chain, but it did not know whether inner was a value field or pointer field. Since Flower source only uses . , the C backend needs to decide whether each hop becomes . or -> . That meant stdlib work was blocked. If I want something like: if strings.equal(string_a, string_b): print("same\n") end then Flower needs to understand that string_a.length , string_a.data , etc. are real typed fields, not just random syntax to dump into C. Originally I thought I could just simply create a Symbol Table to get that to work. Unfortunately, that plan soon failed as it introduced a mariad of issues relating to the import system. At the time, this frustrated me because I knew the import system sucked, but I didnāt want to fix it until a later version. Eventually, I settled on a specific plan which did actually end up changing how imports are handled.. kinda. The Plan The design I landed on was to add a typecheck/type-tracking stage between parsing and codegen: lexer -> parser -> typecheck -> codegen The parser should stay mostly syntax-only. It builds AST nodes like ādot access,ā so I didnāt really change it. The typecheck pass now collects declarations into a TypeEnv : struct TypeEnv { structs: StructInfo[1024], struct_count: int, vars: VarInfo[8192], var_count: int, funcs: FuncInfo[8192], func_count: int, error_count: int } Then it walks expressions and annotates dot access nodes with an access kind: ACCESS_UNKNOWN: int = 0 ACCESS_DOT: int = 1 ACCESS_ARROW: int = 2 So codegen no longer has to fully guess. It can do: if ast.data._dot_access.access_kind == ACCESS_ARROW: fprintf(out, "->%.*s", ...) else if ast.data._dot_access.access_kind == ACCESS_DOT: fprintf(out, ".%.*s", ...) else: // fallback end That fallback is important because Flower is self-hosted-ish right now. The compiler is written in Flower, and the compilerās own source code is full of field access. If the new typechecker is too strict too early, it breaks the compiler while trying to compile the compiler. Very elegant. Very cursed. Just how I like it ;) Import-Aware Type Tracking At first, typechecking only saw the main file, so I added a module loading pass. Instead of codegen discovering and parsing imports late, the compiler now loads modules earlier: load main module load imports recursively collect declarations from all modules typecheck all modules codegen all modules That required a new module structure: struct Module { path: @char, src: @char, tokens: @TokenStream, ast: @AST } struct ModuleSet { modules: Module[128], count: int } Unfortunately, it didnāt go as smoothly as I wanted. Near the end when I was sure everything would work, I ran into an Idempotency failure due to the new handling of system imports. I.. just manually passed it :p
Devlog: Replacing Flowerās Old Function Syntax with func name(...): type This feature started out as what I thought would be a straightforward syntax cleanup. Flowerās old function syntax looked like this: int add(a: int, b: int): return a + b end and exported functions looked like this: prop int test(): return 1 end It worked, technically, but it had started to annoy me more. The biggest issue was that function declarations did not visually match the direction Flower was already heading in, and instead felt much more C-like than I wanted. prop func create(...): Person func main(): int This style says āthis is a functionā up front, gives a clean place for modifiers like prop , and keeps the return type attached to the signature rather than awkwardly leading it. The goal was simple: func name(...): type instead of: type name(...): Simple in theory. not so much when the compiler is written in the language being refactored. The Problem Flowerās parser assumes top-level function definitions start with a type. Old parser logic was built around that: int main(): means: parse a type, an identifier, params, and a body That assumption was scattered through a few different places: normal function definitions prop function declarations forward declarations examples and docs the compilerās own source Now, in retrospect, this was actually one of the easier changes. It didnāt take a whole lot of planning nor brain power, and I was able to change it pretty quickly. Luckily for me, Iāve built codegen to rely purely on ast values rather than shaping. The New Shape The new syntax is: func add(a: int, b: int): int return a + b end and exported functions now look like: prop func test(): int return 1 end This is nicer because: func makes declarations immediately recognizable prop composes more cleanly with func return types now live where people expect them to future syntax has more room to grow without feeling backwards It also feels more in line with Flowerās broader goals: explicit, readable, and not complex. The Refactor Previously, parse_func_def looked for a return type first: type name(...): Now it expects: func name(...): type So the order changed to: expect func parse function name parse parameter list expect : parse return type parse body until end That part was conceptually easy. The more annoying part was updating all the places that assumed if it isnāt a var decl and it looks like a func, itās a func. That fallback had to go (Good riddance!). Instead, top-level parsing needed to become more explicit: prop func ā exported function func ā normal function forward func ā forward declaration The old one worked, but it relied on vague āanything else is probably a functionā rules. The Bootstrap Mistake At one point, I made a bootstrap build so I could use a Flower_new binary to compile the refactored compiler. Unfortunately, I had made a mistake in parse_forward : advancing before peek checks. Feel free to check out the bootstrapper to see why this was an issue ;) This meant my ānew compiler to compile the new compilerā was built from a broken parser. The workaround was cursed, but it worked : check out the commit before the refactor fix the bug compile a new binary switch to the refactor branch use the binary to compile the new version Since the compiled binary was ignored by Git, this was actually fairly simple. Not the most elegant bootstrap story, but it got the compiler to, well, compile.
Devlog: Giving Flower Real Module Support v1.2.x was the point where Flowerās impors had to stop being āyou can import stuff.. and thereās a fake layer of securityā to a prop er (get it?) module system. Before this work, imports and aliases mostly behaved like naming conveniences. You could write: import "math.flo" as math math.add(1, 2) but the compiler was still too loose about what that really meant . Alias names were in emitted C symbol names, top-level declarations were not private, and prop existed more as syntax than as a real feature. That was fine for early bootstrap work, but it was not strong enough for the next stage of the language. So the main goal of v1.2.x became: make imported aliases act like real namespaces make prop define the public interface of a module make top-level declarations private by default lay groundwork for field visibility rules like hidden and readonly Module Semantics Instead of Alias Tricks One of the biggest changes was separating Flower semantics from C lowering. Previously, imported aliases were drifting toward becoming part of emitted symbol identity. A local alias should just be a source-level name bound to a module, not the backend symbol. So now each module has its own lowered symbol prefix, and alias lookup happens semantically during compilation. That means: import "math.flo" as math math.add(1, 2) is resolved as ālook up exported add in module math.flo ,ā not āinvent a C symbol from the local alias text as math_add() .ā That change also forced a cleanup of emitted names so they stopped leaking absolute filesystem paths. Generated symbols now use project-relative module prefixes instead of machine-specific paths. prop Became Real Another major part of this was making prop actually do something. Instead of treating it as a thin wrapper around only functions, the compiler now recognizes prop as a real top-level export marker. That means the moduleās public interface is defined by what it explicitly exports, while non- prop declarations remain internal. This moved Flower closer to the model I wanted all along: explicit modules, explicit public APIs, no heavy object system (OOP), no fake privacy delegated to the C backend. Dot Access, Pointers, and the Annoying Middle Part This work also exposed a weakness in the compilerās dot-access resolution. Flower source always uses . , while the C backend must decide whether a given access becomes . or -> . That mostly worked already, but nested pointer-heavy field chains exposed cases where the type tracker was not propagating enough information, which caused bad fallback behavior during self-hosting. So before field visibility could be trusted, I had to harden nested dot-access resolution. Not fun, but necessary. As it turns out, I was missing several AST kinds which caused the logic to fall through. Very tedious work, but it was well-worth it in the end! Field Flags Groundwork With module ownership and access resolution in better shape, I added the first field visibility modifiers: hidden readonly frozen Originally I debated having these as bitwise operations, but I decided itād be best to stay within the current updateās scope, so sometime in the future Iāll refactor. Right now, hidden and readonly are the meaningful additions: hidden blocks external field access readonly blocks external assignment frozen is groundwork for later. It is parsed, stored, and carried through the compiler, but full assignment-once enforcement is still deferred. Unsure how Iāll go about it, but thatās an issue for future me :p
Devlog: Making Flowerās Bool Support Real Enough to Survive Bootstrap The goal sounded small at first: add proper boolean support, while still lowering booleans to integers in C. In practice, this turned into an overarching type-system problem (typical!). Flower had reached a point where bool could not just be a naming trick over 1 and 0 . The compiler itself needed to understand when an expression was semantically boolean, when it was integer, and when older bootstrap-era shortcuts were no longer valid. A lot of those shortcuts had survived because the backend lowers bool to int anyway. But self-hosting exposed a major issue: source-level typing and C lowering are not the same thing. Things like these started breaking: val: int = parser_peek(ps).kind == TOKEN_TRUE and helper predicates that returned comparison expressions from int -typed functions. So the checkpoint became: keep C lowering simple, but make Flowerās typechecker treat booleans as a real source-level type. The main changes were: parser -> typecheck -> codegen true / false now parse into AST_BOOL_LIT bool literals are still emitted as 0 / 1 in C logical and comparison expressions now resolve to bool arithmetic rejects bool operands if , while , and not now validate condition-compatible expressions variable initializers, assignments, and returns now check types more strictly One of the more annoying bugs turned out not to be āabout boolsā at all. When code like this failed inside the compiler: defined_structs[i].length emitted_imports[i].path the real problem was that for i in 0..count was never registering i in the type environment, so indexed access looked broken when really the loop variable itself had no known type. Once loop indices were typed as int , those field-access failures disappeared (yay!!). The result is a much better place to build from: bool is now semantically distinct in Flower it still lowers cleanly to integer values in generated C bootstrap works again the compiler is stricter without collapsing under its own source That makes the next step much easier: real string support, instead of trying to build strings on top of a type system that still half-thinks everything is an int .
Devlog: Fixing the Typechecker After Bool Enforcement Getting bool into Flower exposed a reallyyyy annoying problem: the typechecker had a couple of tiny logic mistakes (Iām so good at this) which caused the bootstrap to blow up in my face and I ahd no idea why. At first the errors looked unrelated. The compiler started reporting huge numbers of mismatches across main.flo , lexer.flo , module.flo , typecheck.flo , and codegen.flo . I was so confused as to why out of nowhere 903 lines were reporting various typechecking errors when they shouldnāt be. As it turns out, types_match() was the culprit. The function had been inverted in a few places: Mismatched base types and pointer depths were returning success, while normal matching primitive types were falling through to failure. That made the new compiler think ordinary initializers, assignments, comparisons, and returns were all invalid. Once that was fixed, the remaining failures turned out to be a second real compiler bug: pointer arithmetic over arrays was decaying in the wrong direction. Expressions like: mods.modules + j env.structs + env.struct_count arr + 1 should produce pointer types. Instead, the typechecker was reducing pointer depth when arrays decayed, which made perfectly normal indexed access and table walking look type-invalid. So this dev session ended up doing three important things: fixed types_match(...) so actual matches succeed and actual mismatches fail preserved decimal compatibility for float / double matching fixed array-to-pointer decay in pointer arithmetic so compiler internals and examples resolve correctly again What made this especially annoying is that the symptoms looked much larger than the cause. A couple of bad returns in the typechecker created hundreds of downstream errors, and because Flower is self-hosting, that meant the compiler started rejecting its own source. After correcting those core issues, both bootstrap and the example test suite started working again. That is the real value of issues like this: not just āfewer errors,ā but restoring (MY) trust in the compiler and its ability to enforce Flowerās rules and report issues. With that stable again, the path forward is much clearer: continue bool work from a solid base, then move on to the remaining numeric and string improvements without the whole compiler collapsing under one bad predicate.
Devlog: Making Bool Real Without Breaking Bootstrap The original goal, asper usual, was straightforward: before moving on to string , Flower needed bool to actually mean something semantically. Up to this point, boolean-ish behavior mostly worked by accident. Comparisons, conditions, returns, and general expression checking were still loose enough that the compiler could get away with treating a lot of things as āclose enough,ā especially since the C backend ultimately lowers bool to int anyway. That was not going to hold once v1.3 started leaning on richer typing. So this was about drawing a clean line between Flower semantics and C lowering. The Goal In Flower: bool should be its own real type comparisons and logical operators should produce bool arithmetic should not quietly accept bool implicit conversion should stay narrow and predictable explicit casting should remain available through as In C: bool can still lower to int That distinction ended up being the easy part. What Changed The typechecker now treats bool as a proper language type instead of an int-shaped placeholder. Condition checks were tightened so if , while , and not use condition-compatible rules. Arithmetic paths now reject boolean operands, and return / initializer / argument checking now runs through more explicit conversion rules. I also kept implicit widening one-directional: int -> float -> double while leaving narrowing conversions as explicit casts. The actual implementation of booleans and their typing, enforcement, and semantics was a breeze. Itās what came after that got me. What Actually Broke As usual, bootstrap had opinions. The stricter type work exposed older weaknesses that were easy to miss before (This is my coping): function argument checks needed array-to-pointer decay alias and module call lookup paths were too narrow unresolved calls could prevent nested expressions from being fully type-resolved that, in turn, broke some dot-access lowering and caused bad . vs -> emission in generated C So part of this checkpoint turned into compiler stabilization work rather than just bool semantics due to my crappy ātemporaryā logic, error handling ā or lack thereof, and impeccable ability to miss very important details. Iām an amazing programmer, if you couldnāt tell :p Result Flower now has a much firmer semantic base for bool, and the compiler is back to bootstrapping cleanly with those rules in place. That matters because this was really the floor for the next part of v1.3: string . And.. maybe Iāll fix the bootstrap process so it doesnāt blow up in my face again. Oh yea, forgot to mention that. The bootstrapper bootstrapped itself into this very broken parser state that refused to go away so I had to stash my changes, checkout the prior merge (detached), and then recompile manually and fix the parser. Toodles!
Devlog: Building Flowerās String Type Foundation The core goal was to make this work in a meaningful, compiler-owned way: name: string = "Ivy" as string raw: @char = name as @char other: string = raw as string if name == other: print("same\n") end print(name.length) That meant Flower needed more than a typedef in generated C. It needed actual type rules, actual lowering rules, and I needed enough hairs on my head to not be bald after the amount of scares that occurred. What changed The first step was giving string real compiler support without going too far too fast. I added support for: explicit casts between string and @char string equality / inequality string.length runtime helpers in generated C for: flower_string_from_cstr(...) flower_string_eq(...) flower_print_string(...) That gave Flower a usable string foundation while still keeping literals conservative for self-hosting. Right now, string literals are not fully ānative string values everywhereā yet; the compiler still uses explicit casts like "Ivy" as string as the safe bridge. The reason for this āsafe bridgeā is because when I got too ambitious, the compiler would break since everywhere @char was used with a string literal itād break due to no implicity being allowed. I had to comment out the following new changes and keep the legacy support so itād compile: else if ast.kind == AST_STRING_LIT: // fprintf(out, "flowe_string_from_cst(") // fprintf(out, "%.*s", ast.data._string.str_length, src + ast.data._string.str_start) // fprintf(out, ")") // LEGACY CODE HERE and else if expr.kind == AST_STRING_LIT: // set_plain_type(out, TOKEN_STRING) // LEGACY CODE HERE return 1 The part that broke The most annoying issue was not string equality or .length . It was print . Originally, non-string print(...) was basically lowered like this: printf ( expr ); That only works when expr is already a C format string. So something like: print(name.length) generated invalid C: printf ( name . length ); The fix was to make print(...) type-aware. Typecheck now records the operand type, and codegen lowers print differently for string , @char , char , floats/doubles, and integer-like values. That sounds small, but it matters a lot: once string became real, print could no longer get away with pretending every printable value was already a C string. An Unsolved Bootstrap Mystery Somehow Flowerās bootstrap process was breaking, and it will probably break again. Despite the bootstrap requiring it to compile itself, somehow afterwords the binary could become corrupted. l-2: ~/Documents/GitHub/FloC % make bootstrap === Building new version === Compiled ./bin/Flower_new.c ā ./bin/Flower_new === Testing new compiler === Compiled ./bin/Flower_test.c ā ./bin/Flower_test Verified bootstrap build complete l-2: ~/Documents/GitHub/FloC % make bootstrap === Building new version === Luckily, I always make sure to keep a backup Flower bin stored under /bin/Flower_backup so I used that to compile the new binary and then it worked. Where this leaves v1.3 What still remains is the bigger ergonomic question: how fully native string literals should behave, and how to migrate the compilerās own source to that world without setting bootstrap on fire again. Iām not sure yet how I want to approach this question, or what the goals for it should even be, but I guess Iāll have to find out soon enough! That is the next fight. But at least now, it is a fight on solid ground.
Devlog: Finishing Flowerās String Interop Bridge The last round got string into Flower as a real type. This round was about making that foundation actually work lol. The big problem was that once string became real, plain string literals started living in an in-between state: Flower wanted them to mean āFlower string,ā but the compilerās own source still has plenty of places that really mean āraw C string,ā like: RED: @char = "\033[0;31m" if not strcmp(arg, "help") or not strcmp(arg, "h"): ... end Those cases worked before only because everything was basically pretending string literals were already @char . Once that stopped being true, bootstrap started throwing a fit (my spoiled child). What changed The main fix was to make string literal lowering contextual instead of all-or-nothing. If a literal is being used as a real Flower string , it stays a string . If a literal is being used in a C interop position, it gets lowered as a C string instead. That meant tightening a few compiler rules so this kind of thing works cleanly again: name: string = "Ivy" as string raw: @char = name as @char if strcmp(raw, "Ivy") == 0: print(name) end I also fixed top-level declarations so globals like: RED: @char = "\033[0;31m" no longer generate nonsense like: char * RED = (( flower_string ){ ... }); which, unsurprisingly, C does not appreciate. The subtle compiler bug The nastiest issue wasnāt even the globals. It was that builtin C calls like strcmp , strncmp , printf , snprintf , and friends are not real Flower functions. That meant the typechecker could hit one of them inside a larger expression, fail early, and stop walking the rest of the tree. So something like: if not strcmp(arg, "help") or not strcmp(arg, "h"): could partially resolve one side, then leave the other side unprocessed. Very cool. Very stable. Definitely what I wanted. The fix was to add a temporary builtin C-call bridge so the compiler can recognize these calls well enough to keep type resolution and literal lowering consistent during bootstrap. Iām not happy with this fix by any means, but due to the limitations of emitting C, it was the only solution I found that made sense at the time. Tests and examples Once that stopped exploding, I finally wired string testing into the normal types suite instead of leaving it commented out and pretending Iād āget back to it later.ā The string tests now cover: string <-> @char casts string equality / inequality .length empty strings printing strings literal use in current interop cases And the full test suite passed with string included as a first-class part of Types on its first try . Now thatās what I like to see :D What this means This does not mean Flowerās long-term answer is āhardcode libc into the compiler forever.ā It means Flower now has a temporary interop bridge that keeps self-hosting stable while string is worked on. The actual language semantics stay in Flower; the backend-specific weirdness is just being tolerated for now so progress does not stall. In the near, Iāll probably replace all of the necessary C libs with minimal Flower-equivalents. Where this leaves v1.3 At this point, the string foundation feels much sturdier. Not ādone forever,ā not backend-agnostic, and definitely not free of cursed bootstrap energy ā but it works. The next work is no longer rescue work. It is actual forward work: string operations, stdlib basics, and eventually replacing this temporary C bridge with something cleaner when Flower grows past the C backend.
Devlog: Adding String Indexing to Flower This one was fairly quick, and was about making one very normal-looking thing actually work: name: string = "Ivy" as string first: char = name[0] That sounds small, but once string became a real Flower type, indexing could no longer piggyback on the old āarrays and pointers onlyā behavior. The compiler needed to understand that string[index] is its own case. What changed I taught the typechecker to treat string subscripts as char . That means: string[index] now resolves to char the index expression must be an integer string indexing is readonly for now So this is valid: first: char = name[0] but this is not: name[0] = 'X' I wanted reads first, writes later. That keeps the rules simple while the string representation is still compiler-owned. Iām not sure how writes would work with a C backend, due to how āstringsā are allocated. Perhaps a feature for post-v2.0? Lowering it to C Since Flower strings currently lower to a struct with .data and .length , codegen needed a special path for string subscripts. Normal arrays and pointers still lower like: arr [ index ] but strings now lower like: name . data [ index ] That keeps the generated C valid without changing how regular subscripts work elsewhere in the language. So something conceptually like: This checkpoint also forced one strict-but-correct rule that required me to update a WHOLE SINGLE LINE (hehe): arg[i] = tolower(arg[i] as char) to arg[i] = tolower(arg[i] as char) as char Because tolower(...) is effectively treated as returning int , assigning it back into a char subscript needs an explicit cast. I kept that strictness on purpose. I do not want Flower silently narrowing values just because C would let it. Validation I expanded the string example coverage to check: string indexing returns the expected chars string[index] works alongside string <-> @char casts bootstrap still succeeds repeated bootstrap succeeds tests still pass Which, after all the recent bootstrap chaos, was very nice to see. Where this leaves v1.3 Now we can: store strings compare strings print strings inspect length index into them as char This should make it much easier to replace the builtin C functions with a Flower library in the near-near future.
Devlog: Fixing Flowerās Output Driver and Starting the String Stdlib This checkpoint was really two different kinds of progress that ended up helping each other a lot. The first part was not glamorous, but it was necessary: Flowerās compile driver was tripping over its own default output naming. This was a known issue that I had been putting off, but for some reason it really annoyed me this time so I decided enough and to fix it. If no explicit output path was provided, the compiler would generate output.c , then strip the .c and try to emit a binary named output . That worked fine right up until the repo itself already had an output/ directory. At that point, linking failed because the compiler was trying to create a file where a directory already existed. Worse ā because it annoyed me more ā the driver logic was also mixing up āthe generated program exited non-zeroā with ācompilation failed.ā That became especially annoying during bootstrap, because the generated compiler binary would run without CLI arguments, print its own usage error, and then cause bootstrap to report failure even though codegen and C compilation had both succeeded. So I finally got off my butt and cleaned that up. Driver Cleanup The default output path now goes to: output/out.c which naturally produces: output/out as the binary. That avoids the old output filename collision. I also separated compile success from auto-run behavior: explicit output path: compile only default output path: compile, then auto-run if appropriate That means bootstrap no longer āfailsā just because the compiled compiler exits non-zero with missing arguments, and demo/test files can still run automatically when that is actually useful. This sounds like a small driver fix, but honestly it removed a lot of noise from string work ā and more ā immediately. String Stdlib Beginnings Once that output weirdness was under control, I could finish doing what I just started and actually wanted: making string behavior live in Flower instead of endlessly leaning on ad hoc C calls (Call back to last devlog, absolute ball knowledge!!). So I added the first real reusable helpers in src/stdlib/string.flo : is_empty(s) starts_with(s, prefix) ends_with(s, suffix) find_char(s, ch) These are intentionally simple. They mostly exist to prove that the current string support is now strong enough for normal library code to be written on top of it. Not incredibly useful, at least at the level the compiler needs, but at least I could translate some AP Comp Sci A into Flower hehe A string feature does not really feel ārealā until I can build helpers with the language itself instead of only teaching the compiler more special cases. The day I remove the builtin C handlers is the day Iām at peace⦠Validation To exercise that new library surface, I changed string_pass.flo to now act as a small pass file for the experimental library. Its job is not to be impressive. Its job is to answer a more important question: can I import string helpers, call them from normal Flower code, and get expected results through the full compile pipeline? At this point, yes. Where this leaves things This checkpoint did not remove all C string dependencies from the compiler. In fact, it removed essentially none! That is still a separate step, one that may even be in v1.3.7 ;) But it did establish two important things: Flowerās output/driver behavior is now much less annoying. We can start growing a real string library in Flower itself. That is a good place to be, because the next string work can build outward from a stable driver and an actual library surface instead of piling more special behavior into the compiler.
Devlog: Giving Flower an Internal cstr Foundation Even after Flower got a real string type, the compiler itself was still leaning directly on C-style string helpers for its own internal work. That meant a lot of Flower source was still semantically depending on libc behavior: !strncmp(...) strcmp(...) strlen(...) strcpy(...) strncpy(...) strdup(...) strrchr(...) That is not where I want the language to stay. What changed I added a new internal module: import "src/stdlib/cstr.flo" as cstr and gave it compiler-facing helpers like: prop func len(s: @char): int prop func eq(a: @char, b: @char): bool prop func eq_n(a: @char, b: @char, n: int): bool prop func copy(dst: @char, src: @char): @char prop func copy_n(dst: @char, src: @char, n: int): @char prop func dup(src: @char): @char prop func find_last(src: @char, ch: char): @char This helper module is essentially the precursor to a future strings.flo library that can be distributed. But for now, it uses a basic API layer purely meant for in-house usage. Then I migrated compiler internals over to that module across: src/parser.flo src/module.flo src/lexer.flo src/typecheck.flo src/codegen.flo src/globals.flo src/main.flo So instead of using C-string behavior directly everywhere, the compiler now goes through Flower-owned helpers first. The Compiler Strikes Back This was one of those changes that sounds mechanical until it absolutely is not. A big trap was that old code often relied on C comparison functions returning 0 on equality, so patterns looked like this: not strncmp(...) But cstr.eq_n(...) returns an actual bool , which means blindly rewriting those calls gives inverted logic. So this: if ps.alias_lengths[i] == tok.length and not cstr.eq_n(...): was completely wrong. It had to become: if ps.alias_lengths[i] == tok.length and cstr.eq_n(...): That bug showed up in alias parsing first, which made it especially cursed, because it caused normal namespace-style calls like cstr.eq(...) to stop parsing correctly and crash the bootstrap path in confusing ways. I spent way longer than I wish to admit on trying to figure out why it wasnāt playing nice. But, once I figured it out, it was a really quick fix (I literally just cmd + f ād not cstr and replaced it with cstr lol). Are we done yet..? This does not mean Flower is free from the C backend yet. It does mean something important, though: compiler logic is starting to depend on Flower-defined helper semantics instead of scattered raw libc calls. That is a much better stage for the future backend story, because when C eventually stops being the primary lowering target, the compiler will already have more of its own vocabulary. In other words, this was less about āremove Cā and more about āstop letting C define the languageās internal habits.ā Nah just kidding, I really wanted that bloated ābuiltin_c_callā stuff gone. Unfortunately I only managed to skim it, but thatās closer than before! Result After fixing the migration mistakes and the alias/parser fallout, the compiler bootstrapped successfully again. Flower now has an internal cstr layer, and compiler string handling is a little more its own.
Devlog: Cleaning Up v1.3 For Release After many hours of work, bool and `string finally became real, and it was time to cleanup the mess I left behind from the versionās development. Mainly the only thing worked on was some cleanup: roadmap now reflects actual v1.3 features and implementations updated README and contribution documents to match the current compiler pipeline cleaned up string examples so they have the full intended v1.3 style instead of some leftover testing usage pushed the compilerās version to 1.3.0 updated help / usage text so it matches the new output-path and auto-run behavior Prior to this, if I had just merged and shipped, the release wouldvāe been messy: README, Contributing, example files, and guidance commands were all mixing older details which made it confusing ā even for me ā when trying to explore the language and what it has to offer. For a bootstrapped compiler especially, making sure everything is cleaned up and polished is something that should not be ignored. Iām definitely guilty of overlooking this, but Iāve outlayed a whole plan for v1.3 unlike past versions, and part of it was setting up a proper versioning system and polishing its release as it goes. This format will be adopted in future versions, since itās just way cleaner and nicer to look at. Future work At this point, v1.3 is done and has implemented, at minimum, a concrete foundation for post-v2 bools and strings. Next will likely be more subtle improvements, and features that are currently reliant explicitly on C rather than Flower-hosted code. In order for v2.0 , Flower will have to be effectively independent from C if it wants to emit machine code. Currently I am planning on adding features such as Type Aliases and maybe a stdlib prior to that, but anything can change!! Thanks for being here for all of v1.3 <3
Devlog: Making Flowerās Type Aliases Transparent This version was simple to develop on paper (and even in practice it wasnāt too bad, only around 4 or so hours!): type Count = int type Total = Count type Name = string and then have those aliases behave like the real type everywhere: n: Count = 12 total: Total = identity(n) name: Name = "Ivy" if name != "Ivy": return false end if name.length != 3: return false end That meant aliases could not just be parsed and stored, but rather had to be transparent to the compilerās semantic checks. What changed I added type alias declarations to the AST, parser, and type environment, then added the ability to resolve aliases in typechecking before comparing types. That included: return type checks variable initializers function call arguments binary comparisons string-specific comparison logic struct field access The important rule here is that aliases are semantic, not codegen-facing. Count should behave as int , Name should behave as string , and chained aliases like Total -> Count -> int should collapse correctly. In the future, especially post v2.0 , this could change and custom types might become real ā but for now, theyāre just aliases. The bug that exploded bootstrap The first real failure was not in aliases themselves, but in function argument checking. Inside check_call_args(...) , the compiler was resolving the argument expression into expected_type instead of arg_type . That overwrote the parameter type, left the actual argument type uninitialized, and caused the second bootstrap stage to explode into over a thousand misleading errors. This was not a pre-existing issue, it was instead from human error (my error) during the initial implementation where I accidentally put the wrong variable. Once that was fixed, the remaining failures were much more helpful than the bright flash of red and āTypecheck failed with 1224 error(s)ā message! Where this leaves v1.4 With the first step toward ābetter typesā done, aliases are no longer just syntax. That gives v1.4 a solid base for whatever comes next in the type system without having to fake around raw names. During this whole dev session, I did discover that a whole lot more of the source code was left using legacy work-arounds: int instead of bool , name_start; name_length and @char instead of string . In all fairness, some of these arenāt exactly the easiest to refactor. However, I will probably hold off on refactoring the codebase until either right before v2.0 , or right after. Just know itās on my radar ;)
Devlog: Fixing Flowerās Compiler Process So It Stops Fighting the Host This wasnāt really about language design at all buttttt it is much more embarrassing , AND more important: Flowerās compiler process itself was too fragile. The immediate issue showed up on Linux, specifically NixOS (thanks shipwrights <3). The build flow was assuming too much: a previously existing bin/Flower could be reused safely bash would exist at the expected path clang would always be available the checked-in compiler binary would be runnable on whatever machine the repo landed on That worked well enough on my machine until it didnāt. On NixOS ā and by extension probably any other machine without the prexisting binaries I had ā it broke: make targets were inconsistent, the shell script failed on interpreter assumptions, and the compiler binary itself could be the wrong format for the host. What changed The fix was to separate āthe compiler source existsā from āthe current compiler binary is usable on this machine.ā The build process now starts by compiling a fresh host-native bootstrap compiler from bin/Flower.c , instead of trusting whatever happens to already exist in bin/Flower . That means the flow is now: bin/Flower.c -> host-native bootstrap compiler -> new Flower compiler -> self-check instead of: maybe existing bin/Flower -> hopefully works -> maybe bootstrap Ok well thatās kinda a lie; it still relies on hopes and dreams to bootstrap sometimes. BUT itās MUCH safer! And now everyone gets to experience crippling bootstrap anxiety, instead of being met with a failure before the actual compiler gets to.. well, do its thign! I also cleaned up the surrounding tooling: switched the bootstrap script to portable sh restored a clearer build / bootstrap / rebuild / test / clean structure made the compiler use CC and CFLAGS from the environment instead of hardcoding clang What this actually improves Flower is still not universally cross-platform yet. The compiler driver still has POSIX-shaped assumptions in places, and the emitted C can still depend on host APIs depending on what the program uses. Iām not yet at the point of wanting to make it completely universal, especially given how Iām only one person and with v2.0 coming up soon itād ā in my humblest of opinions ā be a waste of time. I am honestly grateful for people reviewing my code and otherwise viewing it catching onto details I have overlooked. My goal is to not make a ājust-barely working on my machineā project; I enjoy sharing development with others, and it hurts knowing people canāt appreciate code, whether it be mine or othersā, due to something as simple as hard-coded sh flags.
Devlog: Formalizing Flowerās Null Foundation Flower already had some of the pieces for null , but they were a bit scattered. The goal here was to make it explicit, consistent, and safe before moving on to nullable syntax like ?T or full union-based nullability later in v1.4 . Another shorter devlog, but still important and distinct enough for me to think āHmm devlog time? Yes, devlog time!ā What changed The main work was in typechecking. I added to the compilerās idea of what null is, how it is represented internally, and what kinds of values are actually allowed to accept it. Rather than letting null-related behavior stay implicit across a few checks, null now follows a clearer rule set: null has one centralized internal type representation pointer-like values can explicitly accept null null comparisons and assignments now go through the same semantic path Why this matters This isnāt all that important on its own, but it matters a lot for where Flower is going next. If null is not defined well, then later features like: ?T better unions smarter narrowing more expressive type flow all become more error-prone (or so I assume given my track record) than I want need them to be. Validation I also expanded the example coverage so null : it now has dedicated behavior checks around assignment, passing values around, and comparison behavior.
Devlog: Adding Pointer-First Nullable Types to Flower I worked on giving Flower its first real nullable type surface without being overambitious and pretending the compiler is ready for full optional-everything semantics yet. The new syntax now works like this: ptr: ?@int = null text: ?@char = null That means there is now an explicit way to say āthis pointer-like value may be absent,ā instead of relying entirely on raw pointer habits from C (If you couldnāt tell by now, I despise C). What changed The main work was split across lexer, parser, and typecheck. I added: ? as a type marker in type positions is_nullable tracking in TypeInfo type rules for nullable pointer/reference values explicit compatibility for: assigning null into nullable pointer-like types comparing nullable values against null casting between @T and ?@T I also kept the scope intentionally narrow: this implementation is pointer-first nullable support , not full nullable scalars. So ?@int makes sense right now, but ?int is still deferred until I make a better semantic union / optional representation for plain values. Why this matters It would have been easy to overreach here and claim ānullable types are done,ā but that would have been a big phat lie. Pointer-like nullability lowers naturally enough with the current backend and current compiler model. Scalar nullability, however, does not. Once you let int or bool become nullable, you need a more real representation for āhas value / no value,ā and that belongs in the later union work, not here. Result explicit absence compiler-owned semantics better future unions stronger type meaning without hidden magic The next real step after this is not more patching around null ā I consider that done for now ā but instead giving Flower the deeper machinery needed for nullable non-pointer values and semantic unions later in v1.4 so it doesnāt come back to bite me in my butt.
v1.4.4 Devlog: Giving Flower Real Semantic Union Types I made it so that semantic unions are now in Flowerās parser and type system ā but not yet its codegen. The goal was to support types like: value: int | string next: @Node | null type Result = int | string Whatās new The parser now understands | inside type positions and builds semantic union type information instead of relying on those old plain aliases or backend-shaped hacks. On the typecheck side, unions are now carried through normal type copying and alias resolution. That means named aliases like: type MaybeName = string | null make sense after resolution, instead of collapsing into nonsense. The typechecker also now accepts union-compatible usage in the places that matter for a foundation: variable initialization assignment parameter passing return checking alias resolution So if a value matches one union member, it is accepted. This is sorta implicit behavior, but I think it gets a pass due to its somewhat explicit nature? What it does not do yet This version was intentionally strict about using unions as values. You cannot yet directly: index a semantic union access a field on a semantic union use arithmetic / comparison operators on one print one directly Instead, Flower now requires an explicit cast before using a union value that way. That may sound harsh, but it is the right restriction.. for now. There is not any narrowing yet, so pretending unions were fully usable would just make the language lie and spit out 2,000 errors. Where this leaves v1.4 Flower now has: transparent type aliases null as a real type-system concept pointer-first nullable types semantic union type representation The next step is the part that will make unions actually usable rather than merely legal: narrowing with is better explicit extraction with as eventually making ?T truly become T | null instead of remaining pointer-first for now No fun screenshot this time :p just frontend work for now⦠Ivy, signing off <3
Devlog: is Checks v1.4.5 added is checks, mostly so code like this can work: if maybe_ptr is @int: real_ptr: @int = maybe_ptr end The idea is (fairly) simple: if the condition proves maybe_ptr is an @int , the inside of the branch should be allowed to treat it like one. Flower did not know how to do that before. It knew what a variable was declared as, but it did not really learn anything from control flow yet. Now it can, at least for the pointer/nullable-ish cases I care about first. This touched the parser, AST, typechecker, narrowing logic, and codegen. So, naturally, the āsmall featureā went everywhere. Iād actually consider this one of the bigger refactors so far, mostly because it added a new TypeAtom structure. Before this, types were still a bit too attached to the places they appeared, and all fell under the TypeInfo . That worked for simpler declarations, but is checks needed type syntax to have something the compiler could pass around to use for comparisons, validations, and narrowing. The parser had to recognize the new expression shape. The AST had to store the left side and the tested type. The typechecker had to make sure the test was allowed and not totally garbage. Then the narrowing logic had to say, āinside this branch, this variable has the proven type of x and therefore we wonāt flag you for being an idiot.ā That last part was where the bug goblin lived. Iām calling them a goblin because they were sneaky (and I also think itās quite a funny and cute name). For a while, Flower had applied narrowing from the if body instead of the if condition, which meant the compiler saw this: if maybe_ptr is @int: real_ptr: @int = maybe_ptr end and somehow still failed on the assignment inside the branch. Very helpful. Thank you, compiler. EVen though itās obviously 100% my fault, I made the compiler, but oh well!! Once I changed the narrowing step to inspect the actual condition expression, it started behaving like it should. The typechecker could see maybe_ptr is @int , attach that narrowed type to the branch scope, and allow maybe_ptr to be used as @int inside the guarded block. For now this explicitness is how I want it. There may come a time in the near future where I decide some implicity is ok, but weāll see ;) is checks are the first real step towards control-flow-aware typing in Flower. Not full union support yet, but definitely the beginning of that road soon to come. Right now it mostly helps with nullable and pointer-like cases. Later, the same idea can support richer unions, better narrowing, and more type-driven control flow without making the programmer manually restate everything the compiler should already know. Also, it bootstrapped cleanly twice ā which.. is obviously the bare minimum, but still!!
Devlog: Semantic Unions Become Actual Values (Part I) In v1.4.6 , I made semantic unions actual runtime values instead of just parsed/typechecked shapes. Before this, Flower could understand: type Value = int | string as a type. It could point at it and say, āyes, that is a union,ā but that was mostly theoretical. The goal was to make this work-work for realsies: type Value = int | string value: Value = 7 if value is int: n: int = value as int end value = "Ivy" if value is string: s: string = value as string end That meant Flower needed more than TypeInfo.is_union = true . It needed a full path from syntax, to type proof, to lowered storage, to runtime extraction. Otherwise unions would just be fancy typechecker thingy-ma-bobbies, which is not very useful when the backend still emits C. What changed Instead of treating a union as a vague āone of these types, probably,ā Flower now lowers it into a tagged structure. Conceptually, this: type Value = int | string becomes something like: struct Value { int tag ; union { int as_int ; flower_string as_string ; } data ; }; Not the final sacred form forever, but that is the shape of it: a tag saying which variant is active, plus storage for the possible members. Since Flower emits C right now, the lowering is C-shaped. I am not fully sure how I want this to look in ASM yet, but I do know it would be way more technical, and uglier. This required a few things to play nicely with one another: if value is int creates a union proof the guarded branch stores narrowing information value as int is only allowed after proof assignments pack values into the right tagged member explicit casts extract the right member from storage Otherwise the compiler is just writing checks its own backend cannot cash. The part that makes it ACTUALLY semantic For pointer narrowing, if value is T mostly refines how the compiler treats an existing value. For semantic unions, the check also becomes a runtime tag test. So this: if value is int: means: check the active tag of value , then inside this branch, treat it as the int variant. Then this becomes valid: n: int = value as int because the branch already proved the active variant. Without that proof, value as int should not be casually allowed. Flower is supposed to be explicit, not psychic, and I am not confident enough yet to implement a proper intuitive implicit checker without summoning something cursed. Assignment and extraction This: value: Value = 7 now packs 7 into the int member and sets the tag to the int variant. Then this: value = "Ivy" does the same thing, but for the string member. So a semantic union is not just some bytes, but rather a tagged runtime object where Flower knows which member is active. Then explicit casts like: value as string can lower into extracting the string member, but only when the typechecker has accepted that the operation is safe in that control-flow path. Why this checkpoint matters Flower can now store variant values, prove which variant is active, and require explicit extraction instead of relying on random magic I threw together. The flower has grown another concerning little organ.
Devlog: Letting Semantic Unions Work In Functions After getting semantic unions working in local declarations, the next problem was fairly obvious (and in my roadmap hehe). This did not work before: func make_value(): int | string return 7 end func accept_value(value: int | string): bool return value is int end Which was annoying, because int | string was already a real union type at this point. Flower could use it in locals, it could pack assigned values, it could check variants. But if I returned 7 from a function declared as int | string , or passed 7 into a parameter expecting int | string , the compiler did not know how to carry that union-lowering information across the boundary. This has been one of the easier changes Iāve made in a long while. It compiled properly first try (if you ignore a tiny misspell I made which I fixed really quickly), and there were no prior hidden bugs that surfaced. This.. is too suspicious. What changed The compiler now carries semantic union info through: function parameters function returns imported alias calls If a function expects: int | string and I call: accept_value(7) typecheck records that 7 needs to be packed as the int member of that union. Same for returns: func make_value(): int | string return 7 end That matters because codegen cannot guess later due to the separation of responsibilities Iāve laid out. By the time Flower is emitting C, it needs to know which tag to set and which member to write. Lowering it properly Codegen already knew how to pack union values for declarations and assignments. The missing part was doing the same thing for call arguments and return statements. So now a value can be packed into a tagged union when it is: stored locally passed into a function returned from a function Alias calls got handled too, so things like: remote.accept(11) remote.make_string() do not become their own weird little cursed island. Why this mattered Without this, semantic unions only worked as long as I never organized my code. They worked in local tests, but not in helper functions, imported providers, or normal inputs and outputs. Now union values can actually move around the program instead of being trapped in the one scope where they were declared ā and for me, forgotten! Very exciting, the union can leave the house. They grow up so fast āāĢ“Ģ ā āĢ“Ģā
Devlog: Adding Obvious Branch-Local Inference to Flower Before this, narrowing mostly worked in the obvious ātrue branchā cases: if maybe != null: real: @int = maybe end and: if value is string: s: string = value as string end But the else branch was still kind of standing there empty-headed, even when the meaning was extremely obvious. Like, if this happens: if maybe == null: return false else: real: @int = maybe end then inside the else , maybe is clearly not null. So now it doesnāt!! What changed Flower now does branch-local narrowing in else for small, explicit cases. That means these now work: if maybe == null: return false else: real: @int = maybe end and: if value is int: return false else: s: string = value as string end It is only applying inference when the condition says something directly and the opposite branch has one obvious meaning. Nullable narrowing For nullable pointer-like values, Flower now understands both sides of simple null checks: if x != null narrows x to non-null in the if body if x == null narrows x to non-null in the else body the opposite side can narrow to null when that is the only meaning left Semantic union narrowing The same idea applies to semantic unions, but a bit more āheld back.ā Essentially, if Flower sees: if value is int: then the if branch narrows to int , like before. Now, if the union only has one other possible member, the else branch can narrow too. So for: int | string the else after if value is int can be treated as string . This is not full control-flow wizardry, since it doesnāt reason across deep boolean chains, early-returns, or giant branches yet. It is deliberately small and local, because I do not want Flower āhelpingā so much that I need a detective board to figure out what type something is.
Devlog: Teaching Flower to Understand Guard Clauses gave Flower branch-local inference. Last update, I added support for branch-local inference, so the compiler could understand things like: if maybe == null: return false else: real: @int = maybe end and: if value is int: return false else: s: string = value as string end That was an improvement, but it still meant narrowing stopped at the end of the branch. That meant stuff like returninging in some conditions still did not really work as naturally as it should: if maybe == null: return false end real: @int = maybe or: if value is string: return false end n: int = value as int In v1.4.9 I fixed that. What changed Now narrowing propagates past very obvious guard clauses. If one branch definitely returns and the other falls through, the compiler now carries the interpretation forward after the if . This means that the compiler can now understand: after if x == null: return ... , x is non-null after if x is string: return ... , a two-member semantic union can narrow to its remaining member I kept this intentionally conservative for now. The compiler is not doing full control-flow analysis yet. It is only recognizing the simplest and most explicit early-exit shape. How it works The main addition was a small semantic check for ādoes this branch definitely return?ā Right now that means: direct return if where both branches definitely return Once the compiler knows one side exits and the other survives, it applies the branchās narrowing to the following statements. Yea.. thatās it lol.
Devlog: Making ?T Actually Mean T | null Before v1.4.10 , ?T was treated as its own nullable system and not really integrated with the rest of the semantic unions. This was unideal, because it created a separation of logic which was cumbersome to maintain. The idea was to make the following be the default: ?int == int | null ?string == string | null ?@int == @int | null Prior to the refactor, nullable types were still mostly pointer-oriented. That worked when ?T basically meant āmaybe this pointer is null,ā but it did not really fit anymore once semantic unions became actual runtime values. If Flower has T | null , then ?T should use that instead of being its own special thing. This is a more pragmatic choice, as it keeps the compiler easier to manage and update later on. What changed Typecheck now lowers ?T into the same semantic-union machinery used by normal unions. That means nullable values now go through the same general path as union values: null checks use union-aware narrowing narrowed nullable values can be extracted with as codegen emits tagged union storage assignments pack into the right union member So this now works as an actual nullable flow: maybe: ?@int = raw if maybe == null: return false end real: @int = maybe as @int The annoying part is that Flower has to track two things at once: the type the programmer is allowed to see after narrowing, and the actual union shape that remains underneath it. After the guard, maybe behaves like an @int . But codegen still has to remember it came from @int | null , because apparently the compiler cannot simply āvibeā its way through storage layout. Tragic! The bugs that annoyed the heck out of me Most of the work was not surface syntax. The syntax was just standing nearby looking innocent. The actual bugs were in the places where Flower knew āthis is non-null now,ā but then forgot how to lower, such as: narrowed nullable values falling back to raw C casts like (int*)(maybe) false branches of == null / != null narrowing to the wrong side (this was my fault lol) null getting packed into the wrong union member That last one was the rude one. For ?@int , generated C could end up doing something like: . tag = 1 , . m0 = NULL instead of packing into the actual null member. So the value looked almost right, but the tag/member pairing was wrong. Then later null checks would fail, because the compiler had technically put null somewhere. Just not the correct somewhere. Very helpful. The fix was separating two questions I had accidentally merged: is this type compatible with this union? which exact union member should this value occupy? Those look related, but they are not the same question. Flower was using the first answer for the second problem, and then acting surprised when everything became soup. Where this leaves Better Types ?T now lowers through the same path as T | null , which means null checks, narrowing, extraction, and storage all line up with the semantic union model. This should make later work cleaner, such as nullable inference, nicer union ergonomics, maybe pattern-like narrowing eventually. Not easy. I am not saying easy near a compiler. That is how they hear you. You do not want them to hear you ..
Devlog: Direct Semantic Union Parameters Now instead of having to do this workaround: type Value = int | string func accept(value: Value): bool You can just pass semantic unions directly: func accept(value: int | string): bool That was it. All I had to do was remove a stale type_error clause in register_params and allow binding variables. Then I updated the two relevant accept functions in /examples.
Devlog: Letting Union Narrowing Follow Field Access Before v1.4.13 , union narrowing only really worked when the thing being narrowed had a variable name due to almost every similarity check relying on name_start and name_length . This was dumb, because semantic unions already knew how to test tags and extract members. Codegen was not the issue, but rather the annoying part was that the typechecker could remember this: if value is int: n: int = value as int end but not this: if box.value is int: n: int = box.value as int end So I still had to do a little temp-variable ritual: tmp: Value = box.value if tmp is int: n: int = tmp as int end Which was gross. Not necessarily catastrophic, just gross and annoying. I wanted needed convenience What changed The compiler was remembering narrowings by variable name, not by expression shape, so box.value looked obvious in source (to me, at least), but to the typechecker it was basically some random expression and not something it could reliably recognize again later. A variable name already had a stable identity, whereas field access chain did not. So the change was to let narrowable expressions represent more than just AST_VAR_REF . For now, that only means stable dot-access chains. The typechecker can record a narrowing for an expression like: box.value and then recognize the same expression later when a cast shows up. So this works directly now: if box.value is int: n: int = box.value as int end Same for the other union members, like string . The detour My first example accidentally wandered into a different feature: if maybe_box.value != null: That exposed a real nullable-field-guard gap, but that is not what this was supposed to be about. Very rude of the test case to have ambition hmph >:( Where this leaves it Semantic union narrowing now persists past field access ā at least for stable dot-access chains ā and the temp-local is no longer needed. Butttt now I gotta work on nullable-field-guards, ugh (hehe)
Devlog: Finishing Nullable Field Narrowing At this point, Flower could already narrow semantic unions through field access in the is / as case, and nullable field checks were supposed to be the obvious follow-through: if maybe_box.value != null: label: string = maybe_box.value as string end Instead, I had forgotten to remove a LOT of stale code, and thus part of it was still behaving like only plain local variables could ever be narrowed. There was also a second, smaller mismatch hiding, where null in type position was not lining up with the compilerās actual internal null representation. ?string and string | null werenāt leading to a congruent output and at times were wobblier than they should be. So the fix was mostly cleanup, but the meaningful kind: make null in type syntax lower the same way the compiler expects remove the stale var-only branches in nullable narrowing let stable field paths like maybe_box.value and holder.box.value narrow properly The funny part is that this felt bigger initially than it actually was once fixed. Nothing fundamentally new had to be invented, I just had to stop the old code from interfering with the newer code, which once I figured out how to do so it was quite quick. I spent an embarrassingly long time figuring it outā¦
Devlog: Syncing Flowerās Docs Back to Reality Just a doc cleanup lol. No code change or compiler updates. Probably did more than needed for now but oh well! The mismatch was REALLY bad. The old docs preserve old assumptions, and someone reading them could walk away with a version of Flower that no longer really exists (or, in some cases, doesnāt exist yet or never ever existed)! What changed I updated the docs that had drifted the most from reality (relatable): README.md now reflects the current type-system shape ROADMAP.md treats v1.4 as accomplished the v1.4.0 milestone doc now includes more of the outcome, not just the original plan contributor docs no longer have stale semantics structure.md is more accurate to what Flower currently is, and what still needs a fuller rewrite later Yea, thatās it.
Devlog: v1.5.1 ā v1.5.5 Following all of the changes Flower has undergone, I felt it was time for some much-needed documentation. On paper this was supposed to be fairly quick, simple, and not require much brain power. Unfortunately for me I got a bit too over-zealous, and included things I thought should work, but in reality hadnāt. For example, in a lot of the code snippets Iād have something like: for i in range 0..10: print(i) end Printing non-string values was not yet supported in Flower. To fix this, I took a small detour back to v1.4 and implemented support for it ā mostly in a single codegen case: if ast.data._print.value_type.base == TOKEN_FLOAT or ast.data._print.value_type.base == TOKEN_DOUBLE: fprintf(out, "printf(\"%%f\", ") gen_expr(ast.data._print.value, out, src) fprintf(out, ");\n") end Afterwards I added more smoke-tests in examples/io/print.flo . Every few runs, however, Iād get a segfault. This was especially odd because it wasnāt simply an error but rather a silent memory bug. Eventually I found out where it was originating ā thanks, ASan! Turns out after the new type system changes, I had forgotten to initialize some values to null / 0 in for loop handlers and a few other places. I just added typeInfo.data = null / 0 where applicable and it fixed the issue! What is v1.5, and why is this devlog so long? To answer the latter first.. I lowkey just forgot to post a devlog for the first two docs I made. Thatās it. For the former question, v1.5 is supposed to be explicitly a documentation pass. First thing I worked on was structure. I cleaned up the docs layout, moved things toward a more consistent lowercase docs/ tree ā I had been trying for so long to do that and I just finally got it to work ā and wrote down the documentation process itself so new pages arenāt just floating about. The point was to try and make the docs feel like a book instead of a folder full of unrelated notes. I wrote and checked the language pages for types, functions, and control flow by reading the compiler itself, not by trusting my (poor) memory. That meant checking parser rules, typecheck behavior, codegen boundaries, and example files before writing anything solid. Types especially needed this, given how Flower now has enough real type machinery that the docs can quickly go from being coherent to completely incorrect: nullable sugar, semantic unions, explicit casts after narrowing, alias behavior, current member limits, and the difference between what the language wants to become and what the compiler supports currently. Functions and control flow had a similar issue. I had to document prop , return rules, direct call forms, logical conditions, range-based for , and the rough edges like break and continue not yet being enforced cleanly as loop-only. That kind of thing is small until someone learns the language from the docs and hits the edge head-first (been there, done that). What Now? Iām just going to keep writing docs. Maybe do one devlog for every new doc, or a batch of docs, who knows! I certainly donāt :p
Hey, itās been a while! Iāve been finding it difficult to stay motivated for this project, especially with how the new payout system works and just my in-general inability to keep commitment despite having a lot of passion. That said, I am going back to working on this diligently, and I think to start Iām going to cut down on the documentation by making perhaps one or two changes, and then going right back to the compiler work. Documentation writing has not been the most fun for me, especially with how long it takes and how itās so difficult to not only write language reference that works, but also keeping the same whimsy Flower should have. Thank you to everyone whoās been following this journey, and I canāt wait to see yāall later!!! With Love, - Ivy <3
Integer Types, Parser Fixes, and Segfaults! Phew ā this one was biiiiiggg. Flower is pretty much just a glorified C transpiler, which is NOT what I want for it! In order to move on, the data has to be handled explicitly by the FloC. So essentially, I implemented i8 , u8 , i16 , u16 , i32 , u32 , i64 , and u64 . For now, int canonically refers to an i32 value. A New Era? With these new literals, the old hoist-sized representation had to go. The decimal source text is preserved, meaning values such as 18446744073709551615 remain after parsing without causing any overflow. Types are picked up from declarations, assignments, function arguments, return values, field writes, array-element writes, * breath in * and binary expressions! Oof, that was a mouthful. That, of course, resulted in proper errors for things like: 256 assigned to u8 ā1 assigned to an unsigned type values beyond u64 unconstrained literals outside the default i32 range I Hate Memory During printing, every width is handled. Integer conditions retain existing zero / nonzero behavior, and literal types print their values rather than a character. Halfway through, I ran into sudden segfaults and memory leaks. I was taken aback, because I didnāt even change anything parser related yet. Turns out, I forgot an assignment in a declaration, which apparently the parser wasnāt able to handle (whoops!). Anyways, I fixed it by propagating errors through the compilation process, so the compiler doesnāt try to typecheck or code gen if the parser reports back errors, and instead will print them out. And thatās it! Not thatās it, but thatās all Iām going to explain for now. More specifics available on the GitHub, of course. Speaking of GitHub thank you so much to S1monr3dst0ne07 on GitHub for fixing some memory leaks in the previous version of Flower ā I forgot to prune allocations before returning from a function :p Love yāall!! <3 P.S.: So glad I gave up on documentation, I was genuinely dreading workong on the project and thatās why Iāve been ianctive for a long time :c
Integers, Integers, Integers Hello!! Been a while :) Lately I have been working on v1.6. I call it the āUsefullnessā update ā rhymes with Grug ā because it adds a ton of long awaited features and various convenience implementations Flower DESPERATELY needs. For example, currently the progress has to do with v1.6.1, or Fixed-Width Integers . When it comes to systems programming and in-general efficiency, having various integer sizes is important as it provides an additional layer of manual control over memory and sizes. I know I would have to add them eventualy, so why not put them at the start of the Usefulness update?? Iām sure theyāll come in handy later on. What Actually Changed? Well, for starters, thereās now fixed-width integers (yay)! Theyāre built in types, so you declare them as you would with any other atom / primitive: type Byte = u8 type Choice = Byte | u16 type OptionalByte = ?Byte struct Packet { pair: Byte[2], size: Choice, owner: OptionalByte } A whole bunch of commits and integer-specific changes regarding indices, arity, unions, nullables, etc etc etc have been made, and they all wonāt fit here so instead, take a look at the current branch ! Whatās In Store? Plenty more features, you can assure yourself! Thereās maybe 6 or 7 ā I swear ā or so commits left for this specific addition, and after that a lot more features laid out in the roadmap for 1.6! As always, thanks for sticking around and watching the fiasco that is this project become more and more estranged with every hour. Love yāall!! Ivy <3
Ships:
Flower is a self-hosted programming language for writing simple, explicit systems code without the abstraction bloat and OOP-heavy direction a lot of modern languages have. The compiler is written in Flower itself, currently targets C, and follows a straightforward pipeline: lexing, parsing, module loading, typechecking, and code generation. Over the past few months, Flower grew from a small lexer/parser/codegen experiment in C into a way bigger language project than I couldvāe imagined. This wasnāt my first attempt at a language, but it has been my favorite! I implemented compiler-enforced module semantics, stronger type-aware codegen, real boolean support, real string support, and a small standard library foundation. Strings now have equality, .length, indexing, and explicit casts to and from @char , while modules support exported prop declarations, aliases as namespaces, and private-by-default top-level declarations. The hardest part was bootstrap stability. I ran into idempotency failures, parser edge cases, compiler corruption scares, and plenty of my own bad logic. A lot of the challenge was getting new features to work not just once, but consistently enough for the compiler to rebuild itself cleanly. One bootstrap it succeeds, and then the next Iām scrambling to figure out why the new binary executable has a corrupted parser despite just working (Still havenāt fixed that yet! It.. was really confusing and Iāve got no clue why it happened lol). Iām proud that I kept pushing through that and ended up with something much more fun to use than where I started ā I mean, I donāt even have to write that much C anymore!! If people want to test Flower, the important thing to know is that it is self-hosted and still experimental, but it does work. The repo includes a bootstrap path, a test suite, and example programs covering types, control flow, memory, imports, strings, and bools. The current release is focused on making the core language feel real and usable before moving on to a larger standard library and a future non-C backend, so donāt be surprised if a C file is shoved in your face!
The compiler is written in Flower itself and currently targets C, so this release was mostly geared towards making the type system have actual Flower semantics instead of a thin little blanket over whatever the backend happened to be doing. The big additions in v1.4 were: transparent type aliases real null nullable types as ?T == T | null semantic unions like int | string explicit narrowing with is explicit extraction with as That support now works across locals, parameters, return types, struct fields, and stable field-expression chains. The work had to touch parser logic, typecheck, narrowing, lowering, codegen, bootstrap, and then all the weird regressions those changes politely dragged into the room. It was.. a process for sure What Iām most proud of is that v1.4 pushed Flower toward a clearer identity that wasnāt defined by C as much anymore. This release also brought the docs back in line with the compiler, which was LONGGGGG overdue. If you want to test it, the main things to look at are the Better Types examples and the self-hosting flow. The compiler should bootstrap cleanly, the test suite should pass, and the examples now cover aliases, nullable values, semantic unions, inference, and struct/field narrowing behavior. For those who will be testing it, DO NOTE that I develop exclusively on my MacBook which is a UNIX system! I do not have the ability to properly develop and provide releases for Linux-specificalities or non-POSIX systems. Iām extremely sorry for this, but alternatively watch the provided video to see Flower in action :) If youāre not able to test it, watch this short (crappy) video instead: https://youtube.com/shorts/DyPtIru6cjY?feature=share...
|
1793105718.1508975
|
1793192118.1508975
|
|
63239
|
alarm clock - light reaction game by @tika_K | Sta alarm clock - light reaction game by @tika_K | Stardance...
|
tika_K
|
0
|
4.59
|
0
|
[]
|
[{"post_id": 79549, "ts": "202 [{"post_id": 79549, "ts": "2026-10-14T15:44:35Z", "hours": 1.6153, "text": "Iām trying to make my alarm clock a game! You wake up your alarm goes off but if you want to stop it you have to press the buttons that light up as fast as you can"}, {"post_id": 72773, "ts": "2026-09-23T18:36:04Z", "hours": 1.0144, "text": "learning how to use kicad"}, {"post_id": 72666, "ts": "2026-09-23T13:46:23Z", "hours": 1.9575, "text": "I am making a clock into a game"}]...
|
Title: alarm clock - light reaction game by @tika_ Title: alarm clock - light reaction game by @tika_K | Stardance
Devlogs:
I am making a clock into a game
learning how to use kicad
Iām trying to make my alarm clock a game! You wake up your alarm goes off but if you want to stop it you have to press the buttons that light up as fast as you can...
|
1793051256.974137
|
1793656056.974137
|
|
69665
|
SW-Crawl by @Nivedh_Govil | Stardance
|
Nivedh_Govil
|
0
|
0.5
|
0
|
[]
|
[{"post_id": 79551, "ts": "202 [{"post_id": 79551, "ts": "2026-10-14T15:52:07Z", "hours": 0.5042, "text": "SW-Crawl Devlog 1 Brainstormed an idea to recreate the iconic Star Wars crawl animation. I am thinking of writing something and displaying it on a website. The text would move like the text at the start of the Star Wars movies. As I donāt know CSS animations well, I am learning them to build this. I worked on the CSS Styles today."}]...
|
Title: SW-Crawl by @Nivedh_Govil | Stardance
Devl Title: SW-Crawl by @Nivedh_Govil | Stardance
Devlogs:
SW-Crawl Devlog 1 Brainstormed an idea to recreate the iconic Star Wars crawl animation. I am thinking of writing something and displaying it on a website. The text would move like the text at the start of the Star Wars movies. As I donāt know CSS animations well, I am learning them to build this. I worked on the CSS Styles today....
|
1792857295.8745313
|
1793462095.8745313
|
|
34042
|
pengui by @Kanashimo | Stardance
|
Kanashimo
|
0
|
52.77
|
0
|
[]
|
[{"post_id": 79556, "ts": "202 [{"post_id": 79556, "ts": "2026-10-14T16:11:14Z", "hours": 6.4461, "text": "pengui - devlog #8 Hello again! Not gonna lie, but when I found out that stardance is has been extended by another month, I switched myself into procrastination mode. So what Iāve changed? I added ruler As I said before that I wanna do this, I rebranded the project from yasu to pengui (but I havenāt updated the stardance page yet) Fixed all the errors related to clipboard See you next devlog š"}, {"post_id": 73224, "ts": "2026-09-24T16:56:17Z", "hours": 7.5731, "text": "yasu - devlog #7 Itās time to hurry! Hereās what Iāve added/changed since last devlog. added toolbar with fancy fonts added pipette removed glew cuz itās buggy as hell, now using glbinding Iāve also fixed minor bugs, tbh Iām little bit worried that there will be no time left to deploy it to flathub. Anyway, Itās time to work work work. Hereās how itās looking after the changes:"}, {"post_id": 71456, "ts": "2026-09-20T21:18:26Z", "hours": 9.0206, "text": "yasu - devlog #6 So since last devlog Iāve worked on: a modular abstraction layer for the main loop error dialog popup instead of cerr (works with KDE and GNOME, cerr is used as a fallback) adding (very) basic README, for now it only contains build information and even that isnāt complete yet some bugfixes with memory and so on And yeah, thatās it. Refactoring took the biggest part of the time. Now I can move on to other things that Iāve been talking about. Oh, and also Iām thinking about rebranding the project in the near future, I think that this name is silly. See ya."}, {"post_id": 70264, "ts": "2026-09-18T20:43:10Z", "hours": 7.5167, "text": "yasu - devlog #5 THERE IS GLOW EFFECT!11!!!1 After messing with shaders a lot, I finally finished it and the effect is kinda neat. Under the hood Iām using the exponential function to achieve smooth and nonlinear increase of transparency with distance. In reference to the previous devlog, Iāve successfully rewritten shader loader as a class. Probably you will not notice because itās very subtle, but thereās also a tween that scales strength of that glow and it lasts something around 0.5s. Moving on, now Iāll focus on these things: screenshot save & clipboard implementation basic UI configuration rewrite of main loop as a class 𤔠(itās unusable rn due to amount of things in it) I want to achieve something similar that you can see in game development industry, there is a main loop, and every submodule is another script that is attached to it. Each āattached scriptā has their own implementation of init and update method so later it can draw things, assign variables and so on."}, {"post_id": 66886, "ts": "2026-09-12T20:43:01Z", "hours": 10.0272, "text": "yasu - devlog #4 Hello, fortunately Iāve recovered from my bipolar delusion of rewriting it in C. Letās say that this has been a fever dream. When writing it, I completely forgot about the number of C++ functions Iāve been using for convenience. Anyway, Iāve implemented dragging. Now you can drag from one point to another, and the rect with blue borders will highlight the area. It works by rendering the same texture (screenshot) that is in the background. Now Iām fighting with shaders because I want to add fancy dandy animations!!111!1! Iāve implemented a custom loader, but now Iām rewriting it as a class. I canāt show you the classic triangle because it doesnāt work yet See you next devlog!"}, {"post_id": 62270, "ts": "2026-09-05T15:43:00Z", "hours": 5.1053, "text": "yasu - devlog #3 So this has been some time, I was busy with my own things and now Iām back. I have 5 hours of work, but this was something like month or two ago, so to be honest I donāt remember what I was doing. Anyway, I can definitely say that Iāve had a lot of problems with ImGui. And it wasnāt my fault, Iām using Meson WrapDB and there was outdated version that led to memory leaks. When I figured this out, I made a PR to Meson WrapDB with the updated one. Thatās all I remember. I came to the conclusion that I probably want to rewrite everything in C, because every library that Iām using is powered by C, not C++. And the only feature of C++ that I use are classes, but my abstraction layer is bloated piece of junk, so whatever."}, {"post_id": 28336, "ts": "2026-07-14T15:03:30Z", "hours": 3.9608, "text": "yasu - devlog #2 Finally, Iāve finished implementing the abstraction layer, so now Iām free from using C libraries in C++ š„¹ Oh waitā¦.. there is glfw hereā¦ā¦. Anyway, there isnāt any visible progress, so thatās why you can see that awesome screenshot (hope staff doesnāt complain š). The codebase in its logic is practically the same, but now itās packed into a pretty class and I added error handling for everything, so now I can catch every possible exception. Also, I (tried to) get rid of all possible memory leaks and yeah, thatās all. Now itās time for the UI. I repeat myself, but Iām going to use GLFW with ImGui. If someone is curious how Iām going to display the screenshots, hereās the explanation: I make one big screenshot with all monitors (thatās how portals work) Then I separate and crop it, so each monitor has itās own I convert each screenshot to raw pixel buffer For each monitor, I create new window with GLFW and I load the screenshot from that buffer And later Iāll add things like cropping etc. but thatās the part of UI, so I will be talking about it in the future devlogs! See ya"}, {"post_id": 27678, "ts": "2026-07-13T13:43:12Z", "hours": 3.1194, "text": "yasu - devlog #1 Yasu is an acronym of yet another screenshot utility , I was thinking a lot about the name and thatās what Iāve come up with. Why? Iāve been playing a lot with Linux on my servers, but never used it as a main operating system on my desktop. Recently, I finally moved over and I can say that Iām a happy user of openSUSE with KDE Plasma. But there is one aspect, that annoys me. I love the screenshot app from Windows 11 available under Win+Shif+S shortcut, and none of the popular Linux equivalents satisfies me. Spectacle from KDE is slow and bloated with too many features and buttons, I just want to make a screenshot that goes into my clipboard without thinking which button to click. Flameshot is just OK, but in its design itās similar to Spectacle. To be honest, Iām not a fan of screen capture app on macOS too. So maybe later I will add the support for Apple devices. It will not be that hard, because Iām using my own abstraction layer over systemās screenshot function, so Iām going to have implement only that part of the code again. So, thatās how my idea has born. Implementation For this project I went with C++ , and no, Iām not using Qt like Spectacle or Flameshot. Iām planning to use OpenGL via GLFW with ImGui for the screen capture UI, and GTK4 for small settings app. One of my other requirements, is that I want this app to be available on all Linux distros, regardless of the display server ( X11/Wayland ), desktop environment is ( GNOME/KDE ) or window manager ( Hyprland etc.). I donāt have any experience in writing apps for Linux, but after a quick research I found that the best solution for me is use of XDG Desktop Portal , and itās made by Flatpak , so Iāve instant support for it. Double win I can say. As Iāve said earlier Iām writing my own abstraction layer over nativeās screenshot function. So I will be able to implement it both for Linux and later for macOS. And maybe even Windows in the future⦠What Iāve done in the past few hours? Iāve set up the project with Meson as a build system, andā¦. Iāve captured my first screenshot! Take a look at it. In the first place I tried to use ScreenCast because itās gives me much more freedom, but finally due to technical reasons I picked Screenshot , main disadvantage of it is that me as a program, receive an URI to a file on a disk, instead of a raw pixels on screen like with ScreenCast . But for the user, itās much more friendly and safer in terms of applicationās permissions. Also, Iām going to have much less compatibility issues later. And also, the given capture, contains all monitors in one image, so Iāve to separate everything by loading the image into RAM, then calculating where is each monitor with GTK , and finally I crop everything with gdk-pixbuf , so Iām left with separate image for each monitor. Now Iām going to focus on writing the abstraction layer, because I havenāt finished it yet. And after Iāll probably move straight forward to implementing the window with GLFW. That was a lot of text, more than I would assume. I hope someone is really going to read this. š Oh, and Iāve made amazing logo in Figma, hope you like it!"}]...
|
Title: pengui by @Kanashimo | Stardance
Devlogs:
Title: pengui by @Kanashimo | Stardance
Devlogs:
yasu - devlog #1 Yasu is an acronym of yet another screenshot utility , I was thinking a lot about the name and thatās what Iāve come up with. Why? Iāve been playing a lot with Linux on my servers, but never used it as a main operating system on my desktop. Recently, I finally moved over and I can say that Iām a happy user of openSUSE with KDE Plasma. But there is one aspect, that annoys me. I love the screenshot app from Windows 11 available under Win+Shif+S shortcut, and none of the popular Linux equivalents satisfies me. Spectacle from KDE is slow and bloated with too many features and buttons, I just want to make a screenshot that goes into my clipboard without thinking which button to click. Flameshot is just OK, but in its design itās similar to Spectacle. To be honest, Iām not a fan of screen capture app on macOS too. So maybe later I will add the support for Apple devices. It will not be that hard, because Iām using my own abstraction layer over systemās screenshot function, so Iām going to have implement only that part of the code again. So, thatās how my idea has born. Implementation For this project I went with C++ , and no, Iām not using Qt like Spectacle or Flameshot. Iām planning to use OpenGL via GLFW with ImGui for the screen capture UI, and GTK4 for small settings app. One of my other requirements, is that I want this app to be available on all Linux distros, regardless of the display server ( X11/Wayland ), desktop environment is ( GNOME/KDE ) or window manager ( Hyprland etc.). I donāt have any experience in writing apps for Linux, but after a quick research I found that the best solution for me is use of XDG Desktop Portal , and itās made by Flatpak , so Iāve instant support for it. Double win I can say. As Iāve said earlier Iām writing my own abstraction layer over nativeās screenshot function. So I will be able to implement it both for Linux and later for macOS. And maybe even Windows in the future⦠What Iāve done in the past few hours? Iāve set up the project with Meson as a build system, andā¦. Iāve captured my first screenshot! Take a look at it. In the first place I tried to use ScreenCast because itās gives me much more freedom, but finally due to technical reasons I picked Screenshot , main disadvantage of it is that me as a program, receive an URI to a file on a disk, instead of a raw pixels on screen like with ScreenCast . But for the user, itās much more friendly and safer in terms of applicationās permissions. Also, Iām going to have much less compatibility issues later. And also, the given capture, contains all monitors in one image, so Iāve to separate everything by loading the image into RAM, then calculating where is each monitor with GTK , and finally I crop everything with gdk-pixbuf , so Iām left with separate image for each monitor. Now Iām going to focus on writing the abstraction layer, because I havenāt finished it yet. And after Iāll probably move straight forward to implementing the window with GLFW. That was a lot of text, more than I would assume. I hope someone is really going to read this. š Oh, and Iāve made amazing logo in Figma, hope you like it!
yasu - devlog #2 Finally, Iāve finished implementing the abstraction layer, so now Iām free from using C libraries in C++ š„¹ Oh waitā¦.. there is glfw hereā¦ā¦. Anyway, there isnāt any visible progress, so thatās why you can see that awesome screenshot (hope staff doesnāt complain š). The codebase in its logic is practically the same, but now itās packed into a pretty class and I added error handling for everything, so now I can catch every possible exception. Also, I (tried to) get rid of all possible memory leaks and yeah, thatās all. Now itās time for the UI. I repeat myself, but Iām going to use GLFW with ImGui. If someone is curious how Iām going to display the screenshots, hereās the explanation: I make one big screenshot with all monitors (thatās how portals work) Then I separate and crop it, so each monitor has itās own I convert each screenshot to raw pixel buffer For each monitor, I create new window with GLFW and I load the screenshot from that buffer And later Iāll add things like cropping etc. but thatās the part of UI, so I will be talking about it in the future devlogs! See ya
yasu - devlog #3 So this has been some time, I was busy with my own things and now Iām back. I have 5 hours of work, but this was something like month or two ago, so to be honest I donāt remember what I was doing. Anyway, I can definitely say that Iāve had a lot of problems with ImGui. And it wasnāt my fault, Iām using Meson WrapDB and there was outdated version that led to memory leaks. When I figured this out, I made a PR to Meson WrapDB with the updated one. Thatās all I remember. I came to the conclusion that I probably want to rewrite everything in C, because every library that Iām using is powered by C, not C++. And the only feature of C++ that I use are classes, but my abstraction layer is bloated piece of junk, so whatever.
yasu - devlog #4 Hello, fortunately Iāve recovered from my bipolar delusion of rewriting it in C. Letās say that this has been a fever dream. When writing it, I completely forgot about the number of C++ functions Iāve been using for convenience. Anyway, Iāve implemented dragging. Now you can drag from one point to another, and the rect with blue borders will highlight the area. It works by rendering the same texture (screenshot) that is in the background. Now Iām fighting with shaders because I want to add fancy dandy animations!!111!1! Iāve implemented a custom loader, but now Iām rewriting it as a class. I canāt show you the classic triangle because it doesnāt work yet See you next devlog!
yasu - devlog #5 THERE IS GLOW EFFECT!11!!!1 After messing with shaders a lot, I finally finished it and the effect is kinda neat. Under the hood Iām using the exponential function to achieve smooth and nonlinear increase of transparency with distance. In reference to the previous devlog, Iāve successfully rewritten shader loader as a class. Probably you will not notice because itās very subtle, but thereās also a tween that scales strength of that glow and it lasts something around 0.5s. Moving on, now Iāll focus on these things: screenshot save & clipboard implementation basic UI configuration rewrite of main loop as a class 𤔠(itās unusable rn due to amount of things in it) I want to achieve something similar that you can see in game development industry, there is a main loop, and every submodule is another script that is attached to it. Each āattached scriptā has their own implementation of init and update method so later it can draw things, assign variables and so on.
yasu - devlog #6 So since last devlog Iāve worked on: a modular abstraction layer for the main loop error dialog popup instead of cerr (works with KDE and GNOME, cerr is used as a fallback) adding (very) basic README, for now it only contains build information and even that isnāt complete yet some bugfixes with memory and so on And yeah, thatās it. Refactoring took the biggest part of the time. Now I can move on to other things that Iāve been talking about. Oh, and also Iām thinking about rebranding the project in the near future, I think that this name is silly. See ya.
yasu - devlog #7 Itās time to hurry! Hereās what Iāve added/changed since last devlog. added toolbar with fancy fonts added pipette removed glew cuz itās buggy as hell, now using glbinding Iāve also fixed minor bugs, tbh Iām little bit worried that there will be no time left to deploy it to flathub. Anyway, Itās time to work work work. Hereās how itās looking after the changes:
pengui - devlog #8 Hello again! Not gonna lie, but when I found out that stardance is has been extended by another month, I switched myself into procrastination mode. So what Iāve changed? I added ruler As I said before that I wanna do this, I rebranded the project from yasu to pengui (but I havenāt updated the stardance page yet) Fixed all the errors related to clipboard See you next devlog š...
|
1792536509.7266257
|
1793141309.7266257
|
|
68278
|
My pet by @rigid_valmeo | Stardance
|
rigid_valmeo
|
1
|
5.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T08:32:23Z", "hours": 5.0, "multiplier": 5.17, "payout": 0, "blessing": "neutral", "text": "I created IchiPett, a small desktop pet inspired by my actual cat. It features a walking cat, occasional idle animations, an interactive fish that can be dragged toward the cat, and floating hearts when the cat is clicked. One of the most challenging parts was making the cat move around the window while keeping the interactions working properly, especially dragging the fish and making it disappear temporarily before reappearing. Iām proud that I was able to turn my idea into a working project and create the sprites and animations myself. To test IchiPett, users can download the project or its available build, follow the instructions in the README, and try clicking the cat and dragging the fish toward it. By the way, I made the artworks too. Those took me about 45 minutes.", "repo": "https://github.com/rigidvalmeo03/ichi-s-pet", "demo": "https://rigid-valmeo.itch.io/ichi-pet"}]...
|
[{"post_id": 79564, "ts": "202 [{"post_id": 79564, "ts": "2026-10-14T16:58:35Z", "hours": 4.9158, "text": "yayyy im so happy this worked! my cat is purfectly running mwehehehe"}, {"post_id": 77489, "ts": "2026-10-07T06:38:39Z", "hours": 0.5014, "text": "HELPPP why is it showing only the corner of my cat drawing lololol"}]...
|
Title: My pet by @rigid_valmeo | Stardance
Devlog Title: My pet by @rigid_valmeo | Stardance
Devlogs:
HELPPP why is it showing only the corner of my cat drawing lololol
yayyy im so happy this worked! my cat is purfectly running mwehehehe
Ships:
I created IchiPett, a small desktop pet inspired by my actual cat. It features a walking cat, occasional idle animations, an interactive fish that can be dragged toward the cat, and floating hearts when the cat is clicked. One of the most challenging parts was making the cat move around the window while keeping the interactions working properly, especially dragging the fish and making it disappear temporarily before reappearing. Iām proud that I was able to turn my idea into a working project and create the sprites and animations myself. To test IchiPett, users can download the project or its available build, follow the instructions in the README, and try clicking the cat and dragging the fish toward it. By the way, I made the artworks too. Those took me about 45 minutes....
|
1792857193.902813
|
1793721193.902813
|
|
69211
|
arrow kyes by @mazobot | Stardance
|
mazobot
|
0
|
3.37
|
0
|
[]
|
[{"post_id": 79566, "ts": "202 [{"post_id": 79566, "ts": "2026-10-14T17:01:50Z", "hours": 3.3683, "text": "My programing language is based on arrow keys and now algortym for Fibinacci number works"}]...
|
Title: arrow kyes by @mazobot | Stardance
Devlogs Title: arrow kyes by @mazobot | Stardance
Devlogs:
My programing language is based on arrow keys and now algortym for Fibinacci number works...
|
1793130748.1844792
|
1793735548.1844792
|
|
356
|
The Unnamed by @Joko26 | Stardance
|
Joko26
|
0
|
0.0
|
0
|
[]
|
[{"post_id": 7958, "ts": "2026 [{"post_id": 7958, "ts": "2026-06-13T08:56:00Z", "hours": 0.0, "text": "We (Hysedux and I) have added new player sprites and status effects to our new game āthe unnamedā an 2d sidescroller dungeoncrawler inspired by hollowknight and minecraft."}]...
|
Title: The Unnamed by @Joko26 | Stardance
Devlogs Title: The Unnamed by @Joko26 | Stardance
Devlogs:
We (Hysedux and I) have added new player sprites and status effects to our new game āthe unnamedā an 2d sidescroller dungeoncrawler inspired by hollowknight and minecraft....
|
1792576439.6993015
|
1793181239.6993015
|
|
59925
|
My very own WebOS by @shronge | Stardance
|
shronge
|
0
|
0.89
|
0
|
[]
|
[{"post_id": 79602, "ts": "202 [{"post_id": 79602, "ts": "2026-10-14T17:46:23Z", "hours": 0.4608, "text": "Working on my onboarding screen!"}, {"post_id": 67281, "ts": "2026-09-13T10:54:57Z", "hours": 0.4303, "text": "The very basics (github is confusing)"}]...
|
Title: My very own WebOS by @shronge | Stardance
Title: My very own WebOS by @shronge | Stardance
Devlogs:
The very basics (github is confusing)
Working on my onboarding screen!...
|
1793029981.933548
|
1793634781.933548
|
|
65476
|
Personal Website -- 0cean by @0ceanmp4 | Stardance
|
0ceanmp4
|
0
|
0.32
|
0
|
[]
|
[{"post_id": 79609, "ts": "202 [{"post_id": 79609, "ts": "2026-10-14T18:18:45Z", "hours": 0.3244, "text": "So after trial.. failure⦠trial⦠and about 5 million more of those⦠success!"}]...
|
Title: Personal Website -- 0cean by @0ceanmp4 | St Title: Personal Website -- 0cean by @0ceanmp4 | Stardance
Devlogs:
So after trial.. failure⦠trial⦠and about 5 million more of those⦠success!...
|
1793087553.4248307
|
1793692353.4248307
|
|
31948
|
Hackpad by @rishitsahu_2008 | Stardance
|
rishitsahu_2008
|
0
|
14.13
|
0
|
[]
|
[{"post_id": 79612, "ts": "202 [{"post_id": 79612, "ts": "2026-10-14T18:22:02Z", "hours": 0.5333, "text": "I was debugging the LEDs of my board. So I was able to make them work but the wave effect I really wanted is not working. Also 2 of the LEDās are not lighting up , so I will first replace them and then further work on the LED part. Then finally I will make the OLED display work. The 3D printed case will also be there in a week or so."}, {"post_id": 77087, "ts": "2026-10-05T16:41:05Z", "hours": 1.0167, "text": "I had forgotten to record myself while soldering the components on the PCB. Right now I was debugging the code. It was not working . So I was able to make the keypresses work but the rotary encoder and OLED display and LED are still not working. Will try to fix them too as soon as possible."}, {"post_id": 30034, "ts": "2026-07-17T09:13:20Z", "hours": 0.4833, "text": "I have now finally completed my project firmware and named it āClutchpadā (ill use it for gaming). All the files and images have been uploaded to github and will now submit the design and hope it gets accepted."}, {"post_id": 29406, "ts": "2026-07-16T10:33:38Z", "hours": 0.7669, "text": "I am working on the firmware for my hackpad. I am using kmk for it and plan to switch to qmk after a while. It is quite challenging as the docs are kinda tough to understand and there are not many yt videos teaching the concept."}, {"post_id": 27615, "ts": "2026-07-13T11:10:44Z", "hours": 1.2153, "text": "I have finally completed the case for my hackpad. I will now once go through all the design again and make any minimal changes if required. Then ill start woking on the firmware for my board."}, {"post_id": 27576, "ts": "2026-07-13T09:01:09Z", "hours": 1.8003, "text": "Hello. I am currently working on making the backplate of the hackpad. This process is taking quite a time as it is my first time using fusion and designing 3d things. Learning many new things while working."}, {"post_id": 27035, "ts": "2026-07-12T06:17:25Z", "hours": 0.4336, "text": "Hello. I am now working on the case. I imported my pcb design file into fusion. Then i figured which type of keyoard layout would be perfect for me. I did some measurements of my pcb and starting to work on the backplate."}, {"post_id": 26590, "ts": "2026-07-11T14:39:56Z", "hours": 1.1006, "text": "Hello. Today I learned fusion 360 by watching a yt video which tought some basics of using the software. I made a simple assembly using it. Now i will start designing the case for the hackpad and will learn new things as they come on my way. If anyone has any suggestions regarding my project pls let me know."}, {"post_id": 25941, "ts": "2026-07-10T13:21:57Z", "hours": 1.4, "text": "Hello. I have now completed the pcb part. I traced the connections on the pcb. had to reduce the no of LEDās by 4 as they have 4 pins so create kindof a problem when spread. Had to repeat everything again like assigning 3d models, arranging etc."}, {"post_id": 25894, "ts": "2026-07-10T11:54:11Z", "hours": 1.8169, "text": "I started routing my pcb. But then i discovered i had made a huge blunder. I had not connected led to the microcontroller and the orientation of things was not perfect so i had to place vias . many of them. Now ill have to start the pcb design over again. I guess ill even have to remove those extra jumpers that i has previously added . T_T"}, {"post_id": 25781, "ts": "2026-07-10T07:32:24Z", "hours": 0.7656, "text": "I added 3d models for each components in kicad. This took quite a time as i couldnt figure out how to add 3d model into footprint. I have 9 switches and 10 led so had to add the 3d model to each one of them. I tried adding it to the footprint and was even succesfull in that but still the 3d models were not coming into the 3d viewer. If someone has any idea regarding how to asign same 3d model to many pieces of same component in kicad pls let me know in the comments. Also if there is any design change that you think will be helpful let me know."}, {"post_id": 25361, "ts": "2026-07-09T16:39:23Z", "hours": 0.6836, "text": "I arranged the components in the pcb editor. The part that was a little challenging was deciding the gap. I searched of the keycap width and breadth and then spaced accordingly. I also made some changes in the led arrangement and added an led. Also i was facing problem with some footprints i had added so i troubleshooted them as well. Then viewed it in 3d and it seems to be good. I will now add a logo or something to the pcb. Then will start working on the 3d case."}, {"post_id": 25267, "ts": "2026-07-09T12:52:52Z", "hours": 0.6836, "text": "I assigned the footprints to the schematic components. Then i converted in into pcb. However i am facing the problem that the 13th pin of the xiao board is also being assigned as 5v . The same problem is happening in the oled module. I thought that i had downloaded the wrong footprint for the board. but then i downloaded from the official site and uploaded them but still facing the same problem. Later i checked the problem was i had done a huge blundr. All the things are correct just at one place i had mistakenly connected the gnd and 5v. (spent too much time but learned something ). Will now work on designing the pcb and the orientation of components. Pls let me know if you have any suggestions for the same."}, {"post_id": 25241, "ts": "2026-07-09T11:38:03Z", "hours": 0.8172, "text": "I realised that the schematic i designed earlier was too basic and could be done better. So I have now added diodes (as i have to use a matrix design cuz it does the task by utilising only 6 pins of the controller). I have also added an oled display and a rotary encoder. I also thought of adding lights to make it cooler and think of controlling them using the rotary encoder. Also i had a pin left so i have provided headers for that extra pin , gnd, 3.3v, 5v, scl and sda(so if i want to add something in the future it will be much more accessible). Will once again check this circuit for any errors and assign footprints and then design the pcb . Currently thinking for some design ideas for the pcb rather than rectangular."}, {"post_id": 24658, "ts": "2026-07-08T11:56:27Z", "hours": 0.3669, "text": "I designed the basic schematic. Might think of adding a feature or two. Learning while working."}, {"post_id": 24111, "ts": "2026-07-07T14:01:12Z", "hours": 0.25, "text": "Currently working on learning kicad so i can design the schematic and pcb."}]...
|
Title: Hackpad by @rishitsahu_2008 | Stardance
De Title: Hackpad by @rishitsahu_2008 | Stardance
Devlogs:
Currently working on learning kicad so i can design the schematic and pcb.
I designed the basic schematic. Might think of adding a feature or two. Learning while working.
I realised that the schematic i designed earlier was too basic and could be done better. So I have now added diodes (as i have to use a matrix design cuz it does the task by utilising only 6 pins of the controller). I have also added an oled display and a rotary encoder. I also thought of adding lights to make it cooler and think of controlling them using the rotary encoder. Also i had a pin left so i have provided headers for that extra pin , gnd, 3.3v, 5v, scl and sda(so if i want to add something in the future it will be much more accessible). Will once again check this circuit for any errors and assign footprints and then design the pcb . Currently thinking for some design ideas for the pcb rather than rectangular.
I assigned the footprints to the schematic components. Then i converted in into pcb. However i am facing the problem that the 13th pin of the xiao board is also being assigned as 5v . The same problem is happening in the oled module. I thought that i had downloaded the wrong footprint for the board. but then i downloaded from the official site and uploaded them but still facing the same problem. Later i checked the problem was i had done a huge blundr. All the things are correct just at one place i had mistakenly connected the gnd and 5v. (spent too much time but learned something ). Will now work on designing the pcb and the orientation of components. Pls let me know if you have any suggestions for the same.
I arranged the components in the pcb editor. The part that was a little challenging was deciding the gap. I searched of the keycap width and breadth and then spaced accordingly. I also made some changes in the led arrangement and added an led. Also i was facing problem with some footprints i had added so i troubleshooted them as well. Then viewed it in 3d and it seems to be good. I will now add a logo or something to the pcb. Then will start working on the 3d case.
I added 3d models for each components in kicad. This took quite a time as i couldnt figure out how to add 3d model into footprint. I have 9 switches and 10 led so had to add the 3d model to each one of them. I tried adding it to the footprint and was even succesfull in that but still the 3d models were not coming into the 3d viewer. If someone has any idea regarding how to asign same 3d model to many pieces of same component in kicad pls let me know in the comments. Also if there is any design change that you think will be helpful let me know.
I started routing my pcb. But then i discovered i had made a huge blunder. I had not connected led to the microcontroller and the orientation of things was not perfect so i had to place vias . many of them. Now ill have to start the pcb design over again. I guess ill even have to remove those extra jumpers that i has previously added . T_T
Hello. I have now completed the pcb part. I traced the connections on the pcb. had to reduce the no of LEDās by 4 as they have 4 pins so create kindof a problem when spread. Had to repeat everything again like assigning 3d models, arranging etc.
Hello. Today I learned fusion 360 by watching a yt video which tought some basics of using the software. I made a simple assembly using it. Now i will start designing the case for the hackpad and will learn new things as they come on my way. If anyone has any suggestions regarding my project pls let me know.
Hello. I am now working on the case. I imported my pcb design file into fusion. Then i figured which type of keyoard layout would be perfect for me. I did some measurements of my pcb and starting to work on the backplate.
Hello. I am currently working on making the backplate of the hackpad. This process is taking quite a time as it is my first time using fusion and designing 3d things. Learning many new things while working.
I have finally completed the case for my hackpad. I will now once go through all the design again and make any minimal changes if required. Then ill start woking on the firmware for my board.
I am working on the firmware for my hackpad. I am using kmk for it and plan to switch to qmk after a while. It is quite challenging as the docs are kinda tough to understand and there are not many yt videos teaching the concept.
I have now finally completed my project firmware and named it āClutchpadā (ill use it for gaming). All the files and images have been uploaded to github and will now submit the design and hope it gets accepted.
I had forgotten to record myself while soldering the components on the PCB. Right now I was debugging the code. It was not working . So I was able to make the keypresses work but the rotary encoder and OLED display and LED are still not working. Will try to fix them too as soon as possible.
I was debugging the LEDs of my board. So I was able to make them work but the wave effect I really wanted is not working. Also 2 of the LEDās are not lighting up , so I will first replace them and then further work on the LED part. Then finally I will make the OLED display work. The 3D printed case will also be there in a week or so....
|
1792806496.5038798
|
1793411296.5038798
|
|
5762
|
RPGproject by @4ermine | Stardance
|
4ermine
|
0
|
88.46
|
0
|
[]
|
[{"post_id": 79613, "ts": "202 [{"post_id": 79613, "ts": "2026-10-14T18:29:12Z", "hours": 28.2375, "text": "DEVLOG #08 Coming back to this after a long time, Iāve been working on the castle map and office map. The next thing Iāll be doing is adding NPCs, castle wall borders, and the exam gameplay in the office. Whatās New Castle exterior map Castle pan added Castle interior map Office map New additions to train map Camera pan update Whatās Next Finish office and castle maps Use exam code to add the exam to the game NPCs!"}, {"post_id": 41845, "ts": "2026-08-06T09:56:00Z", "hours": 10.6997, "text": "DEVLOG #07 Iāve been working on my castle/academy pixel art recently. I am also planning to add an inventory function⦠Most of my recent work is in the form of just code, so I donāt have anything visual to show for it. Whatās New Code for exam and training system Code for castle pan Whatās Next New maps and pixel art Inventory system?"}, {"post_id": 29371, "ts": "2026-07-16T08:47:50Z", "hours": 12.2011, "text": "DEVLOG #06 Iām currently working on the code for my future entrance exam scene. Unfortunately I donāt have any visuals to post for it yet! Since I havenāt posted my updated battle sequence and NPC follow mechanic despite mentioning it, I dedicate this devlog to showing a little snippet of it."}, {"post_id": 25803, "ts": "2026-07-10T08:30:47Z", "hours": 4.5844, "text": "DEVLOG #05 Almost done with the trainās interior! I still have to add the scrolling bg on the window. Whatās new: Train door animation NPCs in subway car: dialogue, sprites, animations NPC walk/follow mechanic in later game Whatās next: Scrolling bg Polish maps/add objects Enemy attack animationā¦"}, {"post_id": 25210, "ts": "2026-07-09T10:03:45Z", "hours": 16.8678, "text": "DEVLOG #04 The train station map has been updated. Using aseprite, I designed a new train/subway and proper wall tiles for the map. Other new additions: Tutorial battle completed, including scripted loss and second battle with NPC icons and dialogue to aid the player New NPC walking cutscene New dialogue and updated older dialogue to ensure clarity Battle UI instruction panel for keyboard mechanics Forest map updated with redesigned train station as well Whatās next: Animate train doors Add objects and NPCs to station map Complete train interior scene Still working on enemy attack animationā¦"}, {"post_id": 14022, "ts": "2026-06-23T00:20:47Z", "hours": 9.1156, "text": "DEVLOG #03 Itās been a while⦠the overall battle ui is almost done! Whatās new: Adaptable party panel (characters can be added and removed) Action menu with four options + key navigation Unique skills for each party member Items and ability to select target party member Attack menu for writing code (currently only one problem type) Background + enemy drawing Escape button mechanics to exit attack, skill, and items menu Whatās next Finish the attack animation for the enemy Modify first battle encounter to fit storyline goals Add option for a speaker name on top of dialogue box (for new character introductions)"}, {"post_id": 3932, "ts": "2026-06-07T01:53:36Z", "hours": 3.86, "text": "DEVLOG #02 Working on pixel art and adding new tiles + objects to the forest map."}, {"post_id": 1841, "ts": "2026-06-04T01:43:24Z", "hours": 2.8969, "text": "DEVLOG #01 Spent way too long working on the bare bones of the battle UI for the game. No art or background yet⦠but at least it works. Next steps: add functionality to all four buttons add timer to text input box draw player/party panel polish visuals"}]...
|
Title: RPGproject by @4ermine | Stardance
Devlogs Title: RPGproject by @4ermine | Stardance
Devlogs:
DEVLOG #01 Spent way too long working on the bare bones of the battle UI for the game. No art or background yet⦠but at least it works. Next steps: add functionality to all four buttons add timer to text input box draw player/party panel polish visuals
DEVLOG #02 Working on pixel art and adding new tiles + objects to the forest map.
DEVLOG #03 Itās been a while⦠the overall battle ui is almost done! Whatās new: Adaptable party panel (characters can be added and removed) Action menu with four options + key navigation Unique skills for each party member Items and ability to select target party member Attack menu for writing code (currently only one problem type) Background + enemy drawing Escape button mechanics to exit attack, skill, and items menu Whatās next Finish the attack animation for the enemy Modify first battle encounter to fit storyline goals Add option for a speaker name on top of dialogue box (for new character introductions)
DEVLOG #04 The train station map has been updated. Using aseprite, I designed a new train/subway and proper wall tiles for the map. Other new additions: Tutorial battle completed, including scripted loss and second battle with NPC icons and dialogue to aid the player New NPC walking cutscene New dialogue and updated older dialogue to ensure clarity Battle UI instruction panel for keyboard mechanics Forest map updated with redesigned train station as well Whatās next: Animate train doors Add objects and NPCs to station map Complete train interior scene Still working on enemy attack animationā¦
DEVLOG #05 Almost done with the trainās interior! I still have to add the scrolling bg on the window. Whatās new: Train door animation NPCs in subway car: dialogue, sprites, animations NPC walk/follow mechanic in later game Whatās next: Scrolling bg Polish maps/add objects Enemy attack animationā¦
DEVLOG #06 Iām currently working on the code for my future entrance exam scene. Unfortunately I donāt have any visuals to post for it yet! Since I havenāt posted my updated battle sequence and NPC follow mechanic despite mentioning it, I dedicate this devlog to showing a little snippet of it.
DEVLOG #07 Iāve been working on my castle/academy pixel art recently. I am also planning to add an inventory function⦠Most of my recent work is in the form of just code, so I donāt have anything visual to show for it. Whatās New Code for exam and training system Code for castle pan Whatās Next New maps and pixel art Inventory system?
DEVLOG #08 Coming back to this after a long time, Iāve been working on the castle map and office map. The next thing Iāll be doing is adding NPCs, castle wall borders, and the exam gameplay in the office. Whatās New Castle exterior map Castle pan added Castle interior map Office map New additions to train map Camera pan update Whatās Next Finish office and castle maps Use exam code to add the exam to the game NPCs!...
|
1792745362.326075
|
1793350162.326075
|
|
64563
|
GLITCH OS by @singhshiv3108 | Stardance
|
singhshiv3108
|
2
|
30.0
|
34
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T18:46:19Z", "hours": 12.0, "multiplier": 2.82, "payout": 34, "blessing": "neutral", "text": "I updated my webos now it has weather, search bar, two new windows one of them having i frame to show case video , new terminal commands and few smaller features and fixes. Most challenging and frustrating part was actually small or big fixes becuz it used to felt boring and repetitive and thanks to me i added animation at starting , so for everytime i have to check whether my fixes worked i had to go through that torturing animation butā¦.. the thing i am proud about is animation itself . I hope you like MY GLITCH OS!!!!!!. āThank you", "repo": "https://github.com/ShivSingh3108/WebOS", "demo": "https://shivsingh3108.github.io/WebOS/"}, {"ship_num": 2, "ts": "2026-10-06T22:56:51Z", "hours": 18.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a Web OS , Challenging part was handling several similar codes like one miss and half of the windows disappears but later i got used to it. I am Actually proud of Whole project , i got to learn alot out of this.", "repo": "https://github.com/ShivSingh3108/WebOS", "demo": "https://shivsingh3108.github.io/WebOS/"}]...
|
[{"post_id": 79614, "ts": "202 [{"post_id": 79614, "ts": "2026-10-14T18:32:49Z", "hours": 5.9747, "text": "DEVLOG 14: The Biggest and the last devlog . iāll divide this log in 3 parts. 1) Add : i added gallery tab , more videos in glitchtv and next and previous button to control them,few more commands such as contact,weather ,gallery, glitchtv. and added a basic manual in iris window. 2)Style: i improved scrollbar style and added scroll bar to windows that needed it .3) Debug: this is where most time is gone, earlier calendar used to show a junk of grid and to fix it user has to toggle with buttons but in this log i removed that junk or whatever you call that, then i saw that when i type beyond viewport of window in notes my window header disappears so i fixed that , terminal scroll bar was also going beyond the windowheader so i made another div it contain it and conntact command also had to much issue ig becuz of tag atlast i fixed searchbar it was the easy i just added name=āqā in form instead of input tag (there might me more fixes but these were major ones)."}, {"post_id": 79020, "ts": "2026-10-12T11:54:30Z", "hours": 1.4344, "text": "DEVLOG 13 Ig: in this devlog i added search bar. search bar wa easy to put but unfortunatly my header css was so weak no matter what i do it wont align as i wanted but somehow i did it . Coming back to search bar it still needs some fix when i search it doesnt show result instead just stays at google homepage."}, {"post_id": 78749, "ts": "2026-10-11T14:21:24Z", "hours": 1.8347, "text": "DEVLOG 12: In this devlog , I fixed video error actually it wasnt error ig. i searched on youtube and i found out i should use go live extension and it worked . i also added weather and it works for all user!!!! you just have to give it permission , earlier it was only showing my weather but then I surfed on yt for how to make it work for every user and i found . (ngl yt helped alot in this devlog)."}, {"post_id": 78672, "ts": "2026-10-11T08:00:05Z", "hours": 1.5678, "text": "DEVLOG 11: In this log i added booting animation , ngl it was hard more like lengthy , i earlier implemented animation in projects but this time it was big . Glitch TV is not debugged yet cuz i was bored with adding new window , it was repetitive so i thought lets add something ."}, {"post_id": 78133, "ts": "2026-10-09T17:55:34Z", "hours": 1.0669, "text": "DEVLOG 10: First Devlog for web OS 2 . In this log i added fully functional new window/app i.e. Glitch tv which uses I frame to show yt video although currently video arenāt working I tried for while but I will fix it by next devlog ."}, {"post_id": 77422, "ts": "2026-10-06T22:22:29Z", "hours": 4.1797, "text": "DEEVLOG 9: The last and the biggest devlog!!!!! in this devlog i added custom drag ,pointer cursor, new terminal commands, new app icons , fullscreen and minimize button ,improved css and few debugging."}, {"post_id": 76757, "ts": "2026-10-04T14:43:14Z", "hours": 2.135, "text": "Devlog 8: In this devlog i added terminal window , improved style and added a custom cursor."}, {"post_id": 76141, "ts": "2026-10-02T14:10:56Z", "hours": 1.9756, "text": "DEVLOG 7: Fixed several issues with notes window (dragging issue , notesās div obstructing welcome windows icon, and majorly i couldnt type anything in notes tab) and Improved Calendars style."}, {"post_id": 75674, "ts": "2026-09-30T18:22:44Z", "hours": 2.3286, "text": "DEVLOG (I donāt remember no. ;) : In this devlog i added a new app calendar and also made its window draggable , closable and obviously openable. I struggled app opening later i found it was some variable name issue. I used Fullcalendar Javascript library to added dynamic calendar interface, currently its css is bit off but iāll polish it later."}, {"post_id": 74462, "ts": "2026-09-27T12:54:09Z", "hours": 0.94, "text": "Devlog 5 : I added closing and opening of my window ."}, {"post_id": 73684, "ts": "2026-09-25T17:59:42Z", "hours": 2.78, "text": "DEVLOG 4: window is now movable, time had some problem but now it shows accurate timing , css of window was messed up so it took some time to fix also added handle to the window ."}, {"post_id": 72768, "ts": "2026-09-23T18:23:15Z", "hours": 0.6478, "text": "Devlog3: Not much in this devlog just added time and fixed viewport problem ."}, {"post_id": 72343, "ts": "2026-09-22T18:23:12Z", "hours": 1.9675, "text": "Devlog 2:Added Window , blur, and improved style. Currently it is going slightly outside of viewport ,although i fixed it but it still seems off so i might check it once."}, {"post_id": 71892, "ts": "2026-09-21T18:22:00Z", "hours": 0.9389, "text": "Devlog 1: I am making a webos named glitch . In this devlog i did basic setup such as background setup , text, and etc"}]...
|
Title: GLITCH OS by @singhshiv3108 | Stardance
De Title: GLITCH OS by @singhshiv3108 | Stardance
Devlogs:
Devlog 1: I am making a webos named glitch . In this devlog i did basic setup such as background setup , text, and etc
Devlog 2:Added Window , blur, and improved style. Currently it is going slightly outside of viewport ,although i fixed it but it still seems off so i might check it once.
Devlog3: Not much in this devlog just added time and fixed viewport problem .
DEVLOG 4: window is now movable, time had some problem but now it shows accurate timing , css of window was messed up so it took some time to fix also added handle to the window .
Devlog 5 : I added closing and opening of my window .
DEVLOG (I donāt remember no. ;) : In this devlog i added a new app calendar and also made its window draggable , closable and obviously openable. I struggled app opening later i found it was some variable name issue. I used Fullcalendar Javascript library to added dynamic calendar interface, currently its css is bit off but iāll polish it later.
DEVLOG 7: Fixed several issues with notes window (dragging issue , notesās div obstructing welcome windows icon, and majorly i couldnt type anything in notes tab) and Improved Calendars style.
Devlog 8: In this devlog i added terminal window , improved style and added a custom cursor.
DEEVLOG 9: The last and the biggest devlog!!!!! in this devlog i added custom drag ,pointer cursor, new terminal commands, new app icons , fullscreen and minimize button ,improved css and few debugging.
DEVLOG 10: First Devlog for web OS 2 . In this log i added fully functional new window/app i.e. Glitch tv which uses I frame to show yt video although currently video arenāt working I tried for while but I will fix it by next devlog .
DEVLOG 11: In this log i added booting animation , ngl it was hard more like lengthy , i earlier implemented animation in projects but this time it was big . Glitch TV is not debugged yet cuz i was bored with adding new window , it was repetitive so i thought lets add something .
DEVLOG 12: In this devlog , I fixed video error actually it wasnt error ig. i searched on youtube and i found out i should use go live extension and it worked . i also added weather and it works for all user!!!! you just have to give it permission , earlier it was only showing my weather but then I surfed on yt for how to make it work for every user and i found . (ngl yt helped alot in this devlog).
DEVLOG 13 Ig: in this devlog i added search bar. search bar wa easy to put but unfortunatly my header css was so weak no matter what i do it wont align as i wanted but somehow i did it . Coming back to search bar it still needs some fix when i search it doesnt show result instead just stays at google homepage.
DEVLOG 14: The Biggest and the last devlog . iāll divide this log in 3 parts. 1) Add : i added gallery tab , more videos in glitchtv and next and previous button to control them,few more commands such as contact,weather ,gallery, glitchtv. and added a basic manual in iris window. 2)Style: i improved scrollbar style and added scroll bar to windows that needed it .3) Debug: this is where most time is gone, earlier calendar used to show a junk of grid and to fix it user has to toggle with buttons but in this log i removed that junk or whatever you call that, then i saw that when i type beyond viewport of window in notes my window header disappears so i fixed that , terminal scroll bar was also going beyond the windowheader so i made another div it contain it and conntact command also had to much issue ig becuz of tag atlast i fixed searchbar it was the easy i just added name=āqā in form instead of input tag (there might me more fixes but these were major ones).
Ships:
I made a Web OS , Challenging part was handling several similar codes like one miss and half of the windows disappears but later i got used to it. I am Actually proud of Whole project , i got to learn alot out of this.
I updated my webos now it has weather, search bar, two new windows one of them having i frame to show case video , new terminal commands and few smaller features and fixes. Most challenging and frustrating part was actually small or big fixes becuz it used to felt boring and repetitive and thanks to me i added animation at starting , so for everytime i have to check whether my fixes worked i had to go through that torturing animation butā¦.. the thing i am proud about is animation itself . I hope you like MY GLITCH OS!!!!!!. āThank you...
|
1793058962.5451574
|
1793145362.5451574
|
|
30441
|
Weather Underground Station Status Checker by @Kru Weather Underground Station Status Checker by @Krupam | Stardance...
|
Krupam
|
0
|
180.79
|
0
|
[]
|
[{"post_id": 79620, "ts": "202 [{"post_id": 79620, "ts": "2026-10-14T18:51:09Z", "hours": 9.4867, "text": "Weather Emails, mobile tweaks, map zoom Soooooooooooooo close to shipping. Map Zoom: The Map will now automatically zoom based the center of the points. Humidity and Dew point data collection: The place the data was being scraped from got changed so I had to update the logic. Weather Emails: Created another CRUD for another email list. This list will get a monthly email summarizing the weather for the past 30 days for each of the stations. I created the web page for it, but need to finish cleaning it up, allowing people to sign up for the service and make the emails send automaticcally. Mobile Tweaks: The mobile version of the website did not look good. I spent a lot of time trying to fix it before I was able to get it to look like this!"}, {"post_id": 77451, "ts": "2026-10-07T02:02:30Z", "hours": 7.9642, "text": "Map! And Develop mode Map I used ArcGISās JS to create a map tab that show cases all stations that have a latitude and longitude value. I am working on getting them on the first ever scrape but you can also edit them within the settings page. There is a link that takes you to the station page as well. Develop Mode Created a toggle within the .env file. If on, the program will use the SQlite db and be able to run on VS Code for example. When it is off, it needs the PostGRESql db to function. Docker Docker is really infuriating lmao. Spent most of my time fixing tiny bugs."}, {"post_id": 74611, "ts": "2026-09-27T19:29:59Z", "hours": 9.5544, "text": "Docker Deployment (ALMOST finished) Hey guys! Docker: I am using Docker for deployment of this system to make it easy for anyone who has a weather station or network of them to showcase and monitor their own data. Docker is a type of virtualization (similar to VMs but instead sharing the kernel) that is a lot less resource intensive and is used for deploying a lot of small projects as well as any type of home labbing work flow (hosting your own server etc.). (Yes I pulled that explanation from my last devlog lmao). I will have a tutorial in the ReadME. Within the docker stack, there are several containers with different jobs and responsibilities: Web: Hosts the FastAPI webserver. It uses a endpoint (/health) to monitor the servers responses. It is hosted on port 8000 by default (configurable in the .env file). I would forward this through Nginx or a Cloudflare tunnel to host it under your own domain. Scraper: Runs the status and weather scrapers every 15 and 5 minutes (offset by two mins) respectively through a crontab file ( scraper.crontab ). It is run using Supercronic. The scraper waits for the web server as well. Flock is used to prevent two instances of a program. DB: PostgreSQL server that holds all of the data. Weather data, users, etc. All of the other containers wait till the DB is healthy to start. Db_backup: A container created by Prodrigestivill to automate backups of Postgres databases. I have it configured to keep the last month and 14 days of backups. It saves all backups to the /opt/mesonet-backups folder. I wrote scripts in order to test restoring backups (creates test table, restores using latest backup, and deletes it), create a manual backup, and restore the last backup. Email Alerts: Fairly similar to how emails are sent in the status-scraper, it obtains admin recpients from the web sever uses enviroment vairbales to send an email. It asks for subject and text using arguments in the terminal, so the user can send emails manually to admins as well. Health-tests: Runs a couple of health based scripts on a Supercronic schedule. Monthly restore test (runs the restore test mentioned before) and a daily backup health (checks how old the backup is). Emails will be sent to admins if the restore fails or the backup is more than 26 hours old. Persistent Storage: All the containers used volumes that continued even if the containers were deleted to be updated, the data (and the backups) are fine."}, {"post_id": 72413, "ts": "2026-09-22T21:20:07Z", "hours": 8.7489, "text": "Docker and Environment Variables Hey guys! It has been a couple of days⦠Time Crunch: So I looked on my calendar a week ago and realized that Stardance was almost over, and thought āthis is plenty of timeā. Then a couple of days ago I really felt the pressure. I wanted to get this out before the program finished so I started on the final bits and deployment to turn this into a usable system. Docker: If you donāt know what docker is, count your lucky stars. Just kidding, its very cool when it works . It is a type of virtualization (similar to VMs but instead sharing the kernal) that is a lot less resource intensive and is used for deploying a lot of small projects as well as any type of home labbing work flow (hosting your own server etc.). I have worked with docker with pre-built images and containers before and never really went into the DIY portion. This was my first intro into it and I had to do a lot of googling and the such. It was really frustrating and required quite a few head banging. NOTE: I did use AI sometimes (tried as little as I could) to get docker working. You can see me sometimes using it in my lapse recordings, but I tried to keep it closed as long as I could to stop me from using it :D. Environment Variables: I was told that hard coding my config values in a config file was a bad ideaā¦and it makes sense. It took a bit, but once I setup environment variables, oh man did it get so much better. This also makes it a lot easier in docker to setup the container. Very happy about this. Help from a friend! I told this story a couple of weeks ago, but one of my friendās dad found my repo and left a couple of issues on my page and these were my last two. I really gotta thank him for these ideas."}, {"post_id": 69905, "ts": "2026-09-18T01:25:16Z", "hours": 7.5397, "text": "API Email Calls, Hardware specifications, Docker? Hey guys, School started two weeks ago, so my posts will be a little delayed lol⦠API Email Calls: I originally hard coded my email lists for Reports, station-specific, admin, and global emails, but I wanted to unify them with the rest of the API. I spent a lot of time creating columns in SQL, endpoint CRUD, settings HTML page CRUD, as well as changing the scrapers to pull the lists and use them. Hardware specifications: I added columns in SQL to add Hardware metadata for the stations. It can be seen in all dashboards (see photo) Docker: I was thinking of creating a docker container for this setup to make deployment easier. Would that be something you guys would like to see? Let me know."}, {"post_id": 59930, "ts": "2026-09-01T23:50:25Z", "hours": 5.4425, "text": "Robots.txt, User login error, API security, credit footer, station hardware Whats up? Robots.txt: For those who donāt know, a ārobots.txtā tells scrapers and any bots where they allowed to go on your website. I only allowed them to go on public html pages. However this is only a recommendation, the big guys can do whatever they want. User Login Error: I had this error where any public accounts (or not admins) would get a error when logging in. I was searching for permissions with the wrong column in the database š
. API Security: I made sure there were no open routes and everything was secured. Credit Footer: This was pretty cool. At the end of ever page, I added this little footer with my name and a link to the github repo. Station Hardware: I added a new column to store station hardware info. This is mainly for what weather station model it is. Ex: Davis Vantage Pro2. I am working on making the update form in the settings page allow to update this info as well as more station info."}, {"post_id": 57799, "ts": "2026-08-30T02:58:26Z", "hours": 6.3317, "text": "Some Help and ReadMe! The project is almost done! (why do I feel like I will be saying that a lotā¦) Some help! Today I saw interesting post on Facebook about a website someone my age built and I commented it on it asking if I could see the code cause I was curious if they used Flask, FastAPI, etc. I also posted my project and to my surprise, the poster is actually my friendās dad (small world am I right) and he reviewed my code and left a few issues on it. He even downloaded it to update my requirements.txt. I then merged his request. Thank you for all of your help! ReadMe: I spent all of today working on the readme, you can read it here . However here is a little sneak peak: Hey! My name is Krupam, and I am a nerd. If you are reading this, you are most likely one as well. I love weather, and learning about it. Other people who love weather will create and host Personal Weather Stations (PWS) and post the data to websites like Weather Underground. I have used these stations for my own research projects. Check one out!. In my area, there is a mesonet (regional network of PWSās) from the Save Barnegat Bay non-profit (check them out, they are awesome!). I have used plenty of their stations in my research. I was given the amazing opportunity to present my research at one of their meetings regarding their mesonet. It was eye-opening! As I listened into the meeting, they discussed one of the current issues; they could never tell when a weather station went down. The station owners would find out days after if not weeks. This program is the solution to that and more. The system is a weather-station data platform and monitoring system. The system collects data from Weather Underground (WU), turns it into usable information, and alerts station owners and administrators when a station needs attention. All data is shown on the website in a easy, user-friendly approach. This includes dashboards, graphing, analysis, scientific tests, and admin controls (accessed through JWT-based auth). The system is coded mostly in Python and there are three main systems: The weather and status scrapers, backend, and frontend website."}, {"post_id": 55719, "ts": "2026-08-27T18:10:45Z", "hours": 8.3564, "text": "Settings Page, API Stations List Call for Scraping System Hey! Here is what I have been up to⦠Settings Page: This is a Admin only page (will pop up in nav bar when admin) that configures, deletes, creates, the main functionalities. This includes stations and users. After every function is run a error/success message will show with detailed intomation depending on the function. These Functions include: Modify User: Change role, username, password Register User: Create Delete User Read User Assigned Stations: Choose a station, the page will reload and show all stations the user can access. Grant User Access: Choose a user, and give them access to a station. This is view only by default Revoke Access: Remove User access to a specific station. On reload after choosing a user it will show any assigned stations Update User Access: Choose a user, on reload it wil show all available stations and when selected, will show what access it has. You then check/uncheck the access you want it to have and submit. Modify Station: Currently only allows to change station name. Create Station: Enter new id and name as well as options to be public and in maintenance mode (default off). Delete Station: Deletes station only from the current stations. Does not delete data. I need to rewrite this to make it so it stops collecting data instead. Read all Stations: Lists all stations and if they are in maintenance or not API Stations List Call I realized around 11 at night that I did something very dumb. All of the stations in the configs for the Weather and Status scrapers were hard coded values and were NOT synced with the current stations database. To combat this, I added a new column to the Stations database table. This column was called collect_active or something of the sort. I plan to migrate the delete function to turning off the collection. I then changed the scrapers to pull a new current list at every run and used that as their truth. I finished this around 3 AM last night š . If you guys have any other ideas, let me know!"}, {"post_id": 54509, "ts": "2026-08-25T15:13:24Z", "hours": 8.2236, "text": "Admin Settings Page (WIP) Settings Page: Now that the main functionality of the site is finished, I started making HTML representations of all the methods I have predefined. This includes CRUD (create, read, update, and delete) functions for several pieces of the website. Here are the ones I started to make: Reset/Update User password, username, role. Register Users Delete User Read User Assigned Stations Grant User Access to a station Revoke User Acccess to a station Modify User Access to a station. Everything uses HTLM forms and when they submit, they will return a pop up success or error message. There are a couple of other features I forgot that I made (Such happens when coding at ungodly hours) but anyone can try out the website (if I am working on it at the same time) at https://sbb.krupamlab.com"}, {"post_id": 54016, "ts": "2026-08-24T19:16:15Z", "hours": 8.4358, "text": "CSV Downloads, Weather Table, Error Details on pages, and a profile indicator! Letās jump into it! CSV Downloads: For graphing, analysis, tests, and table pages, I created CSV downloads. Graphing: Downloads raw data Analysis: Downloads analysis summary and raw data Tests: Downloads test results and raw data Weather Tables: Downloads raw data Weather Tables: In the public dashboards, there is now a table at the bottom with all data from the current day. There are quick buttons to go forward and back a day as well as a day input and go button. Profile Indicator: It is just a blank profile picture icon with your username next to it. It only shows when logged in. When clicked it sends you to the my-stations page. Error Details: If there are specific error details in the backend, they will be sent to the error page. Otherwise a generic 40X error will be show"}, {"post_id": 47248, "ts": "2026-08-15T01:38:47Z", "hours": 8.2772, "text": "Testing Page Finished! (without csvsā¦) HTML Form Bug Fixes: Sup guys, here is what I have been up to⦠Testing Page: Oh man this was pretty hard. I actually had writers block but for code. I just couldnāt think of a solution. I just sat there trying to think of how to implement the system. With enough brute force however and some breaks, I did manage to get it working. What is it? This page allows the user to run scientific tests. These tests include Linear Regressions, ANOVAS, and T-Tests. Linear Regressions look for a relationship between variables. ANOVAS and T-tests determine if there a difference between groups of data (single variable). Functionality: The form will ask the user to choose a test, station, variable, unit, and time range, as well as test-specific inputs to run a test. Once the user submits the test, it will either return a graphical result (for the Linear Regression) or stats of the T-Test or ANOVA. The Tests will only make groups depending on the same time frame but different stations. (I only decided to do one for simplicity) This all works but I need to create the ability to download the csv of the data used for the tests. General Inputs: Test Type (T-test, ANOVA, Linear Regression) Range Type: (Relative or Date) Last ___ (hours, months, etc) Start and end date Units (Imperial or metric) Test Specific Inputs: When a test is chosen, test-specific inputs appear. (this happens for other forms such as graphing and analysis pages. I just forgot to mention it) The appeared inputs are then required (like the other default inputs like time, etc) but when a different test is choosen the required inputs are updated with the new ones. These include: Linear Regression: Station X Variable Y Variable Regression T-Test: Outcome Variable Station A Station B ANOVAS: Outcome Variable Station A Station B Station C HTML Form Fixes: I went through all of the Forms that have inputs that switch and make them work nicely with the backend. I make inputs that switch be required and seen at the right time."}, {"post_id": 42348, "ts": "2026-08-07T00:58:02Z", "hours": 10.1181, "text": "Testing Page (Still WIP), General Bug Fixing, and Site Cleanup Yikes, I got reaaaal close to hitting the 10 hour limit for these devlogs š
⦠Site Cleanup I am really proud of this one. I finally took time to go around and get most of the small detailed squared away. I got the site favicon (small icon in the web tab) and other meta data information fixed (like the .webmanifest) working. I also spent a good chunk of time creating the home page and making it look professional. General Bug Fixing I took some time to go through the website and found some tiny bugs. I also had a few of my friends test out the website (they didnt break it!!!!). Small stuff like making it easier to see the graphs, titles on the tabs, etc. Test Page This page is like the ultimate boss for me haha. I would like this page to contain linear regressions (LR), ANOVAS, and T-tests. These are scientific tests used to find statistical differences in data. (see the below screen shot for a better explanation of all of these tests. The user chooses a station, range mode, range, units, and the type of test. Then based on that test, a few options are given: LR: X Variable Y Variable Title Mode A: Choose 1 station but two time ranges (same variable) Mode B: Choose 2 stations with one time range (same variable) ANOVA: Mode a/b Three or more time ranges/station depending on mode Two ranges/station depending on mode"}, {"post_id": 39249, "ts": "2026-08-02T03:01:23Z", "hours": 8.5142, "text": "A Variable Analysis Page and Graphing with a date system! Hey guys! Here is what I have been up to⦠Graphing Date System: As well as a ālast _ ____ā system (relative range), I created a version that allows me to choose āDate Range.ā Date Range allows you to choose between two dates. It sounds simple but was a lot harder to code š
. As I wrote most of the code while being really sleep deprived, take a look over at @app.get(\"/graph/weather/{station_id}\") on the projectās github page. (I recommend using ctrl + f to find it) Variable Analysis Page: This page is pretty similar to the graphing page (see previous devlogs) where it uses a HTML form with query variables to create calculations. The user selects a weather station, variable, range mode (relative or date), inputs for that mode (hours/date, etc) and the units. Then the latest, minimum, maximum, mean, median, range, sample value (n value), and the overall trend (falling, steady, rising, insufficient data). The time will also be shown if applicable (latest value). You can then download a csv of all the data the calculations were derived from. Under that is another box showing the full time the data is collected from as well as the units Future: I still need to add a tab for more advanced analysis such as linear regressions, anovas, t-tests, etc. If you guys have any more ideas, Let me know!!!"}, {"post_id": 35547, "ts": "2026-07-27T01:45:56Z", "hours": 5.8625, "text": "#Graphing Page!!! As well as other bug fixes⦠Graphing Page This page is created by making a HTML form and submitting as a POST request to the same method that creates the dashboard graphs. All the graph information is a query request (the infomation after a question mark in a url, see photo). This means you can bookmark a graph to see the most recent data with your own personal preset. The user must select the station (from a list), type a title, the time range, (last __ unit), and the variables they would like. They can choose as many variables as they would like. There are also variable type presets a user can choose. It will preset everything to make the graph including the time range and title. Once a graph is generated, it will be displayed with the options to download it as a png, download the csv data, or the clear the graph. I am working on a date range next as well as the analysis page with linear regressions, t-tests, ANOVAS, etc. Bug Fixes I had a couple of friends test out the site to find some bugs, and boy did they deliver. They managed to point out some logical errors I had, and I fixed them."}, {"post_id": 34238, "ts": "2026-07-24T19:31:03Z", "hours": 9.2097, "text": "Owner Dashboard (finished), Maintenace and Public Toggles, Dashboard Graphs, and Graph Page (WIP) A lot has happened, lets dive into it: Owner Dashboard: This dashboard may not look very different from the public dashboard but it hold a lot more features: Status widget with the status time and last status. A green check if online or a red X if not. If offline, no weather data/widgets are shown and instead a gear widget with more information is shown. This includes if a alert was sent, last time connected, first time offline, and consecutive offline checks Maintenance and Public toggles Maintenance toggle: If in maintenance mode, no emails will be sent about the status of the station but it will still be logged. Public toggle: If off, the station will not be shown in the public dashboard list. If you try to go to the url directly it will show a āStation Not availableā Page. Dashboard Graphs Graphs are created using Matplotlib and show cased on both dashboards. This includes solar, precipitation, pressure, and temperature graphs. Graphing Page (and analysis) This page is currently being worked on but will allow anyone to choose the time range, variables (yes multiple!), station, and unit. I also want to have a section for analysis like regressions and so on. Lmk how this is looking so far!"}, {"post_id": 33234, "ts": "2026-07-22T23:24:27Z", "hours": 8.8756, "text": "Owner Dashboard (WIP) and Maintenance Toggle Welcome back to a episode of me going insane! :D (jk) Owner Dashboard (WIP) The owner dashboard is a dashboard that is separate from the public dashboards. You must log in to access a page called āMy Stationsā. This page lists all stations that your account has permission to view. The account that you are using must have the station added by a administrator (rn all of those methods are in the docs. I plan on moving them to html soon) Purpose of Owner Dashboard The owner dashboard holds some extra functionalities based on the status: Online It will show a green or red icon based on the status (along with the circle up by the units toggle) and display the exact time and status of the station. The time of status is separate from weather. If you have the permissions to do so, you can then toggle the maintenance and public modes. (Only maintenance mode has been implemented thus far) The maintenance mode stops any emails from being sent about the station Public mode will allow the stationās public dashboard to be listed on the website. Offline: Shows everything in online*. Does not show weather data Displays how many times the station has been shown to be offline. (consecutive offline) The time of last connection. First offline (this is when the station is set as offline) If an alert email was sent Let me know if you guys have any ideas!"}, {"post_id": 30867, "ts": "2026-07-18T20:24:01Z", "hours": 7.3928, "text": "Public Dashboard and dashboard widgets!!! I had a lot of fun with this⦠Public Dashboard This is a public webpage anyone (no need to log in) for each station, listing the current weather conditions and status in a nice gui. In here are some widgets I made by myself all in CSS and HTML. (I donāt like JS if you couldnāt tellā¦) These weather values include: Temperature Dew Point Humidity Precipitation Rate Precipitation Accumulation UV Index Solar Radiation Atmospheric Pressure Wind Speed Wind Gusts Wind Direction Dashboard Widgets: I made a couple of widgets that update based on the values: Temperature Pressure Wind Temperature: A small thermometer that fills up as the temperature gets higher. (I have to rescale it for Celsius) Pressure: A small barometer that changes based on the pressure. The center pressure (29.92) is the atmospheric pressure at sea level. Wind Speed: A little compass shows the cardinal through tertiary wind directions (16 directions). The current wind is represented by the blue arrow. The arrow is where the wind is coming from (how wind is properly notated) Let Me know if you guys have any other ideas, I would love to hear em!"}, {"post_id": 29927, "ts": "2026-07-17T03:08:44Z", "hours": 7.7744, "text": "Working Error Pages, User Updates, Logouts, Weather Post/Weather History and a (partial) public dashboard Been a couple of days guys, here is what I have been up to: Error Pages: Whenever there is some sort of error such as 404 (not found), 401 (unauthorized), 403 (Forbidden), you will get forwarded to error pages. These pages will prompt you to return or log in, depending on the error. User Updates: Admins can know easily update usernames, passwords, roles, etc. However this is still in the API and not a webpage yet. Logouts: When you sign in, your menu bar will no longer have a sign in option (shocker) and has an option to log out. This ānewā menu bar is created using jinja2 if-statements in the layout.html. Weather/Weather History: A Weather Underground Scraper (I made this for a seperate project, check it out: https://github.com/Krupamc/weather_underground_datascraper ) gathers weather data for each station (returns a null filled json if station is offline) and posts it to the API. The API stores it in the database. We can access the current weather for each station as a well as the history. The default history is 20 entries but can be extended with queries. Public Dashboard: Now this is the fun one. This pulls the current status, weather values, time (as a date and timestamp in a readable format), as well as wind direction in label format (e.g. NNE) and sends it to the public dashboard. The dashboard then takes the values and puts them in an easy format. It is not finished, I plan to have pressure, temperature, and wind widgets that change based on the current values."}, {"post_id": 27946, "ts": "2026-07-13T21:48:30Z", "hours": 4.7169, "text": "Registration Form, Posting Status, Status History Hola guys! Registration There is now a registration form! It takes in a username and password and creates a user. However this user has no permissions and the person has to contact the admin to give them permissions. (in the future, a regular base user will still be able to do more stuff, see more detailed data maybe? But I donāt want to block data based on accounts. Maybe emails of your favorite stations?) Posting Status When the status checker runs, it will send the results over HTTP post to the database (DB) to be saved. The ācurrentā Status DB model is overwritten by new data, but if there is a change in the status in any way, the change will be saved to the Status History DB Model. Time Another tiny detail is that before the status checker would store time in local time, but I changed that to be UTC time. UTC time is now universal and I plan to display the time in the local timezone based on the browser time zone. Easter Egg I added a easter egg in the website, I wonder if someone will find it⦠Thanks for reading these devlogs, this is not necessarily a fancy/flashy project and it means a lot when someone does ā¤ļø."}, {"post_id": 27422, "ts": "2026-07-12T23:48:53Z", "hours": 2.1436, "text": "LOGIN FORMS!!! And Station Lists⦠Hey guys! Whats up? Iāll tell you whats up, the moon. š
Dad jokes aside, I am really excited to update you. Login formsā¦how exciting Wait wait I can explain. It is cool I swear. When you input your credentials into the form and submit it, it will check the database (DB) if you have the right ones. If you donāt you will get the invalid screen shown below (I definitely didnāt forget my own passwordā¦). But if you put in the right credentials, you will be given a access_token cookie. This cookie will let you stay logged in till the cookie expires (set for 30 mins ). Once you are logged it, it will direct you to your account dashboard and show you all the stations you have access to. (I didnāt make that one yet but shhhhh) Station List When you click on the Weather Station tab, it will show you a list of every single weather station in the network. Something else cool, whenever you hover/click a button, it will change color. Just fun for me. Save Barnegat Bay I am building this system as a idea I had for the Save Barnegat Bay (SBB) non-profit organization. I utilize their weather stations all of the time for my projects that I love giving back to their mesonet! Once I am finished building this, you will be able to access the SBB weather stations and see weather points as well as graphs and stuff. Oop canāt spoil all of my planned features"}, {"post_id": 27355, "ts": "2026-07-12T20:56:47Z", "hours": 8.9144, "text": "Website Backend, JWT, and HTML Front End Ok, these dev logs keep getting exponentially longer and longer ;-; What the hell is JWT? JWT (JSON Web Token) is a way for my authenticate a user. It essentially is how I can do logins. When a user is registered, their username and hashed password is stored in the SQL database (DB). When someone would like to authenticate, their password is hashed and sent with the username. The DB check if the username and hashed password match and send back a JWT token that expires after a set time (30 mins but configurable). During this time the user would be able access their station dashboard, etc. Admin accounts have the same log in procedure. They however have the power to give each user (based on their user id in the DB) access to specific stations. This includes the ability to see the station dashboard, toggle maintenance mode, and toggle if the station is public (on our site). Backend: Added functions for creating accounts and logging in. Most functions now require either a general account or a admin account. If this is not fulfilled a 401 error is sent (Unauthorized error). As of right now, only admins can register accounts. The access to each station can be updated by a admin at any time. I did some more stuff but I honestly forgot :) HTML Front End This was honestly my favorite part so far. I started by getting the Jinja2 template system to work as well as mounting the static directory. The layout.html file allows me to change it slightly for every page. That is a bad explanation but it is a really cool system. I got the home page done (needs some text and description but thats a later me issue). I am working on getting the general station page. It will list every station and allow you to click on them to get forwarded to that stations public dashboard. Sanity Check? I am having so much fun with HTML. It gives a certain gratification that SQL canāt give. I feel very happy :D Any ideas pls let me know!"}, {"post_id": 26761, "ts": "2026-07-11T18:56:34Z", "hours": 4.8619, "text": "SQL Database, Website Backend, Dashboard When I said a lot last timeā¦that was nothing compared to now ;-; What am I going on about? Well, I wanted a way for station owners to be able to be able to toggle maintenance mode without the admin (whoever deploys this for their own mesonet) directly editing a json file every time. One thing led to another and now I am making a website⦠Website Plan: This website will run on a FastAPI backend with either Jinja2 or Htmx front-end. There will be a public ādashboardā where anyone can take a look at general station stats and current weather conditions. The weather conditions will also be made graphical with Matplotlib. Historical data will also be accessible. However on the same site, people will be able to log in. Logged in users will be able to access only certain stations they are allotted. They will have a more detailed dashboard with more stats. Certain users will be able to toggle maintenance mode and some wonāt. Admin accounts will be able to see and toggle for all stations. Usernames and passwords will be hashed and saved in the database. The log in system will also make use of cookies/sessions to keep the user logged in. Planned SQLite Models users: (DONE) id username password_hash role (admin, station staff, etc) user_station_access user_id station_id can_view can_toggle_maintenance stations: id station_id is_in_maintenance is_public station_status: station_id last_status consec_offline first_offline last_conected alert_sent station_current_weather: temp dew humd wind_speed wind_gust wind_dir pressure precip_rate precip_accum uv solar Progress? I have made all the models and created basic routes. There is a CRUD (Create, Read, Update, and Delete) for the stations based on another config file. On start, the program will automatically create database entries for new stations and delete ones not in the config file."}, {"post_id": 23865, "ts": "2026-07-07T01:43:32Z", "hours": 3.6336, "text": "Monthly Reports, CSVs, and a little bit of Insanity Hey guys, I have done so much, I might go insane haha! Reports? Every first of the month at 8 AM, a email will be sent out to any emails configured for them. They contain various stats such as, which stations are down, which have been down for the longest, uptime percentage, etc. Emails So I just realized that I never explained all the different emails haha. Recipients: Admin: Email(s) configured to recieve only system error emails Global Recipients: Email(s) configured to receive all emails sent by system concerning status. Report Recipients: Email(s) configured to receive monthly emails. E.g. Mesonet maintainers Station Recipients: Email(s) configured separately for each station. E.g. station owners. Email Types: Offline: Sent after a station is recorded off 3 (default) times in a row. Recovery: Sent once a station is detected to be online after being considered offline Reminder: Sent after 7 days (default) to remind of the status. Monthly Reports: Sent at the first of the month at 8 AM (default) with statistics such as which stations had outages, the station with longest, uptime percentage for each station, etc. System Errors: Sent to system admins for any errors detected, HTTP, Requests, Time, etc. CSVs All of the data is logged on a csv as well. Not much to say Insanity Something about sitting around staring at a screen doing like 5 projects on and off makes you a little crazyā¦on the brightside it is my birthday tomorrow. That means more coding time! ;-;"}, {"post_id": 22449, "ts": "2026-07-04T22:24:34Z", "hours": 3.1547, "text": "Monthly Reports, Maintenance mode, and Reminder Emails: Yolo! Reports? Every month (Rn configured to be the first of the month at 8 AM) a report will be sent for all of the stations with a bunch of stats such as: Total downtime Uptime Percentage of outages Table of outages Longest outage Station with most outages etc. Reminder Emails: Once a station goes down and it has not been resolved in a set amount of days, a reminder email will be resent to the owner Maintenance Mode: Once switched on, emails about status will not be sent for that weather station. Checks will still occur in the background however. In the future, I will create an FastAPI app that will let owners trigger this mode on/off for their station. Suggestions? If you guys have any other ideas, please let me know!"}, {"post_id": 21875, "ts": "2026-07-04T01:26:13Z", "hours": 2.4442, "text": "Error Protection and CSV Logging Long time no see haha! Progress Error Protection through try/excepts and error codes Error codes were creates for the failure points. Any time there is an error, it is emailed to the āadminā email. Every whenever there is an error/email sent/status the data like the station id/name, time, status, etc. is saved (appended) to a csv. All error retry logic is modifiable through the config.py."}, {"post_id": 21793, "ts": "2026-07-03T22:06:04Z", "hours": 1.4372, "text": "IT IS WORKING!!!! Oh my god man. The email notifications were a little annoying to get finished but they are working. The image is more redacted than a Call of Duty game but it is fine. Progress Recovery emails have also been made. Everytime a station is checked, itās āstatsā (such as when their last offline was etc) are updated using a seperate json file. I have mostly spent my time on bug fixing and smoothing out the app."}, {"post_id": 21730, "ts": "2026-07-03T20:26:20Z", "hours": 3.375, "text": "Start! Hey guys! This project is all about improving the experience of personal weather station (PWS) owners. It is a webscraper checking for the status of these weather stations. After it detects it has been off for a while it will email the administrator of the network as well as the owner. (This is a summary, take a look at the project page for a better explanation ;) Progress? The station are scraped and their status is recorded Json files for the current and past status as well as other things is updated/created when the program is run Email notifications (in work) Timestamps in the right timezone (config). Several stations can be checked at once And other stuff I kinda forgot ;-;"}]...
|
Title: Weather Underground Station Status Checker Title: Weather Underground Station Status Checker by @Krupam | Stardance
Devlogs:
Start! Hey guys! This project is all about improving the experience of personal weather station (PWS) owners. It is a webscraper checking for the status of these weather stations. After it detects it has been off for a while it will email the administrator of the network as well as the owner. (This is a summary, take a look at the project page for a better explanation ;) Progress? The station are scraped and their status is recorded Json files for the current and past status as well as other things is updated/created when the program is run Email notifications (in work) Timestamps in the right timezone (config). Several stations can be checked at once And other stuff I kinda forgot ;-;
IT IS WORKING!!!! Oh my god man. The email notifications were a little annoying to get finished but they are working. The image is more redacted than a Call of Duty game but it is fine. Progress Recovery emails have also been made. Everytime a station is checked, itās āstatsā (such as when their last offline was etc) are updated using a seperate json file. I have mostly spent my time on bug fixing and smoothing out the app.
Error Protection and CSV Logging Long time no see haha! Progress Error Protection through try/excepts and error codes Error codes were creates for the failure points. Any time there is an error, it is emailed to the āadminā email. Every whenever there is an error/email sent/status the data like the station id/name, time, status, etc. is saved (appended) to a csv. All error retry logic is modifiable through the config.py.
Monthly Reports, Maintenance mode, and Reminder Emails: Yolo! Reports? Every month (Rn configured to be the first of the month at 8 AM) a report will be sent for all of the stations with a bunch of stats such as: Total downtime Uptime Percentage of outages Table of outages Longest outage Station with most outages etc. Reminder Emails: Once a station goes down and it has not been resolved in a set amount of days, a reminder email will be resent to the owner Maintenance Mode: Once switched on, emails about status will not be sent for that weather station. Checks will still occur in the background however. In the future, I will create an FastAPI app that will let owners trigger this mode on/off for their station. Suggestions? If you guys have any other ideas, please let me know!
Monthly Reports, CSVs, and a little bit of Insanity Hey guys, I have done so much, I might go insane haha! Reports? Every first of the month at 8 AM, a email will be sent out to any emails configured for them. They contain various stats such as, which stations are down, which have been down for the longest, uptime percentage, etc. Emails So I just realized that I never explained all the different emails haha. Recipients: Admin: Email(s) configured to recieve only system error emails Global Recipients: Email(s) configured to receive all emails sent by system concerning status. Report Recipients: Email(s) configured to receive monthly emails. E.g. Mesonet maintainers Station Recipients: Email(s) configured separately for each station. E.g. station owners. Email Types: Offline: Sent after a station is recorded off 3 (default) times in a row. Recovery: Sent once a station is detected to be online after being considered offline Reminder: Sent after 7 days (default) to remind of the status. Monthly Reports: Sent at the first of the month at 8 AM (default) with statistics such as which stations had outages, the station with longest, uptime percentage for each station, etc. System Errors: Sent to system admins for any errors detected, HTTP, Requests, Time, etc. CSVs All of the data is logged on a csv as well. Not much to say Insanity Something about sitting around staring at a screen doing like 5 projects on and off makes you a little crazyā¦on the brightside it is my birthday tomorrow. That means more coding time! ;-;
SQL Database, Website Backend, Dashboard When I said a lot last timeā¦that was nothing compared to now ;-; What am I going on about? Well, I wanted a way for station owners to be able to be able to toggle maintenance mode without the admin (whoever deploys this for their own mesonet) directly editing a json file every time. One thing led to another and now I am making a website⦠Website Plan: This website will run on a FastAPI backend with either Jinja2 or Htmx front-end. There will be a public ādashboardā where anyone can take a look at general station stats and current weather conditions. The weather conditions will also be made graphical with Matplotlib. Historical data will also be accessible. However on the same site, people will be able to log in. Logged in users will be able to access only certain stations they are allotted. They will have a more detailed dashboard with more stats. Certain users will be able to toggle maintenance mode and some wonāt. Admin accounts will be able to see and toggle for all stations. Usernames and passwords will be hashed and saved in the database. The log in system will also make use of cookies/sessions to keep the user logged in. Planned SQLite Models users: (DONE) id username password_hash role (admin, station staff, etc) user_station_access user_id station_id can_view can_toggle_maintenance stations: id station_id is_in_maintenance is_public station_status: station_id last_status consec_offline first_offline last_conected alert_sent station_current_weather: temp dew humd wind_speed wind_gust wind_dir pressure precip_rate precip_accum uv solar Progress? I have made all the models and created basic routes. There is a CRUD (Create, Read, Update, and Delete) for the stations based on another config file. On start, the program will automatically create database entries for new stations and delete ones not in the config file.
Website Backend, JWT, and HTML Front End Ok, these dev logs keep getting exponentially longer and longer ;-; What the hell is JWT? JWT (JSON Web Token) is a way for my authenticate a user. It essentially is how I can do logins. When a user is registered, their username and hashed password is stored in the SQL database (DB). When someone would like to authenticate, their password is hashed and sent with the username. The DB check if the username and hashed password match and send back a JWT token that expires after a set time (30 mins but configurable). During this time the user would be able access their station dashboard, etc. Admin accounts have the same log in procedure. They however have the power to give each user (based on their user id in the DB) access to specific stations. This includes the ability to see the station dashboard, toggle maintenance mode, and toggle if the station is public (on our site). Backend: Added functions for creating accounts and logging in. Most functions now require either a general account or a admin account. If this is not fulfilled a 401 error is sent (Unauthorized error). As of right now, only admins can register accounts. The access to each station can be updated by a admin at any time. I did some more stuff but I honestly forgot :) HTML Front End This was honestly my favorite part so far. I started by getting the Jinja2 template system to work as well as mounting the static directory. The layout.html file allows me to change it slightly for every page. That is a bad explanation but it is a really cool system. I got the home page done (needs some text and description but thats a later me issue). I am working on getting the general station page. It will list every station and allow you to click on them to get forwarded to that stations public dashboard. Sanity Check? I am having so much fun with HTML. It gives a certain gratification that SQL canāt give. I feel very happy :D Any ideas pls let me know!
LOGIN FORMS!!! And Station Lists⦠Hey guys! Whats up? Iāll tell you whats up, the moon. š
Dad jokes aside, I am really excited to update you. Login formsā¦how exciting Wait wait I can explain. It is cool I swear. When you input your credentials into the form and submit it, it will check the database (DB) if you have the right ones. If you donāt you will get the invalid screen shown below (I definitely didnāt forget my own passwordā¦). But if you put in the right credentials, you will be given a access_token cookie. This cookie will let you stay logged in till the cookie expires (set for 30 mins ). Once you are logged it, it will direct you to your account dashboard and show you all the stations you have access to. (I didnāt make that one yet but shhhhh) Station List When you click on the Weather Station tab, it will show you a list of every single weather station in the network. Something else cool, whenever you hover/click a button, it will change color. Just fun for me. Save Barnegat Bay I am building this system as a idea I had for the Save Barnegat Bay (SBB) non-profit organization. I utilize their weather stations all of the time for my projects that I love giving back to their mesonet! Once I am finished building this, you will be able to access the SBB weather stations and see weather points as well as graphs and stuff. Oop canāt spoil all of my planned features
Registration Form, Posting Status, Status History Hola guys! Registration There is now a registration form! It takes in a username and password and creates a user. However this user has no permissions and the person has to contact the admin to give them permissions. (in the future, a regular base user will still be able to do more stuff, see more detailed data maybe? But I donāt want to block data based on accounts. Maybe emails of your favorite stations?) Posting Status When the status checker runs, it will send the results over HTTP post to the database (DB) to be saved. The ācurrentā Status DB model is overwritten by new data, but if there is a change in the status in any way, the change will be saved to the Status History DB Model. Time Another tiny detail is that before the status checker would store time in local time, but I changed that to be UTC time. UTC time is now universal and I plan to display the time in the local timezone based on the browser time zone. Easter Egg I added a easter egg in the website, I wonder if someone will find it⦠Thanks for reading these devlogs, this is not necessarily a fancy/flashy project and it means a lot when someone does ā¤ļø.
Working Error Pages, User Updates, Logouts, Weather Post/Weather History and a (partial) public dashboard Been a couple of days guys, here is what I have been up to: Error Pages: Whenever there is some sort of error such as 404 (not found), 401 (unauthorized), 403 (Forbidden), you will get forwarded to error pages. These pages will prompt you to return or log in, depending on the error. User Updates: Admins can know easily update usernames, passwords, roles, etc. However this is still in the API and not a webpage yet. Logouts: When you sign in, your menu bar will no longer have a sign in option (shocker) and has an option to log out. This ānewā menu bar is created using jinja2 if-statements in the layout.html. Weather/Weather History: A Weather Underground Scraper (I made this for a seperate project, check it out: https://github.com/Krupamc/weather_underground_datascraper ) gathers weather data for each station (returns a null filled json if station is offline) and posts it to the API. The API stores it in the database. We can access the current weather for each station as a well as the history. The default history is 20 entries but can be extended with queries. Public Dashboard: Now this is the fun one. This pulls the current status, weather values, time (as a date and timestamp in a readable format), as well as wind direction in label format (e.g. NNE) and sends it to the public dashboard. The dashboard then takes the values and puts them in an easy format. It is not finished, I plan to have pressure, temperature, and wind widgets that change based on the current values.
Public Dashboard and dashboard widgets!!! I had a lot of fun with this⦠Public Dashboard This is a public webpage anyone (no need to log in) for each station, listing the current weather conditions and status in a nice gui. In here are some widgets I made by myself all in CSS and HTML. (I donāt like JS if you couldnāt tellā¦) These weather values include: Temperature Dew Point Humidity Precipitation Rate Precipitation Accumulation UV Index Solar Radiation Atmospheric Pressure Wind Speed Wind Gusts Wind Direction Dashboard Widgets: I made a couple of widgets that update based on the values: Temperature Pressure Wind Temperature: A small thermometer that fills up as the temperature gets higher. (I have to rescale it for Celsius) Pressure: A small barometer that changes based on the pressure. The center pressure (29.92) is the atmospheric pressure at sea level. Wind Speed: A little compass shows the cardinal through tertiary wind directions (16 directions). The current wind is represented by the blue arrow. The arrow is where the wind is coming from (how wind is properly notated) Let Me know if you guys have any other ideas, I would love to hear em!
Owner Dashboard (WIP) and Maintenance Toggle Welcome back to a episode of me going insane! :D (jk) Owner Dashboard (WIP) The owner dashboard is a dashboard that is separate from the public dashboards. You must log in to access a page called āMy Stationsā. This page lists all stations that your account has permission to view. The account that you are using must have the station added by a administrator (rn all of those methods are in the docs. I plan on moving them to html soon) Purpose of Owner Dashboard The owner dashboard holds some extra functionalities based on the status: Online It will show a green or red icon based on the status (along with the circle up by the units toggle) and display the exact time and status of the station. The time of status is separate from weather. If you have the permissions to do so, you can then toggle the maintenance and public modes. (Only maintenance mode has been implemented thus far) The maintenance mode stops any emails from being sent about the station Public mode will allow the stationās public dashboard to be listed on the website. Offline: Shows everything in online*. Does not show weather data Displays how many times the station has been shown to be offline. (consecutive offline) The time of last connection. First offline (this is when the station is set as offline) If an alert email was sent Let me know if you guys have any ideas!
Owner Dashboard (finished), Maintenace and Public Toggles, Dashboard Graphs, and Graph Page (WIP) A lot has happened, lets dive into it: Owner Dashboard: This dashboard may not look very different from the public dashboard but it hold a lot more features: Status widget with the status time and last status. A green check if online or a red X if not. If offline, no weather data/widgets are shown and instead a gear widget with more information is shown. This includes if a alert was sent, last time connected, first time offline, and consecutive offline checks Maintenance and Public toggles Maintenance toggle: If in maintenance mode, no emails will be sent about the status of the station but it will still be logged. Public toggle: If off, the station will not be shown in the public dashboard list. If you try to go to the url directly it will show a āStation Not availableā Page. Dashboard Graphs Graphs are created using Matplotlib and show cased on both dashboards. This includes solar, precipitation, pressure, and temperature graphs. Graphing Page (and analysis) This page is currently being worked on but will allow anyone to choose the time range, variables (yes multiple!), station, and unit. I also want to have a section for analysis like regressions and so on. Lmk how this is looking so far!
#Graphing Page!!! As well as other bug fixes⦠Graphing Page This page is created by making a HTML form and submitting as a POST request to the same method that creates the dashboard graphs. All the graph information is a query request (the infomation after a question mark in a url, see photo). This means you can bookmark a graph to see the most recent data with your own personal preset. The user must select the station (from a list), type a title, the time range, (last __ unit), and the variables they would like. They can choose as many variables as they would like. There are also variable type presets a user can choose. It will preset everything to make the graph including the time range and title. Once a graph is generated, it will be displayed with the options to download it as a png, download the csv data, or the clear the graph. I am working on a date range next as well as the analysis page with linear regressions, t-tests, ANOVAS, etc. Bug Fixes I had a couple of friends test out the site to find some bugs, and boy did they deliver. They managed to point out some logical errors I had, and I fixed them.
A Variable Analysis Page and Graphing with a date system! Hey guys! Here is what I have been up to⦠Graphing Date System: As well as a ālast _ ____ā system (relative range), I created a version that allows me to choose āDate Range.ā Date Range allows you to choose between two dates. It sounds simple but was a lot harder to code š
. As I wrote most of the code while being really sleep deprived, take a look over at @app.get("/graph/weather/{station_id}") on the projectās github page. (I recommend using ctrl + f to find it) Variable Analysis Page: This page is pretty similar to the graphing page (see previous devlogs) where it uses a HTML form with query variables to create calculations. The user selects a weather station, variable, range mode (relative or date), inputs for that mode (hours/date, etc) and the units. Then the latest, minimum, maximum, mean, median, range, sample value (n value), and the overall trend (falling, steady, rising, insufficient data). The time will also be shown if applicable (latest value). You can then download a csv of all the data the calculations were derived from. Under that is another box showing the full time the data is collected from as well as the units Future: I still need to add a tab for more advanced analysis such as linear regressions, anovas, t-tests, etc. If you guys have any more ideas, Let me know!!!
Testing Page (Still WIP), General Bug Fixing, and Site Cleanup Yikes, I got reaaaal close to hitting the 10 hour limit for these devlogs š
⦠Site Cleanup I am really proud of this one. I finally took time to go around and get most of the small detailed squared away. I got the site favicon (small icon in the web tab) and other meta data information fixed (like the .webmanifest) working. I also spent a good chunk of time creating the home page and making it look professional. General Bug Fixing I took some time to go through the website and found some tiny bugs. I also had a few of my friends test out the website (they didnt break it!!!!). Small stuff like making it easier to see the graphs, titles on the tabs, etc. Test Page This page is like the ultimate boss for me haha. I would like this page to contain linear regressions (LR), ANOVAS, and T-tests. These are scientific tests used to find statistical differences in data. (see the below screen shot for a better explanation of all of these tests. The user chooses a station, range mode, range, units, and the type of test. Then based on that test, a few options are given: LR: X Variable Y Variable Title Mode A: Choose 1 station but two time ranges (same variable) Mode B: Choose 2 stations with one time range (same variable) ANOVA: Mode a/b Three or more time ranges/station depending on mode Two ranges/station depending on mode
Testing Page Finished! (without csvsā¦) HTML Form Bug Fixes: Sup guys, here is what I have been up to⦠Testing Page: Oh man this was pretty hard. I actually had writers block but for code. I just couldnāt think of a solution. I just sat there trying to think of how to implement the system. With enough brute force however and some breaks, I did manage to get it working. What is it? This page allows the user to run scientific tests. These tests include Linear Regressions, ANOVAS, and T-Tests. Linear Regressions look for a relationship between variables. ANOVAS and T-tests determine if there a difference between groups of data (single variable). Functionality: The form will ask the user to choose a test, station, variable, unit, and time range, as well as test-specific inputs to run a test. Once the user submits the test, it will either return a graphical result (for the Linear Regression) or stats of the T-Test or ANOVA. The Tests will only make groups depending on the same time frame but different stations. (I only decided to do one for simplicity) This all works but I need to create the ability to download the csv of the data used for the tests. General Inputs: Test Type (T-test, ANOVA, Linear Regression) Range Type: (Relative or Date) Last ___ (hours, months, etc) Start and end date Units (Imperial or metric) Test Specific Inputs: When a test is chosen, test-specific inputs appear. (this happens for other forms such as graphing and analysis pages. I just forgot to mention it) The appeared inputs are then required (like the other default inputs like time, etc) but when a different test is choosen the required inputs are updated with the new ones. These include: Linear Regression: Station X Variable Y Variable Regression T-Test: Outcome Variable Station A Station B ANOVAS: Outcome Variable Station A Station B Station C HTML Form Fixes: I went through all of the Forms that have inputs that switch and make them work nicely with the backend. I make inputs that switch be required and seen at the right time.
CSV Downloads, Weather Table, Error Details on pages, and a profile indicator! Letās jump into it! CSV Downloads: For graphing, analysis, tests, and table pages, I created CSV downloads. Graphing: Downloads raw data Analysis: Downloads analysis summary and raw data Tests: Downloads test results and raw data Weather Tables: Downloads raw data Weather Tables: In the public dashboards, there is now a table at the bottom with all data from the current day. There are quick buttons to go forward and back a day as well as a day input and go button. Profile Indicator: It is just a blank profile picture icon with your username next to it. It only shows when logged in. When clicked it sends you to the my-stations page. Error Details: If there are specific error details in the backend, they will be sent to the error page. Otherwise a generic 40X error will be show
Admin Settings Page (WIP) Settings Page: Now that the main functionality of the site is finished, I started making HTML representations of all the methods I have predefined. This includes CRUD (create, read, update, and delete) functions for several pieces of the website. Here are the ones I started to make: Reset/Update User password, username, role. Register Users Delete User Read User Assigned Stations Grant User Access to a station Revoke User Acccess to a station Modify User Access to a station. Everything uses HTLM forms and when they submit, they will return a pop up success or error message. There are a couple of other features I forgot that I made (Such happens when coding at ungodly hours) but anyone can try out the website (if I am working on it at the same time) at https://sbb.krupamlab.com
Settings Page, API Stations List Call for Scraping System Hey! Here is what I have been up to⦠Settings Page: This is a Admin only page (will pop up in nav bar when admin) that configures, deletes, creates, the main functionalities. This includes stations and users. After every function is run a error/success message will show with detailed intomation depending on the function. These Functions include: Modify User: Change role, username, password Register User: Create Delete User Read User Assigned Stations: Choose a station, the page will reload and show all stations the user can access. Grant User Access: Choose a user, and give them access to a station. This is view only by default Revoke Access: Remove User access to a specific station. On reload after choosing a user it will show any assigned stations Update User Access: Choose a user, on reload it wil show all available stations and when selected, will show what access it has. You then check/uncheck the access you want it to have and submit. Modify Station: Currently only allows to change station name. Create Station: Enter new id and name as well as options to be public and in maintenance mode (default off). Delete Station: Deletes station only from the current stations. Does not delete data. I need to rewrite this to make it so it stops collecting data instead. Read all Stations: Lists all stations and if they are in maintenance or not API Stations List Call I realized around 11 at night that I did something very dumb. All of the stations in the configs for the Weather and Status scrapers were hard coded values and were NOT synced with the current stations database. To combat this, I added a new column to the Stations database table. This column was called collect_active or something of the sort. I plan to migrate the delete function to turning off the collection. I then changed the scrapers to pull a new current list at every run and used that as their truth. I finished this around 3 AM last night š . If you guys have any other ideas, let me know!
Some Help and ReadMe! The project is almost done! (why do I feel like I will be saying that a lotā¦) Some help! Today I saw interesting post on Facebook about a website someone my age built and I commented it on it asking if I could see the code cause I was curious if they used Flask, FastAPI, etc. I also posted my project and to my surprise, the poster is actually my friendās dad (small world am I right) and he reviewed my code and left a few issues on it. He even downloaded it to update my requirements.txt. I then merged his request. Thank you for all of your help! ReadMe: I spent all of today working on the readme, you can read it here . However here is a little sneak peak: Hey! My name is Krupam, and I am a nerd. If you are reading this, you are most likely one as well. I love weather, and learning about it. Other people who love weather will create and host Personal Weather Stations (PWS) and post the data to websites like Weather Underground. I have used these stations for my own research projects. Check one out!. In my area, there is a mesonet (regional network of PWSās) from the Save Barnegat Bay non-profit (check them out, they are awesome!). I have used plenty of their stations in my research. I was given the amazing opportunity to present my research at one of their meetings regarding their mesonet. It was eye-opening! As I listened into the meeting, they discussed one of the current issues; they could never tell when a weather station went down. The station owners would find out days after if not weeks. This program is the solution to that and more. The system is a weather-station data platform and monitoring system. The system collects data from Weather Underground (WU), turns it into usable information, and alerts station owners and administrators when a station needs attention. All data is shown on the website in a easy, user-friendly approach. This includes dashboards, graphing, analysis, scientific tests, and admin controls (accessed through JWT-based auth). The system is coded mostly in Python and there are three main systems: The weather and status scrapers, backend, and frontend website.
Robots.txt, User login error, API security, credit footer, station hardware Whats up? Robots.txt: For those who donāt know, a ārobots.txtā tells scrapers and any bots where they allowed to go on your website. I only allowed them to go on public html pages. However this is only a recommendation, the big guys can do whatever they want. User Login Error: I had this error where any public accounts (or not admins) would get a error when logging in. I was searching for permissions with the wrong column in the database š
. API Security: I made sure there were no open routes and everything was secured. Credit Footer: This was pretty cool. At the end of ever page, I added this little footer with my name and a link to the github repo. Station Hardware: I added a new column to store station hardware info. This is mainly for what weather station model it is. Ex: Davis Vantage Pro2. I am working on making the update form in the settings page allow to update this info as well as more station info.
API Email Calls, Hardware specifications, Docker? Hey guys, School started two weeks ago, so my posts will be a little delayed lol⦠API Email Calls: I originally hard coded my email lists for Reports, station-specific, admin, and global emails, but I wanted to unify them with the rest of the API. I spent a lot of time creating columns in SQL, endpoint CRUD, settings HTML page CRUD, as well as changing the scrapers to pull the lists and use them. Hardware specifications: I added columns in SQL to add Hardware metadata for the stations. It can be seen in all dashboards (see photo) Docker: I was thinking of creating a docker container for this setup to make deployment easier. Would that be something you guys would like to see? Let me know.
Docker and Environment Variables Hey guys! It has been a couple of days⦠Time Crunch: So I looked on my calendar a week ago and realized that Stardance was almost over, and thought āthis is plenty of timeā. Then a couple of days ago I really felt the pressure. I wanted to get this out before the program finished so I started on the final bits and deployment to turn this into a usable system. Docker: If you donāt know what docker is, count your lucky stars. Just kidding, its very cool when it works . It is a type of virtualization (similar to VMs but instead sharing the kernal) that is a lot less resource intensive and is used for deploying a lot of small projects as well as any type of home labbing work flow (hosting your own server etc.). I have worked with docker with pre-built images and containers before and never really went into the DIY portion. This was my first intro into it and I had to do a lot of googling and the such. It was really frustrating and required quite a few head banging. NOTE: I did use AI sometimes (tried as little as I could) to get docker working. You can see me sometimes using it in my lapse recordings, but I tried to keep it closed as long as I could to stop me from using it :D. Environment Variables: I was told that hard coding my config values in a config file was a bad ideaā¦and it makes sense. It took a bit, but once I setup environment variables, oh man did it get so much better. This also makes it a lot easier in docker to setup the container. Very happy about this. Help from a friend! I told this story a couple of weeks ago, but one of my friendās dad found my repo and left a couple of issues on my page and these were my last two. I really gotta thank him for these ideas.
Docker Deployment (ALMOST finished) Hey guys! Docker: I am using Docker for deployment of this system to make it easy for anyone who has a weather station or network of them to showcase and monitor their own data. Docker is a type of virtualization (similar to VMs but instead sharing the kernel) that is a lot less resource intensive and is used for deploying a lot of small projects as well as any type of home labbing work flow (hosting your own server etc.). (Yes I pulled that explanation from my last devlog lmao). I will have a tutorial in the ReadME. Within the docker stack, there are several containers with different jobs and responsibilities: Web: Hosts the FastAPI webserver. It uses a endpoint (/health) to monitor the servers responses. It is hosted on port 8000 by default (configurable in the .env file). I would forward this through Nginx or a Cloudflare tunnel to host it under your own domain. Scraper: Runs the status and weather scrapers every 15 and 5 minutes (offset by two mins) respectively through a crontab file ( scraper.crontab ). It is run using Supercronic. The scraper waits for the web server as well. Flock is used to prevent two instances of a program. DB: PostgreSQL server that holds all of the data. Weather data, users, etc. All of the other containers wait till the DB is healthy to start. Db_backup: A container created by Prodrigestivill to automate backups of Postgres databases. I have it configured to keep the last month and 14 days of backups. It saves all backups to the /opt/mesonet-backups folder. I wrote scripts in order to test restoring backups (creates test table, restores using latest backup, and deletes it), create a manual backup, and restore the last backup. Email Alerts: Fairly similar to how emails are sent in the status-scraper, it obtains admin recpients from the web sever uses enviroment vairbales to send an email. It asks for subject and text using arguments in the terminal, so the user can send emails manually to admins as well. Health-tests: Runs a couple of health based scripts on a Supercronic schedule. Monthly restore test (runs the restore test mentioned before) and a daily backup health (checks how old the backup is). Emails will be sent to admins if the restore fails or the backup is more than 26 hours old. Persistent Storage: All the containers used volumes that continued even if the containers were deleted to be updated, the data (and the backups) are fine.
Map! And Develop mode Map I used ArcGISās JS to create a map tab that show cases all stations that have a latitude and longitude value. I am working on getting them on the first ever scrape but you can also edit them within the settings page. There is a link that takes you to the station page as well. Develop Mode Created a toggle within the .env file. If on, the program will use the SQlite db and be able to run on VS Code for example. When it is off, it needs the PostGRESql db to function. Docker Docker is really infuriating lmao. Spent most of my time fixing tiny bugs.
Weather Emails, mobile tweaks, map zoom Soooooooooooooo close to shipping. Map Zoom: The Map will now automatically zoom based the center of the points. Humidity and Dew point data collection: The place the data was being scraped from got changed so I had to update the logic. Weather Emails: Created another CRUD for another email list. This list will get a monthly email summarizing the weather for the past 30 days for each of the stations. I created the web page for it, but need to finish cleaning it up, allowing people to sign up for the service and make the emails send automaticcally. Mobile Tweaks: The mobile version of the website did not look good. I spent a lot of time trying to fix it before I was able to get it to look like this!...
|
1792799654.0079603
|
1793404454.0079603
|
|
42446
|
Quadrupedal Robot by @Malteser77 | Stardance
|
Malteser77
|
0
|
21.8
|
0
|
[]
|
[{"post_id": 79621, "ts": "202 [{"post_id": 79621, "ts": "2026-10-14T18:54:40Z", "hours": 5.2669, "text": "Itās red like the martians! Just realised that I have not been posting all of this for a long time and I couldnāt leave you guys in the dark. Finally made the 49:1 gearbox and fixed the legs. However, in this robot I feel as though the brace that connects the gearboxes perpendicularly doesnāt make use of the space. Therefore I need to fix that and see how much room the gearboxes take up. TOODLES DUCKAROOS."}, {"post_id": 61665, "ts": "2026-09-04T18:14:35Z", "hours": 2.19, "text": "Everythings wrong⦠Iāve just managed to finish the linear actuator mechanism and whilst looking for a motor, I found out that the other motor that I was looking for the hip joint has the wrong torque. Was looking at the 5010 360KV and calculated for the 760KV. I have to redesign the gearbox again, which is not ideal. So Iāll recalculate everything and improve the gearbox. Allās well that ends well!"}, {"post_id": 60111, "ts": "2026-09-02T08:35:14Z", "hours": 11.2872, "text": "Finishing the Scapular joint mechanism!!!"}, {"post_id": 50364, "ts": "2026-08-19T15:17:29Z", "hours": 2.4544, "text": "Legs are hard. Just finished with my main vision of what I want it to look like. Iāll change some of the shapes like the camera cap and a bit of the main body but I can do that later."}, {"post_id": 49819, "ts": "2026-08-18T19:22:47Z", "hours": 0.6003, "text": "Session 1: Finding Ratios! Just started the project after much thought! Just started by looking at different robot dogs that I wanted to draw inspiration from and ask AI to find the dimensions of all of the quadrupedal robot dogs and their ratios. Since Iāve got my own size in mind, this was just to ensure that it didnāt look āclunky.ā"}]...
|
Title: Quadrupedal Robot by @Malteser77 | Stardanc Title: Quadrupedal Robot by @Malteser77 | Stardance
Devlogs:
Session 1: Finding Ratios! Just started the project after much thought! Just started by looking at different robot dogs that I wanted to draw inspiration from and ask AI to find the dimensions of all of the quadrupedal robot dogs and their ratios. Since Iāve got my own size in mind, this was just to ensure that it didnāt look āclunky.ā
Legs are hard. Just finished with my main vision of what I want it to look like. Iāll change some of the shapes like the camera cap and a bit of the main body but I can do that later.
Finishing the Scapular joint mechanism!!!
Everythings wrong⦠Iāve just managed to finish the linear actuator mechanism and whilst looking for a motor, I found out that the other motor that I was looking for the hip joint has the wrong torque. Was looking at the 5010 360KV and calculated for the 760KV. I have to redesign the gearbox again, which is not ideal. So Iāll recalculate everything and improve the gearbox. Allās well that ends well!
Itās red like the martians! Just realised that I have not been posting all of this for a long time and I couldnāt leave you guys in the dark. Finally made the 49:1 gearbox and fixed the legs. However, in this robot I feel as though the brace that connects the gearboxes perpendicularly doesnāt make use of the space. Therefore I need to fix that and see how much room the gearboxes take up. TOODLES DUCKAROOS....
|
1792508051.9471805
|
1793112851.9471805
|
|
69737
|
Night Desk by @_Thomas_ | Stardance
|
_Thomas_
|
1
|
0.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T19:32:01Z", "hours": 0.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I built NightDesk , a customizable productivity dashboard using HTML, CSS, and JavaScript. It includes a Google search bar, live clock and date, dark and light themes, English and Czech language settings, and four widgets: Quick Links, To-Do, Notes, and a Focus Timer. The widgets can be moved and resized, and users can customize which ones are visible. Settings and user data are saved, so the workspace stays personalized between visits. One of the biggest challenges was getting the widget positioning system to work properly. I spent time debugging the layout and fixing issues that prevented widgets from being moved freely. This project helped me learn more about frontend development, CSS, JavaScript interactions, saving data in the browser, and how seemingly small changes can affect other parts of an application. Iām most proud that I managed to turn the idea into a working website that people can actually use. I used VS Code as my editor, with ChatGPT and Claude for technical help, debugging, and a few code improvements. I tested and refined the project along the way. How to test it: Open the live demo and try moving and resizing the widgets, switching themes and languages, adding tasks or notes, and using the focus timer. You can also change the settings to customize the dashboard to your liking. (Sorry if the project timeline looks a little confusing! I had some trouble linking Hackatime correctly, so the tracked time doesnāt seem to match the time spent working on the project. I finally got it sorted out and wanted to publish the finished project instead of getting stuck on the setup any longer. :D)", "repo": "https://github.com/Thomio2/Night-Desk", "demo": "https://thomio2.github.io/Night-Desk/"}]...
|
[{"post_id": 79629, "ts": "202 [{"post_id": 79629, "ts": "2026-10-14T19:09:40Z", "hours": 0.2919, "text": "Night Desk"}]...
|
Title: Night Desk by @_Thomas_ | Stardance
Devlog Title: Night Desk by @_Thomas_ | Stardance
Devlogs:
Night Desk
Ships:
I built NightDesk , a customizable productivity dashboard using HTML, CSS, and JavaScript. It includes a Google search bar, live clock and date, dark and light themes, English and Czech language settings, and four widgets: Quick Links, To-Do, Notes, and a Focus Timer. The widgets can be moved and resized, and users can customize which ones are visible. Settings and user data are saved, so the workspace stays personalized between visits. One of the biggest challenges was getting the widget positioning system to work properly. I spent time debugging the layout and fixing issues that prevented widgets from being moved freely. This project helped me learn more about frontend development, CSS, JavaScript interactions, saving data in the browser, and how seemingly small changes can affect other parts of an application. Iām most proud that I managed to turn the idea into a working website that people can actually use. I used VS Code as my editor, with ChatGPT and Claude for technical help, debugging, and a few code improvements. I tested and refined the project along the way. How to test it: Open the live demo and try moving and resizing the widgets, switching themes and languages, adding tasks or notes, and using the focus timer. You can also change the settings to customize the dashboard to your liking. (Sorry if the project timeline looks a little confusing! I had some trouble linking Hackatime correctly, so the tracked time doesnāt seem to match the time spent working on the project. I finally got it sorted out and wanted to publish the finished project instead of getting stuck on the setup any longer. :D)...
|
1793155970.673059
|
1793242370.673059
|
|
47713
|
Velora by @gavrilcatalin | Stardance
|
gavrilcatalin
|
2
|
6.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-14T19:15:47Z", "hours": 1.0, "multiplier": 2.82, "payout": 0, "blessing": "neutral", "text": "I did indeed add 3 new features into the WebOS: I added the Settings app that lets you customize the appearance of your WebOS. I added the Notes app where you can write anything you want. I added a new taskbar, i love it.", "repo": "https://github.com/nyvrixista/Velora", "demo": "https://nyvrixista.github.io/Velora/"}, {"ship_num": 2, "ts": "2026-08-27T19:32:57Z", "hours": 5.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I created m own Web OS, and im proud to call it Velora. Currently, it has 2 apps, the projects app, and an terminal. The terminal itself is something I thought of adding a long time ago. Everything will be available in my github repo. Go try it out!", "repo": "https://github.com/nyvrixista/Velora", "demo": "https://nyvrixista.github.io/Velora/"}]...
|
[{"post_id": 79630, "ts": "202 [{"post_id": 79630, "ts": "2026-10-14T19:12:56Z", "hours": 1.2053, "text": "Well, 2 months just gone, so here is what i made: Settings app - Lets you customize themes between dark and light and the transparency, for making Velora feel truly yours. Notes app - Lets you to write anything you want, and it saves automatically, how cool is that. A TASKBAR!!!! - I am gonna be very honest, this is my most waited feature, like its not perfect, but itās a TASKBAR."}, {"post_id": 55770, "ts": "2026-08-27T19:28:32Z", "hours": 0.8389, "text": "I worked on a new app called Terminal"}, {"post_id": 55714, "ts": "2026-08-27T18:02:59Z", "hours": 4.3714, "text": "I started developing my own Web OS, and honestly, it looks really good."}]...
|
Title: Velora by @gavrilcatalin | Stardance
Devlo Title: Velora by @gavrilcatalin | Stardance
Devlogs:
I started developing my own Web OS, and honestly, it looks really good.
I worked on a new app called Terminal
Well, 2 months just gone, so here is what i made: Settings app - Lets you customize themes between dark and light and the transparency, for making Velora feel truly yours. Notes app - Lets you to write anything you want, and it saves automatically, how cool is that. A TASKBAR!!!! - I am gonna be very honest, this is my most waited feature, like its not perfect, but itās a TASKBAR.
Ships:
I created m own Web OS, and im proud to call it Velora. Currently, it has 2 apps, the projects app, and an terminal. The terminal itself is something I thought of adding a long time ago. Everything will be available in my github repo. Go try it out!
I did indeed add 3 new features into the WebOS: I added the Settings app that lets you customize the appearance of your WebOS. I added the Notes app where you can write anything you want. I added a new taskbar, i love it....
|
1793062313.6727626
|
1793926313.6727626
|
|
64576
|
Anki flashcard project by @r2shergill | Stardance
|
r2shergill
|
0
|
4.0
|
0
|
[]
|
[{"post_id": 79636, "ts": "202 [{"post_id": 79636, "ts": "2026-10-14T19:29:44Z", "hours": 1.5794, "text": "I have currently been working on finishing my code and about to start coding and ordering the use of the subroutines to allow optimisation. Recently I have also been working on commenting all of my code to allow everyone to have a further understanding of each line of code."}, {"post_id": 76789, "ts": "2026-10-04T15:59:48Z", "hours": 2.0958, "text": "Creating the final functions for the Anki Flashcards"}, {"post_id": 71955, "ts": "2026-09-21T20:55:35Z", "hours": 0.3203, "text": "Developing the first function of my code"}]...
|
Title: Anki flashcard project by @r2shergill | Sta Title: Anki flashcard project by @r2shergill | Stardance
Devlogs:
Developing the first function of my code
Creating the final functions for the Anki Flashcards
I have currently been working on finishing my code and about to start coding and ordering the use of the subroutines to allow optimisation. Recently I have also been working on commenting all of my code to allow everyone to have a further understanding of each line of code....
|
1793065753.4109008
|
1793670553.4109008
|
|
30897
|
8-Bit ALU by @Bose-ova | Stardance
|
Bose-ova
|
0
|
14.15
|
0
|
[]
|
[{"post_id": 79647, "ts": "202 [{"post_id": 79647, "ts": "2026-10-14T20:49:09Z", "hours": 4.6594, "text": "nothing special, just soldering! completed 2 more pcbs today, so 6 pcbs done in total. tommorrow iāll complete this project! also soldered the transistors on the other 2 pcbs, only the resistors are left now. im thinking about the power problem tho, as the number of pcbs increases, i think im having some power issues. when i tested with just 4 pcbs, the leds were glowing with good brightness, but now with 6 pcbs the brightness is really low. still have to connect 25 wires and im also running low on transistors, only 3 left. i thought of using them for the leds to get full brightness, but i already added one transistor to a pcb and the brightness is still low. 6 pcbs done today, project should be complete by tommorrow"}, {"post_id": 79148, "ts": "2026-10-12T20:23:01Z", "hours": 2.0333, "text": "All 4 PCBs are soldered and assembled!! I soldered and fixed all of them the day before, but then I started facing some problems while testing them.When I tested them individually, 3 out of 4 PCBs were working fine. But 2 of them had the same issue in subtraction mode and were not doing the subtraction properly. At first, everything seemed fine when I tested them individually, so I thought maybe it was a power supply issue. The 4th PCB also had some problems, so I tried fixing that too.I also spent around 4 extra hours soldering, fixing and troubleshooting all these PCBs. This time wasnt included in my original time tracking, so Im adding it here in the devlog.Heres the timelapse of the work: https://lapse.hackclub.com/timelapse/ybwchpALz-pzAfter that, I installed the spacers and tried running all 4 PCBs together, but something went wrong and the whole setup wasnt working properly š. Even after fixing the individual PCBs and assembling everything, it still didnt work as expected.But today, I finally fixed all the issues and completed the 4-bit adder and subtractor It took quite some time to figure out what was going wrong, but finally got it working!! Now just 4 more PCBs to go"}, {"post_id": 78854, "ts": "2026-10-11T19:44:36Z", "hours": 2.1839, "text": "The 3rd PCB is done!1 PCB was not working because of loose solder joints, so i reheated all the solder joints and it started working again.Soldering is taking a lot of time, it took me around 2 hours just to solder 1 PCB. The PCBs are very small and compact, so its kinda hard to solder everything properly. Also i am using THT resistors which makes it a bit harder to place everything neatly.And i have ADHD so i want everything to be perfect lol. Every resistor should be placed in the same direction and the spacing should be same, and every solder joint should look good. I want the PCB to look clean and organised, not just work properly.For now i am just doing the soldering part, nothing more. Still have more work to do but atleast 3 PCBs are done now. Slowly getting there, one PCB at a time.Nothing much exciting yet, just a lot of soldering and trying to make everything look perfect š"}, {"post_id": 77895, "ts": "2026-10-08T18:04:23Z", "hours": 4.6722, "text": "Inhaling Fumes: Soldering PCBs.Soldered 2 PCBs. Only one is working correctly, while the other one still has some issues. Iām still trying to figure out whatās wrong.It could just be a loose solder joint or a short circuit caused by a solder bridge. I really donāt want to redo the soldering and add more solder, so Iām checking the connections first and trying to find the problem."}, {"post_id": 32572, "ts": "2026-07-21T20:44:47Z", "hours": 0.5992, "text": "Testing on Breadbaord (OR, AND, NAND) lOGIC"}]...
|
Title: 8-Bit ALU by @Bose-ova | Stardance
Devlogs Title: 8-Bit ALU by @Bose-ova | Stardance
Devlogs:
Testing on Breadbaord (OR, AND, NAND) lOGIC
Inhaling Fumes: Soldering PCBs.Soldered 2 PCBs. Only one is working correctly, while the other one still has some issues. Iām still trying to figure out whatās wrong.It could just be a loose solder joint or a short circuit caused by a solder bridge. I really donāt want to redo the soldering and add more solder, so Iām checking the connections first and trying to find the problem.
The 3rd PCB is done!1 PCB was not working because of loose solder joints, so i reheated all the solder joints and it started working again.Soldering is taking a lot of time, it took me around 2 hours just to solder 1 PCB. The PCBs are very small and compact, so its kinda hard to solder everything properly. Also i am using THT resistors which makes it a bit harder to place everything neatly.And i have ADHD so i want everything to be perfect lol. Every resistor should be placed in the same direction and the spacing should be same, and every solder joint should look good. I want the PCB to look clean and organised, not just work properly.For now i am just doing the soldering part, nothing more. Still have more work to do but atleast 3 PCBs are done now. Slowly getting there, one PCB at a time.Nothing much exciting yet, just a lot of soldering and trying to make everything look perfect š
All 4 PCBs are soldered and assembled!! I soldered and fixed all of them the day before, but then I started facing some problems while testing them.When I tested them individually, 3 out of 4 PCBs were working fine. But 2 of them had the same issue in subtraction mode and were not doing the subtraction properly. At first, everything seemed fine when I tested them individually, so I thought maybe it was a power supply issue. The 4th PCB also had some problems, so I tried fixing that too.I also spent around 4 extra hours soldering, fixing and troubleshooting all these PCBs. This time wasnt included in my original time tracking, so Im adding it here in the devlog.Heres the timelapse of the work: https://lapse.hackclub.com/timelapse/ybwchpALz-pzAfter that, I installed the spacers and tried running all 4 PCBs together, but something went wrong and the whole setup wasnt working properly š. Even after fixing the individual PCBs and assembling everything, it still didnt work as expected.But today, I finally fixed all the issues and completed the 4-bit adder and subtractor It took quite some time to figure out what was going wrong, but finally got it working!! Now just 4 more PCBs to go
nothing special, just soldering! completed 2 more pcbs today, so 6 pcbs done in total. tommorrow iāll complete this project! also soldered the transistors on the other 2 pcbs, only the resistors are left now. im thinking about the power problem tho, as the number of pcbs increases, i think im having some power issues. when i tested with just 4 pcbs, the leds were glowing with good brightness, but now with 6 pcbs the brightness is really low. still have to connect 25 wires and im also running low on transistors, only 3 left. i thought of using them for the leds to get full brightness, but i already added one transistor to a pcb and the brightness is still low. 6 pcbs done today, project should be complete by tommorrow...
|
1792497111.4588153
|
1793101911.4588153
|
|
31355
|
Adobe AE on a shoestring budget (updated) by @Adam Adobe AE on a shoestring budget (updated) by @Adam_Lotfalla | Stardance...
|
Adam_Lotfalla
|
0
|
48.73
|
0
|
[]
|
[{"post_id": 79648, "ts": "202 [{"post_id": 79648, "ts": "2026-10-14T21:16:53Z", "hours": 0.8606, "text": "You could try Before Effects now! This will be the Last devlog before first ship (might be as well the last ship :P ) I edited the readme and made executables for windows and linux (waiting for my friend to build it on his mac so I could have that as well). Once I have the mac build as well I will be shipping. Until then, you could try it here I commented out the test paths so users will start with an empty canvas"}, {"post_id": 73299, "ts": "2026-09-24T19:58:02Z", "hours": 4.0678, "text": "Worked on two new features. Seemed simple at the beginning, but I couldnāt help but cleaning up the code, so I introduced more problems and had to fix them :P 1. Random test paths Drawing new paths (squares with distinct colors and names) so I could test layer reordering was taking too much time. I shouldāve started this so much earlier (for example before I finish working on path reordering) but it could help in the future. I will probably remove those before release, but the function is still there and I could call it anytime. 2. Path reordering from viewport using page_up , page_down , home , and end page_up : move up one layer page_down : move down one layer home : move to top end : move to bottom I plan to add buttons for those at the tool bar for the next devlog. Rabbit whole I wanted to move reorderLayer() method from the layerReordered() function (creative naming ) so I could also call it from viewport. I then had to unify the indexing logic between layerReordered() and viewport which meant more STL headaches and more sementation faults"}, {"post_id": 72584, "ts": "2026-09-23T08:56:58Z", "hours": 5.0853, "text": "Back again! This time I only worked on fixing two stubborn bugs (There might be some bug with the devlog time being too much. I will check and ask support if any). Bug #1: Layer reordering does not account for expanded layers Previously, my logic was initial_layer_index = floor(mouse_pos / layer_height target_layer_index = round(mouse_pos / layer_height since layer_height is the height of an unexpanded layer, the program thinks Iām moving the wrong layer to the wrong place. Bug #2: layer reordering does not reflect correctly in the layers_ vector. I keep forgetting that the last layer added to a vector is appended to the end, but is drawn on top of other layers. The problem was in the logic of std::rotate (had to brush up on STL for that). It caused a lot of inconsistency and crashs when reordering layers, especially when I fixed bug 1."}, {"post_id": 63647, "ts": "2026-09-07T15:52:56Z", "hours": 7.1136, "text": "Has been a long time and I wanted to break the silence. Iām honestly getting burned out and Iām not sure if Iām ready to start working on the graph editor (not even sure if the time is enough). For now, Iāve been working on layer reordering and adding some controls to the layers. New features Layer reordering from the layer hierarchy panel that reflects on the viewport Basic ability to rename a path from its corresponding layer. just click on the name Added shortcuts and tool tips for the three tools I have: B for bezier pen, N for node tool, S for select tool Planned features I want to add a tagging / color coding system where you assign a color to a layer and can filter them based on that. I want it just because it looks cool Layer groups. These should work just as normal layers but they do not correspond to a path. The idea is simple but my current spaghetti setup is not helping so I need to clean my code up I want to add a simple reordering control using the page up , page down , home , and end keys to reorder from the viewport itself Want to add a shortcut for timeline playback Space for improvement Clean up some spaghetti code. Maybe go back to drawing board (I didnāt even use one, I just went straight to coding :P ) Layer reordering does not count for if a layer was expanded shortcuts are not global, only if the viewport is active, the shortcut will work"}, {"post_id": 33548, "ts": "2026-07-23T16:13:30Z", "hours": 5.0533, "text": "Keyframe repositionaing is finally here! (the second time I attach the wrong video to the devlog) Timeline is about to be finished. Now you can select keyframes and reposition them. Press shift to add to the selection. Use the selection box to select many keyframes at once. And you can also select keyframes from multiple layers at once. some Quality of life changes Keyframe selection works by searching for the nearest keyframe inside a search radius on the same layer. At first I made it select the keyframe at the exact frame the mouse is currently at, but that became very annoying when zooming out as the frame width gets smaller. Viewport does not update in real time on every mouse move while dragging layers or keyframes, but instead uses some tricks to delay heavy operations until the the mouse button is released. One trick is to when I drag a layer, I only shift the layer drawing, but I do not commit the changes to keyframes yet. To appear as if it was live updating, I send a signal to the viewport to show the viewport a few frames later or prior than the actual current frame is. For keyframe dragging, I actually donāt have a work around. Cavalry uses some visuals like arrows to indicate how that change in keyframes corresponds to changes in viewport but Iām not sure if Iām going to implement it this way (open for suggestions) Additions Added a whilte outline to selected keyframes Click on a keyframe to select it; Click and drag to reposition it Drag over keyframes to select many keyframes using the selection box (called a rubber band) Use shift in combination of the previous two moves to add to the existing selection Time cursor now allows mouse events through instead of blocking it Made pixel level adjustments to layer resizing handles Next, I want to add layer reordering and multi-layer/multi-path selection, then I could consider the timeline milestone finished (maybe I add color coding and tags). I want to move on to the graph editor because I think I spent too much time on polishing the timeline and the event is ending soon (I donāt think 9 weeks are enough :|)"}, {"post_id": 30721, "ts": "2026-07-18T15:15:36Z", "hours": 4.3658, "text": "More layer manipulation! This was, I think, the most enjoyable coding session in stardance because coding went smoothly with almost no headaches figuring out why things do not work. It also brought many new features after many devlogs of mostly debugging. features visibility button to show/hide paths Dragging and resizing layers so the path only renderes at the given boundaries Dragging layers outside of the visible scroller area expands the scroller size (no current way of retracting it. Open for suggestions :D) Different mouse cursors for different layer manipulations Iām thinking now of two missing features of the timeline: dragging keyframes, and reordering layers, then I might consider the timeline milestone finished (maybe will need some cleaning up) and I could start on the next milestone: graph editors"}, {"post_id": 29349, "ts": "2026-07-16T07:21:06Z", "hours": 4.7458, "text": "Help needed! I just noticed that my previous devlog videos are choppy/laggy. That was because of my screen recording software (I used the Win 11 snipping tool because it was convinient). Can someone suggest a fix or something? I donāt want to install a new software if not necessary, but if you know a good one please tell me. (I used windows gamebar to record this one but I donāt like it. The color selector window is not displayed in the recording) A lot of bug fixes š« I didnāt add a lot of features in this devlog, but the fixed bugs made a huge difference. I really hate debugging. You fix something that goes unnoticed if fixed but it takes the life out of you. These are some of the fixed bugs: Color keyframes were not displayed Color interpolation did not work for strokes Color selector did not update the color spinboxes Keyframes were not updating in the attribute panel or the timeline Clicking on a layer inside the scroller did not select it nor did it select the path Bound handles did not visually change the timeline Features Timeline shows color keyframes in 4 RGBA channels for both fill and stroke Bound handles make the timeline darker and give the layers a dark tint (Iām not sure about the choice of 3 colors. The margins for the scroller are the darkes; the area not covered by the bounds are lighter; and the working area is the lightest. Iām thinking of making them only 2 colors. What is your opinion?)"}, {"post_id": 27392, "ts": "2026-07-12T22:31:23Z", "hours": 2.2728, "text": "Updates to viewport Iām currently too tired of working on the timeline again, so I moved to some simple tasks (two of them were not that simple). changes Added cap styles to paths When drawing a path and pressing Enter / Return , the path is completed, and you end up with a curved line :D Choosing the bezier draw tool now deselects any paths (that was annoying, to me at least) You could now select and deselect shapes using node tool without switching to the selection tool (only difference is that you cannot rotate or scale, but you can edit individual nodes and handles)"}, {"post_id": 27156, "ts": "2026-07-12T13:39:51Z", "hours": 4.6306, "text": "Huge update to Layers! Iām proud that the program is getting more usable with updates, and more visually appealing too! The thing Iām most proud of in this update is the huge speed upgrade to the layer algorithm. First major fix is using insertWidget() instead of addWidget() . The former gets and index of the widget position in the layout instead of previously deleting the whole layout and redrawing it. Second major fix is to use a hash map to link the path to its corresponding layer. Previously, when the path asked for a layer update, it emitted a signal that iterated through all layers and updated them, now the hash table stored within the Timeline can search for that layer in O(1) instead of O(n) . the difference is more noticable when many layers are added. features Selected layer is now highlighted Expantion arrow is only displayed when there are keyframes to expand Keyframes are shown as dots on the layer itself, and as green diamonds š¹when expanded. The dots get darker the more there are keyframes on that specific frame (Totally intended behaviour :D) Huge speed upgrade from O(n) to O(1)"}, {"post_id": 25536, "ts": "2026-07-09T21:05:30Z", "hours": 7.0417, "text": "It doesnāt look like Iāve done much, but the whole layering architecture was changed Now the layers support vertical scrolling The new architecture I place the playback controls at the top, then I split the remaining part horizontally. A vertical scroller contains the hierarchy of the layers in the left part. The right part contains a horizontal scroller that contains the tick bar The horizontal scroller contains another vertical scroller linked to the one on the left The aims were to allow vertical and horizontal scrolling on the right, but keeping the left panel and the tick bar visible. Now I have the layers_ vector, the tick bar, and the time cursor all inside the Timeline class, instead of the odd spaghetti way I did it before."}, {"post_id": 24028, "ts": "2026-07-07T09:43:53Z", "hours": 3.4944, "text": "Added a layer keyframe dropdown menu This is the first updated feature of my motion graphics software āBefore Effectsā. I was really annoyed by the old layer system where you know where the keyframes are, but not what attributes are keyed. This is now fixed! Features Added a default path on start so I could debug easily Added a clickable dropdown arrow. When clicked, it shows a bunch of sub-layers named by their corresponding attributes Renamed a lot of variables and functions as a result of my spaghetti-coding habits I still need to draw the keyframe diamonds on their correct sub-layers."}]...
|
Title: Adobe AE on a shoestring budget (updated) b Title: Adobe AE on a shoestring budget (updated) by @Adam_Lotfalla | Stardance
Devlogs:
Added a layer keyframe dropdown menu This is the first updated feature of my motion graphics software āBefore Effectsā. I was really annoyed by the old layer system where you know where the keyframes are, but not what attributes are keyed. This is now fixed! Features Added a default path on start so I could debug easily Added a clickable dropdown arrow. When clicked, it shows a bunch of sub-layers named by their corresponding attributes Renamed a lot of variables and functions as a result of my spaghetti-coding habits I still need to draw the keyframe diamonds on their correct sub-layers.
It doesnāt look like Iāve done much, but the whole layering architecture was changed Now the layers support vertical scrolling The new architecture I place the playback controls at the top, then I split the remaining part horizontally. A vertical scroller contains the hierarchy of the layers in the left part. The right part contains a horizontal scroller that contains the tick bar The horizontal scroller contains another vertical scroller linked to the one on the left The aims were to allow vertical and horizontal scrolling on the right, but keeping the left panel and the tick bar visible. Now I have the layers_ vector, the tick bar, and the time cursor all inside the Timeline class, instead of the odd spaghetti way I did it before.
Huge update to Layers! Iām proud that the program is getting more usable with updates, and more visually appealing too! The thing Iām most proud of in this update is the huge speed upgrade to the layer algorithm. First major fix is using insertWidget() instead of addWidget() . The former gets and index of the widget position in the layout instead of previously deleting the whole layout and redrawing it. Second major fix is to use a hash map to link the path to its corresponding layer. Previously, when the path asked for a layer update, it emitted a signal that iterated through all layers and updated them, now the hash table stored within the Timeline can search for that layer in O(1) instead of O(n) . the difference is more noticable when many layers are added. features Selected layer is now highlighted Expantion arrow is only displayed when there are keyframes to expand Keyframes are shown as dots on the layer itself, and as green diamonds š¹when expanded. The dots get darker the more there are keyframes on that specific frame (Totally intended behaviour :D) Huge speed upgrade from O(n) to O(1)
Updates to viewport Iām currently too tired of working on the timeline again, so I moved to some simple tasks (two of them were not that simple). changes Added cap styles to paths When drawing a path and pressing Enter / Return , the path is completed, and you end up with a curved line :D Choosing the bezier draw tool now deselects any paths (that was annoying, to me at least) You could now select and deselect shapes using node tool without switching to the selection tool (only difference is that you cannot rotate or scale, but you can edit individual nodes and handles)
Help needed! I just noticed that my previous devlog videos are choppy/laggy. That was because of my screen recording software (I used the Win 11 snipping tool because it was convinient). Can someone suggest a fix or something? I donāt want to install a new software if not necessary, but if you know a good one please tell me. (I used windows gamebar to record this one but I donāt like it. The color selector window is not displayed in the recording) A lot of bug fixes š« I didnāt add a lot of features in this devlog, but the fixed bugs made a huge difference. I really hate debugging. You fix something that goes unnoticed if fixed but it takes the life out of you. These are some of the fixed bugs: Color keyframes were not displayed Color interpolation did not work for strokes Color selector did not update the color spinboxes Keyframes were not updating in the attribute panel or the timeline Clicking on a layer inside the scroller did not select it nor did it select the path Bound handles did not visually change the timeline Features Timeline shows color keyframes in 4 RGBA channels for both fill and stroke Bound handles make the timeline darker and give the layers a dark tint (Iām not sure about the choice of 3 colors. The margins for the scroller are the darkes; the area not covered by the bounds are lighter; and the working area is the lightest. Iām thinking of making them only 2 colors. What is your opinion?)
More layer manipulation! This was, I think, the most enjoyable coding session in stardance because coding went smoothly with almost no headaches figuring out why things do not work. It also brought many new features after many devlogs of mostly debugging. features visibility button to show/hide paths Dragging and resizing layers so the path only renderes at the given boundaries Dragging layers outside of the visible scroller area expands the scroller size (no current way of retracting it. Open for suggestions :D) Different mouse cursors for different layer manipulations Iām thinking now of two missing features of the timeline: dragging keyframes, and reordering layers, then I might consider the timeline milestone finished (maybe will need some cleaning up) and I could start on the next milestone: graph editors
Keyframe repositionaing is finally here! (the second time I attach the wrong video to the devlog) Timeline is about to be finished. Now you can select keyframes and reposition them. Press shift to add to the selection. Use the selection box to select many keyframes at once. And you can also select keyframes from multiple layers at once. some Quality of life changes Keyframe selection works by searching for the nearest keyframe inside a search radius on the same layer. At first I made it select the keyframe at the exact frame the mouse is currently at, but that became very annoying when zooming out as the frame width gets smaller. Viewport does not update in real time on every mouse move while dragging layers or keyframes, but instead uses some tricks to delay heavy operations until the the mouse button is released. One trick is to when I drag a layer, I only shift the layer drawing, but I do not commit the changes to keyframes yet. To appear as if it was live updating, I send a signal to the viewport to show the viewport a few frames later or prior than the actual current frame is. For keyframe dragging, I actually donāt have a work around. Cavalry uses some visuals like arrows to indicate how that change in keyframes corresponds to changes in viewport but Iām not sure if Iām going to implement it this way (open for suggestions) Additions Added a whilte outline to selected keyframes Click on a keyframe to select it; Click and drag to reposition it Drag over keyframes to select many keyframes using the selection box (called a rubber band) Use shift in combination of the previous two moves to add to the existing selection Time cursor now allows mouse events through instead of blocking it Made pixel level adjustments to layer resizing handles Next, I want to add layer reordering and multi-layer/multi-path selection, then I could consider the timeline milestone finished (maybe I add color coding and tags). I want to move on to the graph editor because I think I spent too much time on polishing the timeline and the event is ending soon (I donāt think 9 weeks are enough :|)
Has been a long time and I wanted to break the silence. Iām honestly getting burned out and Iām not sure if Iām ready to start working on the graph editor (not even sure if the time is enough). For now, Iāve been working on layer reordering and adding some controls to the layers. New features Layer reordering from the layer hierarchy panel that reflects on the viewport Basic ability to rename a path from its corresponding layer. just click on the name Added shortcuts and tool tips for the three tools I have: B for bezier pen, N for node tool, S for select tool Planned features I want to add a tagging / color coding system where you assign a color to a layer and can filter them based on that. I want it just because it looks cool Layer groups. These should work just as normal layers but they do not correspond to a path. The idea is simple but my current spaghetti setup is not helping so I need to clean my code up I want to add a simple reordering control using the page up , page down , home , and end keys to reorder from the viewport itself Want to add a shortcut for timeline playback Space for improvement Clean up some spaghetti code. Maybe go back to drawing board (I didnāt even use one, I just went straight to coding :P ) Layer reordering does not count for if a layer was expanded shortcuts are not global, only if the viewport is active, the shortcut will work
Back again! This time I only worked on fixing two stubborn bugs (There might be some bug with the devlog time being too much. I will check and ask support if any). Bug #1: Layer reordering does not account for expanded layers Previously, my logic was initial_layer_index = floor(mouse_pos / layer_height target_layer_index = round(mouse_pos / layer_height since layer_height is the height of an unexpanded layer, the program thinks Iām moving the wrong layer to the wrong place. Bug #2: layer reordering does not reflect correctly in the layers_ vector. I keep forgetting that the last layer added to a vector is appended to the end, but is drawn on top of other layers. The problem was in the logic of std::rotate (had to brush up on STL for that). It caused a lot of inconsistency and crashs when reordering layers, especially when I fixed bug 1.
Worked on two new features. Seemed simple at the beginning, but I couldnāt help but cleaning up the code, so I introduced more problems and had to fix them :P 1. Random test paths Drawing new paths (squares with distinct colors and names) so I could test layer reordering was taking too much time. I shouldāve started this so much earlier (for example before I finish working on path reordering) but it could help in the future. I will probably remove those before release, but the function is still there and I could call it anytime. 2. Path reordering from viewport using page_up , page_down , home , and end page_up : move up one layer page_down : move down one layer home : move to top end : move to bottom I plan to add buttons for those at the tool bar for the next devlog. Rabbit whole I wanted to move reorderLayer() method from the layerReordered() function (creative naming ) so I could also call it from viewport. I then had to unify the indexing logic between layerReordered() and viewport which meant more STL headaches and more sementation faults
You could try Before Effects now! This will be the Last devlog before first ship (might be as well the last ship :P ) I edited the readme and made executables for windows and linux (waiting for my friend to build it on his mac so I could have that as well). Once I have the mac build as well I will be shipping. Until then, you could try it here I commented out the test paths so users will start with an empty canvas...
|
1792587008.8346868
|
1793191808.8346868
|
|
58573
|
spacecrew by @jakub-ginal | Stardance
|
jakub-ginal
|
1
|
227.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T10:03:07Z", "hours": 227.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "spacecrew - mission control for your terminal What I made: I got tired of opening five browser tabs to follow space, so I built one command that brings them all together. spacecrew tells you whoās in orbit this second, tells you when the ISS is about to cross your sky, counts down the next liftoff with a rocket photo beside it, displays NASAās Picture of the Day in terminal characters, and tracks solar activity with a verdict on whether youāll see auroras tonight. What was challenging: At one point, every satellite prediction was perfectly calculated, but for the mirror image of Earth. A single flipped sign in the orbital math put passes on the wrong side of the planet, and nothing looked obviously broken until I cross-checked each pass against an independent physics library, minute by minute, until reality matched. The other fight was time itself: switching an app built around UTC to local time without breaking a single countdown. What Iām proud of: The app now distrusts the internet by default. Dead APIs, rate limits, airplane mode: it keeps working from cached data and built-in satellite TLEs whenever possible. It also includes real orbital calculations, satellite tracking, radio frequencies, and a full interactive terminal interface, all installable with a single command. Features: People in Space, NASA APOD, Launches, ISS Tracking, Space Weather, Satellite Passes, Themes, Dashboard The GitHub README includes a detailed breakdown of the features, modes, configuration options, and command-line flags, along with screenshots and examples. Try it yourself: Install with either command: pipx install spacecrew or pip install spacecrew", "repo": "https://github.com/jakub-ginal/spacecrew", "demo": "https://pypi.org/project/spacecrew/"}]...
|
[{"post_id": 79650, "ts": "202 [{"post_id": 79650, "ts": "2026-10-14T21:49:05Z", "hours": 0.5514, "text": "spacecrew - quick terminal tour Quick tour of spacecrew in action: interactive menu, people in space, live ISS position, Tonightās Best satellite passes, a launch countdown with the rocket photo view and more. Video is now available on the GitHub project page."}, {"post_id": 79610, "ts": "2026-10-14T18:19:01Z", "hours": 2.1667, "text": "v1.2.18 and v1.2.19 - Documentation and run fixes **Tzdata dependency ** - added the Windows-only tzdata dependency so timezones resolve correctly instead of falling back to UTC Dashboard navigation - fixed Enter-to-exit on Windows using msvcrt , while keeping existing POSIX behavior unchanged Module execution - python -m spacecrew now works via the new __main__.py Version detection - falls back to pyproject.toml in development checkouts to avoid reporting stale versions Docs - completely rewrote the README with feature sections and screenshots Published - v1.2.19 is now available on GitHub and PyPI"}, {"post_id": 79498, "ts": "2026-10-14T09:55:01Z", "hours": 10.1031, "text": "v1.2.17 - Timezones, rocket photos, and satellite pass fixes Local timezones - added --timezone flag, saved timezone settings, and automatic detection. Times display locally (e.g. 20:00 CEST), with UTC in parentheses in detail views UTC consistency - countdowns and --json output remain in UTC Rocket photos - press p in launch details to view a large, high-resolution rocket photo with minimal accompanying info Satellite pass accuracy - fixed a rotation sign error that caused incorrect predictions, verified against an independent reference to within ±1 minute Low-elevation passes - fixed filtering that silently dropped visible passes Settings persistence - fixed settings that sometimes failed to save Clean JSON output - status banners no longer pollute --json output Published - v1.2.17 is now available on GitHub and PyPI"}, {"post_id": 79399, "ts": "2026-10-13T20:13:28Z", "hours": 10.2, "text": "v1.2.16 - Fixes and configuration improvements Cache control - fixed --no-cache , which was parsed but previously ignored Custom configuration - added --config DIR , SPACE_CREW_CONFIG_DIR , and XDG_CONFIG_HOME support for isolated configs NASA API errors - added clearer DEMO_KEY rate-limit hints with an API link, plus 5xx and offline guidance in the APOD view SatNOGS cache - fixed cache typing to support both dictionaries and lists Offline weather - fixed offline responses to return the complete expected data structure Code cleanup - removed a duplicate docstring Documentation - updated the man page to v1.2.16 and synced README examples for --json and --config Published - v1.2.16 is now available on GitHub and PyPI"}, {"post_id": 79178, "ts": "2026-10-12T22:22:37Z", "hours": 8.0389, "text": "v1.2.15 - Scriptability, radio, and aurora JSON output - added --json support for passes, people, and launches, with machine-readable data for scripts, jq , cron jobs, and home automation Pass data - JSON includes satellite name, group, start/end times, max elevation, duration, magnitude, quality, cloud cover, moon phase, and visibility Downlink frequencies - new FREQUENCIES panel with SatNOGS transmitter data, including frequency, mode, uplink, baud rate, and description Offline frequency cache - transmitter data cached for 90 days and available offline Aurora forecast - dashboard and space weather view now show whether aurora is Overhead possible, Low on horizon possible, or Unlikely based on Kp and your location Reliable satellite data - 396-satellite offline TLE fallback across all 13 groups, with stale-cache failover when Celestrak is unavailable Faster fetching - shorter timeouts and improved data loading Published - v1.2.15 is now available on GitHub and PyPI"}, {"post_id": 79019, "ts": "2026-10-12T11:47:58Z", "hours": 10.3897, "text": "v1.2.14 - Live dashboard, countdowns, satellite info, and fetch improvements Live dashboard - updates every second, with background data refreshes every 60 seconds and Enter-only exit Countdowns everywhere - shows time until passes, red NOW for active passes, and dim ENDED for finished passes Pass filtering - ended passes are filtered out so lists start with the next upcoming pass Satellite info panel - displays NORAD ID, launch date, operator, country, and status from cached SatNOGS data Reliable data fetching - fast failover to stale cache and 396-satellite built-in fallback Parallel fetching - satellite groups load in parallel for better performance Cache protection - empty results never overwrite valid cached data Dashboard accuracy - Tiangong no longer displays ISS data Published - v1.2.14 is now available on GitHub and PyPI"}, {"post_id": 78781, "ts": "2026-10-11T16:18:02Z", "hours": 9.7994, "text": "v1.2.13 - Satellite data, dashboard, performance and documentation Offline satellite data - 396 real satellites across all 13 groups Satellite groups - fixed dead GROUP=other and empty iridium groups Dashboard fixes - q quits, Tiangong displays correct data, and unused imports removed Lazy-loaded images - Pillow and chafa no longer required at startup, with a new --no-image flag Performance improvements - optimized observer calculations and parallel group fetching Cache fixes - empty results no longer overwrite cached satellite data Documentation - updated README with all modes, configuration, and flags Man page - fixed documentation and removed duplicate man directory Published - v1.2.13 is now available on GitHub and PyPI"}, {"post_id": 78657, "ts": "2026-10-11T06:07:37Z", "hours": 11.6944, "text": "v1.2.12 - Bug fixes and packaging improvements Core stability - fixed argument parsing and replaced recursive refresh loops with proper loops Astronaut view - fixed crashes when photos are missing Moon phases - all 8 phases now work correctly, with proper UTC timestamps Satellite passes - fixed filter persistence, empty lists, group tags, and missing URLs ISS tracking - improved retries, offline handling, and location accuracy Dashboard - fixed storm level detection, now shows actual conditions Cache and display - improved corrupted cache handling and screen clearing APOD and space weather - fixed API key handling, date requests, and image loading with fallbacks Packaging - wheel now includes the man page and fallback TLE data Published - v1.2.12 is now available on GitHub and PyPI"}, {"post_id": 78399, "ts": "2026-10-10T17:20:02Z", "hours": 10.4, "text": "v1.2.10, v1.2.11 - Satellite tracker improvements Fallback TLE data - 24 satellites across 6 groups, available when network sources fail Detail view fixes Full-width panels - expanded panels for improved layout Faster TLE fetching Published - v1.2.11 is now available on GitHub and PyPI"}, {"post_id": 78156, "ts": "2026-10-09T20:18:48Z", "hours": 9.8033, "text": "v1.2.9 - Satellite detail view & themes Satellite detail redesign - new panel and table layout matching the launches and people views Header panel - satellite name, group badge, and FAV indicator Next Pass panel - highlighted summary with time, elevation, direction, duration, magnitude, quality, cloud cover, and moon phase Full passes table - date, time, max elevation, direction, duration, magnitude, quality, cloud cover, moon phase, and visibility Visibility indicators - green rows for visible passes and dimmed rows for non-visible passes Refined styling - subtle borders and softer colors for a cleaner look 10 themes - added Dracula Published - v1.2.9 is now available on GitHub and PyPI"}, {"post_id": 77945, "ts": "2026-10-08T22:00:46Z", "hours": 6.5667, "text": "v1.2.8 - Satellite Passes visual improvements Panel-based layout - each satellite now has a bordered card with its number, name, group badge, and [FAV] indicator Multiple passes - up to 3 passes per satellite, configurable Quality-tier borders - Best, Good, OK, and Dim tiers with matching colors Clean pass data - time, elevation, compass direction, duration, magnitude, and quality score Visibility details - cloud cover, moon phase, and VISIBLE status shown for each pass Satellite groups - fixed categorization: ISS & Stations, Starlink, Navigation, Science & Weather, Other Favorites integration - [FAV] badge, favorites-only mode with 5 , and F to toggle favorites Detail view navigation - Enter returns to the previous list instead of the main menu Published - v1.2.8 is now available on GitHub and PyPI"}, {"post_id": 77840, "ts": "2026-10-08T14:16:42Z", "hours": 9.7667, "text": "v1.2.6 - Satellite groups, navigation & visual improvements Satellite groups - proper categorization: ISS & Stations, Starlink, Navigation, Science & Weather, Other Detail view navigation - Enter now returns to the previous list instead of the main menu Cloud cover - displayed as āļø XX% Azimuth - compass direction added, e.g. 45°NE ā 135°SE Moon phase - displayed as Moon XX% Code cleanup Published - v1.2.5 is now available on GitHub and PyPI"}, {"post_id": 77668, "ts": "2026-10-07T19:40:00Z", "hours": 10.5333, "text": "v1.2.6 - Favorites satellites Favorites - add or remove satellites from the detail view with F Favorites mode - press 5 in the satellite passes menu to show only favorited satellites Favorites badge - ā
FAV badge shown in satellite detail view Persistent favorites - saved in ~/.config/spacecrew/config.toml Published - v1.2.5 is now available on GitHub and PyPI"}, {"post_id": 77374, "ts": "2026-10-06T18:11:40Z", "hours": 9.9, "text": "v1.2.5 - Satellite tracker fixes & polish Tonightās Best fixed - no longer loads 10k+ Starlink satellites, only ISS + Stations Tiered quality system - Best (mag < 2, el > 45°, dur > 5 min), Good (mag < 4, el > 25°), OK (mag < 5.5, el > 15°) Filter menu - fixed duplicate code Calculating passes⦠- removed duplicate message Man page - added man spacecrew Shell completions - added bash, zsh, and fish support via spacecrew --generate-completion GitHub Release - added automatic release creation on tag push Published - v1.2.5 is now available on GitHub and PyPI"}, {"post_id": 77171, "ts": "2026-10-05T22:04:11Z", "hours": 5.9333, "text": "v1.2.3 - Pass Predictor fixes and UX improvements Tonightās Best no longer loads 10k+ Starlink satellites Tiered quality system - Best, Good, OK instead of one strict filter Filter menu duplicate code fixed Calculating passes⦠duplicate message removed Night filtering fixed with sun_el_max v1.2.3 on GitHub and PyPI."}, {"post_id": 77035, "ts": "2026-10-05T13:12:07Z", "hours": 10.0, "text": "v1.2.3 - Satellite tracker redesign Pass Predictor redesign - Tonightās Best, All Passes, Specific Satellite Cloud cover from Open-Meteo, cached for 1 hour Moon phase via local Meeus algorithm, fully offline Night pass info - cloud cover and moon phase when relevant Satellite groups reorganized for easier browsing Direct satellite search across all groups Type badges added to satellite details Simplified controls - Enter = back everywhere"}, {"post_id": 76893, "ts": "2026-10-04T23:29:10Z", "hours": 9.3603, "text": "v1.2.3 - Cloud cover and moon phase now appear alongside every predicted pass in the satellite tracker. Cloud cover - Real-time data from Open-Meteo. Shows percentage at exact pass time and location. Cached 1 hour. Moon phase - Local Meeus algorithm, zero API calls. Only shown for night passes (sun elevation < -6°). Displays phase name + illumination: MOON FIRST QUARTER 44%. v1.2.3 on GitHub and PyPI."}, {"post_id": 76707, "ts": "2026-10-04T11:48:44Z", "hours": 10.5, "text": "spacecrew v1.2.1 Dashboard mode (option 8) - 2-column btop-like grid: ISS/Tiangong/Passes left, Weather/People/Launches/APOD right; renders via Rich Layout grid 9 themes: default, Catppuccin Mocha/Latte, Tokyo Night, Gruvbox, Nord, Everforest, Rose Pine, Kanagawa - semantic styles, zero hardcoded colors, persist in config.toml v1.2.1 on GitHub and PyPI"}, {"post_id": 76537, "ts": "2026-10-03T21:14:34Z", "hours": 10.4872, "text": "v1.1.18 - Themes, progress bars, consistent Enter=back 5 themes: default, dark, solarized, dracula, monokai Progress bars: spinner for single fetch, count bar for multi-group TLE Enter = back everywhere for consistent navigation Replaced hardcoded colors with semantic theme styles Theme selection persists in config.toml v1.1.18 on GitHub and PyPI."}, {"post_id": 76264, "ts": "2026-10-02T23:41:38Z", "hours": 10.5508, "text": "v1.1.16-17 - Pass quality scores and real magnitudes: Quality (0-100) - elevation, duration, darkness, magnitude, rarity combined Real mags - per-type standards (ISS -1.3, Starlink 5.5, GPS 4.0) with range + phase correction Phase angle math - proper Sun-sat-observer geometry for realistic brightness UI shows both - mag -2.6 Q80 on every pass in list and detail views All groups covered - stations, Starlink, military, NOAA, GOES, GPS, Galileo, BeiDou, Iridium Offlineāirst - cached TLE, zero network needed The predictor now tells you which passes are worth waking up for. v1.1.17 on GitHub and PyPI."}, {"post_id": 76099, "ts": "2026-10-02T10:05:54Z", "hours": 8.0419, "text": "spacecrew v1.1.15 - Satellite Pass Predictor update. Fixed TLE cache: each group (stations, starlink, military, gps, weather, science, amateur, radar, cubesat, geo, iridium). Menu: full menu (all/tonight/stations/starlink quick/days config), tonightās best (quick 24h), specific satellite picker with group selector, search, pagination, 7-day detail, change location, back. 11 groups, 11,500+ satellites. Works offline (cached TLEs, 1-day TTL). v1.1.15 on GitHub and PyPI."}, {"post_id": 75904, "ts": "2026-10-01T15:35:24Z", "hours": 11.1056, "text": "spacecrew v1.1.14 - Satellite Pass Predictor. Menu option 6 / spacecrew āmode passes. Celestrak TLE data + local sgp4 propagation, no API keys, no rate limits, works offline after first run. Tracks ISS, Starlink trains, and many more satellites. Calculates visible passes for the next three days: elevation >10°, sky dark, satellite sunlit. Shows start time, max elevation, duration, direction, visibility flag. Location saved to config, prompted once. Example: ISS 05:53 UTC max 53° 6min westāeast ā, Starlink-1017 11:21 UTC max 80° 7min ā. v1.1.14 on GitHub and PyPI."}, {"post_id": 75680, "ts": "2026-09-30T18:50:20Z", "hours": 10.3292, "text": "Today I released spacecrew v1.1.10, v1.1.11, and v1.1.12. v1.1.10 - Added āoffline flag: runs entirely from local SQLite cache with zero network requests. Avoids rate limits, works without internet. All four modes work if previously cached. Banner shows āOffline mode: using cached data onlyā. v1.1.11 - Launch countdown timer: live T- in launches list (cyan to yellow to red as launch nears, LAUNCHED for past). Space Weather dashboard (menu option 5, āmode weather): solar flares (X/M/C colored), CMEs with speed, Kp index with storm level (Quiet to G5), NOAA 3-day forecast highlights. All cached (1-day TTL), works offline. v1.1.12 - Fixed few things. Published to GitHub (tags v1.1.10, v1.1.11, v1.1.12) and PyPI via automated workflow."}, {"post_id": 75385, "ts": "2026-09-29T22:02:03Z", "hours": 5.7128, "text": "Today I released spacecrew v1.1.9. The main addition is an ISS Tracker using wheretheiss.at (real-time TLE calculation) as primary source with open-notify.org fallback - shows latitude, longitude, altitude (~425 km), velocity (~27,500 km/h), visibility, and location name via reverse geocoding, plus a Google Maps link. Core improvements: persistent SQLite cache with configurable TTL (30 days default) for all API responses, a config file at ~/.config/spacecrew/config.toml (NASA API key, cache TTL, theme, default mode), CLI arguments for direct mode access (āmode {people,apod,launches,iss}), āclear-cache, āno-cache, Windows-compatible screen clearing, and Python 3.10 support via conditional tomli dependency. Published to GitHub (tag v1.1.9) and PyPI via the automated workflow."}, {"post_id": 74899, "ts": "2026-09-28T15:39:13Z", "hours": 10.4289, "text": "Today I worked on spacecrew and enhanced the project with major improvements. I enhanced NASAās Astronomy Picture of the Day (APOD) with date navigation (previous day), HD image opening in browser, and full metadata display. I also added a new Upcoming Launches feature using The Space Devs API, showing 15 upcoming launches from all agencies with a clean panel-based list view and detailed view including links to launch transmissions when available, mission patch, and info/Wikipedia links. I restructured the CLI with a main menu for three modes (People in Space, APOD, Launches), added NASA_API_KEY environment variable support with DEMO_KEY fallback, and implemented in-memory session caching for both features. Published v1.1.8 to GitHub and PyPI."}, {"post_id": 74542, "ts": "2026-09-27T16:30:32Z", "hours": 4.5878, "text": "Today I worked on spacecrew and made several improvements to the project. I added NASAās Astronomy Picture of the Day (APOD), so users can now view the current astronomical picture directly from the CLI. I also tested the feature, updated the project documentation, and published the updated version to GitHub and PyPI. I also worked on improving the overall project and making the CLI easier to use."}, {"post_id": 74031, "ts": "2026-09-26T15:43:20Z", "hours": 0.2561, "text": "Im working on spacecrew, a linux command line tool for managing and organizing space-related information directly from the terminal. Im improving the CLI, adding features, fixing bugs, and making the project easier to use."}]...
|
Title: spacecrew by @jakub-ginal | Stardance
Devl Title: spacecrew by @jakub-ginal | Stardance
Devlogs:
Im working on spacecrew, a linux command line tool for managing and organizing space-related information directly from the terminal. Im improving the CLI, adding features, fixing bugs, and making the project easier to use.
Today I worked on spacecrew and made several improvements to the project. I added NASAās Astronomy Picture of the Day (APOD), so users can now view the current astronomical picture directly from the CLI. I also tested the feature, updated the project documentation, and published the updated version to GitHub and PyPI. I also worked on improving the overall project and making the CLI easier to use.
Today I worked on spacecrew and enhanced the project with major improvements. I enhanced NASAās Astronomy Picture of the Day (APOD) with date navigation (previous day), HD image opening in browser, and full metadata display. I also added a new Upcoming Launches feature using The Space Devs API, showing 15 upcoming launches from all agencies with a clean panel-based list view and detailed view including links to launch transmissions when available, mission patch, and info/Wikipedia links. I restructured the CLI with a main menu for three modes (People in Space, APOD, Launches), added NASA_API_KEY environment variable support with DEMO_KEY fallback, and implemented in-memory session caching for both features. Published v1.1.8 to GitHub and PyPI.
Today I released spacecrew v1.1.9. The main addition is an ISS Tracker using wheretheiss.at (real-time TLE calculation) as primary source with open-notify.org fallback - shows latitude, longitude, altitude (~425 km), velocity (~27,500 km/h), visibility, and location name via reverse geocoding, plus a Google Maps link. Core improvements: persistent SQLite cache with configurable TTL (30 days default) for all API responses, a config file at ~/.config/spacecrew/config.toml (NASA API key, cache TTL, theme, default mode), CLI arguments for direct mode access (āmode {people,apod,launches,iss}), āclear-cache, āno-cache, Windows-compatible screen clearing, and Python 3.10 support via conditional tomli dependency. Published to GitHub (tag v1.1.9) and PyPI via the automated workflow.
Today I released spacecrew v1.1.10, v1.1.11, and v1.1.12. v1.1.10 - Added āoffline flag: runs entirely from local SQLite cache with zero network requests. Avoids rate limits, works without internet. All four modes work if previously cached. Banner shows āOffline mode: using cached data onlyā. v1.1.11 - Launch countdown timer: live T- in launches list (cyan to yellow to red as launch nears, LAUNCHED for past). Space Weather dashboard (menu option 5, āmode weather): solar flares (X/M/C colored), CMEs with speed, Kp index with storm level (Quiet to G5), NOAA 3-day forecast highlights. All cached (1-day TTL), works offline. v1.1.12 - Fixed few things. Published to GitHub (tags v1.1.10, v1.1.11, v1.1.12) and PyPI via automated workflow.
spacecrew v1.1.14 - Satellite Pass Predictor. Menu option 6 / spacecrew āmode passes. Celestrak TLE data + local sgp4 propagation, no API keys, no rate limits, works offline after first run. Tracks ISS, Starlink trains, and many more satellites. Calculates visible passes for the next three days: elevation >10°, sky dark, satellite sunlit. Shows start time, max elevation, duration, direction, visibility flag. Location saved to config, prompted once. Example: ISS 05:53 UTC max 53° 6min westāeast ā, Starlink-1017 11:21 UTC max 80° 7min ā. v1.1.14 on GitHub and PyPI.
spacecrew v1.1.15 - Satellite Pass Predictor update. Fixed TLE cache: each group (stations, starlink, military, gps, weather, science, amateur, radar, cubesat, geo, iridium). Menu: full menu (all/tonight/stations/starlink quick/days config), tonightās best (quick 24h), specific satellite picker with group selector, search, pagination, 7-day detail, change location, back. 11 groups, 11,500+ satellites. Works offline (cached TLEs, 1-day TTL). v1.1.15 on GitHub and PyPI.
v1.1.16-17 - Pass quality scores and real magnitudes: Quality (0-100) - elevation, duration, darkness, magnitude, rarity combined Real mags - per-type standards (ISS -1.3, Starlink 5.5, GPS 4.0) with range + phase correction Phase angle math - proper Sun-sat-observer geometry for realistic brightness UI shows both - mag -2.6 Q80 on every pass in list and detail views All groups covered - stations, Starlink, military, NOAA, GOES, GPS, Galileo, BeiDou, Iridium Offlineāirst - cached TLE, zero network needed The predictor now tells you which passes are worth waking up for. v1.1.17 on GitHub and PyPI.
v1.1.18 - Themes, progress bars, consistent Enter=back 5 themes: default, dark, solarized, dracula, monokai Progress bars: spinner for single fetch, count bar for multi-group TLE Enter = back everywhere for consistent navigation Replaced hardcoded colors with semantic theme styles Theme selection persists in config.toml v1.1.18 on GitHub and PyPI.
spacecrew v1.2.1 Dashboard mode (option 8) - 2-column btop-like grid: ISS/Tiangong/Passes left, Weather/People/Launches/APOD right; renders via Rich Layout grid 9 themes: default, Catppuccin Mocha/Latte, Tokyo Night, Gruvbox, Nord, Everforest, Rose Pine, Kanagawa - semantic styles, zero hardcoded colors, persist in config.toml v1.2.1 on GitHub and PyPI
v1.2.3 - Cloud cover and moon phase now appear alongside every predicted pass in the satellite tracker. Cloud cover - Real-time data from Open-Meteo. Shows percentage at exact pass time and location. Cached 1 hour. Moon phase - Local Meeus algorithm, zero API calls. Only shown for night passes (sun elevation < -6°). Displays phase name + illumination: MOON FIRST QUARTER 44%. v1.2.3 on GitHub and PyPI.
v1.2.3 - Satellite tracker redesign Pass Predictor redesign - Tonightās Best, All Passes, Specific Satellite Cloud cover from Open-Meteo, cached for 1 hour Moon phase via local Meeus algorithm, fully offline Night pass info - cloud cover and moon phase when relevant Satellite groups reorganized for easier browsing Direct satellite search across all groups Type badges added to satellite details Simplified controls - Enter = back everywhere
v1.2.3 - Pass Predictor fixes and UX improvements Tonightās Best no longer loads 10k+ Starlink satellites Tiered quality system - Best, Good, OK instead of one strict filter Filter menu duplicate code fixed Calculating passes⦠duplicate message removed Night filtering fixed with sun_el_max v1.2.3 on GitHub and PyPI.
v1.2.5 - Satellite tracker fixes & polish Tonightās Best fixed - no longer loads 10k+ Starlink satellites, only ISS + Stations Tiered quality system - Best (mag < 2, el > 45°, dur > 5 min), Good (mag < 4, el > 25°), OK (mag < 5.5, el > 15°) Filter menu - fixed duplicate code Calculating passes⦠- removed duplicate message Man page - added man spacecrew Shell completions - added bash, zsh, and fish support via spacecrew --generate-completion GitHub Release - added automatic release creation on tag push Published - v1.2.5 is now available on GitHub and PyPI
v1.2.6 - Favorites satellites Favorites - add or remove satellites from the detail view with F Favorites mode - press 5 in the satellite passes menu to show only favorited satellites Favorites badge - ā
FAV badge shown in satellite detail view Persistent favorites - saved in ~/.config/spacecrew/config.toml Published - v1.2.5 is now available on GitHub and PyPI
v1.2.6 - Satellite groups, navigation & visual improvements Satellite groups - proper categorization: ISS & Stations, Starlink, Navigation, Science & Weather, Other Detail view navigation - Enter now returns to the previous list instead of the main menu Cloud cover - displayed as āļø XX% Azimuth - compass direction added, e.g. 45°NE ā 135°SE Moon phase - displayed as Moon XX% Code cleanup Published - v1.2.5 is now available on GitHub and PyPI
v1.2.8 - Satellite Passes visual improvements Panel-based layout - each satellite now has a bordered card with its number, name, group badge, and [FAV] indicator Multiple passes - up to 3 passes per satellite, configurable Quality-tier borders - Best, Good, OK, and Dim tiers with matching colors Clean pass data - time, elevation, compass direction, duration, magnitude, and quality score Visibility details - cloud cover, moon phase, and VISIBLE status shown for each pass Satellite groups - fixed categorization: ISS & Stations, Starlink, Navigation, Science & Weather, Other Favorites integration - [FAV] badge, favorites-only mode with 5 , and F to toggle favorites Detail view navigation - Enter returns to the previous list instead of the main menu Published - v1.2.8 is now available on GitHub and PyPI
v1.2.9 - Satellite detail view & themes Satellite detail redesign - new panel and table layout matching the launches and people views Header panel - satellite name, group badge, and FAV indicator Next Pass panel - highlighted summary with time, elevation, direction, duration, magnitude, quality, cloud cover, and moon phase Full passes table - date, time, max elevation, direction, duration, magnitude, quality, cloud cover, moon phase, and visibility Visibility indicators - green rows for visible passes and dimmed rows for non-visible passes Refined styling - subtle borders and softer colors for a cleaner look 10 themes - added Dracula Published - v1.2.9 is now available on GitHub and PyPI
v1.2.10, v1.2.11 - Satellite tracker improvements Fallback TLE data - 24 satellites across 6 groups, available when network sources fail Detail view fixes Full-width panels - expanded panels for improved layout Faster TLE fetching Published - v1.2.11 is now available on GitHub and PyPI
v1.2.12 - Bug fixes and packaging improvements Core stability - fixed argument parsing and replaced recursive refresh loops with proper loops Astronaut view - fixed crashes when photos are missing Moon phases - all 8 phases now work correctly, with proper UTC timestamps Satellite passes - fixed filter persistence, empty lists, group tags, and missing URLs ISS tracking - improved retries, offline handling, and location accuracy Dashboard - fixed storm level detection, now shows actual conditions Cache and display - improved corrupted cache handling and screen clearing APOD and space weather - fixed API key handling, date requests, and image loading with fallbacks Packaging - wheel now includes the man page and fallback TLE data Published - v1.2.12 is now available on GitHub and PyPI
v1.2.13 - Satellite data, dashboard, performance and documentation Offline satellite data - 396 real satellites across all 13 groups Satellite groups - fixed dead GROUP=other and empty iridium groups Dashboard fixes - q quits, Tiangong displays correct data, and unused imports removed Lazy-loaded images - Pillow and chafa no longer required at startup, with a new --no-image flag Performance improvements - optimized observer calculations and parallel group fetching Cache fixes - empty results no longer overwrite cached satellite data Documentation - updated README with all modes, configuration, and flags Man page - fixed documentation and removed duplicate man directory Published - v1.2.13 is now available on GitHub and PyPI
v1.2.14 - Live dashboard, countdowns, satellite info, and fetch improvements Live dashboard - updates every second, with background data refreshes every 60 seconds and Enter-only exit Countdowns everywhere - shows time until passes, red NOW for active passes, and dim ENDED for finished passes Pass filtering - ended passes are filtered out so lists start with the next upcoming pass Satellite info panel - displays NORAD ID, launch date, operator, country, and status from cached SatNOGS data Reliable data fetching - fast failover to stale cache and 396-satellite built-in fallback Parallel fetching - satellite groups load in parallel for better performance Cache protection - empty results never overwrite valid cached data Dashboard accuracy - Tiangong no longer displays ISS data Published - v1.2.14 is now available on GitHub and PyPI
v1.2.15 - Scriptability, radio, and aurora JSON output - added --json support for passes, people, and launches, with machine-readable data for scripts, jq , cron jobs, and home automation Pass data - JSON includes satellite name, group, start/end times, max elevation, duration, magnitude, quality, cloud cover, moon phase, and visibility Downlink frequencies - new FREQUENCIES panel with SatNOGS transmitter data, including frequency, mode, uplink, baud rate, and description Offline frequency cache - transmitter data cached for 90 days and available offline Aurora forecast - dashboard and space weather view now show whether aurora is Overhead possible, Low on horizon possible, or Unlikely based on Kp and your location Reliable satellite data - 396-satellite offline TLE fallback across all 13 groups, with stale-cache failover when Celestrak is unavailable Faster fetching - shorter timeouts and improved data loading Published - v1.2.15 is now available on GitHub and PyPI
v1.2.16 - Fixes and configuration improvements Cache control - fixed --no-cache , which was parsed but previously ignored Custom configuration - added --config DIR , SPACE_CREW_CONFIG_DIR , and XDG_CONFIG_HOME support for isolated configs NASA API errors - added clearer DEMO_KEY rate-limit hints with an API link, plus 5xx and offline guidance in the APOD view SatNOGS cache - fixed cache typing to support both dictionaries and lists Offline weather - fixed offline responses to return the complete expected data structure Code cleanup - removed a duplicate docstring Documentation - updated the man page to v1.2.16 and synced README examples for --json and --config Published - v1.2.16 is now available on GitHub and PyPI
v1.2.17 - Timezones, rocket photos, and satellite pass fixes Local timezones - added --timezone flag, saved timezone settings, and automatic detection. Times display locally (e.g. 20:00 CEST), with UTC in parentheses in detail views UTC consistency - countdowns and --json output remain in UTC Rocket photos - press p in launch details to view a large, high-resolution rocket photo with minimal accompanying info Satellite pass accuracy - fixed a rotation sign error that caused incorrect predictions, verified against an independent reference to within ±1 minute Low-elevation passes - fixed filtering that silently dropped visible passes Settings persistence - fixed settings that sometimes failed to save Clean JSON output - status banners no longer pollute --json output Published - v1.2.17 is now available on GitHub and PyPI
v1.2.18 and v1.2.19 - Documentation and run fixes **Tzdata dependency ** - added the Windows-only tzdata dependency so timezones resolve correctly instead of falling back to UTC Dashboard navigation - fixed Enter-to-exit on Windows using msvcrt , while keeping existing POSIX behavior unchanged Module execution - python -m spacecrew now works via the new __main__.py Version detection - falls back to pyproject.toml in development checkouts to avoid reporting stale versions Docs - completely rewrote the README with feature sections and screenshots Published - v1.2.19 is now available on GitHub and PyPI
spacecrew - quick terminal tour Quick tour of spacecrew in action: interactive menu, people in space, live ISS position, Tonightās Best satellite passes, a launch countdown with the rocket photo view and more. Video is now available on the GitHub project page.
Ships:
spacecrew - mission control for your terminal What I made: I got tired of opening five browser tabs to follow space, so I built one command that brings them all together. spacecrew tells you whoās in orbit this second, tells you when the ISS is about to cross your sky, counts down the next liftoff with a rocket photo beside it, displays NASAās Picture of the Day in terminal characters, and tracks solar activity with a verdict on whether youāll see auroras tonight. What was challenging: At one point, every satellite prediction was perfectly calculated, but for the mirror image of Earth. A single flipped sign in the orbital math put passes on the wrong side of the planet, and nothing looked obviously broken until I cross-checked each pass against an independent physics library, minute by minute, until reality matched. The other fight was time itself: switching an app built around UTC to local time without breaking a single countdown. What Iām proud of: The app now distrusts the internet by default. Dead APIs, rate limits, airplane mode: it keeps working from cached data and built-in satellite TLEs whenever possible. It also includes real orbital calculations, satellite tracking, radio frequencies, and a full interactive terminal interface, all installable with a single command. Features: People in Space, NASA APOD, Launches, ISS Tracking, Space Weather, Satellite Passes, Themes, Dashboard The GitHub README includes a detailed breakdown of the features, modes, configuration options, and command-line flags, along with screenshots and examples. Try it yourself: Install with either command: pipx install spacecrew or pip install spacecrew...
|
1793051341.3816288
|
1793137741.3816288
|
|
44865
|
Meshtastic node by @artostash | Stardance
|
artostash
|
0
|
12.89
|
0
|
[]
|
[{"post_id": 79655, "ts": "202 [{"post_id": 79655, "ts": "2026-10-14T22:36:00Z", "hours": 2.5978, "text": "Basically PCB, BOM, and firmware are finished I finally finished the pcb couple of days ago and started making BOM. BOM took a lot of effort and some help from my kind friend. It was really interesting to learn about difference between temperature resistance of X5R and X7R and also other couple of details such as different antenna connectors, what gerbers are, and choosing options on the PCBWay."}, {"post_id": 76905, "ts": "2026-10-05T00:52:58Z", "hours": 2.6261, "text": "Finished and fixed schematic In this period of time I found myself stretched apart by school assignments, tests, and community as well as other projects in need of my attention. So yeah, itās a bit delayed. I finally finished the schematic and fixed it. Removed the switch for the gnss module because there was no free gpio on the ht-ct62. Battery sense moved from GPIO3 to GPIO0 GPIO3 is the LoRa radioās interrupt line inside the HT-CT62, so it now has a no-connect flag. Decided on Keystone 1042 as the holder for the battery. Added the esd protection for the usb-c Added a fuse, and IC protection circuits to the charging circuit just in case Added an LED to the CHG on the BQ24074RGT, so it would indicate charging and stuff Ran the ERC, added power connector flags cause KiCad didnāt like it Assigned footprints. If anyone sees any errors, Iād appreciate any advice."}, {"post_id": 52706, "ts": "2026-08-23T00:15:13Z", "hours": 1.6944, "text": "Spent some time working on a schematic. Finished it. Now starting to debug and check if everything is correct."}, {"post_id": 51416, "ts": "2026-08-21T03:24:51Z", "hours": 4.2633, "text": "August 20th Today I decided to choose a gps/gnss module or a chip. Turns out that standard gnss has precision of 3-10m so it is what I need Turns out that there are bunch of sattelite systems. Reading a bit I chose the SAM-M10Q module since it is a low-cost gnss module which incorporates built-in chip, circuitry, and antenna. Then I started reading datasheet of ht-ct62 and then sx1262. Also I then checked the firmware for ht-ct62. Thank God it was available. For the display I chose ssd1306 since it is a low-cost OLED display module. Since I do want to have a 18650 battery power supply, I need to have a buck boost converter that can step up and step down the voltage. So the whole thing would be something like this: flowchart TD USB[\"USB-C <br/> 5 V\"] --> CHG[\"BQ24074RGTR <br/> charger\"] BAT[\"18650 battery<br/> 3.0ā4.2 V\"] --> CHG CHG --> SYS[\"SYS <br/> 3.0ā4.5 V\"] SYS --> BB[\"TPS63001 <br/> buck-boost converter\"] BB --> RAIL[\"3.3 V rail\"] RAIL --> MAIN[\"HT-CT62 + OLED\"] RAIL --> LOAD[\"TPS22917 <br/> load switch\"] LOAD --> GPS[\"SAM-M10Q <br/> GPS module\"] I then set up the usb_c and charging IC bq24074gtr. For setting up the charging IC I followed this logic EN1 and EN2 configuration EN2 = 0 EN1 = 1 Which places the charger in USB 500 mA input-limit mode: EN2 EN1 Mode 0 0 100 mA USB 0 1 500 mA USB 1 0 Current set by ILIM resistor 1 1 Standby For the buck boost converter it has to be pretty much like datasheet except for PS/SYNC. It controls the operating mode PS/SYNC state Mode LOW/GND Power-save mode enabled HIGH Power-save disabled; forced fixed-frequency operation Clock signal Synchronizes switching to an external clock So in this session I: Researched additional components Chose to add SAM-M10Q GPS module, SSD1306 oled, BQ24074RGTR battery charger, and TPS63001 buck-boost converter Read the datasheets for each component Started the schematic Next steps: Continue schematic Review the schematic and make any necessary changes"}, {"post_id": 50507, "ts": "2026-08-19T17:56:35Z", "hours": 1.7128, "text": "August 18th This is honestly my first journal entry. First hackclub project. I started my day by researching what kind of hardware Meshtastic nodes generally use. I looked at bunch of brands like heltec, lilygo, and seed studio. Each board usually has microcontroller (built-in wifi or bluetooth or both) LoRa module (such as sx1262 or sx1278) antenna connection and antenna USB-C display and it usually runs on a battery or solar power. Some nodes are used for tracking, so they have GPS modules. Some nodes are used for monitoring, so they have sensors for temperature, humidity, etc. For my node I decided it to be an off-grid messaging device so I would like it to have gps and be pretty low-power but also being able to be charged via USB-C from a powerbank. Now coming to the choice of parts I figured there are 2 main ways to go: Use a bare chip or SoC (system on a chip) ESP32-C3 - less powerful than S3, single core risc-v (wifi, bluetooth) cheap and simple, less pins too ESP32-S3 - more powerful than C3, dual core xtensa lx7 (wifi, bluetooth) more expensive, more pins nRF52840 (bluetooth) really low power, but no wifi Use a module (pre-built with a SoC and other components) ESP32-C3-WROOM-1 ESP32-C3-MINI-1 ESP32-S3-MINI-1U HT-CT62 (built-in esp32-c3 + sx1262 lora transciever) not a lot of pins but seems like a really good fit nRF52840 module like Raytac MDBT50Q The thing is if I go with first option, I would need to add a lot of things myself like decoupling, crystals, rf antenna ciruitry, and layout around the chip which is not ideal since I want to build a quick prototype and itās basically my first RF project. So really I should just decide between choosing esp32-c3-wroom-1 or ht-ct62 (or nRF52840 module). I think for now ht-ct62 is the best option since it has a built-in esp32-c3 and sx1262 lora transciever, and is relatively cheap. SX1262 SX1276 SX1278 RFM95 so 127 * are the older gen transceivers and 126 * are the newer gen transceivers. and RFM95 is a module that uses older sx1276 chip. Since Iām going with HT-CT62 , I donāt need to add any of thse because ht-ct62 already has a built-in sx1262 lora module. Now Lora radios use different frequencies and I figured that US/Canada uses 915 MHz which is part of the license-free ISM band. Turns out there are many ways to classify radio communication. By frequency like high frequency (HF), medium frequency (MF), or low frequency (LF). By radio services like amateur radio, general mobile radio service, family radio service, and citizens band. And itās crazy that amateur radio can travel thousands of miles without satellites, repeaters, intermediate nodes or cellular towers. This can happen because the wave is launched at an angle and when it hits the ionosphere it is refracted back to Earth instead of only traveling line of sight. Going a bit further into research I found a reticulum network - a pretty interesting project which is a secure decentralized communication network which allows creation of independent local and wide area networks. Pretty cool! Back to the project. I decided to add to the board standard usb-c, reset button, antenna, gps, and maybe oled. Oh and also I want to add 18650 battery since I want to run the board on battery power and not just usb power. So in this session I: researched about mcu vs module learned about reticulum network read about different radio transceivers and modules discovered for myself a lot of interesting things about radio communication decided to use HT-CT62 as my radio module for the project"}]...
|
Title: Meshtastic node by @artostash | Stardance
Title: Meshtastic node by @artostash | Stardance
Devlogs:
August 18th This is honestly my first journal entry. First hackclub project. I started my day by researching what kind of hardware Meshtastic nodes generally use. I looked at bunch of brands like heltec, lilygo, and seed studio. Each board usually has microcontroller (built-in wifi or bluetooth or both) LoRa module (such as sx1262 or sx1278) antenna connection and antenna USB-C display and it usually runs on a battery or solar power. Some nodes are used for tracking, so they have GPS modules. Some nodes are used for monitoring, so they have sensors for temperature, humidity, etc. For my node I decided it to be an off-grid messaging device so I would like it to have gps and be pretty low-power but also being able to be charged via USB-C from a powerbank. Now coming to the choice of parts I figured there are 2 main ways to go: Use a bare chip or SoC (system on a chip) ESP32-C3 - less powerful than S3, single core risc-v (wifi, bluetooth) cheap and simple, less pins too ESP32-S3 - more powerful than C3, dual core xtensa lx7 (wifi, bluetooth) more expensive, more pins nRF52840 (bluetooth) really low power, but no wifi Use a module (pre-built with a SoC and other components) ESP32-C3-WROOM-1 ESP32-C3-MINI-1 ESP32-S3-MINI-1U HT-CT62 (built-in esp32-c3 + sx1262 lora transciever) not a lot of pins but seems like a really good fit nRF52840 module like Raytac MDBT50Q The thing is if I go with first option, I would need to add a lot of things myself like decoupling, crystals, rf antenna ciruitry, and layout around the chip which is not ideal since I want to build a quick prototype and itās basically my first RF project. So really I should just decide between choosing esp32-c3-wroom-1 or ht-ct62 (or nRF52840 module). I think for now ht-ct62 is the best option since it has a built-in esp32-c3 and sx1262 lora transciever, and is relatively cheap. SX1262 SX1276 SX1278 RFM95 so 127 * are the older gen transceivers and 126 * are the newer gen transceivers. and RFM95 is a module that uses older sx1276 chip. Since Iām going with HT-CT62 , I donāt need to add any of thse because ht-ct62 already has a built-in sx1262 lora module. Now Lora radios use different frequencies and I figured that US/Canada uses 915 MHz which is part of the license-free ISM band. Turns out there are many ways to classify radio communication. By frequency like high frequency (HF), medium frequency (MF), or low frequency (LF). By radio services like amateur radio, general mobile radio service, family radio service, and citizens band. And itās crazy that amateur radio can travel thousands of miles without satellites, repeaters, intermediate nodes or cellular towers. This can happen because the wave is launched at an angle and when it hits the ionosphere it is refracted back to Earth instead of only traveling line of sight. Going a bit further into research I found a reticulum network - a pretty interesting project which is a secure decentralized communication network which allows creation of independent local and wide area networks. Pretty cool! Back to the project. I decided to add to the board standard usb-c, reset button, antenna, gps, and maybe oled. Oh and also I want to add 18650 battery since I want to run the board on battery power and not just usb power. So in this session I: researched about mcu vs module learned about reticulum network read about different radio transceivers and modules discovered for myself a lot of interesting things about radio communication decided to use HT-CT62 as my radio module for the project
August 20th Today I decided to choose a gps/gnss module or a chip. Turns out that standard gnss has precision of 3-10m so it is what I need Turns out that there are bunch of sattelite systems. Reading a bit I chose the SAM-M10Q module since it is a low-cost gnss module which incorporates built-in chip, circuitry, and antenna. Then I started reading datasheet of ht-ct62 and then sx1262. Also I then checked the firmware for ht-ct62. Thank God it was available. For the display I chose ssd1306 since it is a low-cost OLED display module. Since I do want to have a 18650 battery power supply, I need to have a buck boost converter that can step up and step down the voltage. So the whole thing would be something like this: flowchart TD USB["USB-C <br/> 5 V"] --> CHG["BQ24074RGTR <br/> charger"] BAT["18650 battery<br/> 3.0ā4.2 V"] --> CHG CHG --> SYS["SYS <br/> 3.0ā4.5 V"] SYS --> BB["TPS63001 <br/> buck-boost converter"] BB --> RAIL["3.3 V rail"] RAIL --> MAIN["HT-CT62 + OLED"] RAIL --> LOAD["TPS22917 <br/> load switch"] LOAD --> GPS["SAM-M10Q <br/> GPS module"] I then set up the usb_c and charging IC bq24074gtr. For setting up the charging IC I followed this logic EN1 and EN2 configuration EN2 = 0 EN1 = 1 Which places the charger in USB 500 mA input-limit mode: EN2 EN1 Mode 0 0 100 mA USB 0 1 500 mA USB 1 0 Current set by ILIM resistor 1 1 Standby For the buck boost converter it has to be pretty much like datasheet except for PS/SYNC. It controls the operating mode PS/SYNC state Mode LOW/GND Power-save mode enabled HIGH Power-save disabled; forced fixed-frequency operation Clock signal Synchronizes switching to an external clock So in this session I: Researched additional components Chose to add SAM-M10Q GPS module, SSD1306 oled, BQ24074RGTR battery charger, and TPS63001 buck-boost converter Read the datasheets for each component Started the schematic Next steps: Continue schematic Review the schematic and make any necessary changes
Spent some time working on a schematic. Finished it. Now starting to debug and check if everything is correct.
Finished and fixed schematic In this period of time I found myself stretched apart by school assignments, tests, and community as well as other projects in need of my attention. So yeah, itās a bit delayed. I finally finished the schematic and fixed it. Removed the switch for the gnss module because there was no free gpio on the ht-ct62. Battery sense moved from GPIO3 to GPIO0 GPIO3 is the LoRa radioās interrupt line inside the HT-CT62, so it now has a no-connect flag. Decided on Keystone 1042 as the holder for the battery. Added the esd protection for the usb-c Added a fuse, and IC protection circuits to the charging circuit just in case Added an LED to the CHG on the BQ24074RGT, so it would indicate charging and stuff Ran the ERC, added power connector flags cause KiCad didnāt like it Assigned footprints. If anyone sees any errors, Iād appreciate any advice.
Basically PCB, BOM, and firmware are finished I finally finished the pcb couple of days ago and started making BOM. BOM took a lot of effort and some help from my kind friend. It was really interesting to learn about difference between temperature resistance of X5R and X7R and also other couple of details such as different antenna connectors, what gerbers are, and choosing options on the PCBWay....
|
1792601683.2411246
|
1793206483.2411246
|
|
64625
|
AuroraOS by @waffles888 | Stardance
|
waffles888
|
2
|
21.0
|
19
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T00:04:23Z", "hours": 8.0, "multiplier": 2.32, "payout": 19, "blessing": "neutral", "text": "This is my ship for the WebOS 2 mission. Itās built off of the original WebOS mission site but even flashier. The notes app I have created is what I am the most proud of because notes can be saved and loaded even if the page is refreshed. It was complicated getting all of it to work but Iām really happy and enjoyed getting it to a finished state.", "repo": "https://github.com/waffles-888/AuroraOS", "demo": "https://waffles-888.github.io/AuroraOS/"}, {"ship_num": 2, "ts": "2026-09-30T22:04:52Z", "hours": 13.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "This WebOS is themed around subnautica, I found alot of the javascript challenging, understanding how to make the code and ensuring it all works too without any issues took me a while, this was why one of the devlogs had 6 hours logged. I am really proud of the project overall and I really liked how I started to understand JavaScript to make some of the features I wanted such as the sonar effect when the desktop thing.", "repo": "https://github.com/waffles-888/AuroraOS", "demo": "https://waffles-888.github.io/AuroraOS/"}]...
|
[{"post_id": 79657, "ts": "202 [{"post_id": 79657, "ts": "2026-10-14T22:56:35Z", "hours": 1.4453, "text": "Devlog 8 - Saving Notes I added the ability for notes to be saved to the browser so that even on a refresh of the page you could still use the notes already made. I spent a lot of time debugging this as it was super complex to get working but it finally works."}, {"post_id": 79307, "ts": "2026-10-13T13:37:47Z", "hours": 3.685, "text": "Devlog 7 - Second app This app is a pretty basic app yet its still a little complicated to make. I had to clean up little bits of code from other things and adjust it to make it easier to make new apps and add onto the code that was already made. Styling was easy as it all uses one mostly universal theme. Notes can be saved and deleted however I want to add the ability to load them off of the desktop which I may work on."}, {"post_id": 78382, "ts": "2026-10-10T16:38:41Z", "hours": 2.9364, "text": "Devlog 6 - Intro Animation I cleaned up code to make it overall more optimised. The main thing I got to do was adding an intro animation to the site. It made it look a little fancier and reminiscent to the intro of subnautica itself. I got stuck getting text to show up on the page but after a bit of debugging I made the overlay work and now it works great"}, {"post_id": 75707, "ts": "2026-09-30T20:00:51Z", "hours": 0.7897, "text": "Devlog 5 - Click animation This was way easier to make compared to the things I had to make before this, all it is, is a simple effect that plays when the desktop is clicked, its simple but I think looks nice and fits the theme overall of the site."}, {"post_id": 75548, "ts": "2026-09-30T12:23:42Z", "hours": 6.4742, "text": "Devlog 4 - My first app I created my first basic app for the webOS, it holds a little information about some of the creatures that can be found in subnautica. This has taken me a large amount of time of debugging and testing to get things to work such as window selection and styling. This was mainly due to javascript as I dont really have a big understanding on it."}, {"post_id": 73710, "ts": "2026-09-25T19:10:18Z", "hours": 2.0164, "text": "Devlog 3 - Windows After a bit of debugging I finally added the function to open and close the window, being able to actually get the windows to be moveable was less of a hassle. The javascript is set up to make making new windows easier for apps I created on the OS. Next is actually making my first app for this."}, {"post_id": 73349, "ts": "2026-09-24T23:24:51Z", "hours": 1.5544, "text": "Devlog 2 - OS bar I learnt a little more about javascript making this part of the WebOS as I had to use javascript in order to get the date and time to line up with the current time inside of the bar. I also decided to move where the was when I first created it to the bottom similar to how windows is. Finally I also made the welcome message which I thought was nicely made and im ready to make the moveable windows for the OS"}, {"post_id": 73156, "ts": "2026-09-24T14:32:48Z", "hours": 2.4892, "text": "Devlog 1 - The Start I started creating my WebOS which is themed around subnautica, I added my profile picture and made it so that it can be clicked to get to my GitHub account, I also added a little photo of a pet I have."}]...
|
Title: AuroraOS by @waffles888 | Stardance
Devlog Title: AuroraOS by @waffles888 | Stardance
Devlogs:
Devlog 1 - The Start I started creating my WebOS which is themed around subnautica, I added my profile picture and made it so that it can be clicked to get to my GitHub account, I also added a little photo of a pet I have.
Devlog 2 - OS bar I learnt a little more about javascript making this part of the WebOS as I had to use javascript in order to get the date and time to line up with the current time inside of the bar. I also decided to move where the was when I first created it to the bottom similar to how windows is. Finally I also made the welcome message which I thought was nicely made and im ready to make the moveable windows for the OS
Devlog 3 - Windows After a bit of debugging I finally added the function to open and close the window, being able to actually get the windows to be moveable was less of a hassle. The javascript is set up to make making new windows easier for apps I created on the OS. Next is actually making my first app for this.
Devlog 4 - My first app I created my first basic app for the webOS, it holds a little information about some of the creatures that can be found in subnautica. This has taken me a large amount of time of debugging and testing to get things to work such as window selection and styling. This was mainly due to javascript as I dont really have a big understanding on it.
Devlog 5 - Click animation This was way easier to make compared to the things I had to make before this, all it is, is a simple effect that plays when the desktop is clicked, its simple but I think looks nice and fits the theme overall of the site.
Devlog 6 - Intro Animation I cleaned up code to make it overall more optimised. The main thing I got to do was adding an intro animation to the site. It made it look a little fancier and reminiscent to the intro of subnautica itself. I got stuck getting text to show up on the page but after a bit of debugging I made the overlay work and now it works great
Devlog 7 - Second app This app is a pretty basic app yet its still a little complicated to make. I had to clean up little bits of code from other things and adjust it to make it easier to make new apps and add onto the code that was already made. Styling was easy as it all uses one mostly universal theme. Notes can be saved and deleted however I want to add the ability to load them off of the desktop which I may work on.
Devlog 8 - Saving Notes I added the ability for notes to be saved to the browser so that even on a refresh of the page you could still use the notes already made. I spent a lot of time debugging this as it was super complex to get working but it finally works.
Ships:
This WebOS is themed around subnautica, I found alot of the javascript challenging, understanding how to make the code and ensuring it all works too without any issues took me a while, this was why one of the devlogs had 6 hours logged. I am really proud of the project overall and I really liked how I started to understand JavaScript to make some of the features I wanted such as the sonar effect when the desktop thing.
This is my ship for the WebOS 2 mission. Itās built off of the original WebOS mission site but even flashier. The notes app I have created is what I am the most proud of because notes can be saved and loaded even if the page is refreshed. It was complicated getting all of it to work but Iām really happy and enjoyed getting it to a finished state....
|
1793062038.2482326
|
1793148438.2482326
|
|
23550
|
SpacePad!!! by @Ahmed-Tantawy | Stardance
|
Ahmed-Tantawy
|
0
|
26.18
|
0
|
[]
|
[{"post_id": 79661, "ts": "202 [{"post_id": 79661, "ts": "2026-10-14T23:38:07Z", "hours": 1.6503, "text": "Iāve just made it!!! Iāve just finished my very first own macropad, Iāve made the case and the code, but i forgot to save the colored version of my step files, but i donāt care i will only change the filament color, hope you loke it :) The Space pad has 6 switches with 3 profiles to change between by holding on the encoder and it will change between the profiles with simple animations on the screen(hopefully) and the screen will show you which profile name and number are you in, and it has RGB which is enough."}, {"post_id": 77065, "ts": "2026-10-05T15:11:36Z", "hours": 0.6328, "text": "Iām working on the Case, when I finish it I will share it with you."}, {"post_id": 76868, "ts": "2026-10-04T21:33:48Z", "hours": 3.5542, "text": "REMAKING SPACE PAD, Iām making space pad from the beginning, Iāve just finished the PCB and now making the Case, The Changes: decreased the 9 switches to 6, decreased the 14 RGB LEDs to 12, ADDED THE OLED SCREEN!!! What is your opinion about the new one?"}, {"post_id": 75247, "ts": "2026-09-29T15:49:49Z", "hours": 1.7969, "text": "I have just finished the Firware and also edited my case, BUT!!! I donāt know how to log the time of the code in the same as the CAD and PCB, so i accedintlly logged a ( 2-hours and 27 min ) session of coding on another folder."}, {"post_id": 73348, "ts": "2026-09-24T23:21:56Z", "hours": 1.8617, "text": "I have just finished the Case of Space Pad, Itās AMAZING for me as the first CAD project, hope you like it like me, heading to software hopefully."}, {"post_id": 72223, "ts": "2026-09-22T14:14:54Z", "hours": 5.2889, "text": "Iām amazed by what I have done with the case, when I finish it completely I will show you the masterpiece I made, not that amazement, but Iām very happy with it as my first CAD project."}, {"post_id": 72118, "ts": "2026-09-22T06:28:10Z", "hours": 1.195, "text": "Iām close to finish the bottom layer of the case, but i have a question, if made the holes for the m3 insertsā diameter is 4.7, although that the insert is 5 mm diameter, so i can heat it using the soldering iron to insert it, do i have to make a hole in the bottom to add a nut or is it okay to have the m3 insert only?"}, {"post_id": 69836, "ts": "2026-09-17T21:33:06Z", "hours": 0.3669, "text": "Uploaded the 3D models of the parts of the PCB, and prepared for the CAD."}, {"post_id": 68658, "ts": "2026-09-15T14:18:31Z", "hours": 1.25, "text": "Iām suffering :( i am stuck in the CAD and case design and i am not even able to do one shell, and I didnāt make any CAD before, and pleaseeeeeeeeeeeeeeeeee if anyone made this mission before, please help me."}, {"post_id": 66119, "ts": "2026-09-11T18:47:33Z", "hours": 0.5669, "text": "Made slight changes in the silkscreen and made the drawings more simple, and changed the PCB size from 100.5 Length and 81 Width, to 99.5 Length and 81 Width, so it fits the rules of the PCB making step as Hack Club Guide has mentioned."}, {"post_id": 64488, "ts": "2026-09-08T22:24:52Z", "hours": 0.8511, "text": "I can say that I FINALLY!!! made the PCB, Iāve just removed the not needed silkscreen and added the cool Orphus and hack club drawings, and of course my cool octopus, and i made the PCB with smooth curved edges, waiting for your comments"}, {"post_id": 64324, "ts": "2026-09-08T16:44:34Z", "hours": 1.8522, "text": "I know that Iām a bit crazy and that I took too much for the most simple and easy part in the HackPad mission:) but i returned to the concept of the RGBs instead of the OLED Screen, the screen may be more useful but it will make the design not as i wanted it to be, do I made this hopefully last version⦠if you have any comments or advices i will appreciate it especially if the advice is about the Case Design."}, {"post_id": 61505, "ts": "2026-09-04T13:37:47Z", "hours": 0.9186, "text": "No real progress today, but i need help, if i want to have the Hack Pad vertically and i donāt want to move the encoder, switches, or the OLED Screen, where should I put the XIAO, and if i put it in the B.Cu can i put the GND area in the B.Cu when i do this? if anyone helped me Iāll appreciate it too much"}, {"post_id": 61064, "ts": "2026-09-03T19:38:54Z", "hours": 0.8508, "text": "In the first, Iām sorry for not recording anything for 3 days, truthfully I have no arguments because it was my laziness, i mad some remakes in the PCB because I knew that i was using the wrong footprints for the diodes, and also I mad differences in the place of the XIAO, and if any of you have any advice for me I will appreciate it, specially an advice in the CAD please because Iām very bad in it."}, {"post_id": 57695, "ts": "2026-08-29T22:43:27Z", "hours": 0.6344, "text": "Finally!!! Iāve finished the whole PCB, I was trying to have more graphics but it will ruin the electricity, Iā m very proud of the final result, hope all of you love it, and if any of you have any comments I will be soo thankful :)"}, {"post_id": 57551, "ts": "2026-08-29T18:47:03Z", "hours": 0.4172, "text": "Adding the Mounting holes, Ground area and putting the last details."}, {"post_id": 56735, "ts": "2026-08-28T16:38:32Z", "hours": 0.6669, "text": "Remaking the routes of the PCB so that if i made the space under the xiao visible, there will be some cool wiring Routes 0_o"}, {"post_id": 56702, "ts": "2026-08-28T15:53:46Z", "hours": 0.8261, "text": "working on the Routing of the PCB"}, {"post_id": 54413, "ts": "2026-08-25T12:43:56Z", "hours": 0.3508, "text": "Remaking the PCB, I felt like that the RGBs isnāt very important, so i deleted them and added an OLED screen instead of it, and changed the places of some rows.. If any of you have some tips to me about the placement, i will be soo thankful to know it :)"}, {"post_id": 37799, "ts": "2026-07-30T18:50:57Z", "hours": 0.2672, "text": "Finallyyyy! Iāve just finished the PCB, I know that it is very messy, but Iām proud of my first PCB, if you have any comment you want to add, i will be happy to know :)"}, {"post_id": 35470, "ts": "2026-07-26T22:36:49Z", "hours": 0.3836, "text": "Iām working on the schematic of my MacroPad ( SpacePad ), i made it with 9 switches with 9 diodes, 1 rotary encoder ( a knob ), RGB Lights, and of course the microcontroller, Iām too excited to finish this project!!!"}]...
|
Title: SpacePad!!! by @Ahmed-Tantawy | Stardance
Title: SpacePad!!! by @Ahmed-Tantawy | Stardance
Devlogs:
Iām working on the schematic of my MacroPad ( SpacePad ), i made it with 9 switches with 9 diodes, 1 rotary encoder ( a knob ), RGB Lights, and of course the microcontroller, Iām too excited to finish this project!!!
Finallyyyy! Iāve just finished the PCB, I know that it is very messy, but Iām proud of my first PCB, if you have any comment you want to add, i will be happy to know :)
Remaking the PCB, I felt like that the RGBs isnāt very important, so i deleted them and added an OLED screen instead of it, and changed the places of some rows.. If any of you have some tips to me about the placement, i will be soo thankful to know it :)
working on the Routing of the PCB
Remaking the routes of the PCB so that if i made the space under the xiao visible, there will be some cool wiring Routes 0_o
Adding the Mounting holes, Ground area and putting the last details.
Finally!!! Iāve finished the whole PCB, I was trying to have more graphics but it will ruin the electricity, Iā m very proud of the final result, hope all of you love it, and if any of you have any comments I will be soo thankful :)
In the first, Iām sorry for not recording anything for 3 days, truthfully I have no arguments because it was my laziness, i mad some remakes in the PCB because I knew that i was using the wrong footprints for the diodes, and also I mad differences in the place of the XIAO, and if any of you have any advice for me I will appreciate it, specially an advice in the CAD please because Iām very bad in it.
No real progress today, but i need help, if i want to have the Hack Pad vertically and i donāt want to move the encoder, switches, or the OLED Screen, where should I put the XIAO, and if i put it in the B.Cu can i put the GND area in the B.Cu when i do this? if anyone helped me Iāll appreciate it too much
I know that Iām a bit crazy and that I took too much for the most simple and easy part in the HackPad mission:) but i returned to the concept of the RGBs instead of the OLED Screen, the screen may be more useful but it will make the design not as i wanted it to be, do I made this hopefully last version⦠if you have any comments or advices i will appreciate it especially if the advice is about the Case Design.
I can say that I FINALLY!!! made the PCB, Iāve just removed the not needed silkscreen and added the cool Orphus and hack club drawings, and of course my cool octopus, and i made the PCB with smooth curved edges, waiting for your comments
Made slight changes in the silkscreen and made the drawings more simple, and changed the PCB size from 100.5 Length and 81 Width, to 99.5 Length and 81 Width, so it fits the rules of the PCB making step as Hack Club Guide has mentioned.
Iām suffering :( i am stuck in the CAD and case design and i am not even able to do one shell, and I didnāt make any CAD before, and pleaseeeeeeeeeeeeeeeeee if anyone made this mission before, please help me.
Uploaded the 3D models of the parts of the PCB, and prepared for the CAD.
Iām close to finish the bottom layer of the case, but i have a question, if made the holes for the m3 insertsā diameter is 4.7, although that the insert is 5 mm diameter, so i can heat it using the soldering iron to insert it, do i have to make a hole in the bottom to add a nut or is it okay to have the m3 insert only?
Iām amazed by what I have done with the case, when I finish it completely I will show you the masterpiece I made, not that amazement, but Iām very happy with it as my first CAD project.
I have just finished the Case of Space Pad, Itās AMAZING for me as the first CAD project, hope you like it like me, heading to software hopefully.
I have just finished the Firware and also edited my case, BUT!!! I donāt know how to log the time of the code in the same as the CAD and PCB, so i accedintlly logged a ( 2-hours and 27 min ) session of coding on another folder.
REMAKING SPACE PAD, Iām making space pad from the beginning, Iāve just finished the PCB and now making the Case, The Changes: decreased the 9 switches to 6, decreased the 14 RGB LEDs to 12, ADDED THE OLED SCREEN!!! What is your opinion about the new one?
Iām working on the Case, when I finish it I will share it with you.
Iāve just made it!!! Iāve just finished my very first own macropad, Iāve made the case and the code, but i forgot to save the colored version of my step files, but i donāt care i will only change the filament color, hope you loke it :) The Space pad has 6 switches with 3 profiles to change between by holding on the encoder and it will change between the profiles with simple animations on the screen(hopefully) and the screen will show you which profile name and number are you in, and it has RGB which is enough....
|
1792691458.5795295
|
1793296258.5795295
|
|
32906
|
Pegboard by @OrangeJuice | Stardance
|
OrangeJuice
|
1
|
5.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T01:00:43Z", "hours": 5.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Pegboard My personal site in the style of a pegboard! Includes: Shelf with links to my socials About me sections Project sections, Each keychain is linked to a project of mine Vinyl shelf that includes some of my fav albums!", "repo": "https://github.com/Orangejuiceonntop/Pegboard", "demo": "https://orangejuiceonntop.github.io/Pegboard/"}]...
|
[{"post_id": 79667, "ts": "202 [{"post_id": 79667, "ts": "2026-10-15T00:50:11Z", "hours": 1.0811, "text": "Pegboard My personal site! Background info Hi guys itās been a whileeeeš. I noticed that I never finished this website, so I decided to finally come back and finish it! Whatās new Added keychain images Linked each keychain to a project of mine! Changed the hover animations from border-sizing change to scale Finished writing the Readme This project will be shipped soon. Thanks for reading! Until next time!"}, {"post_id": 36260, "ts": "2026-07-28T07:47:49Z", "hours": 1.4339, "text": "Pegboard My personal site! Whatās new Not much has been added. I mostly work on this website in between my other projects as a ābreakā, so I like to keep this website pretty simple to give my brain a break š Added image links to my socials on the top shelf Clicking on the vinyls/albums brings you to spotify Originally, clicking on the album would play a song and a panel would show up saying what song it is, but I decided to just link it to spotify instead because itās more convenient and would make the website less cluttered Added hover animations Just to make the website a little more fun To-do Add keychain drawing for the projectās section Decorate the website a little bit more Thatās it for now. Until next time!"}, {"post_id": 28575, "ts": "2026-07-14T22:14:06Z", "hours": 1.1561, "text": "Pegboard My personal site! Whatās new Iāve been working on this website while I work on other projects so not much has been added so far Projects area There will be keychains of my projects where you can hover over them to see more information Vinyl shelf Added some of my fav albums Eventually Iāll make so when you click them, music plays Hanging plant For some greenery Whatās next Add keychains for projects Add links to my github and itch.io Until next time!"}, {"post_id": 25166, "ts": "2026-07-09T06:46:41Z", "hours": 1.0753, "text": "Pegboard My personal site! First Devlog! I wanted to take a little break from my other project, so I decided to make this website. I wanted to make it look like those aesthetic pinterest pegboards. Right now itās super bare bones and doesnāt have much going on. What I have so far A shelf (the gray bar) I couldnāt find any shelf pngs so I made one. Itāll get a makeover soon tho Links to my github and itch.io will be placed on it My profile pic About me section + programs I use section To do Add links on top of shelf Add a projects section Work on the overall visuals of the website Iāll try to make a lot of progress next time I make a devlog. Until then!"}]...
|
Title: Pegboard by @OrangeJuice | Stardance
Devlo Title: Pegboard by @OrangeJuice | Stardance
Devlogs:
Pegboard My personal site! First Devlog! I wanted to take a little break from my other project, so I decided to make this website. I wanted to make it look like those aesthetic pinterest pegboards. Right now itās super bare bones and doesnāt have much going on. What I have so far A shelf (the gray bar) I couldnāt find any shelf pngs so I made one. Itāll get a makeover soon tho Links to my github and itch.io will be placed on it My profile pic About me section + programs I use section To do Add links on top of shelf Add a projects section Work on the overall visuals of the website Iāll try to make a lot of progress next time I make a devlog. Until then!
Pegboard My personal site! Whatās new Iāve been working on this website while I work on other projects so not much has been added so far Projects area There will be keychains of my projects where you can hover over them to see more information Vinyl shelf Added some of my fav albums Eventually Iāll make so when you click them, music plays Hanging plant For some greenery Whatās next Add keychains for projects Add links to my github and itch.io Until next time!
Pegboard My personal site! Whatās new Not much has been added. I mostly work on this website in between my other projects as a ābreakā, so I like to keep this website pretty simple to give my brain a break š Added image links to my socials on the top shelf Clicking on the vinyls/albums brings you to spotify Originally, clicking on the album would play a song and a panel would show up saying what song it is, but I decided to just link it to spotify instead because itās more convenient and would make the website less cluttered Added hover animations Just to make the website a little more fun To-do Add keychain drawing for the projectās section Decorate the website a little bit more Thatās it for now. Until next time!
Pegboard My personal site! Background info Hi guys itās been a whileeeeš. I noticed that I never finished this website, so I decided to finally come back and finish it! Whatās new Added keychain images Linked each keychain to a project of mine! Changed the hover animations from border-sizing change to scale Finished writing the Readme This project will be shipped soon. Thanks for reading! Until next time!
Ships:
Pegboard My personal site in the style of a pegboard! Includes: Shelf with links to my socials About me sections Project sections, Each keychain is linked to a project of mine Vinyl shelf that includes some of my fav albums!...
|
1793156123.3300617
|
1793242523.3300617
|
|
69026
|
pigpy by @diynotaguy | Stardance
|
diynotaguy
|
0
|
14.94
|
0
|
[]
|
[{"post_id": 79668, "ts": "202 [{"post_id": 79668, "ts": "2026-10-15T00:50:56Z", "hours": 8.6183, "text": "evlogday 2 devlog 2 in piglatin I havenāt posted a devlog in over 8 hours of work because Iāve been working on pretty much the same function for ages!! I think Iād better just bite the bullet and write about it even when itās still not finished What Iām working on: Iām writing a function called combine that will combine the translated English 3D list input (which I talked about in the previous devlog) into a list of all the possible full translations of the pigpy program I will then create a new python file, then write and test each full translation on that document by writing one of the elements of the combine output and then executing it as a python file. Most of the opening, writing, and executing (with try:, except:) is complete, I just need to finish writing combine. One of my many issues: One issue I encountered was that when you multiply a list in python - e.g.: lst = lst * 2 - the added section on the end of the new lst, which is a repeat of the original lst, will actually point to the same memory as the original lst. This is an issue because after multiplying the list, I need the elements to be able to branch off into having different content to make different translation combinations, but that wasnāt working. To solve this I had to import copy and use copy.deepcopy() alongside for loops to make sure they would point to different memory locations Improvements: I have started using a tests.py file (see screenie) to test functions using assert. Iām very new to this, but it does seem quite useful I am in the process of making organisation changes: I am planning on having multiple .py files so that I can write a lot of functions in one of them, then import them into the other to reduce clutter. I think itās so cool that you can import your own files just like regular libraries, though I suppose thatās just what libraries are! ^- This will be especially useful for the combine function, because it is (imo) so long and complex, and Iād like to break it up into smaller functions to make it easier to read, understand, and debug!!"}, {"post_id": 78410, "ts": "2026-10-10T18:04:47Z", "hours": 6.3222, "text": "ollehway umanshway! Pig latin is not a good language⦠Iām working on a python program that runs pigpy and outputs the result. Iām not sure if Iām the first to make pigpy as a language, but itās essentially python where each word is translated into pig latin. The major flaw: Now, you may think this program is simple enough since I just have to translate pig latin into english then run it through python, but thereās one major flaw. English to pig latin translation is a many-to-one function: up to two English words can translate to the same pig latin word. E.g. āinā and āwinā both translate to āinwayā. Because of this, thereās no way to tell if inway should translate back to in or way. Luckily , in most cases where pig latin translates to two possible words, only one of them makes sense, and is an actual word. Thus I can use this to my advantage when narrowing down possbile translations. What Iāve made: Separation function that separates pigpy words from the symbols in the user-written code Translation function that translates each separate pigpy word into its possible English versions. Statement that checks possible translations against set of English words and python keywords. Invalid words are eliminated Error message and quitting if a pigpy word has no valid English translations (i.e. pigpy spelling is wrong) Function that calculates how many possible full translation combinations there are based on the remaining valid English translation possibilities ##The screenshot: The screenshot shows the output of separating and finding translations for a pigpy program before adding the dictionary. After adding the dictionary, the totalPossibilities (for the full translation) reduced by 508 to just 4 ! Whatās next? Next is to test each translation combination by running them through python. Hopefully all but one combination are eliminated, and therefore the correct output can be given to the user."}]...
|
Title: pigpy by @diynotaguy | Stardance
Devlogs:
Title: pigpy by @diynotaguy | Stardance
Devlogs:
ollehway umanshway! Pig latin is not a good language⦠Iām working on a python program that runs pigpy and outputs the result. Iām not sure if Iām the first to make pigpy as a language, but itās essentially python where each word is translated into pig latin. The major flaw: Now, you may think this program is simple enough since I just have to translate pig latin into english then run it through python, but thereās one major flaw. English to pig latin translation is a many-to-one function: up to two English words can translate to the same pig latin word. E.g. āinā and āwinā both translate to āinwayā. Because of this, thereās no way to tell if inway should translate back to in or way. Luckily , in most cases where pig latin translates to two possible words, only one of them makes sense, and is an actual word. Thus I can use this to my advantage when narrowing down possbile translations. What Iāve made: Separation function that separates pigpy words from the symbols in the user-written code Translation function that translates each separate pigpy word into its possible English versions. Statement that checks possible translations against set of English words and python keywords. Invalid words are eliminated Error message and quitting if a pigpy word has no valid English translations (i.e. pigpy spelling is wrong) Function that calculates how many possible full translation combinations there are based on the remaining valid English translation possibilities ##The screenshot: The screenshot shows the output of separating and finding translations for a pigpy program before adding the dictionary. After adding the dictionary, the totalPossibilities (for the full translation) reduced by 508 to just 4 ! Whatās next? Next is to test each translation combination by running them through python. Hopefully all but one combination are eliminated, and therefore the correct output can be given to the user.
evlogday 2 devlog 2 in piglatin I havenāt posted a devlog in over 8 hours of work because Iāve been working on pretty much the same function for ages!! I think Iād better just bite the bullet and write about it even when itās still not finished What Iām working on: Iām writing a function called combine that will combine the translated English 3D list input (which I talked about in the previous devlog) into a list of all the possible full translations of the pigpy program I will then create a new python file, then write and test each full translation on that document by writing one of the elements of the combine output and then executing it as a python file. Most of the opening, writing, and executing (with try:, except:) is complete, I just need to finish writing combine. One of my many issues: One issue I encountered was that when you multiply a list in python - e.g.: lst = lst * 2 - the added section on the end of the new lst, which is a repeat of the original lst, will actually point to the same memory as the original lst. This is an issue because after multiplying the list, I need the elements to be able to branch off into having different content to make different translation combinations, but that wasnāt working. To solve this I had to import copy and use copy.deepcopy() alongside for loops to make sure they would point to different memory locations Improvements: I have started using a tests.py file (see screenie) to test functions using assert. Iām very new to this, but it does seem quite useful I am in the process of making organisation changes: I am planning on having multiple .py files so that I can write a lot of functions in one of them, then import them into the other to reduce clutter. I think itās so cool that you can import your own files just like regular libraries, though I suppose thatās just what libraries are! ^- This will be especially useful for the combine function, because it is (imo) so long and complex, and Iād like to break it up into smaller functions to make it easier to read, understand, and debug!!...
|
1793130441.533369
|
1793735241.533369
|
|
69760
|
HTMS Aircrafter by @OrcaTheWhale | Stardance
|
OrcaTheWhale
|
0
|
1.74
|
0
|
[]
|
[{"post_id": 79670, "ts": "202 [{"post_id": 79670, "ts": "2026-10-15T00:56:36Z", "hours": 1.735, "text": "Hello! So, I lowkey have been sidetracked a lot and I didnāt really want to deal with The YuumiBoard, in all honesty⦠Umm, even though itās supposed to be a gift, my friend said that it was fine so Iāll surprise him with it later for like Christmas or something. Iāll release it while Stardance is still active as a design if I canāt finish the build. Anyways, I figured I want more hours into Stardance and I felt like I was wasting an opportunity, so I wanted to create something and ship stuff. My original idea was to make a devboard smaller than the Teensyās newer generation of devboards, but then veered more into just⦠creating something? I guess? I figured I wanted it to be cool, so Iām going to be modeling the thing like an Aircraft carrier. However, the project is gonna be two parts; the chip is gonna be a separate module, and the carrier is just going to be the⦠well⦠carrier, for the chip module. Well, anyways, for today, module schematic is done(I think), and I need to figure out the castellated edges later."}]...
|
Title: HTMS Aircrafter by @OrcaTheWhale | Stardanc Title: HTMS Aircrafter by @OrcaTheWhale | Stardance
Devlogs:
Hello! So, I lowkey have been sidetracked a lot and I didnāt really want to deal with The YuumiBoard, in all honesty⦠Umm, even though itās supposed to be a gift, my friend said that it was fine so Iāll surprise him with it later for like Christmas or something. Iāll release it while Stardance is still active as a design if I canāt finish the build. Anyways, I figured I want more hours into Stardance and I felt like I was wasting an opportunity, so I wanted to create something and ship stuff. My original idea was to make a devboard smaller than the Teensyās newer generation of devboards, but then veered more into just⦠creating something? I guess? I figured I wanted it to be cool, so Iām going to be modeling the thing like an Aircraft carrier. However, the project is gonna be two parts; the chip is gonna be a separate module, and the carrier is just going to be the⦠well⦠carrier, for the chip module. Well, anyways, for today, module schematic is done(I think), and I need to figure out the castellated edges later....
|
1792857359.9408836
|
1793462159.9408836
|
|
975
|
JevTalk by @ciaran | Stardance
|
ciaran
|
0
|
5.19
|
0
|
[]
|
[{"post_id": 79672, "ts": "202 [{"post_id": 79672, "ts": "2026-10-15T01:01:48Z", "hours": 0.8447, "text": "The web interface is now in full working order, so now itās time to make it look pretty."}, {"post_id": 79663, "ts": "2026-10-14T23:56:22Z", "hours": 0.9208, "text": "OHHHH, thatās why it was talking to itself."}, {"post_id": 78003, "ts": "2026-10-09T04:36:29Z", "hours": 3.4222, "text": "Iāve got the main groundwork done. At first i tried just having a model consult Jev but it was really just the model talking, so i had jev select each word from a pool given by 6 luna. After that, sometimes Jevād start responding as the user, but its mostly fixed. Plus, its so earnest that its kinda just cute. Just needs a web UI."}]...
|
Title: JevTalk by @ciaran | Stardance
Devlogs:
Iā Title: JevTalk by @ciaran | Stardance
Devlogs:
Iāve got the main groundwork done. At first i tried just having a model consult Jev but it was really just the model talking, so i had jev select each word from a pool given by 6 luna. After that, sometimes Jevād start responding as the user, but its mostly fixed. Plus, its so earnest that its kinda just cute. Just needs a web UI.
OHHHH, thatās why it was talking to itself.
The web interface is now in full working order, so now itās time to make it look pretty....
|
1792716632.18975
|
1793321432.18975
|
|
46565
|
Fun with Squares by @noahplaysmario | Stardance
|
noahplaysmario
|
0
|
22.48
|
0
|
[]
|
[{"post_id": 79678, "ts": "202 [{"post_id": 79678, "ts": "2026-10-15T01:26:38Z", "hours": 1.0539, "text": "Improved the demo scene so it represents the actual game better and I can work on making the graphics good."}, {"post_id": 79528, "ts": "2026-10-14T13:28:26Z", "hours": 0.5383, "text": "OH MY GOODNESS I FINALLY GOT IT WORKING I finally figured out (with the help of claude) where the bug was and I fixed it (myself). Now I can actually see the world instead of just a screen full of sky!"}, {"post_id": 63308, "ts": "2026-09-07T01:54:33Z", "hours": 2.9153, "text": "Got the 3d texture set up but not working⦠Help wanted! I got the 3D texture working, but I just see a screen full of sky. I am going to work on debugging it myself, but if you want to look at the code and you see something weird, I would like to know."}, {"post_id": 60771, "ts": "2026-09-03T11:20:43Z", "hours": 5.8661, "text": "Did some optimizations, discarded some to do later instead, kept 1, and started work on sending world data from CPU. Note: No git commit for this one because I need to finish the code for tracking the world on the CPU, but thereās a good idea of what Iām doing in the screenshot!"}, {"post_id": 47701, "ts": "2026-08-15T19:46:24Z", "hours": 3.26, "text": "Refractions, Reflection, and Skybox I added refractions, reflections, and a skybox. I also made the camera move. The next steps for the project are lighting, optimizing the shader for performance(so I can have a reasonable render distance because 64 looks like a lot but the player is actually 8 blocks wide because this game is more detailed than Minecraft), and sending the world data from the CPU instead of generating it while rendering."}, {"post_id": 47036, "ts": "2026-08-14T17:10:13Z", "hours": 4.9458, "text": "I finally got a start to ray tracing! The game is finally rendering using raytracing, although itās currently very minimal and for some reason thereās a blue bar on the left. If anyone can help figure out why, it would be much appreciated."}, {"post_id": 45464, "ts": "2026-08-11T23:09:42Z", "hours": 2.5631, "text": "The Test Triangle Look! A triangle! (This is a very common test to make sure a graphics library works)"}, {"post_id": 45149, "ts": "2026-08-11T13:36:16Z", "hours": 1.3356, "text": "Finally got the window drawing! (WGPU is hard)"}]...
|
Title: Fun with Squares by @noahplaysmario | Stard Title: Fun with Squares by @noahplaysmario | Stardance
Devlogs:
Finally got the window drawing! (WGPU is hard)
The Test Triangle Look! A triangle! (This is a very common test to make sure a graphics library works)
I finally got a start to ray tracing! The game is finally rendering using raytracing, although itās currently very minimal and for some reason thereās a blue bar on the left. If anyone can help figure out why, it would be much appreciated.
Refractions, Reflection, and Skybox I added refractions, reflections, and a skybox. I also made the camera move. The next steps for the project are lighting, optimizing the shader for performance(so I can have a reasonable render distance because 64 looks like a lot but the player is actually 8 blocks wide because this game is more detailed than Minecraft), and sending the world data from the CPU instead of generating it while rendering.
Did some optimizations, discarded some to do later instead, kept 1, and started work on sending world data from CPU. Note: No git commit for this one because I need to finish the code for tracking the world on the CPU, but thereās a good idea of what Iām doing in the screenshot!
Got the 3d texture set up but not working⦠Help wanted! I got the 3D texture working, but I just see a screen full of sky. I am going to work on debugging it myself, but if you want to look at the code and you see something weird, I would like to know.
OH MY GOODNESS I FINALLY GOT IT WORKING I finally figured out (with the help of claude) where the bug was and I fixed it (myself). Now I can actually see the world instead of just a screen full of sky!
Improved the demo scene so it represents the actual game better and I can work on making the graphics good....
|
1792669995.756712
|
1793274795.756712
|
|
15701
|
Lively by @naver | Stardance
|
naver
|
1
|
2.0
|
14
|
[{"ship_num": 1, "ts": "2026-0 [{"ship_num": 1, "ts": "2026-06-13T09:25:57Z", "hours": 2.0, "multiplier": 8.58, "payout": 14, "blessing": "neutral", "text": "I made a audio visualizer using python with the Turtle library as visualization. This project sparked up on me when ı saw another example of audio visualization made by Scott W Harden who has a excellent blog on using a image and a html page including javascript to visualize the image without adding a hefty gui. The hardest part of this project was understanding the logic behind the code and writing it in a way so others with no understanding of the code may easily apprehend the code i think i did a half decent job at that . But be informed AI was used to make the code (using code from Scott W Hardens blog and looking through other codes, getting the ideas i like). Since this will be my first time shipping a project be harsh because what will i do if i donāt learn.(Sorry for my English)", "repo": "https://github.com/20Cuneyt10/lively", "demo": "https://20cuneyt10.github.io/lively/"}]...
|
[{"post_id": 7968, "ts": "2026 [{"post_id": 7968, "ts": "2026-06-13T09:12:30Z", "hours": 1.3467, "text": "Added the explanation for the README currently working on adding comments for the code to make it more readable. Image down below is just the web demo you can access through my github profile or just https://20cuneyt10.github.io/lively/ Iām planning to add a variable corner to so you can experiment on the web demo"}, {"post_id": 6890, "ts": "2026-06-11T15:31:00Z", "hours": 0.3358, "text": "This is a project I started after my exams to play around with how Python interacts with sound. I want to implement 3D objects and games into this scope soon so I can at least call it a project, rather than just me learning the fundamentals of sound waves and how an ADC works."}]...
|
Title: Lively by @naver | Stardance
Devlogs:
This Title: Lively by @naver | Stardance
Devlogs:
This is a project I started after my exams to play around with how Python interacts with sound. I want to implement 3D objects and games into this scope soon so I can at least call it a project, rather than just me learning the fundamentals of sound waves and how an ADC works.
Added the explanation for the README currently working on adding comments for the code to make it more readable. Image down below is just the web demo you can access through my github profile or just https://20cuneyt10.github.io/lively/ Iām planning to add a variable corner to so you can experiment on the web demo
Ships:
I made a audio visualizer using python with the Turtle library as visualization. This project sparked up on me when ı saw another example of audio visualization made by Scott W Harden who has a excellent blog on using a image and a html page including javascript to visualize the image without adding a hefty gui. The hardest part of this project was understanding the logic behind the code and writing it in a way so others with no understanding of the code may easily apprehend the code i think i did a half decent job at that . But be informed AI was used to make the code (using code from Scott W Hardens blog and looking through other codes, getting the ideas i like). Since this will be my first time shipping a project be harsh because what will i do if i donāt learn.(Sorry for my English)...
|
1793130823.2966697
|
1793217223.2966697
|
|
69690
|
Neo by @melodelete | Stardance
|
melodelete
|
0
|
1.66
|
0
|
[]
|
[{"post_id": 79686, "ts": "202 [{"post_id": 79686, "ts": "2026-10-15T02:04:55Z", "hours": 1.6594, "text": "grrrr after long long got the ui and the shortcuts to work, turns out iām stupid because shift changes the character of the shortcut :<"}]...
|
Title: Neo by @melodelete | Stardance
Devlogs:
gr Title: Neo by @melodelete | Stardance
Devlogs:
grrrr after long long got the ui and the shortcuts to work, turns out iām stupid because shift changes the character of the shortcut :<...
|
1792857323.8981965
|
1793462123.8981965
|
|
69770
|
Python by @syedakhter | Stardance
|
syedakhter
|
1
|
2.0
|
1
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T02:13:57Z", "hours": 2.0, "multiplier": 1.0, "payout": 1, "blessing": "neutral", "text": "I made a website about python it tells you about python why its important python features and diffrent versions of python", "repo": "https://github.com/8051987-eng/Python", "demo": "https://8051987-eng.github.io/Python/"}]...
|
[{"post_id": 79688, "ts": "202 [{"post_id": 79688, "ts": "2026-10-15T02:12:43Z", "hours": 2.0147, "text": "I made a website about python"}]...
|
Title: Python by @syedakhter | Stardance
Devlogs: Title: Python by @syedakhter | Stardance
Devlogs:
I made a website about python
Ships:
I made a website about python it tells you about python why its important python features and diffrent versions of python...
|
1793127198.9469802
|
1793213598.9469802
|
|
69776
|
Wet or Warm by @Jazil | Stardance
|
Jazil
|
1
|
2.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-15T02:46:39Z", "hours": 2.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I made a weather app using api i know this is basic but this help me to study using api with getting by class", "repo": "https://github.com/JazilJafar/Weather-Finder", "demo": "https://jaziljafar.github.io/Weather-Finder/"}]...
|
[{"post_id": 79693, "ts": "202 [{"post_id": 79693, "ts": "2026-10-15T02:44:51Z", "hours": 2.3792, "text": "I made a weather getting app using api v1.0 is live https://jaziljafar.github.io/Weather-Finder/"}]...
|
Title: Wet or Warm by @Jazil | Stardance
Devlogs: Title: Wet or Warm by @Jazil | Stardance
Devlogs:
I made a weather getting app using api v1.0 is live https://jaziljafar.github.io/Weather-Finder/
Ships:
I made a weather app using api i know this is basic but this help me to study using api with getting by class...
|
1793134404.0766468
|
1793220804.0766468
|
|
1736
|
Stormfall by @myth0 | Stardance
|
myth0
|
0
|
75.48
|
0
|
[]
|
[{"post_id": 79704, "ts": "202 [{"post_id": 79704, "ts": "2026-10-15T03:53:42Z", "hours": 0.9122, "text": "I added this cool wind gust shader to my game! Eventually Iām going to have gameplay mechanics where wind pushes the player, which can boost (or limit) the playerās jump distance. For now I just focused on the visuals for this mechanic and I still need to implement the physics. To make the visual effect, I intially tried a unity particle system based approach. This looked really bad however so I made a shader for the wind instead. Basically the shader scrolls the X UV offset on a gradient noise node. The tiling of the gradient noise is super stretched out so it looks like streaks of wind instead of dots. It was simple to make and turned out pretty good! Now time to implement the physicsā¦"}, {"post_id": 79457, "ts": "2026-10-14T03:26:58Z", "hours": 3.2947, "text": "Wow, its been a while since I devlogged on here! Iām back with some more progress on my metroidvania. In the last few hours I started refining the art and level design for the gameās 2nd area. I added a bunch of sprites like tilesets, rock formations, animated dead bushes, and spikes. Then I started assembling the area in the editor. It took me a while to get the areaās art to match what I had imagined without creating visual clutter on the screen. I think it looks pretty good now and Im proud of how it turned out! I also learned a lot from building the previous area and so this time I made a ton of art/environment prefabs right away. This is going to save me a loooot of time when filling in the art for the rest of the area. I also greyboxed a bunch of the level design. I have the level design built for about 1/2 of the area now. This area is where the player unlocks wall jump, and itās also going to have some fun wind mechanics that can boost the playerās jump distance (I still need to code this). Iām trying to build the level design to complement these features so that the area has a unique play style compared to the first area."}, {"post_id": 75073, "ts": "2026-09-29T02:14:04Z", "hours": 6.7061, "text": "In the last several hours, I made a whole bunch of progress. First I fixed a whole bunch of relatively minor bugs. Things like getting stuck on ability obtained screens, minor potential scene loading issues, and scenes unloading when the player revives after falling on spikes. I added a screen with an autosave notice. It wasnt really nessecary but makes the game look professional. Updated some small things like the gameās splash screen, internal name, and game icon. Added a custom cursor when in the game window. I added a knockback system! Enemies now actually get knocked back when hit. I used an interface that I attached to the enemy health manager script to create this system. I added a new music track for the village area that the player can find after finishing the first gameplay area. Then I actually started working on the village area. I used existing sprites to make a castle-like structure for the player to pass through. I also made a really nice animated flag sprite for the village. I worked on level design for the 2nd major area of the game. Iām about halfway done the level design for this area at the moment! And since stardance is going for an extra month, Iāll probably have time to ship the 2nd area now!"}, {"post_id": 70271, "ts": "2026-09-18T20:58:14Z", "hours": 5.4206, "text": "I did a ton of stuff over the last 5 hours of work! Hereās some of the main things I added: Added a jump animation to the player! This is a feature that many people have requested, but I kept procrastinating adding it. I had briefly tried to draw an animation for this in the past and I just couldnāt get the animation to look right. This time I spent more time and effort on it and I think it turned out pretty good now. Restructured the interaction system. I wanted parry and interact (the input used to talk to NPCs, pick up items, etc) to both use the right mouse button. For most of development I had temporarily set the interact button to a random key on the keyboard to prevent conflict. However, I now implemented a context-based system that detects whether or not the player is nearby an interactable object. If they are, then it executes an interaction, if not, it will parry. This required significant rewriting for the scripts attached to most interactable objects. However the system is now much cleaner and will be easier to maintain in the future. Interaction is now handled from a centralized singleton class, rather from each interactable item script independently. Added a dust trail effect to the player. When the player walks, dust particles will play behind them, making a nice visual effect. There are a couple of weird places the player can reach when using movement abilities accessed from the Beta Features mode. I added a couple little easter eggs to these places for the players who explore everything. Fixed a lot of bugs, including: Breakable objects having iframes that last for too long, effectively making them seem to have much more health than they should. Input not being disabled when the player first loads in, causing potential problems with the intro movement tutorial. Fixed issues with the new jump animations interrupting combat animations, which can cause combat animations to not play when they should. Renamed a couple files to make script names more cohesive. Fixed some collider bugs, including a particular spot where the player kept catching on a seam. Fixed an issue where the player sometimes didnāt count as being grounded when on the very edge of a platform."}, {"post_id": 66794, "ts": "2026-09-12T17:58:57Z", "hours": 6.3628, "text": "I implemented a data-driven tutorial system to my game! Whenever the player gains a new skill or ability, a short tutorial will now pop up explaining how to use the ability. I intentionally made this system super flexible so I can easily add more abilities in the future. Each tutorial is defined by a scriptable object with information including: Tutorial text contents and location on the screen Focused object (A vignette will appear on the screen centered around the object. Usually this is just set to the player but there are some special cases where it should be focused on something else.) Input the player needs to press to use their new ability and clear the tutorial. Overall, the game should be a lot more intuitive to play now. Players will no longer have to read through all the controls, instead the controls get gradually explained to them as they unlock more abilities. This is unrelated to the tutorial system, but I also updated my old dialogue system. I added a function to display fullscreen dialogue. This will be used in key points of the game, where it will fade to white and display some important lines of dialogue. So far, I used this for the gameās āprologueā, a short text-based intro that appears when you first create a new save file."}, {"post_id": 62381, "ts": "2026-09-05T18:28:47Z", "hours": 3.7819, "text": "I finally finished the 10th room of the game! This room introduces a ton of new mechanics in its level design. Iāve been working on the mechanics for this room for the last several devlogs, so itās nice to finally have finished it! In this room, the player must navigate to 2 different levers that, when triggered, open a gate in the floor. Players can then fall down a chasm into an ancient battlefield room. Then they obtain the shield ability from a fallen soldier. Then some of the newest enemy types spawn in and the player must sucessfully defeat them. To survive the battle, the player needs to utilize the new shield ability which allows them to block attacks. I also added a beta features toggle to the pause menu. The toggle allows the player to use certain in-game abilities that are still in development, like sprinting, dashing, wall jumping, double jumping, lunge attacking, shield bouncing, and more."}, {"post_id": 60580, "ts": "2026-09-03T01:04:49Z", "hours": 6.3033, "text": "Iāve havenāt made too much progress on my project over the last little while because of classes starting :( But Iām finally devlogging some of the changes Iāve made over the last week or so. First, I refactored the combat system for the possibly the 4rd or 5th time since first starting the project (almost a year ago now!) This time around, I implemented an upwards and downwards attack, as well as better implementing the lunge attack. I also switched the attack logic to be partly animation-driven rather than coroutine-driven like it was before. Attack damage is now properly synced to the attack animation, and the weird state bugs I was having before are basically gone. Some parts of the new system still feel a little buggy, but overall I think the attack system is much better now. The second major thing I did was finishing implementing the pathfinding of one of the first ārealā enemies (the crawler guys I already have donāt really count). The new enemy now tracks the player correctly. If no player is in range, it will pace back and forth and pause occasionally. It has ledge and wall detection. If the player is in attack range, it will attempt to attack the player. Currently the enemy code architecture isnāt structured very well, but Iām kinda rushing to quickly wrap up this stage of the project so I can ship soon! Now I just gotta polish the game a bit over the next couple days/weeks and then it should be ready to ship!"}, {"post_id": 51756, "ts": "2026-08-21T16:12:58Z", "hours": 3.6508, "text": "I added the UI interface for player customization. Currently this screen is only accessible from the pause screen, but in the future I will incorporate it into the gameplay so the player customize the character at specific locations throughout the world. I also fixed some issues with how the UI menus were structured. I made every screen into a unity Canvas Group. I also fixed some bugs where the player could get stuck in certain menu screens. Last but not least I added a new upward attack animation for the player, though I still need to implement the functionality."}, {"post_id": 49039, "ts": "2026-08-17T17:03:05Z", "hours": 3.8592, "text": "I started working on character customization mechanics! Many metroidvanias just use a static character with little to no customization options so I thought this would be a nice way to differentiate my game from other similar games. Basically for now the player can recolor the knightās cape, helmet plume, and sword hilt. The knight sprites were originally colored blue, making it tricky to use simple color adjustment shaders to recolor it. Rather than going back and redrawing tons of sprites, I wrote a shader that detects saturated areas on the original sprites and overlays a new color on top. Overall it works pretty well now, and now I just need to add a menu to select a color scheme. I also spent like 30 mins working on enemy pathfinding mechanics for a new enemy type!"}, {"post_id": 41477, "ts": "2026-08-05T18:16:47Z", "hours": 2.3075, "text": "I finally fixed some problems I was having with the playerās collider catching on seams. This bug was pretty rare and not too much of an issue. However in certain parts of the map, mainly near any slopes, the slopeās collider has a tiny seam where it joins the rectangular tilemap collider. The old player collider would get stuck on this seam occasionally. After a lot of messing around with colliders and 2d physics materials, I fixed this issue by changing the playerās collider to a composite collider. The composite collider contains a capsule collider and a box collider. The rounded edges of the capsule allows the player to walk over top of seams easily, and the box collider makes it so the player doesnt slip off the edges of platforms."}, {"post_id": 40887, "ts": "2026-08-04T18:07:42Z", "hours": 2.0378, "text": "For the time tracked in this devlog, I mostly worked on environment decoration in the newest room of the game. I added a really nice looking torch sprite with a fire shader. I also added various details to the game world, like floating platforms in the background, torches, and ancient ruins. I also updated some of the level design. I added platforms to make certain areas possible to reach."}, {"post_id": 40223, "ts": "2026-08-03T17:01:11Z", "hours": 4.5128, "text": "I took a long break from Stardance to work on other projects, but Iām finally back with another devlog for my metroidvania. I mostly finished the art pass for the latest room of the game. I also fixed a bunch of unity inspector warnings that Iāve had for a looong time now and just never got around to fixing. The main warning I fixed were that some of the render textures I used for water reflections and fullscreen shockwaves didnāt have a depth buffer attached. While they did technically work, it wasnāt the ideal way to have the render textures set up. This was a relatively easy fix thankfully."}, {"post_id": 23558, "ts": "2026-07-06T16:23:47Z", "hours": 3.2408, "text": "I continued working on the art for the 9th and 10th rooms of the game. I also fixed some issues in my custom render feature that I use to render special effects, including a few potential memory leaks. I also reworked my āsafe zoneā mechanic that detects where the player should respawn if they fall onto spikes. Now it tracks specific safe respawn locations instead of the old logic, which was to track any zone where the player shouldnāt respawn."}, {"post_id": 16286, "ts": "2026-06-26T14:11:19Z", "hours": 2.4736, "text": "Continued working on level design. Iāve finished the level design for the entire first area of the game now! I added a room with another lever puzzle that introduces the shortcut mechanics to the player. I also added an area where the player will obtain the shield ability. Now I need to start filling in the art for the new rooms, and create the gameās first boss fight."}, {"post_id": 15107, "ts": "2026-06-24T15:26:36Z", "hours": 3.6742, "text": "Worked a bit on the art for the new rooms. I also added some new gameplay mechanics, like platforms that fall to a new location after the player hits them. I also fixed another instance where the combat animations desynced from the code logic."}, {"post_id": 13726, "ts": "2026-06-22T14:33:17Z", "hours": 3.62, "text": "For the last few hours of work, Iāve been working on level design! Iām very close now to finishing the level design of the first area of the game. I added some generic transversal rooms, a lever puzzle room, and a platforming room with spikes. Next, Iām going to add a room where the player can find the shield, which will grant the parry/block ability."}, {"post_id": 12055, "ts": "2026-06-19T17:43:15Z", "hours": 1.2886, "text": "Added levers! When the player toggles them, they can do various things like open gates, open shortcuts, and maybe even spawn enemies. In the future, Iām going to use them to build puzzle areas that will hopefully make the level design more standout and unique. Iām really happy with how the animations for the new mechanics turned out, especially the gateās animations shown in the video."}, {"post_id": 11370, "ts": "2026-06-18T16:39:19Z", "hours": 0.66, "text": "This devlog is on the shorter side, but I finally fixed something that Iāve been meaning to fix for a while. Sometimes when spamming the attack button, the code running the attack logic got desynced from the visual animations, causing weird situations where the animation wouldnāt play for a few seconds, or would transition to the next state way too quickly. I was scared it would take hours to debug this problem, but it turned out to be super simple. I fixed it by simply making sure the animationās exit time in the unity animator exactly matches the cooldown window defined in the code."}, {"post_id": 9629, "ts": "2026-06-16T01:06:14Z", "hours": 3.1986, "text": "Continued refining the stamina mechanics! I mostly finished hooking up the combat system to the stamina system. Attacking and blocking now deplete a set amount of stamina, and a successful, correctly timed block/parry restores a bunch of stamina. The stamina meter also now slowly refills over time, and refills much faster when near a save point. I also made the code and artwork for āstamina flowersā (still need to think of a cool name), which when broken will spawn a stamina orb that flies towards the player and refills a bunch of stamina when picked up. This involved pathfinding logic using trig functions that make the orb fly at the correct angle and velocity towards the player. I plan to use this pathfinding logic for future pickup items as well. Lastly, I added a particle effect that plays when the playerās stamina meter is full, and another effect that plays when it is close to empty. Overall the stamina system feels really polished now, and I feel like the combat is a lot better now with the added stamina mechanics!"}, {"post_id": 8159, "ts": "2026-06-13T16:36:08Z", "hours": 2.8875, "text": "Added a stamina mechanic! Attacking now requires stamina. When stamina is used up, it will slowly refill back to the maximum over time. In the future, I plan to make successfully parrying enemy attacks also refill some stamina. The hardest part of this was creating the visual stamina bar in the UI. I used a shader to offset the spriteās UV depending on what percentage of stamina the player has remanining. The shader also applies a multiplier to the sprite colorās intensity to make the stamina meter glow more when it is closer to full."}, {"post_id": 6369, "ts": "2026-06-10T18:44:22Z", "hours": 5.2822, "text": "First devlog on Stardance! You might remember this project from flavortown, and Iām going to keep working on it for stardance. Iāve added a ton of stuff to the game in the last month, like 3 or 4 new player abilities, new animations, and polishing various things based on feedback I received. The ~5 hours in this devlog were mostly me trying to set up a system where I can have 2 post processing profiles active at once, but affecting different layers. I used this to create an intense bloom effect that only renders on certain sprites, specifically the spark particles in combat. I finally got it working using render features and render graphs, and Iām super happy with the result."}]...
|
Title: Stormfall by @myth0 | Stardance
Devlogs:
F Title: Stormfall by @myth0 | Stardance
Devlogs:
First devlog on Stardance! You might remember this project from flavortown, and Iām going to keep working on it for stardance. Iāve added a ton of stuff to the game in the last month, like 3 or 4 new player abilities, new animations, and polishing various things based on feedback I received. The ~5 hours in this devlog were mostly me trying to set up a system where I can have 2 post processing profiles active at once, but affecting different layers. I used this to create an intense bloom effect that only renders on certain sprites, specifically the spark particles in combat. I finally got it working using render features and render graphs, and Iām super happy with the result.
Added a stamina mechanic! Attacking now requires stamina. When stamina is used up, it will slowly refill back to the maximum over time. In the future, I plan to make successfully parrying enemy attacks also refill some stamina. The hardest part of this was creating the visual stamina bar in the UI. I used a shader to offset the spriteās UV depending on what percentage of stamina the player has remanining. The shader also applies a multiplier to the sprite colorās intensity to make the stamina meter glow more when it is closer to full.
Continued refining the stamina mechanics! I mostly finished hooking up the combat system to the stamina system. Attacking and blocking now deplete a set amount of stamina, and a successful, correctly timed block/parry restores a bunch of stamina. The stamina meter also now slowly refills over time, and refills much faster when near a save point. I also made the code and artwork for āstamina flowersā (still need to think of a cool name), which when broken will spawn a stamina orb that flies towards the player and refills a bunch of stamina when picked up. This involved pathfinding logic using trig functions that make the orb fly at the correct angle and velocity towards the player. I plan to use this pathfinding logic for future pickup items as well. Lastly, I added a particle effect that plays when the playerās stamina meter is full, and another effect that plays when it is close to empty. Overall the stamina system feels really polished now, and I feel like the combat is a lot better now with the added stamina mechanics!
This devlog is on the shorter side, but I finally fixed something that Iāve been meaning to fix for a while. Sometimes when spamming the attack button, the code running the attack logic got desynced from the visual animations, causing weird situations where the animation wouldnāt play for a few seconds, or would transition to the next state way too quickly. I was scared it would take hours to debug this problem, but it turned out to be super simple. I fixed it by simply making sure the animationās exit time in the unity animator exactly matches the cooldown window defined in the code.
Added levers! When the player toggles them, they can do various things like open gates, open shortcuts, and maybe even spawn enemies. In the future, Iām going to use them to build puzzle areas that will hopefully make the level design more standout and unique. Iām really happy with how the animations for the new mechanics turned out, especially the gateās animations shown in the video.
For the last few hours of work, Iāve been working on level design! Iām very close now to finishing the level design of the first area of the game. I added some generic transversal rooms, a lever puzzle room, and a platforming room with spikes. Next, Iām going to add a room where the player can find the shield, which will grant the parry/block ability.
Worked a bit on the art for the new rooms. I also added some new gameplay mechanics, like platforms that fall to a new location after the player hits them. I also fixed another instance where the combat animations desynced from the code logic.
Continued working on level design. Iāve finished the level design for the entire first area of the game now! I added a room with another lever puzzle that introduces the shortcut mechanics to the player. I also added an area where the player will obtain the shield ability. Now I need to start filling in the art for the new rooms, and create the gameās first boss fight.
I continued working on the art for the 9th and 10th rooms of the game. I also fixed some issues in my custom render feature that I use to render special effects, including a few potential memory leaks. I also reworked my āsafe zoneā mechanic that detects where the player should respawn if they fall onto spikes. Now it tracks specific safe respawn locations instead of the old logic, which was to track any zone where the player shouldnāt respawn.
I took a long break from Stardance to work on other projects, but Iām finally back with another devlog for my metroidvania. I mostly finished the art pass for the latest room of the game. I also fixed a bunch of unity inspector warnings that Iāve had for a looong time now and just never got around to fixing. The main warning I fixed were that some of the render textures I used for water reflections and fullscreen shockwaves didnāt have a depth buffer attached. While they did technically work, it wasnāt the ideal way to have the render textures set up. This was a relatively easy fix thankfully.
For the time tracked in this devlog, I mostly worked on environment decoration in the newest room of the game. I added a really nice looking torch sprite with a fire shader. I also added various details to the game world, like floating platforms in the background, torches, and ancient ruins. I also updated some of the level design. I added platforms to make certain areas possible to reach.
I finally fixed some problems I was having with the playerās collider catching on seams. This bug was pretty rare and not too much of an issue. However in certain parts of the map, mainly near any slopes, the slopeās collider has a tiny seam where it joins the rectangular tilemap collider. The old player collider would get stuck on this seam occasionally. After a lot of messing around with colliders and 2d physics materials, I fixed this issue by changing the playerās collider to a composite collider. The composite collider contains a capsule collider and a box collider. The rounded edges of the capsule allows the player to walk over top of seams easily, and the box collider makes it so the player doesnt slip off the edges of platforms.
I started working on character customization mechanics! Many metroidvanias just use a static character with little to no customization options so I thought this would be a nice way to differentiate my game from other similar games. Basically for now the player can recolor the knightās cape, helmet plume, and sword hilt. The knight sprites were originally colored blue, making it tricky to use simple color adjustment shaders to recolor it. Rather than going back and redrawing tons of sprites, I wrote a shader that detects saturated areas on the original sprites and overlays a new color on top. Overall it works pretty well now, and now I just need to add a menu to select a color scheme. I also spent like 30 mins working on enemy pathfinding mechanics for a new enemy type!
I added the UI interface for player customization. Currently this screen is only accessible from the pause screen, but in the future I will incorporate it into the gameplay so the player customize the character at specific locations throughout the world. I also fixed some issues with how the UI menus were structured. I made every screen into a unity Canvas Group. I also fixed some bugs where the player could get stuck in certain menu screens. Last but not least I added a new upward attack animation for the player, though I still need to implement the functionality.
Iāve havenāt made too much progress on my project over the last little while because of classes starting :( But Iām finally devlogging some of the changes Iāve made over the last week or so. First, I refactored the combat system for the possibly the 4rd or 5th time since first starting the project (almost a year ago now!) This time around, I implemented an upwards and downwards attack, as well as better implementing the lunge attack. I also switched the attack logic to be partly animation-driven rather than coroutine-driven like it was before. Attack damage is now properly synced to the attack animation, and the weird state bugs I was having before are basically gone. Some parts of the new system still feel a little buggy, but overall I think the attack system is much better now. The second major thing I did was finishing implementing the pathfinding of one of the first ārealā enemies (the crawler guys I already have donāt really count). The new enemy now tracks the player correctly. If no player is in range, it will pace back and forth and pause occasionally. It has ledge and wall detection. If the player is in attack range, it will attempt to attack the player. Currently the enemy code architecture isnāt structured very well, but Iām kinda rushing to quickly wrap up this stage of the project so I can ship soon! Now I just gotta polish the game a bit over the next couple days/weeks and then it should be ready to ship!
I finally finished the 10th room of the game! This room introduces a ton of new mechanics in its level design. Iāve been working on the mechanics for this room for the last several devlogs, so itās nice to finally have finished it! In this room, the player must navigate to 2 different levers that, when triggered, open a gate in the floor. Players can then fall down a chasm into an ancient battlefield room. Then they obtain the shield ability from a fallen soldier. Then some of the newest enemy types spawn in and the player must sucessfully defeat them. To survive the battle, the player needs to utilize the new shield ability which allows them to block attacks. I also added a beta features toggle to the pause menu. The toggle allows the player to use certain in-game abilities that are still in development, like sprinting, dashing, wall jumping, double jumping, lunge attacking, shield bouncing, and more.
I implemented a data-driven tutorial system to my game! Whenever the player gains a new skill or ability, a short tutorial will now pop up explaining how to use the ability. I intentionally made this system super flexible so I can easily add more abilities in the future. Each tutorial is defined by a scriptable object with information including: Tutorial text contents and location on the screen Focused object (A vignette will appear on the screen centered around the object. Usually this is just set to the player but there are some special cases where it should be focused on something else.) Input the player needs to press to use their new ability and clear the tutorial. Overall, the game should be a lot more intuitive to play now. Players will no longer have to read through all the controls, instead the controls get gradually explained to them as they unlock more abilities. This is unrelated to the tutorial system, but I also updated my old dialogue system. I added a function to display fullscreen dialogue. This will be used in key points of the game, where it will fade to white and display some important lines of dialogue. So far, I used this for the gameās āprologueā, a short text-based intro that appears when you first create a new save file.
I did a ton of stuff over the last 5 hours of work! Hereās some of the main things I added: Added a jump animation to the player! This is a feature that many people have requested, but I kept procrastinating adding it. I had briefly tried to draw an animation for this in the past and I just couldnāt get the animation to look right. This time I spent more time and effort on it and I think it turned out pretty good now. Restructured the interaction system. I wanted parry and interact (the input used to talk to NPCs, pick up items, etc) to both use the right mouse button. For most of development I had temporarily set the interact button to a random key on the keyboard to prevent conflict. However, I now implemented a context-based system that detects whether or not the player is nearby an interactable object. If they are, then it executes an interaction, if not, it will parry. This required significant rewriting for the scripts attached to most interactable objects. However the system is now much cleaner and will be easier to maintain in the future. Interaction is now handled from a centralized singleton class, rather from each interactable item script independently. Added a dust trail effect to the player. When the player walks, dust particles will play behind them, making a nice visual effect. There are a couple of weird places the player can reach when using movement abilities accessed from the Beta Features mode. I added a couple little easter eggs to these places for the players who explore everything. Fixed a lot of bugs, including: Breakable objects having iframes that last for too long, effectively making them seem to have much more health than they should. Input not being disabled when the player first loads in, causing potential problems with the intro movement tutorial. Fixed issues with the new jump animations interrupting combat animations, which can cause combat animations to not play when they should. Renamed a couple files to make script names more cohesive. Fixed some collider bugs, including a particular spot where the player kept catching on a seam. Fixed an issue where the player sometimes didnāt count as being grounded when on the very edge of a platform.
In the last several hours, I made a whole bunch of progress. First I fixed a whole bunch of relatively minor bugs. Things like getting stuck on ability obtained screens, minor potential scene loading issues, and scenes unloading when the player revives after falling on spikes. I added a screen with an autosave notice. It wasnt really nessecary but makes the game look professional. Updated some small things like the gameās splash screen, internal name, and game icon. Added a custom cursor when in the game window. I added a knockback system! Enemies now actually get knocked back when hit. I used an interface that I attached to the enemy health manager script to create this system. I added a new music track for the village area that the player can find after finishing the first gameplay area. Then I actually started working on the village area. I used existing sprites to make a castle-like structure for the player to pass through. I also made a really nice animated flag sprite for the village. I worked on level design for the 2nd major area of the game. Iām about halfway done the level design for this area at the moment! And since stardance is going for an extra month, Iāll probably have time to ship the 2nd area now!
Wow, its been a while since I devlogged on here! Iām back with some more progress on my metroidvania. In the last few hours I started refining the art and level design for the gameās 2nd area. I added a bunch of sprites like tilesets, rock formations, animated dead bushes, and spikes. Then I started assembling the area in the editor. It took me a while to get the areaās art to match what I had imagined without creating visual clutter on the screen. I think it looks pretty good now and Im proud of how it turned out! I also learned a lot from building the previous area and so this time I made a ton of art/environment prefabs right away. This is going to save me a loooot of time when filling in the art for the rest of the area. I also greyboxed a bunch of the level design. I have the level design built for about 1/2 of the area now. This area is where the player unlocks wall jump, and itās also going to have some fun wind mechanics that can boost the playerās jump distance (I still need to code this). Iām trying to build the level design to complement these features so that the area has a unique play style compared to the first area.
I added this cool wind gust shader to my game! Eventually Iām going to have gameplay mechanics where wind pushes the player, which can boost (or limit) the playerās jump distance. For now I just focused on the visuals for this mechanic and I still need to implement the physics. To make the visual effect, I intially tried a unity particle system based approach. This looked really bad however so I made a shader for the wind instead. Basically the shader scrolls the X UV offset on a gradient noise node. The tiling of the gradient noise is super stretched out so it looks like streaks of wind instead of dots. It was simple to make and turned out pretty good! Now time to implement the physicsā¦...
|
1792778012.0932453
|
1793382812.0932453
|