stardance has been extended another month! the new deadline is october 31 :)

You are browsing as a guest. Sign up (or log in) to start making projects!

gabriel_ferreira

@gabriel_ferreira

Joined June 16th, 2026

  • 46Devlogs
  • 2Projects
  • 1Ships
  • 18Votes
Just a guy addicted to programming.
(Im from Brasil btw, 16y)
Ship

What did i made

I made an complete music play system that will help users to learn while listening to musics! I used youtube, flask, python, mysql, js and hope to make this!

What else

  • Solved a lot of painful bugs that were stopping the project from working
  • Finished and made the music queue work
  • Added music description labels
  • Improved a lot the performance
  • Made the website responsive
  • Added a keyboard based navigation
  • Fixed so much errors at the cover-flow that now i forgot how many
  • Added bug checks before the play of each video on the player
  • Created an toast component to show errors or infos
  • Added 54 musics to choose and listen

Challenges

The most painful code was the player and the cover-flow, they were with a lot of hidden bugs that i had to figure out, feats that i had to make and pain to suffer! Now i figured out that i love and HATE making a website responsive!

What im proud of

  • MutationObserver: An observer that loads / hides an image based on its position at the cover-flow, this system took a while and worked very well.
  • Error checks at player: The system can handle the error that happen and dont crash!
  • Keyboard navigation: Everyone can use the keyboard to navigate now!
  • Oracle VM: For the first time i used an ssh and hosted an website in my own machine (oracle, not mine)!

How to test

Access http://ritualia.duckdns.org/, when you join and the page loads you will find a screen to choose an genre, select which one you want, after you will see an emotion selector, select the emotion that you wanna feel! You will see the player screen and an audio explaining the music (The audio is in portuguese), after the audio the music will play.

Notice: The github and the website are in portuguese, please use your browser built-in translator or any that you want to use the software properly!

Follow the installation guides at github if you want to install

  • 41 devlogs
  • 148h
  • 18.45x multiplier
  • 2310 Stardust
Try project → See source code →
Open comments for this post

23m 26s logged

It is time to ship!

Now the system is working perfectly fine running at a vm in oracle cloud with a public domain, and a dns with duckdns at http://ritualia.duckdns.org/
Warning: It is just HTTP!

0
0
17
Open comments for this post

1h 20m 46s logged

Configuring an ssh server!

I configured an oracle cloud vm with ubuntu to host my website 24/7, that was because nest wasnt working in a while. Im running it at a local IP with http only, i will configure https today and maybe an domain, the IP is http://164.152.55.252, notice that some browsers may block you from accessing and http website.

UPDATE AFTER THE DEVLOG: I put an domain using duck dns: http://ritualia.duckdns.org

Hardwork

I had absolutely not a single knowledge about oracle cloud vm, so configuring it was an hell. Sometime my internet stopped working so i had to use my smartphone, this lead me to configuring an invalid ssh key and i had do configure everything from scratch, i spent 5 hours configuring everything, but that was ssh and wasnt tracked. But now everything is working fine.

Thx oracle

This vm is a 24/7 entire OS (Virtual Machine) that has some good free plans, without any cold start.

Thx stardance

Stardance now will have one more mount!!!!!! I still has roughly 40 hours of deep development to do after this ship, i will love to finish that in stardance!

0
0
17
Open comments for this post

1h 56m 12s logged

Fixing a runtime error

The ESP32 memory is limited and is reaching an end, the system is rebooting because it is running out of memory. Im trying to fix this without losing the music quality.
Also i made the 3d models for the project, i just need add it on the github (In the meantime i forgot how to use freecad…).

0
0
5
Open comments for this post

2h 58m 14s logged

Added install guides

Now there is guides to help the user install for ubuntu, arch and windows.
Notice that im a linux user and my pc is weak, so i could not test it on another operational system. Also the guide is in portuguese (all of them), please use your browser built-in translator or any of them to read if u dont understands portuguese
I could test it on another linux distro, but i would have to go through all the install steps. Also i cannot try installing windows because it normally wipe out another OS installed on the same disc (i know that it just replaces the bootloader) and using a VM was not possible due to the amount of RAM and the processor that i have.

0
0
62
Open comments for this post

4h 57m 22s logged

The accessibility workings is done

Features

Now the system has a new navigation system that allow users to navigate with just the keyboard! (The video was with just the keyboard)

Why

