Author Topic: Beginner Question: How should maps relate to objects?  (Read 7789 times)

Mathematikus

  • Newcomer
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Beginner Question: How should maps relate to objects?
« on: November 22, 2015, 06:50:08 PM »
Recently I have studied the Complete Roguelike Tutorial, using python+libtcod (http://www.roguebasin.com/index.php?title=Complete_Roguelike_Tutorial,_using_python%2Blibtcod) and I have been trying to implement some of the ideas with Python 3 and PyGame. Mostly I have been thinking about basic things like how objects should be modelled, how to split the required tasks to separate files etc. More sophisticated things like procedural generation of dungeons and Field of View algorithms are not top priority. I (suppose) am a novice in programming so a lot of the problems I have are probably elementary. I can do basic stuff like player object moving inside a map (list of lists of Tile objects).

If I have understood the code of the tutorial correctly, when going to the next map the new map is written over the old map. What if I want to keep the old maps and their contents?
I think maps should have their own class, but what I'm wondering is how the maps should relate to objects within them. Should maps have a 'list of objects' attribute that keeps track of what objects are inside it? Should the objects have an attribute or a function that identifies the map that they are inside of? Both? I would like to know how is this problem has been solved by more experienced people. The tutorial has a global variables 'map' and 'objects' (the list of objects). I think what I want is a list or a dictionary of maps. I am assuming the game is structured in a way that is similar to the tutorial (object composition etc).

Ancient

  • Rogueliker
  • ***
  • Posts: 453
  • Karma: +0/-0
    • View Profile
Re: Beginner Question: How should maps relate to objects?
« Reply #1 on: November 22, 2015, 11:08:53 PM »
If I have understood the code of the tutorial correctly, when going to the next map the new map is written over the old map. What if I want to keep the old maps and their contents?
Copy the global map somewhere, for example into an array. You can then let current map be overwritten with new level.

I think maps should have their own class, but what I'm wondering is how the maps should relate to objects within them. Should maps have a 'list of objects' attribute that keeps track of what objects are inside it? Should the objects have an attribute or a function that identifies the map that they are inside of? Both?
Depends on your needs really. Bear has written a very valuable post on this.

Short version:
(location -> item) mapping is needed for finding an item when you have only map square. For example checking what is on given tile. When that blind gelatinous cube wanders aimlessly and happens to stumble on something soluble you go through map to access items.

(item -> item) is needed for containers. If you do not plan on them there is no need to worry about items "owning" other items.

(item -> location) is needed when your items can act by themselves. For example a dragon egg hatching needs to know where it is on the map to place the hatchling. Otherwise you would be searching whole map for this item or possibly several, since you asked for a way to store more of those.

You can read Bear's archived post on data design requirements here: rgrd newsgroup archive.
Michał Bieliński, reviewer for Temple of the Roguelike

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Beginner Question: How should maps relate to objects?
« Reply #2 on: November 23, 2015, 01:07:47 PM »
In OOP style there should never be a global map, but a list of map (or level) instances in a world class.

There is no right way to handle map tiles, they can be "dumb" terrain tiles and objects could be stored in a list and only have a map representation of them (sometimes even a pointer to the object). Yet what I would suggest is make the map tile contain everything (game objects, items, terrain, etc.) from the start and also make the terrain tile itself an object rather than dumb tile id number. That way when the game is extended it's easier to handle terrain as object, very useful for more complex interactions for terrain. This approach could be called "everything is an object", because I think it's deceivingly easy to think that terrain is "just" simple terrain which leads into all kinds of problems later.

Omnivore

  • Rogueliker
  • ***
  • Posts: 154
  • Karma: +0/-0
    • View Profile
Re: Beginner Question: How should maps relate to objects?
« Reply #3 on: December 22, 2015, 12:49:59 AM »
Try thinking of the game world as being a collection of collections.  Restricting yourself to a single array representation can, beyond a certain point, make things harder instead of easier. 

I find there is a tendency when using 'everything that is here' objects in arrays to start using pointers (or references or indices) between objects to express relationships - that makes saving and restoring map/world information much more difficult that it needs to be.  The maps can quickly become 'brittle' and hard to track bugs can easily ruin your day.

As a mental exercise, try representing your game world as a relational database.   The various relationships should quickly become apparent.  You can borrow an idea from the RDBMS camp and use a unique identifier for each game object.  Then you can express relationships as ID value collections.

The use of ID values together with treating your game world as a collection of collections, makes it much easier to reliably save and restore slices of game data such as level maps. 

Tip: immutable coordinate objects and hash maps/sets are your friends.

Hope this helps,
Brian aka Omnivore - and Happy Holidays to all :)