miwafoxl's creations

My failed 2D block-game (Devlog)

âš  Heads-up: Page has many animated images that may consume your data

All the images on the page are made by me, and are under Creative Commons CC BY-NC 4.0 International.

In 2018-2019, I was very curious and enthusiastic about Exoplanets and other "Earth-like" planets. The exploration rovers on Mars were a huge drive for me to study more about this field and it was very fascinating to me. Of course, I'm just a enthusiast in the field and I can't say I have deep knowledge about the subject, still I used to admire it a lot.

So much that, late 2018, I started conceptualizing a 2D sandbox game (that I wish it was 3D) codenamed Uniexplorer. A Minecraft-inspired 2D sandbox block-game that was going to be about surviving and discovering other planets, a similar premise of another game that I forgot the name. No Man's Sky? Ehh, nah. I don't reeeeally like the idea of infinite procedural worlds. Instead, I would prefer hand-crafted worlds with their custom thing. Very much more time consuming? Absolutely, but I believe it would create a nice, more unique experience by creating the worlds at my taste.

Now, Uniexplorer was one of my first "real" games, where before I had lots of small separate ideas and a lot of testing of seemingly arbitrary mechanics. I'm much more experienced to handle such thing today but, my first time was kinda of chaotic. I didn't start writing notes about the ideas I had for the game until a lot later during development. This was my first mistake while making this game that led my to a lot of trouble down the line, and its unevitable fate.

The Idea

Planet System

With this game I wanna to put someway for players to explore other worlds with rovers and rockets, build technology required to step into a uniquely hostile planet and gather new resources.

Explaning Uniexplorer Biomes
This was one of my first "written" sketches. The image is in Portuguese but I'll explain it. There is three solar systems nearby: Plaonic, Famer and Mesa, respectively. The first circle of each row represents the sun of that planet system, and the other filled circles represents solid exoplanets that orbits around its sun. You'll notice there is smaller circles near a planet; a filled circle with the same color of said planet is its moon(s), and the white circle represents a planet ring, which may contain very specific resources that the player can gather.

When you created a new save, you would be spawned randomly at any of the solid planets. Your player statistics would match the planet you spawned in, like if you were born there. Planets have different suns so their flora are naturally different from each other, as well as wild-life and intelligent life (though I didn't got too much into this part).

Planets would obviously have different proprieties, such as gravity, atmosphere, materials, humidity... There would be a temperature mechanic where distant planets would be colder. Players would require technology to breath and protect themselves in hostile conditions.

Biomes

Explaining biome regions This is the usual 2D biome distribution of an Plaonic (earth-like) planet. This is North to South, horizontally (kinda dumb now that I think about it), and the Y axis represents altitude. You would spawn in the middle, and as an arbitrary rule, the sun would be nearer the spawn, making distant locations colder.

Wrapping around the world

The idea is: when you're walking to the world border, you would see the other border of the world, like if you're going AROUND the world. Of course this is an illusion as the game world is flat, not spherical; I think it greatly improves immersion and transportation around the game world.

This also forces me to leave to not exaggerate in the world size like Minecraft does. The world should be just enough big to be walked around in a reasonable amount of time. In Minecraft, it should take you more than 10 years to walk from the spawn to the world border in one singular axis. A world that would take you in average 4 to 6 hours to loop completely around the world is much more reasonable to be and would encourage players to use all the space and resources available before hopping into another planet.


Devlog

From the start to the end of the project. Unfortunately, as I said before, I didn't wrote notes while I was doing this project. I'm fully relying on memory and those GIFs I've recorded while I was coding this.

indev 0.0.1

dev 0.0.1
This is my first ever attempt at the world generation. I wasn't aware of Perlin Noise technique at this time, so I was using random smooth noise to create the world height. I know, this is terrible, I know. I'd discovered Perlin Noise some versions after this.

indev 0.1.1

dev 0.1.1
Now, the game has a render distance and "block worker" (the magenta rectangle) that keeps generating blocks, while the "world worker" would delete blocks outside of the range to keep only what the player can see visible. As always, I was implementing this in a very stupid way: every single block you're seeing is one object. You can read up there that this has over 6k objects being rendered at the same time. Still smooth random for generation, everything about this is stupid for now. If you are angry, I am too.

indev 0.2.0

indev 0.2.0
For this version, I rewrote the entire generation code, this time using a different approach. I did learned about chunks, so I've made 1x256 (?) chunks I suppose. This time though, I'm using tileset instead of individual objects. The green square is the generation worker, it gonna keep generating new chunks if it's not beyond the player's render distance. This is much more performant but it comes its own downsides, mainly issues when prettifying everything later. I was worth the shot, and still no Perlin Noise.

dev 0.2.0 chunkmanager test
Despite this version still not being good enough, it did work and I felt proud of it. The chunks were being loaded correctly and performance was 2 to 3 times better than the first version.

indev 0.2.1

dev 0.2.1
Made some programmer art for the game, added character movement and now you can break blocks, it was okay! :)

