|
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
|
|
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....
|
1793213617.4422674
|
1793300017.4422674
|
|
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
|
|
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...
|
1793199173.874629
|
1793285573.874629
|
|
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
|
|
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...
|
1793163170.7194276
|
1793767970.7194276
|
|
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
|
|
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
|
|
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
|
|
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....
|
1793177235.0736358
|
1793782035.0736358
|
|
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
|
|
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...
|
1793213605.5796056
|
1793300005.5796056
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 👋...
|
1793202938.5319667
|
1793807738.5319667
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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😄...
|
1793195675.58084
|
1793282075.58084
|
|
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
|
|
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
|
|
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....
|
1793199006.50502
|
1793285406.50502
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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....
|
1793217140.7169464
|
1793303540.7169464
|
|
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
|
|
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
|
|
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
|
|
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
|
|
69622
|
Starbie by @Brokie | Stardance
|
Brokie
|
0
|
4.5
|
0
|
[]
|
[{"post_id": 79488, "ts": "202 [{"post_id": 79488, "ts": "2026-10-14T08:33:59Z", "hours": 4.495, "text": "Made this digital pet console something like Tamagotchi where u play and feed with the pet to keep it alive"}]...
|
Title: Starbie by @Brokie | Stardance
Devlogs:
Ma Title: Starbie by @Brokie | Stardance
Devlogs:
Made this digital pet console something like Tamagotchi where u play and feed with the pet to keep it alive...
|
1792857253.9842932
|
1793721253.9842932
|
|
40871
|
FPS OS by @cooki | Stardance
|
cooki
|
0
|
113.91
|
0
|
[]
|
[{"post_id": 79484, "ts": "202 [{"post_id": 79484, "ts": "2026-10-14T08:01:07Z", "hours": 14.1244, "text": "Devlog 11: Notepad After my holiday break, I am back working on the project. The main feature added for this devlog is the Notepad app . Grab a note from the tray, click on it, then type. The notes convert Markdown into HTML. The HTML is sanitised so it can’t be used to run malicious scripts. Top Tip Try adding the FPS OS logo as a sticker by typing:  into any Notepad window. Bonus feature: More Physics It is now possible to add physics to the 3DUI windows (PC screen/notepad notes). Along with this change, it is much more fun to throw objects around. Objects now keep momentum when let go. Top Tip The 3DUI system used for the windows is kinda buggy. For best results face yourself towards the wall with the door on it and place the window in front of you. Bonus feature: More grabbing More objects are able to be picked up including the clock, shelf and rug. Some objects are still work in progress. Bug fixes Objects can now be thrown out the windows You can walk through the doorway after you delete the door Current bugs Right click doesn’t work on MacBooks (fixed!) The velocity from the player is being subtracted instead of added to dropped objects (fixed!) Moved PC windows can not be interacted with (fixed!) Coming soon… My current checklist is: [x] Computer [Window] [x] Notepad [Window] [ ] Clipboard [ ] Gun? (it is an FPS after all…) [ ] Settings [Window] [ ] Ship to WebOS 1"}, {"post_id": 73856, "ts": "2026-09-26T06:05:54Z", "hours": 11.7192, "text": "Devlog 10: Picking things up I have added the ability to pick up objects. This currently includes the pillow on the armchair (throwing coming soon) and the the PC screen. How it works Interactable objects show a circle around the crosshair when hovered and grabbable objects with have a progress bar fill up as you hold click. After the bar fills up you can drag and let go to drop. The rest of the sounds All of the sound effects have now been implemented. This includes walking, jumping, getting the passcode right/wrong, pulling the blinds, and more! Shaders I added some simple shaders with the postprocessing library. There is bloom, vignette and chromatic aberration. They aren’t overboard and don’t hurt the performance. Unfortunately, my laptop sometimes goes into throttled mode when I unplug it and makes it hard to measure the performance. Mobile fix You can now interact with objects on mobile. It’s tricky at the moment because of the UI layout which I will be fixing later. Today is (not) the day :( I am hoping to ship the project today. I had to pack for a trip so I couldn’t work on the project. Progress will be slower while on my trip but luckily the Stardance deadline has been extended. My current checklist is: Notepad Clipboard Settings"}, {"post_id": 73021, "ts": "2026-09-24T07:16:47Z", "hours": 11.5483, "text": "Devlog 9: User experience In this update, I wanted to improve the usability and feel of the OS. I did this by adding more signals, adding functionality to the virtual machine and including sound effects. The Virtual Machine (PC) Situated on the desk, the PC lets you access the web browser to boot a Web OS or (almost) any other website. Soon, you’ll be able to pick up the screen instance and hang (or throw) it wherever you want. The Bed You can put the OS to sleep by clicking on the bed. Clicking again wakes it up. The Clock There is an now an analog clock on the wall. It shows the real-life time, if you can read it. Sound I added some sound effects. By default, the OS is muted. The sound effects still need to be tweaked. The sound is supposed to be ambient and give more life to the otherwise static objects in the environment. The Hand Next time, I am adding adding the ability to pick up certain objects as well as the next app, Notepad. I will also be adding a settings panel. Then, I can finally ship this version to Web OS 1."}, {"post_id": 71643, "ts": "2026-09-21T06:42:33Z", "hours": 10.5822, "text": "Devlog 8: Objects and furnishings As promised last devlog, I have added a few objects from my checklist. Some are for OS functionality and some are just to fill in the space. The light Based off the light design from the hit YouTube ARG “Summon House”, I turned the plain square on the ceiling into a lamp that reacts to the switch by the door. For the best effect, try enabling dark mode. Dark mode? In the lighting department, I also added blinds to each of the windows. Clicking them pulls them up and down. Each one down subtracts from the global light level. A little context You can now interact with objects through the context menu (right click). For now there is only one option: Delete. If you delete something, you can’t get it back. This includes the floor. Things for later The recycling bin, blue paper tray, PC and wallpaper are currently being developed. For now, they aren’t fully functional Furniture For now, there is a rug, an armchair, a desk, a shelf and a poster. I will be adding more later. I will add the ability to sit in the chair and use the shelf. The deadline approaches I am hoping to ship this week after I add in notepad as my first app. For now, you can check out this update at cookistudios.com/fps-os ."}, {"post_id": 69430, "ts": "2026-09-17T01:17:20Z", "hours": 9.81, "text": "Devlog 7: Building the environment In this update, I added the room and skybox. I added windows by using a boolean modifier on the walls. I made the directional light from the sun lines up with the skybox. Wallpaper I made a 16:9 tiling wallpaper with the letters of FPS OS on it. Right now, it can be toggled on and off but later will be able to be set any imported image. Door optimisation I don’t know if it’s because of how websites work or something with my GPU driver but the FPS would drop to 60 when looking at the door/keypad. Just in case I removed the 3D depth with the symbols and replaced them with a texture. The door was also a physics object and I spent quite a bit of time getting it to work but never ended up fixing it. Instead, I kept the door as regular meshes. This allowed me to animate it from inside Blender. After seeing an Andymation video on YouTube, I got reminded of the animation principle of anticipation which I added to the door. Mobile buttons I also added the jump and crouch button for mobile. The crouch button is toggled while the jump button needs to be held. I need to change the CSS to make the jump button show the pressed state when using multiple fingers across the screen. I will come back to mobile support later as there are many issues, especially related to zooming. Next time on FPS OS: I have constructed a plan of where each object will be in the room. You’ll have to wait and see in the next devlog."}, {"post_id": 66234, "ts": "2026-09-11T22:51:43Z", "hours": 10.0431, "text": "Devlog 6: Life is an open door (!Video has sound!) The latest improvement to FPS OS is that you can now unlock the OS! This is accomplished by entering your passcode into the door (by default 0000). What took so long? In order to get the door to open (and close), I had a lot of trial and error. The way the USDC scene file is imported means that it has offsets of the meshes that require a specific tree of groups. In order to have physics objects in Jolt, the meshes need to be in world space. However, if the meshes are in world space they don’t have the offsets they need to move as a group around the origin points. I tried putting a reverse offset and putting physics objects in local space but nothing worked. Eventually, I decided to just have the base of the door in physics world space and then have the rest of the meshes in one local group that copies its rotation from the door. Changes Fixed the player rotation being confined to physics Changed note to say “c0000” and not “0000” in case it wasn’t clear you have to reset after a mistake Added noclip Allowed the game to move the player for cutscenes Added a function to rotate physics objects around a pivot point Added a function to add debug points to visualise why the pivot points are wrong Better mobile support coming soon Try it out at cookistudios.com/fps-os ."}, {"post_id": 62732, "ts": "2026-09-06T07:15:02Z", "hours": 11.52, "text": "Devlog 5: The intro cutscene After getting the player movement done, I decided it would be cool to add a Linux-style boot console as the content loads in the background. I also added in a title screen with some smooth animation. The main scene now places the player in front of the passcode input screen (I might decide to remove it until the user makes a password). Patched some bugs I finally fixed the shadow system. The player was clipping a tiny bit into the ground which left a circle of no shadow. I tried combating this by changing the shadow normalBias . This caused the shadows on detailed objects like the keypad to be broken. I tried fixing it again by moving the player mesh up. Then I found it still had the same issue on the door handle. I fixed it by setting the player mesh’s shadowSide to double sided. I also made the player slower when crouching. What’s next? I need to add functionality to the keypad and create the base room. For my first app, I will make a notepad that you can type into. I will also try adding a “virtual machine” that can run my friend @pinetree182 ’s Web OS tundra. Luckily, I found an official three.js example that can render iframes in a scene: link to example . I also need to add more buttons to mobile so the player can jump and crouch. As always, FPS OS is hosted at cookistudios.com/fps-os . Every time I make a commit, it updates. This means you can access content before I’ve made a devlog about it."}, {"post_id": 60706, "ts": "2026-09-03T08:15:20Z", "hours": 11.3656, "text": "Devlog 4: Movement complete I wanted to add in bhopping/air stafing movement to the project as I find it more fun to control than the generic character controller. I found this script which seemed good and I wanted to try and translate it to my Three.js setup. I tried multiple times to put in the code then rename parts and scrap it. Eventually I decided to just take the most bare bones parts I needed and make a better system. After a few tweaks, the movement, physics, and lighting systems are finally done. Next, I am adding a cool loading screen to the OS and then I’ll start modelling the new environment and objects. The latest version is available at cookistudios.com/fps-os . Here are the current keybinds: WASD/Touch Joystick - Move Mouse move/On-screen Swipe - Look around Space - Jump (hold to keep jumping) C - Crouch R - Toggle speedometer ` - Show colliders ~ - Show player collider (You can only move and look on mobile at the moment)"}, {"post_id": 46805, "ts": "2026-08-14T09:56:04Z", "hours": 11.8444, "text": "Devlog 3: Getting the ball rolling So, it’s been a couple of weeks since my last devlog. Last week, I spent time having a break from the project. However, that doesn’t mean there hasn’t been any updates this week! Player in motion As seen in the video above, you may have noticed that you can actually run around and do parkour now! The player physics uses a VirtualCharacter , equivalent to a CharacterBody3D in Godot. I had to set up gravity which was difficult as the built-in gravity from Jolt doesn’t work very well on non-simulated objects like the VirtualCharacter . Lighting improvements I removed baked lighting as it was increasing load time and didn’t look good combined with real-time. So I have switched to full real-time lighting. I added in cascading shadow maps (CSM) that is like LODs. This means that further away shadows have lower quality textures. (I tried to make it not noticeable though.) Bug catching Using Jolt in JavaScript means uses WebAssembly (WASM). WASM needs manual garbage collection for most objects you instantiate. I have patched all the possible memory leaks I could find in my physics code. Mobile support I have implemented the ability to actually control yourself and not run at 5 FPS on mobile. You can try it out, right now, at cookistudios.com/fps-os/ . P.S. I will be trying to write devlogs more often as development will be speeding up over time."}, {"post_id": 37495, "ts": "2026-07-30T09:00:32Z", "hours": 8.1308, "text": "Devlog 2: It’s all a simulation That’s right, I got physics working! Using the link I saved in the last devlog, I worked out how to use Jolt properly with Three.js. I also built a scene in Blender and set up lighting. Baking with Blender To create this simple test scene, I hopped into Blender and spawned in a few different objects. I didn’t want to make anything too fancy as I just wanted to test physics collisions. As I worked on it, I would export to a USD scene and import that into Three. I thought about how game engines normally do lighting and I remembered about baked lighting. It took a while but I made it so dynamic objects with mesh names starting with “D_” will have real-time shadows but static objects (like the floor and floating boxes) will have baked shadows. This means that shadows are much less expensive to render. Decentralisation A problem I had with my original code is that it was all in one spaghetti file. I split up the code into different files like input, lighting and physics. These are then called from the main file. This creates more organisation so when I add more features later it doesn’t become impossible to read. Taking action I set up input actions to be much easier to work with. A list of actions is set up as a key value pair. I save the keys that are pressed and remove them when released from a separate key value list. I then set it up to create CustomEvent s for each keybind. These are then used with EventListener s to send signals to the other parts of code to run. Deployment issues I also had a couple issues with my code that caused problems with the deployed site. The first was setting the base in the Vite config to “/FPS-OS/” and not “/fps-os/”. It meant you had to use capital letters in the URL to load the site. The other issue was that the objects were trying to get physics before Jolt had been initialised. It seemed to be a race condition that happened sometimes. Luckily it is fixed now. What’s next? Next, of course I need to get player movement working so you can actually walk and jump around. Then I need to follow the requirements of the WebOS 1 mission. It looks like all I need to do is add draggable windows. This OS isn’t exactly going to have windows though. At least not as they are normally. Also I need to add a welcome screen, “desktop” environment, app shop and toolbelt. And all of those require the main room components to be modelled and textured. New update released Go to cookistudios.com/fps-os/ to try out the latest features before I’ve even written devlogs on them. See you later!"}, {"post_id": 36303, "ts": "2026-07-28T09:57:37Z", "hours": 3.2203, "text": "Devlog 1: Setting the scene I started the project by initialising it from Vite using Bun (I would use Deno but Bun is just so fast). I imported Three.js to use for everything 3D and used the default cube scene from the documentation. I also added in the PointerLockControls to let you look around as the camera. Issues arised You can’t move yet because I tried adding different kinds of movement with all the different physics libraries but it kept causing the player to fall over or not move and then suddenly zip around. I think I’ve decided to use Jolt Physics (but not the built-in Three.js one!) as this site showcases some simple code to get physics working. Next steps I have come up with plans for the OS like how the text editor will be an actual notepad you have to pick up and how you’ll be able to build out the space with different floor tiles and furniture. I also want to add CS:GO/Momentum Mod style movement as an option just because I find it fun to bhop around everywhere. It also looks like Jolt has a built in class called CharacterVirtual that I hope is similar to CharacterBody3Ds in Godot. Once I have the movement set up I will start modelling some assets to add. I would also like to try using the new HTML-to-Canvas API but it is experimental so it’s not best to use it in a production build that anyone could be running on any device. See you soon! This project might take a while to start looking user-friendly but if you want to test it out any time, head on over to: cookistudios.com/FPS-OS"}]...
|
Title: FPS OS by @cooki | Stardance
Devlogs:
Devl Title: FPS OS by @cooki | Stardance
Devlogs:
Devlog 1: Setting the scene I started the project by initialising it from Vite using Bun (I would use Deno but Bun is just so fast). I imported Three.js to use for everything 3D and used the default cube scene from the documentation. I also added in the PointerLockControls to let you look around as the camera. Issues arised You can’t move yet because I tried adding different kinds of movement with all the different physics libraries but it kept causing the player to fall over or not move and then suddenly zip around. I think I’ve decided to use Jolt Physics (but not the built-in Three.js one!) as this site showcases some simple code to get physics working. Next steps I have come up with plans for the OS like how the text editor will be an actual notepad you have to pick up and how you’ll be able to build out the space with different floor tiles and furniture. I also want to add CS:GO/Momentum Mod style movement as an option just because I find it fun to bhop around everywhere. It also looks like Jolt has a built in class called CharacterVirtual that I hope is similar to CharacterBody3Ds in Godot. Once I have the movement set up I will start modelling some assets to add. I would also like to try using the new HTML-to-Canvas API but it is experimental so it’s not best to use it in a production build that anyone could be running on any device. See you soon! This project might take a while to start looking user-friendly but if you want to test it out any time, head on over to: cookistudios.com/FPS-OS
Devlog 2: It’s all a simulation That’s right, I got physics working! Using the link I saved in the last devlog, I worked out how to use Jolt properly with Three.js. I also built a scene in Blender and set up lighting. Baking with Blender To create this simple test scene, I hopped into Blender and spawned in a few different objects. I didn’t want to make anything too fancy as I just wanted to test physics collisions. As I worked on it, I would export to a USD scene and import that into Three. I thought about how game engines normally do lighting and I remembered about baked lighting. It took a while but I made it so dynamic objects with mesh names starting with “D_” will have real-time shadows but static objects (like the floor and floating boxes) will have baked shadows. This means that shadows are much less expensive to render. Decentralisation A problem I had with my original code is that it was all in one spaghetti file. I split up the code into different files like input, lighting and physics. These are then called from the main file. This creates more organisation so when I add more features later it doesn’t become impossible to read. Taking action I set up input actions to be much easier to work with. A list of actions is set up as a key value pair. I save the keys that are pressed and remove them when released from a separate key value list. I then set it up to create CustomEvent s for each keybind. These are then used with EventListener s to send signals to the other parts of code to run. Deployment issues I also had a couple issues with my code that caused problems with the deployed site. The first was setting the base in the Vite config to “/FPS-OS/” and not “/fps-os/”. It meant you had to use capital letters in the URL to load the site. The other issue was that the objects were trying to get physics before Jolt had been initialised. It seemed to be a race condition that happened sometimes. Luckily it is fixed now. What’s next? Next, of course I need to get player movement working so you can actually walk and jump around. Then I need to follow the requirements of the WebOS 1 mission. It looks like all I need to do is add draggable windows. This OS isn’t exactly going to have windows though. At least not as they are normally. Also I need to add a welcome screen, “desktop” environment, app shop and toolbelt. And all of those require the main room components to be modelled and textured. New update released Go to cookistudios.com/fps-os/ to try out the latest features before I’ve even written devlogs on them. See you later!
Devlog 3: Getting the ball rolling So, it’s been a couple of weeks since my last devlog. Last week, I spent time having a break from the project. However, that doesn’t mean there hasn’t been any updates this week! Player in motion As seen in the video above, you may have noticed that you can actually run around and do parkour now! The player physics uses a VirtualCharacter , equivalent to a CharacterBody3D in Godot. I had to set up gravity which was difficult as the built-in gravity from Jolt doesn’t work very well on non-simulated objects like the VirtualCharacter . Lighting improvements I removed baked lighting as it was increasing load time and didn’t look good combined with real-time. So I have switched to full real-time lighting. I added in cascading shadow maps (CSM) that is like LODs. This means that further away shadows have lower quality textures. (I tried to make it not noticeable though.) Bug catching Using Jolt in JavaScript means uses WebAssembly (WASM). WASM needs manual garbage collection for most objects you instantiate. I have patched all the possible memory leaks I could find in my physics code. Mobile support I have implemented the ability to actually control yourself and not run at 5 FPS on mobile. You can try it out, right now, at cookistudios.com/fps-os/ . P.S. I will be trying to write devlogs more often as development will be speeding up over time.
Devlog 4: Movement complete I wanted to add in bhopping/air stafing movement to the project as I find it more fun to control than the generic character controller. I found this script which seemed good and I wanted to try and translate it to my Three.js setup. I tried multiple times to put in the code then rename parts and scrap it. Eventually I decided to just take the most bare bones parts I needed and make a better system. After a few tweaks, the movement, physics, and lighting systems are finally done. Next, I am adding a cool loading screen to the OS and then I’ll start modelling the new environment and objects. The latest version is available at cookistudios.com/fps-os . Here are the current keybinds: WASD/Touch Joystick - Move Mouse move/On-screen Swipe - Look around Space - Jump (hold to keep jumping) C - Crouch R - Toggle speedometer ` - Show colliders ~ - Show player collider (You can only move and look on mobile at the moment)
Devlog 5: The intro cutscene After getting the player movement done, I decided it would be cool to add a Linux-style boot console as the content loads in the background. I also added in a title screen with some smooth animation. The main scene now places the player in front of the passcode input screen (I might decide to remove it until the user makes a password). Patched some bugs I finally fixed the shadow system. The player was clipping a tiny bit into the ground which left a circle of no shadow. I tried combating this by changing the shadow normalBias . This caused the shadows on detailed objects like the keypad to be broken. I tried fixing it again by moving the player mesh up. Then I found it still had the same issue on the door handle. I fixed it by setting the player mesh’s shadowSide to double sided. I also made the player slower when crouching. What’s next? I need to add functionality to the keypad and create the base room. For my first app, I will make a notepad that you can type into. I will also try adding a “virtual machine” that can run my friend @pinetree182 ’s Web OS tundra. Luckily, I found an official three.js example that can render iframes in a scene: link to example . I also need to add more buttons to mobile so the player can jump and crouch. As always, FPS OS is hosted at cookistudios.com/fps-os . Every time I make a commit, it updates. This means you can access content before I’ve made a devlog about it.
Devlog 6: Life is an open door (!Video has sound!) The latest improvement to FPS OS is that you can now unlock the OS! This is accomplished by entering your passcode into the door (by default 0000). What took so long? In order to get the door to open (and close), I had a lot of trial and error. The way the USDC scene file is imported means that it has offsets of the meshes that require a specific tree of groups. In order to have physics objects in Jolt, the meshes need to be in world space. However, if the meshes are in world space they don’t have the offsets they need to move as a group around the origin points. I tried putting a reverse offset and putting physics objects in local space but nothing worked. Eventually, I decided to just have the base of the door in physics world space and then have the rest of the meshes in one local group that copies its rotation from the door. Changes Fixed the player rotation being confined to physics Changed note to say “c0000” and not “0000” in case it wasn’t clear you have to reset after a mistake Added noclip Allowed the game to move the player for cutscenes Added a function to rotate physics objects around a pivot point Added a function to add debug points to visualise why the pivot points are wrong Better mobile support coming soon Try it out at cookistudios.com/fps-os .
Devlog 7: Building the environment In this update, I added the room and skybox. I added windows by using a boolean modifier on the walls. I made the directional light from the sun lines up with the skybox. Wallpaper I made a 16:9 tiling wallpaper with the letters of FPS OS on it. Right now, it can be toggled on and off but later will be able to be set any imported image. Door optimisation I don’t know if it’s because of how websites work or something with my GPU driver but the FPS would drop to 60 when looking at the door/keypad. Just in case I removed the 3D depth with the symbols and replaced them with a texture. The door was also a physics object and I spent quite a bit of time getting it to work but never ended up fixing it. Instead, I kept the door as regular meshes. This allowed me to animate it from inside Blender. After seeing an Andymation video on YouTube, I got reminded of the animation principle of anticipation which I added to the door. Mobile buttons I also added the jump and crouch button for mobile. The crouch button is toggled while the jump button needs to be held. I need to change the CSS to make the jump button show the pressed state when using multiple fingers across the screen. I will come back to mobile support later as there are many issues, especially related to zooming. Next time on FPS OS: I have constructed a plan of where each object will be in the room. You’ll have to wait and see in the next devlog.
Devlog 8: Objects and furnishings As promised last devlog, I have added a few objects from my checklist. Some are for OS functionality and some are just to fill in the space. The light Based off the light design from the hit YouTube ARG “Summon House”, I turned the plain square on the ceiling into a lamp that reacts to the switch by the door. For the best effect, try enabling dark mode. Dark mode? In the lighting department, I also added blinds to each of the windows. Clicking them pulls them up and down. Each one down subtracts from the global light level. A little context You can now interact with objects through the context menu (right click). For now there is only one option: Delete. If you delete something, you can’t get it back. This includes the floor. Things for later The recycling bin, blue paper tray, PC and wallpaper are currently being developed. For now, they aren’t fully functional Furniture For now, there is a rug, an armchair, a desk, a shelf and a poster. I will be adding more later. I will add the ability to sit in the chair and use the shelf. The deadline approaches I am hoping to ship this week after I add in notepad as my first app. For now, you can check out this update at cookistudios.com/fps-os .
Devlog 9: User experience In this update, I wanted to improve the usability and feel of the OS. I did this by adding more signals, adding functionality to the virtual machine and including sound effects. The Virtual Machine (PC) Situated on the desk, the PC lets you access the web browser to boot a Web OS or (almost) any other website. Soon, you’ll be able to pick up the screen instance and hang (or throw) it wherever you want. The Bed You can put the OS to sleep by clicking on the bed. Clicking again wakes it up. The Clock There is an now an analog clock on the wall. It shows the real-life time, if you can read it. Sound I added some sound effects. By default, the OS is muted. The sound effects still need to be tweaked. The sound is supposed to be ambient and give more life to the otherwise static objects in the environment. The Hand Next time, I am adding adding the ability to pick up certain objects as well as the next app, Notepad. I will also be adding a settings panel. Then, I can finally ship this version to Web OS 1.
Devlog 10: Picking things up I have added the ability to pick up objects. This currently includes the pillow on the armchair (throwing coming soon) and the the PC screen. How it works Interactable objects show a circle around the crosshair when hovered and grabbable objects with have a progress bar fill up as you hold click. After the bar fills up you can drag and let go to drop. The rest of the sounds All of the sound effects have now been implemented. This includes walking, jumping, getting the passcode right/wrong, pulling the blinds, and more! Shaders I added some simple shaders with the postprocessing library. There is bloom, vignette and chromatic aberration. They aren’t overboard and don’t hurt the performance. Unfortunately, my laptop sometimes goes into throttled mode when I unplug it and makes it hard to measure the performance. Mobile fix You can now interact with objects on mobile. It’s tricky at the moment because of the UI layout which I will be fixing later. Today is (not) the day :( I am hoping to ship the project today. I had to pack for a trip so I couldn’t work on the project. Progress will be slower while on my trip but luckily the Stardance deadline has been extended. My current checklist is: Notepad Clipboard Settings
Devlog 11: Notepad After my holiday break, I am back working on the project. The main feature added for this devlog is the Notepad app . Grab a note from the tray, click on it, then type. The notes convert Markdown into HTML. The HTML is sanitised so it can’t be used to run malicious scripts. Top Tip Try adding the FPS OS logo as a sticker by typing:  into any Notepad window. Bonus feature: More Physics It is now possible to add physics to the 3DUI windows (PC screen/notepad notes). Along with this change, it is much more fun to throw objects around. Objects now keep momentum when let go. Top Tip The 3DUI system used for the windows is kinda buggy. For best results face yourself towards the wall with the door on it and place the window in front of you. Bonus feature: More grabbing More objects are able to be picked up including the clock, shelf and rug. Some objects are still work in progress. Bug fixes Objects can now be thrown out the windows You can walk through the doorway after you delete the door Current bugs Right click doesn’t work on MacBooks (fixed!) The velocity from the player is being subtracted instead of added to dropped objects (fixed!) Moved PC windows can not be interacted with (fixed!) Coming soon… My current checklist is: [x] Computer [Window] [x] Notepad [Window] [ ] Clipboard [ ] Gun? (it is an FPS after all…) [ ] Settings [Window] [ ] Ship to WebOS 1...
|
1792781359.0674555
|
1793386159.0674555
|
|
69461
|
CHECKY by @bihanghimire | Stardance
|
bihanghimire
|
0
|
18.03
|
0
|
[]
|
[{"post_id": 79476, "ts": "202 [{"post_id": 79476, "ts": "2026-10-14T06:07:41Z", "hours": 1.3994, "text": "added 2 new openings , kings gambit and london . finished kings gambit working on london . the structure of my previous pages broke a bit so fixed that too . learned kings gambit a bit myself while adding it . ( a pretty fun opening but not my type tbh ) really excited to finish london and start adding my fav opening that is catalan minimized the site so it may look weird in ss"}, {"post_id": 79254, "ts": "2026-10-13T06:36:03Z", "hours": 16.6275, "text": "iam currently working on expanding the openings and finishing it as fast as i can . will post more dev logs"}]...
|
Title: CHECKY by @bihanghimire | Stardance
Devlog Title: CHECKY by @bihanghimire | Stardance
Devlogs:
iam currently working on expanding the openings and finishing it as fast as i can . will post more dev logs
added 2 new openings , kings gambit and london . finished kings gambit working on london . the structure of my previous pages broke a bit so fixed that too . learned kings gambit a bit myself while adding it . ( a pretty fun opening but not my type tbh ) really excited to finish london and start adding my fav opening that is catalan minimized the site so it may look weird in ss...
|
1792849850.9097493
|
1793454650.9097493
|
|
69280
|
Morning Message by @raycoding | Stardance
|
raycoding
|
1
|
0.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-19T18:09:55Z", "hours": 0.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "Daybreak is supposed to help someone start their day with a list of things that they can already do and not have to plan as much.", "repo": "https://github.com/rayha-m/daybreak", "demo": "https://daybreak-opal-delta.vercel.app"}]...
|
[{"post_id": 79466, "ts": "202 [{"post_id": 79466, "ts": "2026-10-14T04:55:10Z", "hours": 0.4361, "text": "I have been working on getting the API keys to read my calendar."}]...
|
Title: Morning Message by @raycoding | Stardance
Title: Morning Message by @raycoding | Stardance
Devlogs:
I have been working on getting the API keys to read my calendar.
Ships:
Daybreak is supposed to help someone start their day with a list of things that they can already do and not have to plan as much....
|
1793155913.3329062
|
1793242313.3329062
|
|
33543
|
Car Project by @Sourish-D | Stardance
|
Sourish-D
|
0
|
13.77
|
0
|
[]
|
[{"post_id": 79451, "ts": "202 [{"post_id": 79451, "ts": "2026-10-14T01:54:17Z", "hours": 4.2417, "text": "#Time to fix the low torque issues In this devlog, I attempted MANY fixes for the gearbox, because it turns out there are a LOT of ways to do it wrong. I used plastic straws as bearings instead of cardboard, reducing the friction by a LOT I realigned the frame to ensure the axles would all be aligned I changed from a DC motor to a stepper motor, which I then will step down rather than step up to get a little bit more speed than I had in the first devlog I changed the stepper motor code to be 2 wave so that it’s stronger and has a little bit more power Also got some insights into gear making and designing, when 3D printing clustered gears, always either add a little gap between the small gear and the large gear or make the small gear have a lot more depth than the large gear. This solves two problems, 1. If the large gears are even slightly off and angled they won’t mesh and stop rotation as easily and 2. There will be less friction with the large gears rubbing against each other And now it works! (somewhat) It still feels a little weak, but I pray that it’ll do for now to complete the project. Now I had to reattach it to the frame that I made in the previous devlogs and ensure the code still runs properly. I also want to work on the wheels, they were pretty uneven last time and could easily cause it to end up going wonky rather than straight. Finally, I do have an issue with the power situation. I have a 5v battery attached to a power module to try to power the whole thing, but the stepper motor takes too much power and won’t run if powered ONLY by the 5v battery. To sweep this problem under the carpet for now, I have it powered by my laptop, but it’s a problem I’ll have to deal with sooner rather than later."}, {"post_id": 57780, "ts": "2026-08-30T02:18:49Z", "hours": 1.8453, "text": "I’m dreading the next devlog. So, I made a lot of progress since the last devlog. In the last devlog, I managed to finish the gearbox to convert the dc motor’s high speed into a lot more torque. In this devlog, I managed to add a front and the top of the car, which means all the wiring was done too! The front uses a servo to rotate the front two wheels (with disconnected axles because they turn at different speeds) which is connected to my xbox controller, so I can control it wirelessly. In this video you can see it in action, I use the d-pad because I do have stick drift so it’s just more consistent. Anyways, the x button centers the motor so you can instantly switch back to going forward immediately. Now the bad news, when I tried making the car actually turn forward, the gears don’t turn. I assume this is because there isn’t enough torque being created, which would suggest another gear, but I don’t have the time before my vacation for that. Instead, I’ll focus on optimizing the current design as much as possible. The first of which: re-making the gearbox AGAIN. This time, it’ll be a lot quicker, I already have the ‘template’ of the gearbox ready and I plan on ensuring the gears are aligned properly and adding straws as barriers between the cardboard and the wood axles. This is because the cardboard probably causes lots of friction, losing torque. So yeah, tons of lessons learnt, but still a long road ahead."}, {"post_id": 55280, "ts": "2026-08-27T00:22:34Z", "hours": 4.3256, "text": "Big changes to the car project! The old design began to stop working because the cardboard gears kept wearing down and the stepper motor was a lot slower than I wanted it to be, which is why I decided to switch to 3d printed gears. With this switch, I also decided to change from using the stepper motor primarily to now using a dc motor. The first step to making the dc motor usable, was making a gearbox, and the first iteration didn’t go very well… I made it gears first and motor last, which caused the gears to not have enough play and required too much torque from the dc motor. Which is why I had to rebuild it, with right spacing and now it works! The video should be a short showing of how the gearbox works!"}, {"post_id": 42952, "ts": "2026-08-07T22:47:35Z", "hours": 1.3628, "text": "Today I got a little bit of building done. I managed to add another layer to the car, because the previous layer was too sloped to allow for the breadboard to rest properly. The middle layer is also properly supported now and will not fold in half from the weight. I also wired everything properly and no wire can slip now."}, {"post_id": 41659, "ts": "2026-08-06T00:46:23Z", "hours": 1.9986, "text": "First devlog. I started working on this project weeks ago but the hardware portion of this website was not completely done so this devlog is to log the two hours of timelapse I recorded before I gave up on trying to use this website. This project is to make a car that is remote controlled, at the moment it’s getting close to finishing. I have most of the frame created and managed to get it to move, but a lot of adjustments are needed. For one, the car is moving slowly. It also keeps breaking from the weight of the power bank. And finally, it also needs to be connected to the external controller (at the moment controlled by a button and potentiometer)."}]...
|
Title: Car Project by @Sourish-D | Stardance
Devl Title: Car Project by @Sourish-D | Stardance
Devlogs:
First devlog. I started working on this project weeks ago but the hardware portion of this website was not completely done so this devlog is to log the two hours of timelapse I recorded before I gave up on trying to use this website. This project is to make a car that is remote controlled, at the moment it’s getting close to finishing. I have most of the frame created and managed to get it to move, but a lot of adjustments are needed. For one, the car is moving slowly. It also keeps breaking from the weight of the power bank. And finally, it also needs to be connected to the external controller (at the moment controlled by a button and potentiometer).
Today I got a little bit of building done. I managed to add another layer to the car, because the previous layer was too sloped to allow for the breadboard to rest properly. The middle layer is also properly supported now and will not fold in half from the weight. I also wired everything properly and no wire can slip now.
Big changes to the car project! The old design began to stop working because the cardboard gears kept wearing down and the stepper motor was a lot slower than I wanted it to be, which is why I decided to switch to 3d printed gears. With this switch, I also decided to change from using the stepper motor primarily to now using a dc motor. The first step to making the dc motor usable, was making a gearbox, and the first iteration didn’t go very well… I made it gears first and motor last, which caused the gears to not have enough play and required too much torque from the dc motor. Which is why I had to rebuild it, with right spacing and now it works! The video should be a short showing of how the gearbox works!
I’m dreading the next devlog. So, I made a lot of progress since the last devlog. In the last devlog, I managed to finish the gearbox to convert the dc motor’s high speed into a lot more torque. In this devlog, I managed to add a front and the top of the car, which means all the wiring was done too! The front uses a servo to rotate the front two wheels (with disconnected axles because they turn at different speeds) which is connected to my xbox controller, so I can control it wirelessly. In this video you can see it in action, I use the d-pad because I do have stick drift so it’s just more consistent. Anyways, the x button centers the motor so you can instantly switch back to going forward immediately. Now the bad news, when I tried making the car actually turn forward, the gears don’t turn. I assume this is because there isn’t enough torque being created, which would suggest another gear, but I don’t have the time before my vacation for that. Instead, I’ll focus on optimizing the current design as much as possible. The first of which: re-making the gearbox AGAIN. This time, it’ll be a lot quicker, I already have the ‘template’ of the gearbox ready and I plan on ensuring the gears are aligned properly and adding straws as barriers between the cardboard and the wood axles. This is because the cardboard probably causes lots of friction, losing torque. So yeah, tons of lessons learnt, but still a long road ahead.
#Time to fix the low torque issues In this devlog, I attempted MANY fixes for the gearbox, because it turns out there are a LOT of ways to do it wrong. I used plastic straws as bearings instead of cardboard, reducing the friction by a LOT I realigned the frame to ensure the axles would all be aligned I changed from a DC motor to a stepper motor, which I then will step down rather than step up to get a little bit more speed than I had in the first devlog I changed the stepper motor code to be 2 wave so that it’s stronger and has a little bit more power Also got some insights into gear making and designing, when 3D printing clustered gears, always either add a little gap between the small gear and the large gear or make the small gear have a lot more depth than the large gear. This solves two problems, 1. If the large gears are even slightly off and angled they won’t mesh and stop rotation as easily and 2. There will be less friction with the large gears rubbing against each other And now it works! (somewhat) It still feels a little weak, but I pray that it’ll do for now to complete the project. Now I had to reattach it to the frame that I made in the previous devlogs and ensure the code still runs properly. I also want to work on the wheels, they were pretty uneven last time and could easily cause it to end up going wonky rather than straight. Finally, I do have an issue with the power situation. I have a 5v battery attached to a power module to try to power the whole thing, but the stepper motor takes too much power and won’t run if powered ONLY by the 5v battery. To sweep this problem under the carpet for now, I have it powered by my laptop, but it’s a problem I’ll have to deal with sooner rather than later....
|
1792626678.789972
|
1793231478.789972
|
|
69231
|
My awesome macropad! by @playnmaker123 | Stardance
|
playnmaker123
|
0
|
9.1
|
0
|
[]
|
[{"post_id": 79447, "ts": "202 [{"post_id": 79447, "ts": "2026-10-14T01:01:28Z", "hours": 4.7831, "text": "Finished PCB + CAD"}, {"post_id": 79218, "ts": "2026-10-13T02:10:17Z", "hours": 1.8, "text": "PCB Session 3, Worked on PCB Wiring"}, {"post_id": 79176, "ts": "2026-10-12T22:09:18Z", "hours": 2.5136, "text": "PCB Session 1"}]...
|
Title: My awesome macropad! by @playnmaker123 | St Title: My awesome macropad! by @playnmaker123 | Stardance
Devlogs:
PCB Session 1
PCB Session 3, Worked on PCB Wiring
Finished PCB + CAD...
|
1793130782.3423073
|
1793735582.3423073
|
|
53116
|
Risc-V Compiler by @kphoherz | Stardance
|
kphoherz
|
0
|
43.79
|
0
|
[]
|
[{"post_id": 79445, "ts": "202 [{"post_id": 79445, "ts": "2026-10-14T00:54:26Z", "hours": 8.8428, "text": "I have done a lot of work on functions, variables, and control flow. I have also set up the required functions included automatically in each program. This part of the program manages things such as memory and function calls, which are essential to the execution of user code. This allowed me to generate functions, variables, and if statements now. The compiler outputted a 173 line program, but below shows a small section of the output. As you can see, the compiler is working!"}, {"post_id": 75412, "ts": "2026-09-30T00:52:42Z", "hours": 8.0597, "text": "I made a lot of progress on the special parser. It converts the input into postfix notation, with the operators after the operands. Then, the ASM Generator uses the postfix notation to generate actual assembly! As you can see from the ✨Beautiful✨ picture I drew, this simple equation actually expands into many assembly instructions. Unfortunately, to make the special parser I had to get rid of most of the type checking.😐"}, {"post_id": 71305, "ts": "2026-09-20T16:30:44Z", "hours": 9.7256, "text": "I worked on adding type checking. It is still missing a lot but if I don’t move on I am going to run out of time. I was able to get it to check for type errors within equations and assignments. I also started working on converting the tree into actual assembly, but I realized that it was parsing my addition right to left 🥀🥀. So I started the process of making a dedicated shunting yard parser for the equations"}, {"post_id": 65706, "ts": "2026-09-11T01:15:09Z", "hours": 7.7964, "text": "Big progress!!! The syntax checking is done! I spent quite a long time creating the context-free grammar in an excel sheet. This defines all of the syntax rules allowed, and outlines which result in errors. This means that all of the functions/symbols for the language have been defined. I also added some error messages and started the semantic analyzer, which checks type errors."}, {"post_id": 58597, "ts": "2026-08-31T02:19:35Z", "hours": 3.1114, "text": "I received my two Pico 2s today. I spent some time trying out examples and modifying them, and I managed to get the LED to blink, which was surprisingly difficult to find examples for because I needed it in Risc-V assembly. Then I worked on generating a tree from the parser I made in the last devblog. It seems to work well, but it is kind of hard to tell. Next I think I’ll either do semantic error checking, or skip right to the assembly generation and worry about the semantics later :)"}, {"post_id": 54782, "ts": "2026-08-25T21:56:19Z", "hours": 3.4928, "text": "I worked on creating the Syntax analyzer for my Risc-V compiler. This stage checks the structure of the program and any grammatical errors. I had to do a lot of research on CFGs (Context free grammars). They define the rules for the language. Below is a spreadsheet of the CFG. I will improve it in the future to add more functions. I implemented an LL(1) parser. I was successfully able to check the grammar of a simple program. I still need to make the parser construct an abstract syntax tree. I realized that it is quite difficult to find pictures to post because it mostly happens in the console, but trust me, interesting things are happening!"}, {"post_id": 52787, "ts": "2026-08-23T04:03:52Z", "hours": 2.7661, "text": "I have just started working on my first compiler. I have coded a couple of interpreters before, but this is my first time creating a compiler. I am designing it for the Pico 2 W and will be translating a modified C into Risc-V assembly. So far I have created the lexer which separates the source code into tokens. I have also set up a nice starting infrastructure including some error tracing. Below is the output of a test source code tokenized. Funnily enough, I’m running this compiler on a Pico as well. In the future, I hope to incorporate this compiler into a Pico based OS."}]...
|
Title: Risc-V Compiler by @kphoherz | Stardance
D Title: Risc-V Compiler by @kphoherz | Stardance
Devlogs:
I have just started working on my first compiler. I have coded a couple of interpreters before, but this is my first time creating a compiler. I am designing it for the Pico 2 W and will be translating a modified C into Risc-V assembly. So far I have created the lexer which separates the source code into tokens. I have also set up a nice starting infrastructure including some error tracing. Below is the output of a test source code tokenized. Funnily enough, I’m running this compiler on a Pico as well. In the future, I hope to incorporate this compiler into a Pico based OS.
I worked on creating the Syntax analyzer for my Risc-V compiler. This stage checks the structure of the program and any grammatical errors. I had to do a lot of research on CFGs (Context free grammars). They define the rules for the language. Below is a spreadsheet of the CFG. I will improve it in the future to add more functions. I implemented an LL(1) parser. I was successfully able to check the grammar of a simple program. I still need to make the parser construct an abstract syntax tree. I realized that it is quite difficult to find pictures to post because it mostly happens in the console, but trust me, interesting things are happening!
I received my two Pico 2s today. I spent some time trying out examples and modifying them, and I managed to get the LED to blink, which was surprisingly difficult to find examples for because I needed it in Risc-V assembly. Then I worked on generating a tree from the parser I made in the last devblog. It seems to work well, but it is kind of hard to tell. Next I think I’ll either do semantic error checking, or skip right to the assembly generation and worry about the semantics later :)
Big progress!!! The syntax checking is done! I spent quite a long time creating the context-free grammar in an excel sheet. This defines all of the syntax rules allowed, and outlines which result in errors. This means that all of the functions/symbols for the language have been defined. I also added some error messages and started the semantic analyzer, which checks type errors.
I worked on adding type checking. It is still missing a lot but if I don’t move on I am going to run out of time. I was able to get it to check for type errors within equations and assignments. I also started working on converting the tree into actual assembly, but I realized that it was parsing my addition right to left 🥀🥀. So I started the process of making a dedicated shunting yard parser for the equations
I made a lot of progress on the special parser. It converts the input into postfix notation, with the operators after the operands. Then, the ASM Generator uses the postfix notation to generate actual assembly! As you can see from the ✨Beautiful✨ picture I drew, this simple equation actually expands into many assembly instructions. Unfortunately, to make the special parser I had to get rid of most of the type checking.😐
I have done a lot of work on functions, variables, and control flow. I have also set up the required functions included automatically in each program. This part of the program manages things such as memory and function calls, which are essential to the execution of user code. This allowed me to generate functions, variables, and if statements now. The compiler outputted a 173 line program, but below shows a small section of the output. As you can see, the compiler is working!...
|
1792738116.0978436
|
1793342916.0978436
|
|
69379
|
Student-Exam-Predictor by @Hadi | Stardance
|
Hadi
|
0
|
1.56
|
0
|
[]
|
[{"post_id": 79437, "ts": "202 [{"post_id": 79437, "ts": "2026-10-13T23:57:11Z", "hours": 0.8994, "text": "Today i learned several ML concepts like giving a test grade, calculating how far it is from my real grade, and averaging it out based on all my data. Next steps are learning how to take steps to calculating a lower loss value, and also finishing main.py so i can start linear regression. Thats still a long way though since I am trying to learn everything while doing it so hopefully i will be able to do it but not anytime soon."}, {"post_id": 79101, "ts": "2026-10-12T17:43:37Z", "hours": 0.6583, "text": "Made a model class, added sample data and started to make the graph using matplotlib and pandas. I have never done anything like this before and I’m trying to learn by building so I’m asking a lot of guidance from AI. The end goal is to finish this project and start a new one where I can apply my learning."}]...
|
Title: Student-Exam-Predictor by @Hadi | Stardance Title: Student-Exam-Predictor by @Hadi | Stardance
Devlogs:
Made a model class, added sample data and started to make the graph using matplotlib and pandas. I have never done anything like this before and I’m trying to learn by building so I’m asking a lot of guidance from AI. The end goal is to finish this project and start a new one where I can apply my learning.
Today i learned several ML concepts like giving a test grade, calculating how far it is from my real grade, and averaging it out based on all my data. Next steps are learning how to take steps to calculating a lower loss value, and also finishing main.py so i can start linear regression. Thats still a long way though since I am trying to learn everything while doing it so hopefully i will be able to do it but not anytime soon....
|
1792810311.3613183
|
1793415111.3613183
|
|
69001
|
cool python rock paper scissors game by @swee02856 cool python rock paper scissors game by @swee02856 | Stardance...
|
swee02856
|
1
|
5.0
|
0
|
[{"ship_num": 1, "ts": "2026-1 [{"ship_num": 1, "ts": "2026-10-13T23:51:51Z", "hours": 5.0, "multiplier": null, "payout": 0, "blessing": "neutral", "text": "I created a really simple python game that may look very simple and “not professional” but in my opinion this project helped me learn many stuff about python like fixing code, finding out about functions and modules, and so much more!", "repo": "https://github.com/swee02856-prog/Python-Rock-Paper-Scissors", "demo": "https://github.com/swee02856-prog/Python-Rock-Paper-Scissors/releases/tag/v1"}]...
|
[{"post_id": 79435, "ts": "202 [{"post_id": 79435, "ts": "2026-10-13T23:49:06Z", "hours": 4.8722, "text": "Made it so that the characters do a greeting right after you pick who your opponent will be, some stay to the plot and act tough, others will ruin the plot and completely say random stuff."}]...
|
Title: cool python rock paper scissors game by @sw Title: cool python rock paper scissors game by @swee02856 | Stardance
Devlogs:
Made it so that the characters do a greeting right after you pick who your opponent will be, some stay to the plot and act tough, others will ruin the plot and completely say random stuff.
Ships:
I created a really simple python game that may look very simple and “not professional” but in my opinion this project helped me learn many stuff about python like fixing code, finding out about functions and modules, and so much more!...
|
1793155888.3007843
|
1793242288.3007843
|
|
69439
|
MacPPCEmulator by @ianl | Stardance
|
ianl
|
0
|
7.4
|
0
|
[]
|
[{"post_id": 79432, "ts": "202 [{"post_id": 79432, "ts": "2026-10-13T23:12:58Z", "hours": 2.1286, "text": "The PowerPC Vintage OS Emulator Distro is complete! When users build from the HDD, they are met with this simple install window to aid them in their installation! Now, working on emulation via QEMU!"}, {"post_id": 79251, "ts": "2026-10-13T06:29:01Z", "hours": 2.1803, "text": "Lots and lots of debugging! I am trying to get Debian to run smoothly on actual Intel Mac hardware. It’s been a challenge for sure, lots and lots of debugging! (9 disk image revisions so far 😔). Also, i’ve learned that it may be able to run on Apple Silicon, which I think would be pretty cool, but I don’t have an Apple silicon computer unfortunately :/"}, {"post_id": 79226, "ts": "2026-10-13T03:06:23Z", "hours": 3.0922, "text": "I just started my vintage PowerPC Emulator project! it is based off of Debian 12. I used github’s copilot in order to layout the basic debian distro and nececarry dependencies. There are many errors/mistakes that I am slowly but surely working out!"}]...
|
Title: MacPPCEmulator by @ianl | Stardance
Devlog Title: MacPPCEmulator by @ianl | Stardance
Devlogs:
I just started my vintage PowerPC Emulator project! it is based off of Debian 12. I used github’s copilot in order to layout the basic debian distro and nececarry dependencies. There are many errors/mistakes that I am slowly but surely working out!
Lots and lots of debugging! I am trying to get Debian to run smoothly on actual Intel Mac hardware. It’s been a challenge for sure, lots and lots of debugging! (9 disk image revisions so far 😔). Also, i’ve learned that it may be able to run on Apple Silicon, which I think would be pretty cool, but I don’t have an Apple silicon computer unfortunately :/
The PowerPC Vintage OS Emulator Distro is complete! When users build from the HDD, they are met with this simple install window to aid them in their installation! Now, working on emulation via QEMU!...
|
1792835414.6038945
|
1793440214.6038945
|