doggy-dentures / tnt

Other
3 stars 1 forks source link

The .funk files #1

Open Scriptshatter opened 1 year ago

Scriptshatter commented 1 year ago

What are they (Well I mean they're obviously image files), How do they work, and how can I edit/make my own?

doggy-dentures commented 1 year ago

This is going to be a LONG explanation (tldr at the end)...

If you haven't noticed already, TNT loads levels really quickly while also taking up little memory at the same time. This is mostly thanks to the game's sprites using a more optimized image/texture format that I created for the mod, the FUNK files.

So basically, PNGs are compressed and optimized to have the smallest file size possible without making image quality worse. This means that you have to spend a bit of CPU time decompressing/converting them into the pixels that can display on your screen. This is great for something like internet pages where download speeds are the weakest link in how long it takes for an image to show up. But for something like a game, where all the files are on your disk and disk transfers are way faster than download transfers, the whole turn-PNG-into-pixels process will actually end up becoming the weakest link. What's more, the compression algorithm used for PNGs is also quite old at this point and has been outclassed by other algorithms in both speed and file size.

In addition, PNGs are very much NOT optimized for video games when you consider how much memory they take up, especially in HaxeFlixel. HaxeFlixel stores its image data in both main memory (RAM) and GPU memory (VRAM). Furthermore, it stores the image data as a bitmap (if you don't know what those are, all you need to know about bitmaps is that they take up tons of memory). If that wasn't already bad enough, the way PNGs store image data requires HaxeFlixel to also do some additional processing on the bitmaps before it can send the data to the GPU.

So the process of having a PNG display on your screen looks like this in HaxeFlixel: Load PNG from disk -> Decompress PNG data into a bitmap (slow) -> Process the bitmap into something the GPU can accept (slow) -> Store the bitmap in System RAM -> Store the bitmap in GPU VRAM -> GPU displays the image

This is not the norm for modern games, which will only store image data in the GPU to avoid wasting memory. Most modern games also use something called "texture compression". Basically, image data isn't stored as a bitmap, but rather a format that makes images take up way less memory in GPU (this comes at the cost of image quality but unless you're working with pixel art, the quality loss is usually tolerable and sometimes unnoticeable).

For a game like FNF with very big sprites, storing textures in only VRAM and employing texture compression provides very big performance benefits. Funny thing is, OpenFL, and therefore HaxeFlixel, have the capacity to do both of these things. The way to actually do it in HaxeFlixel is unfortunately not very exposed due to the complexity. For example, texture compression is very platform-specific. You have to do it differently depending on if the system is PC, Android, or iPhone because all these systems have different GPUs that historically have employed different, incompatible types of texture compression (there's sometimes overlap depending on the GPU they use, but that's a complicated topic for later). There are also certain sprite features in HaxeFlixel/OpenFL that will not work on GPU-only sprites since they depend on having a bitmap in system RAM.

Anyways, the FUNK files for TNT use PC-specific compressed textures for its image data. Since this data is already in a format that the GPU can accept, this allows us to skip the step where we do additional processing. Also, remember how I said before that there are superior compression algorithms than what PNG uses? I used one of them to compress the texture data. Specifically, I used a compression algorithm called LZ4, famous for having super fast decompression speeds.

With all of that in consideration, the process of having a FUNK file display on your screen looks like this in HaxeFlixel: Load FUNK from disk -> Decompress FUNK data into texture data (super fast) -> Store texture in GPU VRAM -> GPU displays the image

When developing TNT, I made some scripts that batch convert PNG into FUNK files. I didn't include them in the repo since I didn't really think anyone would bother to care about the FUNK format. If you really want those scripts, let me know.

If you want to convert FUNK files back into PNGs, I didn't make any scripts to do that, but it is possible. You shouldn't be doing it though because the FUNK files will always have worse image quality. This repo already includes the high-quality PNG versions of each FUNK file used in TNT.

tl;dr: FUNK files are an entirely different image format compared to PNGs. PNGs are designed for the internet while FUNK files are designed for game engines. I made FUNK files for TNT because they improve performance.

Scriptshatter commented 1 year ago

I do think you should include those scripts, hell I think you should consider making your own engine! especially with how well you handled everything in the backend! One think I think you should consider is also using MIDI with the sound fonts for the songs. Maybe an option or something? idk. Still, you did a really good job when it comes to this mod!

doggy-dentures commented 1 year ago

Ok, I added the scripts to a folder called "texture tools" inside the repo. The folder includes a readme on how to use the scripts to convert PNG files to FUNK files.

Scriptshatter commented 1 year ago

Sounds good! I really like what you've done with this mod!

SomeGuyWhoLovesCoding commented 4 months ago

Ok, I added the scripts to a folder called "texture tools" inside the repo. The folder includes a readme on how to use the scripts to convert PNG files to FUNK files.

Can you please make a haxe version?