Spike & killtile talk (collision vs representation)

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Spike & killtile talk (collision vs representation)

Post by FrankenGraphics »

In the espinete thread, na_th_an wrote
While it may seem odd, I've been struggling to implement decent spikes since I began making games... I think it's about time I open a discussion in the dev forums about how you guys implement spikes and spiky objects, and how you make interact actors with them, 'cause I never seem to get them 100% right.
I find them tricky too. Especially tricky is when tiles are above ground, at the player characters' level. Here's some things you can do from a tile- and level design perspective, if lethal properties are decided on a per tile basis. Red colour shows kill pixels that are supposed to be air. If a tile contains black, that means it is nonlethal.
spikes.bmp
spikes.bmp (30.12 KiB) Viewed 9060 times


Fig. 1
This is subtle, but i'm adding a few pixels on top and to the sides to make the spike look slightly bigger than the kill area. It's no problem if you want to replace the sides with grass tufts here and there or some other bg tile , but the points are kind of important.
Cons:
-it's just a tiny nudge in the right direction

Fig. 2
Same as before, but placing lesser, non-lethal spikes on the sides. Player will jump prematurely, less risk of hitting unfair kill pixels, and they're within the diagonal line of the first (nonlethal) spike.
cons:
-player can walk a bit into the spikes without being killed. The game rules may feel a bit loose then.

Fig 3.
This shows two pretty airtight solutions to whenever a spike is below normal ground level. It feels very natural to have the player actually fall a distance before getting killed. The size of the spikes can be varied - if the player character overlaps them by some at kill time, the action looks better. Spending some time on it, i might've made the spikes a size between the two examples shown.

Fig 4.
One or a few bigger spikes in the middle helps the player evaluate the situation and jump appropriately, and the spikes become more visible.

Fig 5.
By offsetting the spikes so that they're off-centre, you can achieve the smoothest result. The kill pixels are only between sets of spikes this way, never at the edge of a spike field. Collision wise, this is almost perfect.
Con:
-You might have a bit of attribute clash and placement problems this way, but it can be worked around.
-My example is nonsymmetrically shifted. This should be more exact if the player comes form the left (often the case), but not as exact if coming from the right). You may want to even that out. As it is, it's debatable if the rightmost tile should be non-lethal as showed, or lethal.

Fig 6.
Same as 5, but with bigger spikes and a more even offset to both right and left. Again, falling a bit through spikes before getting killed looks more natural than getting killed directly on contact with the top of the spike. The tricky part here is balancing how much (the height of the spike) against not allowing any kill pixels outside the spike fields' borders.


Same goes for lava and the like, except it is easier since it's mostly a horizontal line.

None of these examples except maybe fig 1 cover circular or omni-directional kill tiles. 2x2 tile kill blocks hanging in the middle of the air are hard this way.


Other, non graphic-related methods on top of my head:

screen position checking:
If player_y (or x) is more/less than n, assume player is killed by spikes/lava. Metroid does this in horz scrolling rooms.
Pros:
-You can very precisely set the height when the damage/kill happens.
-You can also make it wave up and down along with some tile animation.
Cons:
-you may need to create exception clauses/attributes if you don't want it to be universal.
-no middle of the room placements, unless you want to do a lot of checks for every kill object on the level.

conditional sub-tile hit detection:
-if colliding with a kill tile (or meta-tile), try the player position against a hit mask. It doesn't need to be full 8x8 (or 16x16) granularity - 2x2 hit fields or the like might suffice. The amount of frames the player object is valid for these extra checks are few.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Spike & killtile talk (collision vs representation)

Post by tepples »

Or do what games like Prince of Persia do: check for spike damage only when the vertical velocity indicates having fallen onto them, and allow walking (slowly) through spikes. The latter represents stepping carefully around them.
User avatar
gauauu
Posts: 779
Joined: Sat Jan 09, 2016 9:21 pm
Location: Central Illinois, USA
Contact:

Re: Spike & killtile talk (collision vs representation)

Post by gauauu »

For traditional spikes, I prefer if they're never on a level floor, but always inset and lower, (figure 3 above) so it's never possible to brush against the spike from the side. So it becomes a level design fix.

That doesn't help with wall spikes or floating spiky-balls though.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Spike & killtile talk (collision vs representation)

Post by Bregalad »

Mega Man 2 has spikes where their graphic makes it obvious they're also dangerous from the sides - compare it with its direct predecessor where Mega Man can die from approaching sprites from the sides which is ridiculous (he's not even touching them, and not in the dangerous direction).
na_th_an
Posts: 558
Joined: Mon May 27, 2013 9:40 am

Re: Spike & killtile talk (collision vs representation)

Post by na_th_an »

Thanks for the posts. I'll study them carefully.