Why not? It was meant to improve the accessibility for users without mouse, or any another problem and because i was tired of having to use the mouse to debug something.

How it was made

Again with a lot of pain, the feature itself was easy but i had to fix some errors that went unnoticed, so it took more time. The feature detects when the user press a key and do an action based on wich key was.
The accessibility was easy to get 100, but the metrics at lighthouse dont give all what the users will need, i had to think about the website usage and how would be the easiest way for the user.

Results

The accessibility went from nearly 69 to 100!

What next

Now i will work on the best practices!
Update after the devlog: Nearly every metric is already maxed out lol, i will ship it very soon!

0
0
14
Open comments for this post

1h 41m 26s logged

The performance workings is finished and bug fix

Fixes

Now the logo z-index is lower, that is because the logo was ‘eating’ the click in more important elements.
Also i did a small change at the cover-flow, that change fix the bug of the scroll at the element sudently stoping when at a certain position.
The copa script had some old references to images that were leading to bugs, i changed it.

Performance

I already finished it in the past devlog, i was just checking if there was anything worth improving, but everything is working fine and now is time to improve acessibility.
Most of the logged time was me trying to improve more some metrics at the lighthouse, but the work was too much for anything that is already good, so i decided to stop before i started focusing too much in it.

0
0
67
Open comments for this post

1h 30m 18s logged

Fixing an error at the youtubeHelper

Now the youtubeHelpers checks if the youtube API is ready before sending commands.

Why

Sometimes the API maybe is not finished yet, that was leaving an untreated error that was braking the entire website.

How was made

