Bore blasters

Wishlisted! :heart:

2 Likes

Looks great, wish you the best.
no enemies to fight with? interesting :slight_smile:

2 Likes

Thanks for AABB again :wink:

There will be some enemies, but none implemented yet. Enemies will be less of a focus than in Void Scrappers.

4 Likes

Looks amazing!!

2 Likes

Wishlisted!

I wonder how you implemented the world, is it a tile map?

2 Likes

Thank you for the wishlist!

No!

Each block is a game object → sprite → tilesource. This is so that I can apply auto-tiling.

Here’s what a tilesource looks like:

Each animation in the tilesource corresponds to a bitmask. I used this excellent guide to figure out how to use bitmasking for auto-tiling.

Happy to share more if people have any questions about the project.

13 Likes

One thing I was grappling with for a while was garbage collection. I frequently spawn/despawn lots of blocks as the player moves around in the world. This eventually triggers the garbage collector, which results in a really noticeable stutter.

I used the discussion in this thread as a starting point for a solution. Thank you @cornedbeer - your thoughts were really useful and I would have struggled to realise that placing this script in the main collection would ensure it runs last.

The idea is that I run the garbage collector in tiny increments each frame, until I reach the time limit (e.g. 0.167 seconds for 60 fps). I have also implemented a flag which prevents the garbage collector from running on particularly intensive frames (e.g. if I despawn a chunk of blocks).

Simplified, it looks something like this:

	if garbage.intensive_frame then

		--Don't run the garbage collector during a particulary intensive frame
		--This flag can be set by any script and will prevent garbage collection from running that frame

		collectgarbage("stop")
		garbage.intensive_frame = false

	else

		--Run garbage collection steps until finished or we run out of time this frame
		-- https://forum.defold.com/t/solved-optimizing-frame-stability-avoiding-garbage-collector-related-hitches/70930/3

		frame_time_diff = socket.gettime() - frame_start_time

		garbage_finished = false
		while not garbage_finished and frame_time_diff < frame_time_target do

			garbage_finished = collectgarbage("step", 1)

			frame_time_diff = socket.gettime() - frame_start_time
		end

	end

	frame_start_time = socket.gettime()

A key component of making this work is setting a reasonable step size for the garbage collector. For me, this was 110:

collectgarbage("setstepmul", 110)
16 Likes

Thanks! These are really lots of very useful information.
Maybe you can create a separate thread where you can discuss some of your solutions?

1 Like

Thank you! I really don’t mind sharing a mix of general updates and technical stuff. If it becomes too cluttered though I’d be happy to start separate threads.

1 Like

Maybe a small blog post? It’s very interesting and helpful! :slight_smile:

2 Likes

Great tips! Personally, I love everything about code optimisation :star_struck:

Please tell us more details about why does spawning/despawning blocks stress GC? I assume it’s because a lot of tables are created and deleted, right? Are they created by collectionfactory?

4 Likes

Thanks! I am very proud about pulling off the garbage collection implementation (but of course it wasn’t my idea!). Otherwise I actually find code optimisation a bit stressful, but I keep making really intense games so I guess I have to learn some things :sweat_smile:

Just regular factories actually.

Each block has two tables associated with it - permanent data (such as what type it is, location, etc). It also has temporary data when it is spawned (game object reference, AABB id for collisions, etc). The table with temporary data is created/deleted when I perform culling.

I’m not entirely sure what exactly stresses out the garbace collector. What I found, surprisingly, is that deletion is much costlier than creation. I haven’t narrowed down whether that is go deletion or table splicing or something else.

When I have to spawn block “sectors” (sector is what I call a set of blocks that ~cover the player’s window), I batch them so that one sector is spawned each frame. When I have to remove sectors, I batch it so that one row of a sector is deleted each frame (so it takes about 20 frames to remove one sector). If I delete an entire sector in a frame, I get a stutter!

2 Likes

Glad my thread was helpful! Since then I’ve actually discovered one very unfortunate issue with Lua’s GC that you may or may not run into depending on the scope of the project/how much you rely on pre-processing and storing data and how you structure that data.

Luckily the work-around isn’t too bad, but it’s something that might drive you crazy if you start running into issues and don’t know why. I’ll make a post about it in my original thread for anyone who’s interested.

Good luck with the new project, the destructible terrain looks really satisfying already!

8 Likes

Thanks for the heads up! Very interesting, and you are correct in saying that would be very hard to debug. I think this project will manage to avoid hitting these large numbers, because I do end up doing a fair bit of table nesting + the mining shafts are finite in depth and width.

4 Likes

I love destruction and chain reactions so this vein of explosive ores was a great idea (courtesy of wife)!

14 Likes

@Alex_8BitSkull Wishlisted

3 Likes

Thank you! This helps us out a lot :muscle:

3 Likes

Infested caves! Been working on enemies a bit. I think this feels super satisfying (and the wriggly eggs are disgusting).

12 Likes

We’ve got a fresh new trailer out! Would love to hear what you think. You can check it out here:

https://twitter.com/8BitSkull/status/1699815459795664986

11 Likes

Looks great, wishlisted!

2 Likes