My main problem is to handle collision with floating spike balls or spiky objects in games where the player just loses a life but is not respawned. How you implement bouncing? I usually bounce the player in the axis with bigger velocity, but this seems to introduce a lot of complexity on how I handle movement and collisions and maybe my design is flawed.

I usually do collision checks in each axis separately (first vertical, then horizontal or the way around). I first test if the player has entered a non walkable tile, if it hasn't, I test if the player has entered a "killing" tile. I raise two flags, hit_v and hit_h in each check. Afterwards I handle the bounce, after both axes have been checked. It mainly works, but, how do you do it?

A different implementation I've used consists in not testing for "killing" tiles during the normal collisions checks per axis, but examining the kind of tile the center of the collision box is hitting, and register the hit and bounce the player in the axis with bigger velocity. It's not precise at all, but it works in some games where collisions needs to be more forgiving to make it playable.
Rahsennor
Posts: 479
Joined: Thu Aug 20, 2015 3:09 am

Re: Spike & killtile talk (collision vs representation)

Post by Rahsennor »

Never actually put spikes in a game, but I always end up making my collision systems distinguish individual sides of tiles anyway, so I'd only mark the pointy side as dangerous. Walking into the non-pointy sides would either act as a regular (safe) solid tile, or let the character enter the spike field harmlessly, Prince of Persia style.

If you've got one-way platforms (that you can stand on, but also jump up through) then you should already have everything you need to do floor spikes this way.
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Spike & killtile talk (collision vs representation)

Post by Sumez »

First of all, I'm not a fan of spikes/kill-tiles just freely sticking out of a floor like in most of these examples. To me it makes no sense to have an obstacle like this, that should be dedicated to something like a stationary enemy or such. I would always have them lowered in an inset like on figure 3, or on the ceiling, etc. Mega Man is a pretty good example.

That said, it of course depends entirely on your game design. Some games rely very little on enemies, but mostly on stage design, like Celeste, Super Meat Boy, etc. and they of course need to have spikes and such out in the open, so you still need to handle those situations right.

If you do have them out in the open, I consider something like figure 2 the best approach. You want the hurtbox of stuff like this to be lenient, especially for situations where you are expected to make tight jumps over groups of spikes, getting the experience of being a pixel further into a spike than you thought you could never makes for a fun game.
NEVER make the entire tile kill the player if the entire graphic is contained within the tile in a non-square manner (unless of course the spikes are placed in an inlet as discussed, at that point it doesn't matter).

It's a design question of course. Figure 1 is alright too, but I'm not a fan of the lethal area sticking out of the top left/right corners. If you want to have only one spike graphic for optimization reasons, either make the leftmost and rightmost tiles non-lethal (similar to figure 5), or only check on the center of the player's feet, as opposed to their entire hitbox.
Figure 4 is probably the best solution of them all, and it looks really good, but it also has a very stylized look to it that might not be fitting for every game.

Figure 6 is an issue because, as briefly discussed in other posts, it looks like the spikes aren't lethal from the sides. Most videogame savvy players will recognize the danger, but will probably end up doubting whether they are actually right, which can be an issue in a situation where it might actually make a difference.

tepples wrote:Or do what games like Prince of Persia do: check for spike damage only when the vertical velocity indicates having fallen onto them, and allow walking (slowly) through spikes. The latter represents stepping carefully around them.
This is a much broader design aspect. Prince of Persia is designed entirely around this level of realism, and it wouldn't make sense to do it like that in a typical arcade'y platformer, where simple consistency is much more important. Especially when the 2D side perspective doesn't indicate any depth allowing the player to visually step around them.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Spike & killtile talk (collision vs representation)

Post by FrankenGraphics »

Thanks for all the input, everybody.
sumez wrote:Figure 6 is an issue because, as briefly discussed in other posts, it looks like the spikes aren't lethal from the sides.
I agree, and i thought about it while drawing, but forgot to do something about it.
I think a good rule of thumb is to always have pointy ends protuding from a surface of lethality if the player can approach it from it, in case the object in question doesn't look like a sharp edge without doubt. The waved shading make my example spikes look conical, which is the wrong sort of materiality for this context. So, something like this would work better:
fig_7.png
fig_7.png (1.54 KiB) Viewed 8852 times
In this version, the player will litterally have to run through the pointy things on the side to get to the lethal tile, so there will be visual proof of the trespass.

sumez wrote:That said, it of course depends entirely on your game design.
Yes! I think spikes above ground are commonly avoided in many games because it is trickier to get right. with a limited tile/metatile economy and a coarse hit detection, it can be challenging to portray surfaces/bodies of lethality adequately on all sides, than if the kill tiles are simply lowered into a pit. So they aren't inherently bad - just harder to implement. "Death pit" spikes are the failsafe goto option if you want nothing more varied from your platforming challenge, and not much can be discussed on those except they simply work and should be considered. What i really want to discuss are the trickier options, because sometimes, maneuvering varied damage/death tile challanges is precicely what you want to design. Hence the focus on "above floor" type spikes in the example nametable i uploaded.

gauauu wrote:That doesn't help with wall spikes or floating spiky-balls though
&
na_th_an wrote:My main problem is to handle collision with floating spike balls
Int's not a solve-all solution, but Area 3 of Project Blue solved floating damage balls by using sprite based objects (looks like round anti-ship mines, 2 by 2 tiles). That means we can't keep a lot of them on screen, but i found that we don't need too either.

Speaking of project blue, i'm currently doing another pass going over some very spiky sections of area 2 right now to make them less brutal. This was prompted because of a new and more nuanced checkpoint system that differentiates checkpoints for losing a life and checkpoints for losing all lives - which means you can't brute-force rooms as much any more. You'll want to hang on to your extra lives a bit more, even if the setback for losing all of them is still less than most classic nes games. The level is sort of themed around concrete debris, with pointy rebar being very prominent on some screens.

Here's one draft room where i think the spikes are all addequately safe. Payer comes from either bottom left or top left depending on if they took a shortcut or not. (Not shown is some sprite objects that make it impossible to go from the top left to the bottom left - it's a unidirectional passage. The first challenge (if from the bottom right) is to grab the ladder over the inset/lower spike field. The second challenge have some sharp things protuding above ground, but the player must make a jump to get there in the first place, and the jump is quite easy to make - just a little nerve tingling. The leftmost diagonal rebar is actually not marked for hurting, which is a bit wonky compromise in the players' favour
Screen18.png
Screen18.png (7.81 KiB) Viewed 8852 times
.
na_th_an wrote:but examining the kind of tile the center of the collision box is hitting, and register the hit and bounce the player in the axis with bigger velocity. It's not precise at all, but it works in some games where collisions needs to be more forgiving to make it playable.
This sounds like it'd work really well for small player objects, 2-by-2 tiles or so. For it to be exact center (meaning the same depth of overlap from all sides, if that's deemed important), the bounding box shoild probably be an odd amount of pixels.
bregalad wrote:Mega Man 2 has spikes where their graphic makes it obvious they're also dangerous from the sides - compare it with its direct predecessor where Mega Man can die from approaching sprites from the sides which is ridiculous (he's not even touching them, and not in the dangerous direction).
I've honestly not played enough mega man to know what you're referring to, but i'm imagining the difference is a bit like the one above? I'll take a look at some point.