With a lot of pain and suffer. I thought “Oh hey, that will be a 15 minutes fix” - i spent 1 HOUR FIGHTING with the iframe itself, nothing was working and at some point i started thinking that even the API of YOUTUBE wasnt working, even the most basic function that should be triggered when the youtube finished the loading wasnt beeing activated, even the console.log(“Api READY!”) wasnt working, even when it worked it wasnt working well, the variable of the player was a promise and not the result. At the end i shut down my PC, defeated, without any energy left, with just hope that in the next day (this) that would be fixed (if not i was planning to ignore and make it a feature “Easter egg, if u dont join the website for a while it will not load!”.
The problem here was just the position were the iframe api was in the HTML, it was being loaded before the helper script, so the helper was not there to check if it the iframe was ready or not, the fix was just move it a little down.

Architecture

It was just an promise, if the function checks that the iframe isnt available it await for it to be available. The check if it was available use the onYoutubeIframeAPIReady, easy easy (except for all the suffer that i went into).

0
0
23
Open comments for this post

1h 8m 20s logged

The loading is done and working!

Fix

I fixed the error that were happening when the cover had a certain amount of elements.

Problems

The fix itself was very easy to do, but doing it in a readable or without using 10 lines of code (i want things concise) was way harder than i expected. So i spent this entire time trying different ways to do it, each of them making everything worse.

Reasoning

The bug were with less than 14 elements, the script were calculating the first and last element index, it happened that these elements were behind the screen focus. Why? Because the values that the system was using were leaving these values, so i had to fix the way it was calculating things.

0
0
17
Open comments for this post

1h 19m 49s logged

The loading is done

Features

Now the loading at the mutationObserver is finished, it finally loads or unloads the images that should be (or not) loaded!
The new observer is way faster, because it can detect the image way before it enters the screen, loading it before and having more time to do it. Also the system loads just a maximum of images (with the configs that i put it is 13), so it will not fry an cellphone.

Problems

The loading part was easy to do, i already done it before in the past observer (intersectionObserver), so i just had to pass the old code to the new part. But when the cover-flow element dont got atleast 13 elements the mutationObserver code breaks completely! Im still pondering how to solve it, when i do i will post about!

Results

  • The performance went from 78 to 100!
  • The system is way faster!
  • The user does not see a blank image anymore!

Why

The old method was slow even with a good internet connection, because it was loading the images just when the element was already in the screen, leaving to a perceptive delay for the user and a blank image to the user. Also i thought about creating an observer from scratch (maybe i was a little off my ideas, because that was insane), but the browser already had exactly what i wanted (the mutationObserver)

Videos

  1. The new features
  2. The performance of the new feats
  3. The old features

Reasoning

While i was trying to sleep i thought about a system that fill the cover-flow with a maximum of images (like 10, or 13, or the code decides) at the DOM, using less memory to run. That system will free a lot of memory based on how many cards the cover-flow have. But that will have noticeable effects just with a lot of elements and probably would be hard to develop, maybe i will do in next updates.

What next

Im leading to the shipping, so i will improve metrics about the lighthouse, improve the readme and post it.

0
0
10
Open comments for this post

7h 13m 40s logged

Adding a mutationObserver

Now, instead of an intersectionObserver, the system use a mutationObserver that monitors the angle of the cylinder itself. With that the loading of the images will be insanely better, faster and user-friendly. Now the changes in the cover-flow is observed at the cylinder angle, not at each card. There was some problems in the journey like, for some reason, unexpected cards being loaded or not, the loading script at the observer dont triggering at all (that was caused by the speed of the observer) and an insane amount of cards being triggered at the same time (i still did not figured out why, but that isnt ‘harmful’). But man, i had to be creative here and remember about some concepts like concurrent programming, buffer / queue and apply some delays (because the mutationObserver is insanely fast and can trigger every millisecond). That all was meant to decrease the speed of the mutationObserver, because it was triggering with the most small change in the cylinder, so i made it trigger just when an expected amount of movement was made.
The red/yellow collor is for me to visualize the loading state, it is just for debug
The code isnt finished, i still need to implement the loading part, for now i just implemented the observer and basics of the loading part

0
0
15
Open comments for this post

4h 16m 57s logged

The observer is finished (nearly)

Now the cover-flow has an observer that checks the position of the images and changes it styles based on that, so the images that the user is seeing is loaded while the others is hide.
It still has some bugs and space for improvements that im still figuring out how to solve, like the image loading too late on the screen or, in slow internet connections, the image takes too long to load.
Most of these bugs are because the observer (an intersectionObserver) was designed for 2d contexts, not 3d (that were and still is an giant problem to solve). For this reason i was thinking about creating an observer from scratch in C++ that can work better in my 3d element, but the overhead would be high so im trying to solve in other ways before that.
The feature was made using fetchPriority, contentVisibility and src (the system add the source just when the image is near the screen).

OBS: I found about MutationObserver after this post, maybe i will use that instead of insersectionObserver. Oh man, at least if had found about this before… Aaaaaahhhhh i spent 9 hours in that, but at least a Lot of the new logic will be used. Anyway, lets cook

0
0
8
Open comments for this post

5h 25m 19s logged

Adding an observer

Now the script observe the card elements at the cover-flow component, classify their position and changes it visibility based on that.
Im using an IntersectionObserver to observe every card, but it was designed to observe the position of 2d elements, so i had to figure out how to make it work well in an 3d element. The way it works is when the observe activates (it basically means that some card is in the range to load) it get the card info (like position and angle) and changes it visibility state based on that. Simple, right? No, it was a headache for the start to the top, nearly 4 hours of what i did was to fix the fact that it was meant for 2d. The observer were activating for cards that were in the back of the element, so i had to classify the card position into back or front by using its angle.
But if i tried to use the card angle without anything else the script would broke (and did for 3 hours until i realized how to fix), so i had to use an second angle which is 360 - cardAngle (the 360 is the angle of an circle), so this new angle is based on the circle end while the other is based on the circle start.
But the system still broke, because at some point one of these values would become negative and makes the if that classify the elements fail. The fix was using the absolute value in the if (it took 1 hour until i figured that; oh i were so happy when it worked).

Why

To improve the performance, so the browser will just load what is really important and not 50 images that the user cant even see.

What else

All that work definitely improved a lot my logic thinking and for the first time i used the truth table well.
Now i just need to use the new code to change more the style of the images that are not in the screen.
I did not deleted the code that i wrote in the past devlog, it was used in the new code to select how many images should be loaded in the same time.

** The first video is the result, the others is some problems that i had **

0
0
12
Open comments for this post

4h 32m 53s logged

Improving the loading performance

Now the system selects some images that needs to be shown faster than the others and making them load with priority. It was made by selecting the images that the user is seeing and defining some params like fetchPriority = "high" and decoding="sync", the other images have the params: decoding="async"; loading="lazy"; contentVisibility="auto";. With that config the LCP went from 2.4s to 0.5s. Also it loads the image in the start and dont change that config again, so the browser will be lazy while downloading these images. The problem is: only the first images are chosen as high priority, but their positions will be changed while the configs stays the same, that makes the browser lazy while loading them and makes the runtime performance became worse.
To fix that i found about IntersectionObserver, that are meant to solve the problem of updating the images position fast. It was not applied yet, i found about it like 1 hour ago.

What else

  • Now the perspective of the emotionDrum is based on the elements that it have, before it was based just in the screen and would broke if something changes.
  • I did a little change in the way that the script checks for clicks in the screen, now it has more accuracy (I changed the round system).
0
0
18
Open comments for this post

7h 41m 13s logged

Improving the LCP (Largest content paint) performance

I am improving the way that the website create and downloads the images, the main reason is to make the user see something faster. Before the system were doing 2 main things:

  • Go trough the entire list of images, creating the elements and placing them into the page.
  • Position them.
    But the position of the items were being done after the creation of the images, in another function. Now they are in the same function: it create the element, position it and add it to the page.
    That does not seem like much, but the code got way faster with that, probably because it dont need to go item by item in an list twice just to create an element. I tested the time to load the first element and it went from 8.63s to 6.43s, the test was made with 2200 elements (Yeah ik, it is a lot and normally it isnt that much, but i had to see how they were holding with more than 22 items).

Also i fixed a bug that passed unnoticed while improving the responsiveness: At some point of images the visibility of the elements broke, that was because the perspective (what makes the 3D perspective of the component, and makes it visible with 3D effects) was based on the screen size, not the elements itself. What was the problem in that: Each element takes a size in the screen ‘makes the circle that shows the element be more and more near of our point of view’ (i cant explain it any better, search what is ‘perspective in an 3d element at HTML’ ). While it was approaching our point of view (POV), our POV were exactly at the same position (based on the screen size), so at some point the circle perspective would pass the POV and we would be unable of seeing it well. Now it is based on the elements: The 3d elements were basically a circle, i just used the diameter to change the perspective based on it.
TODO: Maybe i lowered the image quality too much… I will fix it in the next updates.
Also i were trying to improve the font settings to improve the performance, but that wast working so i decided to move on to this because it was more critical (took a while for me to jump to this, maybe like 2 hours trying and trying values in the font settings).
i am also working in a way to load the images in parallel, with that it will take way less time
(I didnt known about LCP before so i spent a while figuring out the way it works).

0
0
4
Open comments for this post

2h 39m 48s logged

Improving the performance

After finishing the improvements in the responsiveness, now i decided to improve the performance. I used lighthouse to get insights (i learned about it in an tiktok video) and figured out that the images size were too high (were an png of 1280x1280px), so i saw more about that in the page: https://developer.chrome.com/docs/performance/insights/image-delivery (an link that google lighthouse gave).
With that i saw how to decrease the size while staying with quality, i reached up to the sharp-cli tool, that makes the work of resize, convert and compress the image for me. The command used was that:

npx sharp-cli -i *.png -o ./output resize 320 -f avif -q 50 --effort 6 --smartDeblock --preset photo

The 320 is the size that i want it to be at the end, i got that value by seeing what was the computed value (the value that is being used in the website) in an high resolution pc (not the most higher one, the high but normal pc) with the resolution of 2500x1714px.
With this simple changing the image went from 2mb to 40Kb! Nearly 100% decrease, and take in mind that there is more than one img, so the change were even higher.
Also i created 5 different images: 320px, 480px, 640px, 960px e 1280px. With them the browser can choose which one is better for each device. With these changes i went from 35 points of performance to 59.

0
0
5
Open comments for this post

52m 18s logged

The home is now fully responsive

Ah that took a while, but finally it is fully responsive. Now the description at the player UI resizes based on the screen size and active a scroll behaviour when need, also i did some minor change at the emotionDrum perspective to make it show more emotions at the same time, removed the padding in the arrows at the emotionDrum so they will have more space and fixed an error in the genre drum that was making it perspective broke.
After all these devlogs i improved how i make a code responsive.

0
0
8
Open comments for this post

2h 32m 16s logged

The emotionDrum is now responsive!

Now the buttons that you use to select the emotion are in the same side as the div that displays the emotion, so they dont fight for space anymore. This change is meant to fix the low size of the items in screens that are too small, in the new way we have more free space to display the emotions, there is not much to say.

What else

I did some minor changes in the size of some items at the player area, now they are easier to read! (I increased the size of some items)

0
0
21
Loading more…

Followers

Loading…