It is currently Mon Dec 10, 2018 12:28 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Aug 08, 2018 8:07 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
When you have a game where the maps goes only from left to right and the exit is always at the end then it is quite easy to manage the exit point (end of the map) or the bottomless bit (other holes in the map) but what if your map would allow to exit at multiple locations, either by falling through a hole in the middle of the current map and ending up in another one, having some possible ladder that either goes up or down which causes multiple branching point and bottomless pits?

For now I'm not sure yet where and how to manage it so before starting to implement, I thought it would be a good idea to listen to other people opinion before making some mess.

For now, one possible way could be when processing the current frame:

- while processing user input, if actor goes out of bound (up/down of screen or begin/end of current map), raise a flag
- later during the frame processing, if flag out of bound, check location
? this is where I'm not sure "what" location means:
- current screen in the map (1 screen is 256 pixel), check if exited up/down/left/right and react on that
- x, y position again possible hitboxes (seems intensive)
- have a list of exit point and check somehow against them (not sure what and how yet, seems similar to hitbox)

Maybe there is something even easier, it just that I don't see it yet. I write these days the logic in C so it's a lot easier to visualize so idea in either C or asm and why it is better that way will be really appreciated.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 8:58 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20851
Location: NE Indiana, USA (NTSC)
In The Curse of Possum Hollow, each map has a list of exit points. Each exit point has a source (in 16x16 pixel units), a destination map ID, and a destination position. When one is on screen, the engine checks to see if the player is inside it.

In addition, in both Curse and its predecessor Haunted: Halloween '85, each map has a side, top, or bottom exit and an exit size. Touching a full-height wall at the right side activates the side exit. Approaching the top or bottom of the screen activates a top or bottom exit, so long as the player is close enough to the end of the map. (If not, it's processed as an ordinary ceiling or pit.)

Here's the exit logic that both Haunted games use, roughly translated into C:

Code:
// These are set to 0 at the start of every map
unsigned char boss_running = 0;
unsigned char want_exit = 0;

// This is in the main loop
void check_exit() {
  switch (level.exit_type) {
    case EXIT_RIGHT:
      if (actor_x[0] >= map_width - 8) {
        want_exit = true;
      }
      break;
    case EXIT_TOP:
      if (actor_x[0] >= map_width - level.exit_argument
          && actor_y[0] < 16) {
        want_exit = true;
      }
      break;
    case EXIT_BOTTOM:
      if (actor_x[0] >= map_width - level.exit_argument
          && actor_y[0] >= level.pit_height - 16) {
        want_exit = true;
      }
      break;
    case EXIT_BOSS:
      if (actor_x[0] >= map_width - 160
          && !boss_running) {
        boss_running = level.exit_argument;
        boss_setup_procs[boss_running]();
      }
      break;
  }
  // Omitted: Scan the level's exit point list
}

// The main loop also calls this.
// During a boss, its run procedure will set want_exit
// once the boss is defeated.
if (boss_running) {
  boss_run_procs[boss_running]();
}


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 9:28 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
That gives me some ideas, thank you for the pseudo-code.

This mean in your case that if you map has multiple pits, any pits becomes "the bottom exit" case. What if you have one case where you have a ladder that goes at the bottom after the pits. Since your example show the bottom exit tested first, would the exit list still be tested later even thought the flag was set? Or because the flag was set, it would check if the exit exist in the list to know which one it is? (and unknown one would means a bottomless pit, I guess?)


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 9:50 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20851
Location: NE Indiana, USA (NTSC)
Banshaku wrote:
This mean in your case that if you map has multiple pits, any pits becomes "the bottom exit" case. What if you have one case where you have a ladder that goes at the bottom after the pits.

