Unnamed Rhythm Game: Devlog

I have come to fulfill a promise…

Currently the test song is “Grave” Mistake by @InvalidProject from his Free Music! topic. (Thanks Invalid!)
Feel free to make suggestions and ask questions below. This is currently just a tech demo and proof of concept, and I’ll be adding all the bits and bobs like a menu, multiple buttons, and longer “hold button” dots later on. I made this demo in only about 4 hours total, so it’s very bare bones. 99% of the code is just a copy/paste of the built in makecode music player. I’ll keep y’all updated here!

If you would like to add music to the game, this is the topic to share it! Depending on how much has been developed, you may have to wait quite a while before you music is added. You will have to wait even longer if you want an explanation on how to design your own dot patterns. Please specify whether you want to create the pattern or you want me to do it for you. You may also want to specify a vague difficulty level.

12 Likes

I need to dig my copies of Rock Band out of storage. I really miss playing…

Very nice demo, WoofWoof!

3 Likes

@WoofWoof it must be done

7 Likes

i love this sm!!!

4 Likes

I… uhh….
@richard is there a way to make custom instruments that appear in the music editor? I… I need an electric guitar…

6 Likes

Dyers Eve By Metallica! I love that song and i think it would be a pretty good hard level song. I could try and make it but i suck at music so idk.

3 Likes

I feel I should clarify that by “add music to the game” I mean music you have created in the Makecode song editor, not just any song. I have no clue how to take a song and recreate it in the music editor, and I’m not willing to spend any time doing that for you, sorry.

3 Likes

Use The Car, It’s The Most Like It

2 Likes

Pretty cool

6 Likes

Because this is indeed a devlog, I will be making some explanations as to how this is being done.

TLDR: The way it works is that I copied and pasted basically all the music code from base arcade and changed the namespace names to avoid conflicts between my version and the normal version. Then I changed some stuff so that it calls my own dot creation function when a note is played, and then I delay the actual sound from happening till 1 second later, when the note has dropped.

How the first demo worked

When makecode plays a song, it is first broken up into “tracks” that each play a specific instrument. The reason you can’t have a long and short note of the same instrument at the same time is because these tracks can only have one “note” starting/playing at a time, but each “note” can be multiple tones at the same time, so you can have multiple tones play at the same time, they just have to be the same length and start at the same time, which is an unfortunate limitation of the song editor that I’ve never understood until now.
Anyways, what I did was create a function to create those dots falling from the top of the screen, and used the built in control.millis() function - which outputs the number of milliseconds since the console was turned on - to make sure these notes cross that block line after exactly 1000 milliseconds, or 1 second. Then I put that function into this bit of code that “renders” an instrument, because everytime a note is played it calls this function to play the note, and made that bit of code play the note 1000ms after it’s supposed to play it:


Where that code “delay - audioDelay” bit of code is, there used to be a “0” which would just play the note instantly. “Delay” is 1000ms, and that “audioDelay” variable was added because I was playing with bluetooth headphones and bluetooth has a slight delay to it, so I added that to correct the delay. I’ll probably make a small mini-game like bit later on for people to click and hear their audio delay so they can correct it… maybe, idk. I never could get the delay to feel correct, so I just stopped playing with bluetooth and set that back to 0.

Oh and I also added an end screen that counts how many dots you missed, hit perfectly, hit imperfectly, ect.

If you look at the code right now, you may notice this isn’t how it works anymore, that’s because this is just how I got that first demo to work. I’ve now fully changed everything so that I can make dot patterns separate from the actual audio. They are super annoying to make though, so for now I’m not making an explanation for how to make your own or anything. Right now the song has changed to some random tune I made, and I’ll be adding actual music only when I’ve got multiple streams of dots + multiple button you have to press to hit them.

5 Likes

not today!

4 Likes

Should have seen it when it was Invalid’s song lol

Screenshot hidden so it isn’t an annoyingly tall post just for a single image


This was my best. Every time a note played, a dot fell, unless the previous dot was less than 50ms apart ofc, cause that’s how I filtered the ones that were way too close.

1 Like

hmmm… I might have a solution… I’m using the drum tracks 11 - 8 (the ones at the top of the music editor) for defining 4 rows of falling notes, and I have plans to use a normal instrument for defining long dots, but the rest of the drums ( 7 - 0 and 23 - 12 in the bass clef ) could call… well… whatever I want them to call…
If anyone wants extra visual effects or maybe physical (changing how notes work somehow) please respond with ideas! I have an idea where, mid song, all the note rows could collapse into one in the center, and all the notes can be hit using any key. Also color changing effects too! I could literally make a custom function that you can “call” mid song that can do whatever you want, even stuff like fade in and out volume, color palette, etc!

This game (and that effect idea) is heavily inspired by the game Milthm, a rhythm game that’s free on Steam! It’s really cool looking, and it’s more for people playing on an iPad than for keyboard players (me), but I still really enjoy the lower difficulty levels! Anyways, that was a bit of a side tangent. In other news, how about I make this even longer by adding a devlog! Whoo!

Devlog! Whoo!

