Home|Projects|About

Terraria "Clone" 2, C++, 12.13.2022

After being upset with the direction my first attempt at making a Terraria inspired game went, I decided to try again (read here to see why I wanted to make one to begin with.) I also believed that I had improved as a programmer, and might be able to create a project which suffered less from code rot.
As I was, I decided to use Raylib, and I can somewhat pin this as the reason the project was abandoned, though that doesn't come up for a while.

In order to assure that this project didn't end up like the other one, I spent quite a large amount of time before coding laying out how I wanted basic engine components to function for future reference, trying to think as much as I could how they would interact. This is definitely something that I should start doing with all of my projects, though honestly I probably spent a little longer than I should have working on this (especially considering how little time needed to occur for me to realize I would need major redesigns)

After getting some debug text drawn to the screen (which I never actually remove, btw) and setting up some basic camera rendering, I started working on chunks. In the gif the chunks are differentiated by slightly different colours, and are obviously hard coded.

Those clever among you may notice that this is really advanced and really specific for what it needs to be. One thing which ended up being a massive headache was that I didn't load in all the supported chunks until you started to move. Considering chunks are purely veritcal, you will only be able to move up and down, so there is no reason to not just preload all the chunks you can handle. Needless to say, but it's generally not a good idea to make your code more complex for no benefit.

Next I had an argument that was far longer than it needed to be over whether it was worth checking if the player velocity was greater than zero before applying the velocity. I was on the side that it wouldn't provide any benefit since the player will be moving every frame due to gravity.
Next I actually added the chunk loading algorithm.
Chunks are arrays of tiles which are themselves stored in an array. Due to overengineering, I decided to make the number of chunks dynamic instead of always having 64 loaded. Like I said before, there is no reason to do this. It created such a headache its genuinely incredible.
If you travel into a different chunk it would check if the top or bottom of the gameworld is beyond some threshold, and if it was it would add a new 16 chunks to a "load" list and add the furthest 16 chunks to the "unload" list. Theoretically, this would cause problems if you were traveling more than 16 chunks in one frame, but thats unlikely to happen.
Every frame it would deallocate (and theoretically save) a chunk from the unloaded chunks, and then it would generate/load a chunk from the loaded chunks list to replace it. It would then sort the chunks array so that they are in order by depth in the world. This would eventually switch to being threaded, but this was good enough for now.

Next I added fairly robust collision detection. Because it was using a simple algorithm to check for collisions against an array of tiles, I made a system which dynamically generated points to check for collisions, and it would iteratively move the player in small increments until it found a collision or ran out of velocity.
You can see in the gif above what happened when I added bounciness, and made the bounce coefficient larger than 1.

Next, I tried to add threading to the chunk loading and unloading code. This... Just didn't work. As far as I can tell, its an issue with GCC? I wasn't even able to compile test code, and I asked multiple people for help and nobody was able to understand why it wasn't working (even though other C++11 features worked fine.)

Leaving a bitter taste in my mouth, I decided to work adding some terrain. I also updated the aesthetics. Harsh red on black may sound cool, but my eyes started to hurt after debugging for more than a few minutes.

With terrian I could finally enable gravity. The terrain code is similar to the first iteration, only this time I made the noise compare to another noise instead of a fixed value (for whether a tile should be solid or not). This resulted in some areas being naturally more open, and in some being naturally more claustrophobic. Keeping in mind that there would be different layers to the world (including, ideally, a surface) I made it so the noise function would vary by depth. Right now, caves just get more open the further down you go.
Next up, I wanted to add basic lighting. I did this in a similar way to the first attempt, though this time I was DETERMINED to make actual lighting, and not just a fog-of-war style system. There were a lot of near misses (and not so near misses) though I eventually got it more or less working. I ran into a slight issue with quickly moving light sources, but over all I think I could have gotten it to work eventually.

I say could because this was the end of the project. I tried to get threading to work one final time, and when I couldn't all the issues I had faced with C++ and raylib overwhelmed me, and I decided to move back to using SDL with pure C for my next project.

If you'd like to try what I did have (for some reason) you can download it here. I did add a texture to the game which I didn't showcase, but thats it.