Improbable Icon

2d Tilemap tiles - represented as Entities?


#1

So in a standard single player example, for a top-down 2d game that relies on tiles and a tilemap as the basis of it’s terrain, normally I would set up files on the client that each represent an area of the game, are binary, and would have something like 2000 x 2000 or so tiles inside. Client would load the tiles when needed and tiles would have simple information about their location and what tile set/image they use.

However, in SpatialOS, i’m unsure how tilemaps would best be stored and delivered. Would it be appropriate to have each tile as it’s own entity? However, unless i’m missing something, i’m quite sure that entities have a good bit of memory overhead, even if they contain fairly simple data (x/y position of tile, height, terrain type).

What would be the proper way to store and deliver a tilemap on the server and to clients?


#3

Hey @Swizzlewizzle
While I’m not the most experienced in this, from the top of my head I’d advise batching up sets of tiles into “chunks” and storing them as entitites.
You can store the state of the tiles in each chunk in spatial components if you want then. And if you size them right then it’ll allow your world to dynamically load as the player moves between chunks (very much like minecraft).

You’re right though, if I were you I wouldn’t try to store each tile as it’s own entitiy, that’s going to murder performance! :slight_smile:

You could also consider not loading the tiles as entities at all if that suits your game. Just instruct the client which tiles to load where once then do all that work clientside :wink:


#4

Makes a lot of sense Kaffo.

Definitely need to do some work server-side in the future (tiles get blown up… change to crater… etc…), so probably following your idea of having area chunks set as entities, and then storing tile state information inside is the way to go. I didn’t consider thinking of it like that, thanks! :slight_smile:

I’ll probably store the same data on the client, and then just have the server push any changes from the base to the client when needed. That way if a bunch of tiles get blown up, I would only need to send a small bit of data to change the structure already existing on the player’s side… makes a lot of sense.

I suppose on the backend spatialOS tries to optimize the data and transmission of that data between server<-> client as much as possible? I noticed some good stuff related to changes to schema information being automatically updated and such. Great. :slight_smile:

@kaffo one thought I did have though… the chunks/areas would probably need to be decently small to avoid issues with having many workers sharing all of the state changes between areas due to boundaries. I mean, let’s imagine I had a 10km2 area, and split it into only 2 chunks (just for examples sake). In this case, in very many cases, multiple workers would be mirroring changes to both terrain “entities” since they are just so large that the boundary between them would likely be very frequently covered by multiple works. I suppose then there is a balance to be made between not having the terrain entities (areas/chunks) be too large, as well as not being too small, where overhead in memory/handling from having too many entities would occur. Anyways… something to think about for sure. :slight_smile:


#5

You’re thinking the right way :wink:

You can set the size of granularity in your spatialos.json that your workers can break your world down to, so technically you could set your granularity to a 5km2 area and have two workers, but that’d be pretty daft :slight_smile:

I haven’t found the “right” size of tile yet myself, I’m using terrain though so I’m cutting up heightmap data into chunks rather than doing the opposite :smile: so I think you’ll need to experiement a little!

Regarding data updates, two things to consider First, you could not store state in the component, and instead just send events to tell the client/server about state updates (explosion at tile X of size Y etc) but then you chance desync of course.
Second thing, which is important and is still true to my knowledge, when you update a value on a component, the update contains information on all of its values. Even ones that didn’t change. I’ve been trying to make my compoents as small as possible to save on bandwidth due to this :wink:

Also, come hang out on the Spatial community discord, you could muse with us over there!