Ok, I found something very cool that makes my job super easy, at least when it comes to the drum tracks. I have no idea if this is the case for the normal notes… idk it probably is the case now that I think about it.

I have been coding in a way to play both a “music” track and a “dots” track at the exact same time, using the timekeeping system of the music track to also call the code that “plays” the dots track system, so no matter the lag they can’t possibly get too far apart! There is still that 1000 ms delay between the song track “playing” the sound and the sound actually happening, so if somehow that ended up taking longer or shorter, or the dots (which aren’t sprites because sprites suck) did something weird (even though they move each frame based on the milliseconds passed since they spawned, so them taking longer or shorter to fall shouldn’t be possible) it could end up with a tiny bit of desync, which I think is alright because idk how I would fix that. Playing on hardware might be interesting… I have hardware… hmm…

The way I’m “playing” two tracks is by editing everything so I can pass in two song buffers to be played instead of just one in the fmusic.createSong function. The “f” stands for “fake” because it’s my fake music system, and because using a single letter made renaming the conflicting bits faster. Basically, at every place where a function is used to handle something for the normal track, I copy the code and make it handle the dots track too. This worked well and by the time I was making the previous devlog, I already had synced song and dots tracks working well. At the time, the second track was simply creating dots everytime a note was scheduled to play from the dots track and then just… not playing the note. Melodic notes and drums are two sorta separate things in the music system, so only playing when notes play and not when drums play, or vice versa, is a single property check (a single “if”).

The thing that made the drum tracks easy was that they call a “renderDrumInstrument” that takes in a single number representing which drum it is. Yep. Just a number. A single number that essentially tells the function which line the drum instrument is on. So yeah, I just copied the code that enters that number into the function, and now I can easily know which line a drum is playing on. (See the first paragraph of this post for the slightest idea of the possibilities I just unlocked!). If I haven’t got multiple falling note lines at the same time working before this gets approved… idk, maybe something happened to me in the next maybe hour at most it will take to code this now that I have it working… or maybe I just got distracted and forgot to update the link, who knows.

Side note, I got kinda confused at the start of this project because none of my functions were being called like they should be, like, the “renderInstrument” function wasn’t being called, but the music was still playing. That’s when I realized that there are two music players. One is the normal one that runs when hardware is playing the music, and the other one only runs when the music is played in the simulator, which is calling a bunch of C++ functions instead of the javaScript ones! (C++ is just a guess, idk)

@richard, does this second music player just for the simulator exist so that songs can play using a C++ version instead of using the javaScript? When I deleted it, the music sounds the same playing from the hardware version as it does using the sim version. Is it just more laggy in JavaScript or is there another reason for this separate version? Also, last time I had a music related idea on stream, I got you all sidetracked for the rest of stream. It was very funny, but would you prefer I ask code questions on stream or on the forum?

3 Likes

@WoofWoof you can ask questions on stream or forum! i like talking about music stuff so it’s really my fault…

and the reason for the separate sequencer in the simulator is that it keeps much better time than the one implemented in our typescript due to how our simulator codegen is implemented (it’s not great for timing sensitive tasks). so yeah, lag is the only reason.

for the next arcade release i actually plan to move the browser sound generation over to an implementation much closer to what runs on the hardware so there will be fewer glitches overall; no plans to change the sequencer though.

5 Likes

Yeah, I can tell sometimes that the timing of a song… suffers occasionally. I’m guessing this is an issue with the pause() function being… finicky somehow, and susceptible to lag, especially when combined with control.runInParallel(). Is this an issue with it handing off control of the thread and then not getting control back in time?

3 Likes

Short dev note: Fixed end screen to correctly display statistics and I added a "Hit time deviation (ms)” stat that averages the number of ms you are away from “perfectly on time” for every note. This is useful for certain things, namely finding how delayed your audio is when using bluetooth, which is what I needed it for. In my experience, if your deviance is greater than 15 you should probably pay attention to that number, especially if you are consistently getting imperfect (orange) note hits below the line, which may be a result of audio lag. You can try to correct this lag by changing the “audioDelay” variable (line 59 right now, but that might change, idk. I’ll probably make it a thing so you can change in the settings of the game later, so people don’t have to edit the code). To give you a starting place, my own bluetooth (Raycons) “feel right” when I set that number to 300, and my deviation is around 5 with that setting. I’m also adding a “up scroll” setting to the system menu, for people who prefer the notes going up from the bottom.

3 Likes

excited for more songs! Will you take requests? I would also like to see different combinations, like double clicking or holding on some of the dots.

1 Like

I just love this game! As a piano player, dfjk really confused me. I need the keys not separated, so the spacing in-between doesn’t feel. Difficulty wise, great! I love a challenge. After a few tries I was able to get up to 58%.

1 Like

I’ll make them re-mappable later! Someone I know irl has already complained about that, so I’ve been thinking about it and I think it should be fairly simple.

2 Likes

Keys have been changed to be FGHJ while I figure out key remapping.
@Richard is there any way to have a control.onEvent() function that only looks for the “src” and then reports the “value” when it occurs? This would be really useful for remapping keys, instead of having to create listening events for every possible key press.

2 Likes