Simple RPG Map Design/Actions

I’ve managed to cobble up a simple map editor for a simple tile-bsaed RPG, as well as a demo app that loads a map made by that editor, and lets the player’s sprite walk around on it. Pretty straightforward so far.

But here comes the noobish question: How do I store what monsters can attack the player in different regions of the map? Is that information typically stored in the map itself (i.e., each tile contains infomation on what monsters can attack, and with what probability, etc.)? Or at a higher level than that?

Just wondering what the connon and/or simple ways of doing this are.

You can do it either way, but you’ll probably find that storing them in a tile will be annoying because when you want a list of all monsters, you’ll need to search through all of the tiles.

In my game the enemies and human players are all in a big List, which makes it easy to update and manipulate them. Each stores their own position (as float x & y) so it’s easy to find the closest one to another player.

I hope that helps! :slight_smile:

In a way it should be stored in the map because the spawn regions are map specific.

You should modify you tile editor to allow placing events. These invisible elements you add on top of the tiles. Never associate an event with a tile image directly, it limits flexibility.

If you want to keep it simple with only 1 event per tile then you could just have another array that stores these events. Define your own event class. In this way you never have to use the tiles except for drawing, the functionality of the map is defined seperately.

malberts that doesn’t seem like very good advice. You don’t know the scope or goal of his game: events could be completely inappropriate.

What I find generally works best is to have at least two layers in the tiles, and one list of objects. The bottom-most tile layer is background objects and all images and sprites. The middle layer is everything the player interacts with, which isn’t actually drawn. This way you can put walls, doors, teleporters, etc. in the middle layer, and you’ve got images separate from actual logic. It allows for stuff like “passwalls,” pushable blocks, etc. You can also add more layers on top and bottom if you want multiple layers of art, and your game logic is not affected.

Keith’s reasoning for having a list of objects is exactly the reasoning I have as well.

Hi.

My opinion is that there is no way to give the correct answer to this question without knowing more about the problem. If the map is as simple as can be, with no obstacles, no traps, and always a possible path from the monster to the player, and it’s a given that a monster is aware of the player, then I’d definitely go with the Monster list suggested by CommanderKeith.

However, if all or most of the premises above are false, then you’ll end up quering environmental settings (potentially heavy ones) at each monster in your list. In this case, it might be better to store information in the map, and iterate over the necessary subset of your map.

If the monsters are always spawn within the same region of your map, you could have a Map object with the regionID as key ,and a list of monsters as values. If the monsters move out of one region, and into the other, you shift them from one list to the other. For huge complicated maps, this basically just makes the list suggested by CommanderKeith more effective, as you only worry about a subset of your monsters.

It all depends on what the mechanics of your map and monsters are, and how flexible you want stuff.

Maybe I misunderstood what you asked.

What I understand as the region where monsters can attack the player is a certain area where if the player walks around long enough a battle will start. For exampe a desert area will spawn a different kind of monster than a grass area, but not all the desert/grass tiles spawn monsters and the player cannot see these monsters until a battle starts (like in old FinalFantasy games).

The tilemap array (graphics) is a different entity than the events arrays (walls, doorway, spawn area). You would then have an array for tiles, an array for walls, an array for doors (links to other maps), an array for spawnable areas. What I meant was that your game shouldn’t do the logic like this: check tile image and then decide what to do.

