Recommended Posts

I'm still playing with various different ways of representing maps and have now come to handling entities within maps.

Naively I have the static 2d tilemap and I have a list of entities that are just an array of all entities currently in play.

My question is about how to relate the underlying map structure with the entity array:

Should I tie the two structures together?

i.e. Should each tile have an array with a load of references to instances within the entity array? Or should both of these structures be entirely independent? How do you do it? What are the pros/cons you have found to each approach?

Entities within tiles

const entities = {
  <id>: <entityData>
}

const tilemap = [
  <tile<tileObject | array:entityId>>
]

i.e.

const entities = {
  'id1': { name: 'an entity instance' ... },
  'id2': { name: 'another entity instance' ... },
  ...
}

const tilemap = [
  { 
    tileType: 'stone',
    entities: []
  },
  {
    tileType: 'ground',
    entities: [ 'id1' ]
  },
  ...
]
  

The advantages I can see is that rendering and access could be simpler, i.e. rendering can just iterate the tilemap, draw the base tile, then iterate that tiles entity list, perform a lookup on the entity object (or an array and perform a find operation on the id) and draw that entity at the current tile position. Similarly, if an entity is at [10, 10] and can view 1 tile in any direction then I can just use a tilemap search function to find the [3, 3] block of tiles that that entity can 'see' and they'll also get all the entities in that area as well.

Downside is that movement now becomes harder as I'd have to update the entity data in the entity object/array and also change references in the tilemap (i.e. remove from old location, add to new location).

Additionally, would you make any distinction about static vs dynamic entities? i.e. a cave on the tile map could be a tileEntity that is pretty much static, whereas a creature/enemy/ally would be more dynamic, would you differentiate between entity types?

I can also see that this sort of system can be quite easily generalised to allow tiles/entities to have inventories, but I am a little worried about creating two-way links between 'things' in the game world.

Any advice you have for me would make a good discussion

Share this post


Link to post
Share on other sites

Matt,

It's a shame no-one has yet replied to this because it is not a totally uninteresting question.

(For beginners: There is clearly a distinction between 'entities' which are objects in a game and 'objects' which are particular kinds of things in JavaScript (and other languages). A game entity is very likely to be represented by a JavaScript object but we need to be clear about the difference.)

The question is whether each entity should have a record of its coordinates (generally x, y, z in 3D space rather than a tile number) or instead each space position (or tile on a 2D ground) should have a list of entities which are currently at that position.

As you suggest, there is a difference between fixed entities and mobile ones. Fixed ones can clearly be referenced directly from tiles so that they can be drawn whenever the relevant tile is drawn.

Difficulties arise when the mobile entities move. Should we scan through all positions (tiles) to find entities to move or, given a moveable entity how do we find the tile at its position?

It seems to me that the most natural way is for each entity to keep a record of its position. But then the question is, for any given space/ground position is there an entity here?

The way I do it in The Forest (www.myforest.uk) is indeed for a moveable entity (represented by an object of type Mover) to have properties x and y for its position. Then when generating the terrain within method Terrain.terra (x, y) there is a test to see whether this.placed [x + ',' + y] is undefined. If not, that object property (which looks like an array element but is not) contains a reference to an entity at that position.

This relies on the optional way of representing object properties in JavaScript, where the name of the property looks like an array index of type String. Notice how I build the index string in the most compact but unambiguous way possible (x + y would be ambiguous: many possible value of x and y could give the same sum). The lookup is really done as a hash table, so it is very efficient.

When one of my entities moves from (x1, y1) to (x2, y2) the previous property of the object this.placed is deleted and a new one is created and given a reference to the entity:

delete this.placed [x1 + ',' + y1];
this.placed [x2 + ',' + y2] = entity;

I find this works very efficiently within my (effectively infinite) terrain. I have a few objects that move every time the user does something.

(For beginners: see https://www.grelf.net/jscourse/hashes.html and pages around there for more about ways of writing object properties and https://www.grelf.net/jscourse/moreops.html for the use of the keyword delete.)

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.