How to make Friday Night Funkin' in Roblox PART 2

Wow! Glad to see someone fixed my mistakes LOL. Good thing you caught that memory leak, I actually never noticed it was there.

Also, nice FNF game!

3 Likes

lol you are crazy I thought it was impossible

I’ve been messing with it for a while, and now I realized theres one last thing missing
Which I couldn’t figure out as I can’t understand how that insane Loadstring script works

How do we get custom notes to work?

  • Its fairly easy to set up in Note moudle, but there is no way to detect which notes are custom notes and which are not

  • In the Main moudle we only have NoteTypes which are names in the strumline, left to right

I’ve read a source code from Kade Engine but It doesnt help either
they just set up a new public var NoteType:Int = 0;

then add
if (FlxG.keys.pressed.ONE) noteType = 1;
if (FlxG.keys.pressed.ALT) noteType = 2;
to the function which spawns in notes, and it somehow works. The rest was just setting up the notes behaviour and appearance which is already done by the code above

You don’t need to work on this but I’d appreciate a reply to this one. I also played your game, nice work!

2 Likes

You should be able to check what the NoteType of the note is in the functions.
In my Unbuildable song, I used Psych Engine’s hurt notes as a way to allow the 2nd and 3rd characters to sing (this is why there is some leftover code to make hurt notes invisible)

In Psych Engine, note types are usually the 4th entry. So try changing that to 4 and you should be good.
image

1 Like

Thank you!
One of the most jarring things is the fact that you decided to preload every note at the start. While this may not cause issues for songs with a lower note count, my song had over 3,000 notes. As a result, it took over 7 seconds to load and the FPS was not good. (my xbox took over a minute and it was like 5 fps) So yeah, the onSectionHit function was a must as it preloads the next sections over time, and now it loads within less than a tenth of a second.

1 Like

okay i think i got it working
another problem though, custom notes appear invisible?

  • At first I tried with another image with different aspect ratio, I thought the image size was the problem so I increased it to 2048 x 1024 keeping the notes original size, It didnt work

  • Another attempt was not changing the note skin at all. since my goal is to use 1 specific animation for the custom note, I printed out the names and colors used for each arrow the moudle is spawning, which gave this result
    image

For now, I want it to show up as a normal up note, so I simply changed this line
image
to this:

but it’s still appearing invisible

Edit: my bad, I forgot to update the note after it spawns
image

1 Like

You solved the issue?
I think you did because of the edit but I just want to make sure.

1 Like

Yeah, I do admit that wasn’t very good on my part, now that I’ve realized how many holes this thing has.

I sort of wish I could update this tutorial, but it won’t be very useful as the whole genre of this game is pretty dead, and a newer tutorial would probably be insanely hard to write without even more flaws.

yes i did, thank you
I’ll ask one last question about this event detection

I put this line in Stage moudle ( Marked with green )
image
as I read from your scripts, this is supposed to fire whenever the main moudle detects the event,
but it actually never does along with every other event until I add this in Main moudle
image

not only does this make that single event fire, it also makes SOME of the rest fire as well:

As your scripts were erroring, i mixed up both files. I have all the functions inserted and everything seems to be working fine but I dont really understand how that small change affects the script so much

Has this happened to you or is there something I could be missing? Or could this be on Roblox’s end?
I can give you an rbxm file if you want to look deeper into it, Because I literally copy + pasted each one of your functions in each moudle without changing them

1 Like

You need to remove to put eventName == "Add Camera Zoom" or eventName == "Camera Zoom Bump"

1 Like

There are probably a few things that are giving errors that I forgot to remove :sweat_smile:

Some things like SoundService for a miss sound effect. Should have probably removed them before giving a copy of it.

1 Like

I was aware of that, yet that wouldn’t fix the issue here

I took a long break and just saw the obvious reason for all this


in Main, the script was cancelling every event that it was unfamiliar with, how blind I am.

1 Like

Well, There weren’t much critical errors actually

My problem was that my charts weren’t loading properly, I could’ve messed something up while removing some unwanted stuff. I also already had some of the features you’ve listed above so I messed with it a bit as I thought my stuff worked much simpler. It’s probably my fault :face_with_diagonal_mouth:

2 Likes

The problem with spawning notes as the song progresses may create lag spikes and ruin the Gameplay.

results will vary obviously but i have an 11th gen cpu with integrated graphics (and eight gigs of ram)

and this is what i got when i tested both versions

really just pick your poison here as both end up being extremely laggy, and you just die instantly for some reason at the end with all the notes on my version (haven’t tested original)

How do insert other strums? When I try to change notes, they just looks like this

I believe this issue you are encountering might be due to XMLs not corresponding with the texture. Are you using the right XML data?

Yes i think so. Maybe it’s because there are less frames for the strum animations?


custom.xml (3.3 KB)

Ok, so it turns out it was two different things causing this.

  1. The texture is sized 2611x153 pixels, making it larger than roblox’s maximum 1024x1024.
    Roblox resolves this by scaling the offending dimension down to 1024 and doing the same to the other dimension.
    We can figure out the scale factor of this by doing (1024 / 2611), which outputs 0.3921869, which is our scale for the sprites. This is implemented like so:
    Main (line 161)