Have a look at OHRRPGCE (http://hamsterrepublic.com/ohrrpgce) to see what I mean.

The event that I refer to is the event that an enemy will spawn. So none of the enemy’s stats or positions are stored in the tile, only an event that specifies that theres a probability of a spawn in every x steps and what enemy(s) gets spawned.

The list used by Keith is a list of players, but a spawning point is not a player, it’s an event just like teleporting. If you stored the spawn points in a list then you would have to traverse the list everytime you wanted to see if you are standing on a spawning point, which is slower than just seeing if the spawns[player.x][player.y] has a spawning point.

But if you wanted to know how to store the enemies and their probabilities of hitting a player then use a list as said here.

Well if you’re thinking more monsters walk around and if you touch one to start a battle, you’d want the list. It is a very good point that your current objectives are vague.

In fact, if you have a truly tile-based game, where pressing the Up key moves you up the exact distance of one block to another, etc., then the monsters should be directly in the tile map. Then you just iterate over everything each timestep and tell it to act. If it’s a block, it will iterate its animation, if it’s a monster, it will move, etc. Cheap and collisions and the like are ridiculously easy.

Sorry if my objective wasn’t clear in my first post.

The game would be played like an old 8- or 16-bit Final Fantasy or Dragon Warrior game. A map is just a big grid of square tiles, and the player moves one square at a time. Monsters aren’t visible on the map; battles just seem to happen “randomly” as you walk around.

My understanding (which could be wrong) was that monster locations weren’t predefined on the map in cases like these. Rather some formula was used to determine whether a battle should occur whenever the player moved to a new tile (something that seems random, often involving variables like “steps the player has taken since the last battle”). The formula is designed and tweaked so that, to a player, it just seems like every 12 steps or so, a battle usually occurs.

I think malberts had the general idea right in his last post. Different “regions” of the map will spawn different enemies. These map regions aren’t explicitly told to the player, but the player can usually just figure it out because it’s based on the map’s “geography” - on grassy plains, for example, weaker monsters attack, in forests stronger monsters attack, when sailing around at sea, sea monsters attack, etc. Monster types shouldn’t be tied to tile types though, because a “grassy plain” towards the start of the game will have weaker monsters than a “grassy plain” closer to the final dungeon. My question was “how should this information be organized?”

My initial idea on implementing this was to have a regionID associated with each location in the map grid. This is kind-of what I meant by “stored in the map itself.” This regionID mapped to a Region object of some sort, which includes the formula that determines whether a battle should occur. If one should occur, then the Region would also know what kinds of monsters attack in it, how many attack at a time, etc., so it could set up the battle scenario.

This could also be implemented with events as malberts suggested. Each tile would have an event that used a formula to determine whether a battle should occur.

I hope that’s more clear. Let me know if I’m way off base with my ideas.

How will you add a Region onto the map? By using tiles?

A rough idea of what you could do is to make a class SpawnEvent which stores:

  • the probability
  • the type of monster (or multiple types) to spawn
  • the number of each monster to spawn
  • the scene type for the battle (like forest or grassy)
  • and optionally a multiplier of some sort that increases the probability/types of monsters/number of monsters depending on the player’s level

You store a list of possible SpawnEvents. Then you have an int array of the same size as your map and add the number of the SpawnEvent into that array. Then whenever the player moves to a different tile you check if theres a SpawnEvent for that tile and the number of steps have been made, then start a battle.

Or you can make a region array and assign those SpawnEvents to a region. In this way you can assign multiple SpawnEvents per region for example if the player has a certain item then a different kind of SpawnEvent must trigger.

I think that furthering that idea you should just have one midground array and one background array. The midground holds all events and collidable tiles, the background holds all drawn images. Then you can just use your level editor to draw spawn zones matching certain background images behind it. Similarly, you can draw impassable walls for mountains and that sort of thing.

Thats basically what I had in mind.

About the impassable tiles, if you are going to have full impassability then the above should be easy. If you are going to have impassabiliy from one or more of the sides (like in OHRRPGCE) then a single midground might be slightly harder because then you will have multiple events per tile. However multiple events per tile in this kind of RPG is uncommon, but with clever level design you won’t have to worry about multiple events per tile.

That’s very true. If you keep it that way, you can have problems with multiple things existing in the same place at once. For example, if the player wants to drop their inventory on one tile, this is impossible. Depending upon how complex you want to get, one solution can be to have your midground be an array of “buckets,” which are lists that contain everything present in that tile. Another approach is to store any object that may be a bit overly dynamic (such as items) in a separate list. You lose a bit of efficiency if you do that, but it can be smarter than the bucket approach.

Thanks guys. You’ve all given me some great ideas to work with.

FWIW, what I’d do is something like the following (my example takes the map layout as XML, for readability):


<Map>
 <Tile x='0' y='0' image='grass.png' blocking='false'>
  <Events>
   <Event type='my.rpg.event.battle.OrcBattle' chancePercentage='10'/>
   <Event type='my.rpg.event.battle.SuperRareDragonBattle' chancePercentage='0.00001'/>
   <Event type='my.rpg.event.TextMessage'>I hope I get to fight some Super Rare Dragon!</TextMessage>
  </Events>
  <Items>
   <Item type='my.rpg.item.Gold' monetaryValue='10'/>
  </Items>
 </Tile>
 <Tile x='1' y='0' image='rock.png' blocking='true'/>
 ...
 ...
</Map>

Then load the XML into your data structure for your map (which will have a similar structure as the XML), during the game check on which tile you are iterate through the Tile’s Event and Item objects.