This is another raycaster. If you haven't guessed, anything thats either an ASCII roguelike or a 2.5 raycaster is instantly Rogue Adjacent n+1. It's name was originally a joke, but now its just sort of a title.
This one was created for two reasons. Firstly, I wanted to make a raylib project, and its always nice to learn new things one at a time (thus making something you've already made.) Secondly, I wanted an excuse to make a wave function collapse algorithm, which you may have seen is the project beneath this one. I decided to split them, because honestly that one was its own hole mess.
Setting up the raycasting code was way easier the second third time, and the function was around 1/5 the length of the last one.
Only around an hour into the writing of this program and we already have something resembling a raycaster! And with much more robust code than the first 2 iterations.
Another 20 minutes and we had textured walls. Already full days ahead of the previous attempts (even the forgotten second, where I mostly just stole my old code lol)
Also another occurance of the fabled brick texture!!
After a days break, I came back and added support for multiple textures, fixed some minor perspective warping, seperated the sky and floor more, and did a lot of behind the scenes tweaks to make working in the codebase less awful. Next: I wanted floors.
What the average reader of this site (if there is a reader reading this, hi! also, why?!) may not know, is that floors and ceilings are one of the things that KILLED the original second rogue adjacent
As you can see, I actually got pretty close right away. I just had to tweak some values to get it to fully work.
Now, I will explain why what I am doing is fucking retarded and nobody should ever render anything like this
What I am doing is, for each scanline on the map, bringing the point at the bottom of the wall closer and closer to the player, each time stepping forward (around, using calculus for an approximation actually!! First time its ever been helpful) the length of one pixel on the viewport, and using some trig to project its global position onto a texture (for now just a debug gradient,) then onto the screen. This isn't the worst way to render a floor, but the issue relies on the fact I am using the GPU to render these pixels.
But a GPU is supposed to be fast, right? Gpus excel at prosessing thousands of different operations per second, given to them by the CPU. In this case, the CPU is giving the GPU an instruction of a single draw call, waiting for it to finish, then asking for another seperate draw call. Were I doing this in something like a vertex array object in opengl, it would be fine, but because I am doing it literally pixel by pixel, it makes it orders of magnitude slower than a standard software renderer.
I mention this because I was left scratching my head how, in classic raycasters, they were able to get such detailed textures on the floors with none of the artifacting I got. Ends up, its because they weren't sending individual pixel instructions to the GPU. I blame the first raycasting tutorial I watched for this, he made it seem like a normal thing to do.
Here's what I ended up doing, you have little gravel flecks on the ground and stars in the sky. I think it ended up looking okay for what it was, the distortions sort of made the stars look like they were twinkling. The other gif was just a WIP one where I got the numbers sorta messed up, I just thought it had its own sort of charm.
After having some interesting moments and arguing with the visual studio linker for a while, I managed to get 2d sprites drawn into 3d space as physical objects which can be covered by eachother.
Next thing you know, worlds greatest walk cycle.
After that I spent like 2 weeks trying to implement wave function collapse. Its honestly an even bigger project than this, so I'll leave it for next time
After getting to a 'good enough' point with wave function collapse, I implemented it as a level generator, and moved to something else. I was still somewhat dissatisfied with the floor and 'ceiling' code, so I decided to try writing my own shader to display a textured plane.
Boom! A useful shader! I had written some shaders prior to this (mostly noise generation shaders) but now I had a full blown projection shader! As far as I'm aware, SDL doesn't have (as easy of a way) to implement custom shaders into your code, and the idea that I could do something like this was actually a major reason I wanted to try raylib.
Now I just have to put it in the game, right?
Que several hours of banging my head against the wall trying to find the perfect values for getting the plane to render at the right level. Eventually I did it by doing this
Boom! Instant upgrade! I ended up tweaking it a lot after this, but I honestly still think this version has a certain aesthetic to it that I wasn't able to capture again.
Added multiple cloud layers, it's hard to see but theres also stars in the very very background, you can barely see them through occasional gaps.
I also spent a lot of time doing this.
Then I added a hand... and realized I didn't want anything to do with the project anymore lol. Another that was lost to lack of interest.
The last version is available here. Fair warning, this might just not work. Its not like anyones gonna be downloading these anyway.