Should I Render The Entire Level In My Tile Based Game?

This is a slightly more technical question. (You can probably just skip to the bold)
I’m starting development of a Tile-Based game (in Unity, of course) (Think: Stardew Valley)
I want the game to be VERY easy to mod, and thus expect end users to be able to make their own maps and have them supported by the engine.

I have some options for how to generate levels/tiles:

  1. moving nothing and having the movement be 1 (32x32 pixel) tile at a time, which will look horrible
  2. spending extra time on code to have a few tiles rendered in front of the camera and have them move around between 4+ positions so player movement is smoother
    Or what seems to be the easiest option:
  3. when a new level is loaded, destroy all tile objects and create the right number of tile objects and place them in a grid array the size that level is (ie a 100x100 grid) and just move the player and camera

My question is: are there any downfalls to going with option three? If I have 9,000,000 tiles (3000 by 3000) loaded at once, each one taking one integer value (3 bytes in c#, I believe) for the type of tile it is, and each being 32x32 pixels, all that and entity data and all the game processes - there should still be very little effect on data, right?
Or does Unity automatically only render what cameras show aka frustum culling - meaning I’m just stupid and wasting everyone’s time?
Do I need to make it so my program uses occlusion culling manually?

I’m not sure I understand the structure of your game, but there shouldn’t be any reason to lock entities’ movement to discreet tiles.

Again, it’s hard to tell what you mean by a Tile. Why do you need to render extra tiles for the player to move?

Why do you need to destroy and recreate all the objects? Why not just keep the ones you have?

There’s something that needs clarifying - when you say tile object, do you mean a C# object, or a Unity GameObject in the scene with components on it?

If it’s C#, an int is 4 bytes, so going off your 9M tiles, (assuming the only other variable they have is a Vector3 for position), that’d be about 144Mb total, which should be fine for the majority of hardware (though obviously you’ll have the rest of your game on top of this, that 144Mb is just for the tile objects).

If you mean GameObjects, then it’s way too much. Each GameObject has a slight overhead. It’s not noticeable until you start getting into several thousand, but at that point it’s worth switching over to purer data implementation.

Unity automatically does frustrum culling on GameObjects, but if you’re going with a custom data implementation then you’ll need to code it yourself. Occlusion culling is different - it’s for objects occluded by (behind) other objects.

Sorry for the questions, can’t give a detailed answer without a bit of clarification though :slight_smile:

Also, this forum is more for Design questions and discussion. You might have a bit more luck in the scripting forum.

2 Likes

I imagine you don’t need to see all those 9M tiles all at the same time. Why not dividing them in let say 10 sections. Each section is an Additive Scene loaded where nearby !!???

I believe Unity doesn’t render sprites which are out of the cameras view. You just need to make sure all of your code is very well optimised and only affectiing the tiles that it needs to.

Really as with most questions about optimisation, try it first, optimise it if you need to.

You can’t have 9 million GameObjects at once, regardless; Unity will crash. That’s a massive amount of overhead. As for rendering out of the camera view, frustum culling still has to calculate which objects to render, so that takes time, even if you could have 9M objects.

–Eric

1 Like