In top and bottom exits, level.exit_argument is a width value that distinguishes the ladder from the pits. If the ladder is 64 pixels from the right side of the map, and the pits are 128 pixels from the right side of the map, set it to 96 so that the actor_x[0] >= map_width - level.exit_argument test distinguishes the two.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 10:15 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11010
Location: Rio de Janeiro - Brazil
Whenever I need metatiles to have special behaviors that need extra parameters, I flag them as having the specific behavior (in this case there would be an "exit" flag somewhere in each metatile's definition), and whenever there's a collision with them I look them up in a list of special behavior blocks sorted by coordinate, where I can find the remaining parameters to execute whatever is that the block does (in this case, the target location). If the list is long, I use binary search instead of comparing element by element.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 6:13 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
@tepples

The part that confuse me is when you say "from the right side of the map", like either the map represent 1 screen (8 bit value) and there is an exit in that current location or there is only 1 exit from the top from this 16 bit value. Then later other exit point are confirmed from a list. You example gives me a lot of ideas to start make my own, I just want to make sure I understand your example properly.

@Tokumaru

I was thinking about that too, making a metatile with a special attribute for the exit point. My current issue with that is that is even though I would like to implement it, my current test code from 10 years ago was using some kind of ideas of the top 4 bits was for the color for the metatile and the bottom 4 bits are used for some flag. The issue with that is that it reduce the amount of possible flags to 16 values only, which could be enough. If not, I would need to separate the extra attribute per metatile in its own byte but that would increase the size and require to edit it either manually or updating the code of the map editor I didn't touch in 10 years. The other thing is that it would increase the count of metatile for special case like these per screen. Maybe this is not an issue, need to test it first. I will keep that idea in mind, thanks ;)

Another thing I see in Tepple example is "exiting" the screen doesn't mean to be out of bound ( y < 0 or > 240) from an hardware point of view but more from a specified logical boundary. For action game similar to mega man, ninja gaiden etc maybe this would be fine too, which is what I hope to be able to make with such an engine. I don't know why I was so much set on an hardware boundary. I will see how much impact it as with a different offset.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 7:37 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20851
Location: NE Indiana, USA (NTSC)
Banshaku wrote:
The part that confuse me is when you say "from the right side of the map", like either the map represent 1 screen (8 bit value) and there is an exit in that current location or there is only 1 exit from the top from this 16 bit value. Then later other exit point are confirmed from a list. You example gives me a lot of ideas to start make my own, I just want to make sure I understand your example properly.

There are two different exit systems. One is based on reaching the end of the map, which can be up to 8192 by 240 pixels in size. A map can have only one exit using that method. All secondary exits use the 16x16-pixel exit points.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 8:42 pm 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 419
I like give each block type an effect field. Could be "do nothing", "pick up coin", "finish level", "go up one room", "go down one room"... it's just a jump table, stored in parallel to attributes like solid/water/air/etc, and triggered whenever the player (or even a monster if I want that) touches a block of the coresponding type.

They're arbitrary code, so they can read data from elsewhere, like "number of room above", "last saved overworld map location", "is player holding key", "is player on ladder" and so on as needed. They can even be completely generic, jumping through a second per-level table or toggling multipurpose flags that can be used by other 'scripts'. Standing on a block with the "toggle flag 1" effect might open a door, trigger a trap, spawn a boss or even all three, depending on what reads that flag in the current level.

That's on PC though, I guess the overhead might be a problem on the NES. I'd probably still use it anyway, just for the flexibility.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 9:05 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11010
Location: Rio de Janeiro - Brazil
If you want to make different bottomless pits lead to different places, you can simply have a list specifying the X coordinates where the destination changes, and what the destinations are (could even be death, despite the fact that making mortal dangers indistinguishable from passageways isn't a great game design choice). Then, when the player goes out of bounds, scan the list and stop when you find an X coordinate greater than the player's, and the destination before that is the one you should use.

If you want exits that are not out of the level's bounds, you can simply create an "exit" object, which can have the dimensions you need. If your object definitions are anything like mine, you'll have a parameter byte that each object type uses for a different purpose. For the "exit" object, this parameter could be the destination, if it fits in 8-bits, or the index of a more complex entry in a table of exits.


Top
 Profile  
 
PostPosted: Wed Aug 08, 2018 11:58 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
My current test maps maybe don't have anything complicated yet so I think I can get away with simple testing of location for the first phase until I define my real game. I just did some quick hack and was able to go from maps to maps based on everyone comments. Now I need to write the real thing. For the first testing, an out of bound check based on direction (up/down/left/right) and x location was just enough to do the job.

I think it is very uncommon for game like mega man to have bottomless pit and exit point pit in the same map so I guess that case was maybe overthinking and bad design, like you mentioned.


Top
 Profile  
 
PostPosted: Thu Aug 09, 2018 3:14 am 
Online
User avatar

Joined: Thu Sep 15, 2016 6:29 am
Posts: 819
Location: Denmark (PAL)
It's my impression that classic 8 bit games with this mechanic usually do it in one of two ways, depending on which makes sense for their game design:

1. Store your world/level data in a way that the game engine is able to automatically calculate which "room", etc. to load up depending on where you leave the previous one. Ie. if you fall through the floor of room A with an X coordinate of 729, you'll automatically spawn in the top of room B with the same X coordinate. This allows for really dynamic map design that makes more sense for the player, and it saves a lot of work defining exit and entry points.
Obviously there's a lot of overhead to this, and it requires you to design your game in a very specific way. It's definitely overkill if your game isn't a large sprawling metroidvania from the get-go. To get around the limitations, it might even be a good idea to combine with method #2

2. Simply define the exit point by coordinate limits. Eg. coordinate 0+: Room X, coordinate 600+: Room Y, etc. Though they probably exist, and it's definitely common in modern games, I don't recall seing any game of the NES era treating exits outside the bounderies of the level as "objects" in the level. (but if you have stuff like doors in the background they of course are)
Super Mario Bros. has a really primitive implitation of this mechanic, which is the reason for famous glitches like the minus world, or the green pipe to the 4-2 warp zone that speedrunners use. The exit location simply changes when the scoll coordinate progresses to a specific coordinate.


Top
 Profile  
 
PostPosted: Thu Aug 09, 2018 3:33 am 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 629
There is basically one method.

Volumes. You put down a "volume" and detect that the player entered it then warp as needed.

If you make separate AABB collision volumes and use them.
If you make Special collision data flags
If you make custom meta tiles that do it

Its all the same thing, just implementation details.

If you are limited to flags at 16. Do you have more than 16 per screen or "area". You can make them index into a "warp coords for this screen/map/node/portal/area"

If you don't use all your "metatiles/blocks" then you can say have F0 F1 F2 FX where X is the warp index etc


Top
 Profile  
 
PostPosted: Thu Aug 09, 2018 4:36 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
I think the trick with the metatile is an interesting one. I will keep that in mind. thanks!


Top
 Profile  
 
PostPosted: Thu Aug 09, 2018 8:38 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3141
Location: Tampere, Finland
If I wanted something quick, I'd use the object system for it (assuming you have one in place). Simply make an invisible object that checks for collisions against the player.

Depending on your game you might not want to waste an object slot for this though.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Thu Aug 09, 2018 9:20 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2119
Location: Fukuoka, Japan
For now the only entity that is managed is the main actor so no system is in place yet. Now that I'm getting close to a current milestone (transition between maps and basic but not perfect movement of main actor) I need to start to implement such system so I will keep that idea in mind too. Thanks!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google Adsense [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group