indev 0.3.0

dev 0.3.0
At this point, the code was messy because I was experimenting a lot trying to find a way to make this work. After I hit what it looked like a nice generation, I decided to rewrite it once again but more efficiently.

dev 0.3.2
Added some dirt and stone. I was thinking on how I would implement caves. I was hella confused on how to implement caves in the first place. What kinda of magic can make caves real? (Note: What's Perlin Noise?)

indev 0.3.3

dev 0.3.3
This version adds the "wrap around" feature. I decided to do that because, one of my biggest references (Terraria) had oceans at each corner of the world, which I wasn't a fan of. I wanted the terrain to continue indefinitely but I also didn't want it to have a hard limit like traditional 2D platform games where you hit a "screen wall".

indev 0.4.0

dev 0.4.0
FINALLY, PERLIN NOISE! I finally was aware of Perlin Noise and in this version I've once again rewritten the entire generation code to take advantage of the new technique. Still getting used to how it works, but the important is that this is working :)

dev 0.4.1
This shows the "chunk worker" in action, this time all chunks are generated at the size of 16x256 blocks. It's not perfect yet, sometimes the chunk worker would just not follow the player for some reason. Took me some time to figure this out.

indev 0.5.0

dev 0.5.0
Because I was strulling with the chunk worker, I've created a new chunk worker that uses cubic 16x16 chunks. This GIF shows the chunks being rendered as the player moves across the world.

indev 0.6.0

dev 0.6.0
I've mashed everything together and I've started working on a multiplayer feature, so I can test the game with a friend. P2p was simple to implement, but it was partially working. Sometimes the world would just desync and I didn't know what to do in this scenario. Maybe I could do some MD5 checking to see if the chunks were the same for both players but I wasn't aware of hashing at this time, and even now I don't know if that would be the most effective approach.

indev 0.7.0

dev 0.7.0
And here it is, the last version that I've worked on the game. I've added a lot of things such as a simple hotbar, nickname and stuff. I've built some stuff while testing the building mechanics of the game.

The end of the project

The main reason I've stopped working on the game is that I've realised the limitations of the engine I was working on. For the entirety of the project I was working in Construct 2, an engine that I've mastered along the years, but it presents me no use case as it has a lot of limitations, plus the fact that it's over a decade old now. Even for it's new version, Construct 3, still have no flexibility enough to make this project possible.

The thing that I wanted to added after this version was shadows. A way to darken the underground blocks, so I can start adding ores and caves, as well as torches and lighting. The thing is, there is no way of implementing that the way I wanted. I wanted it to be dynamic, like if a broke the ceiling of a cave, it would immediately reveal the cave slightly as the skylight make its way inside the cave.

The tile-set object on Construct 2 provides no control over every block inside it. I can only set and unset a tile there and that's why it is so performant, it has nothing to do with those blocks. However, I needed the control in order to make lighting work, because I need to update the blocks individually and fast for the light calculation. So here I've hit a brick-wall and decided to stop working in the project all together. Skill issue? Strongly agree, I could do this project much better today, but I would probably hit the same problem but in another aspect of the game if I keep on the same engine.

It was fun while it lasted, I've learned a lot of things about procedural generation and algorithms that I use to this day in my personal projects.

#devlog #game development #indie games