Edit:
sumez wrote:NEVER make the entire tile kill the player if the entire graphic is contained within the tile in a non-square manner (unless of course the spikes are placed in an inlet as discussed, at that point it doesn't matter
I would like to extend the exception to this rule to whenever there is significant, immediate proof that the player would be hurt/dead anyway at that position and trajectory within one-two frames or so. The player has already noted the characters' fate at that ppint. It's just the cases where it looks like you could've passed over (or under) that are aggravating. The challenge then becomes to ensure that the level is built so that the aggravating cases don't happen or at least are hard and unintuitive for the player to make happen.
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: Spike & killtile talk (collision vs representation)

Post by Sumez »

FrankenGraphics wrote:So they aren't inherently bad - just harder to implement. "Death pit" spikes are the failsafe goto option if you want nothing more varied from your platforming challenge
I wasn't really thinking in terms of how hard they are to implement well. Though that's definitely an issue, I just don't think the idea of being able to run directly into a death trap is particularly entertaining for anything other than a game designed already entirely around evading death traps (again, stuff like Super Meat Boy and similar precision platformers). I think most of na_th_an's games fall into that category, though.
3gengames
Formerly 65024U
Posts: 2284
Joined: Sat Mar 27, 2010 12:57 pm

Re: Spike & killtile talk (collision vs representation)

Post by 3gengames »

Dumb optimization idea, spawn an object and handle the hit detection against it with it in object code, and then just put background tiles as graphics like normal and remember when moved to re-adjust object data.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Spike & killtile talk (collision vs representation)

Post by FrankenGraphics »

Interesting. So then a collision with the tile associated with the "hurt property" (or whatever you want them to mean) is simply the conditional to not branch past the spawning of the temporary object. Different tile or metatile ID:s or a modulo of the same can be used to point to different x/y radius properties in a LUT.
3gengames
Formerly 65024U
Posts: 2284
Joined: Sat Mar 27, 2010 12:57 pm

Re: Spike & killtile talk (collision vs representation)

Post by 3gengames »

That's the sorta idea I had. That way if you don't save all tile info in another huge table of RAM you can still decide if they're hurt without as much math, but more objects to process, which I think it cheaper I'd bet.
Post Reply