--\\ Only load what we need
local scale = 0.3921
		
NewStrum:AddByPrefix(NoteXML, NoteImageID, scale, 24, "static", "arrow"..string.upper(Directions[i]))
NewStrum:AddByPrefix(NoteXML, NoteImageID, scale, 24, "press", Directions[i].." press")
NewStrum:AddByPrefix(NoteXML, NoteImageID, scale, 24, "confirm", Directions[i].." confirm")

Note (line 85)

--\\ Only load what we need!
local Name = Directions[((NoteData % 4) + 1)]
local Color = ColorDirections[(NoteData % 4) + 1]
	
local scale = 0.3921
	
if Name == "left" then --\\ We have to do these shenanigans because of a typo the FNF developers made :|
	if IsHoldNote then
		if IsHoldEnd then
			NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name.." end", "pruple end hold")
		else
			NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name.." hold", Color.." hold piece")
		end
	else
		NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name, Color)
	end
else
	if IsHoldNote then
		if IsHoldEnd then
			NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name.." end", Color.." hold end")
		else
			NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name.." hold", Color.." hold piece")
		end
	else
		NewSprite:AddByPrefix(XML, ImageID, scale, 24, Name, Color)
	end
end
  1. The XML data doesn’t have the frame numbers in it, which normally wouldn’t be a problem in HaxeFlixel, but the roblox parser freaks out when this happens, so an easy fix is to just append ‘0000’ to every frame like so:
return [[
<?xml version="1.0" encoding="UTF-8"?>
<!--
Created with Funkin Packer v0.1.3 https://neeeoo.github.io/funkin-packer/
-->
<TextureAtlas imagePath="senpai.png" width="2611" height="153">
	<SubTexture name="arrowDOWN0000" x="732" y="0" width="153" height="152" frameX="-2" frameY="-1" frameWidth="158" frameHeight="153"/>
	<SubTexture name="arrowLEFT0000" x="100" y="0" width="152" height="151" frameX="-5" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="arrowRIGHT0000" x="255" y="0" width="152" height="151" frameX="-1" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="arrowUP0000" x="888" y="0" width="153" height="152" frameX="-2" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="blue hold end0000" x="0" y="0" width="47" height="46" frameX="-0" frameY="-0" frameWidth="47" frameHeight="46"/>
	<SubTexture name="blue hold piece0000" x="50" y="0" width="47" height="54" frameX="-0" frameY="-0" frameWidth="47" frameHeight="54"/>
	<SubTexture name="blue0" x="1044" y="0" width="154" height="152" frameX="-2" frameY="-1" frameWidth="158" frameHeight="153"/>
	<SubTexture name="down confirm0000" x="1358" y="0" width="158" height="153" frameX="-0" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="down press0000" x="410" y="0" width="158" height="151" frameX="-0" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="green hold end0000" x="0" y="0" width="47" height="46" frameX="-0" frameY="-0" frameWidth="47" frameHeight="46"/>
	<SubTexture name="green hold piece0000" x="50" y="0" width="47" height="54" frameX="-0" frameY="-0" frameWidth="47" frameHeight="54"/>
	<SubTexture name="green0" x="1201" y="0" width="154" height="152" frameX="-2" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="left confirm0000" x="1519" y="0" width="154" height="153" frameX="-2" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="left press0000" x="1676" y="0" width="152" height="153" frameX="-3" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="pruple end hold0000" x="0" y="0" width="47" height="46" frameX="-0" frameY="-0" frameWidth="47" frameHeight="46"/>
	<SubTexture name="purple hold piece0000" x="50" y="0" width="47" height="54" frameX="-0" frameY="-0" frameWidth="47" frameHeight="54"/>
	<SubTexture name="purple0" x="1831" y="0" width="152" height="153" frameX="-3" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="red hold end0000" x="0" y="0" width="47" height="46" frameX="-0" frameY="-0" frameWidth="47" frameHeight="46"/>
	<SubTexture name="red hold piece0000" x="50" y="0" width="47" height="54" frameX="-0" frameY="-0" frameWidth="47" frameHeight="54"/>
	<SubTexture name="red0" x="1986" y="0" width="152" height="153" frameX="-3" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="right confirm0000" x="2141" y="0" width="154" height="153" frameX="-2" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="right press0000" x="2298" y="0" width="152" height="153" frameX="-3" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="up confirm0000" x="2453" y="0" width="158" height="153" frameX="-0" frameY="-0" frameWidth="158" frameHeight="153"/>
	<SubTexture name="up press0000" x="571" y="0" width="158" height="151" frameX="-0" frameY="-2" frameWidth="158" frameHeight="153"/>
</TextureAtlas>
]]

and this should fix it!

1 Like

i didnt change anything and im getting this error


image

You should add a check for whether or not ‘MainGui’ exists in the first place; or at least wait for it if not.