Sign in to follow this  

Handling a trap room in a zelda-like game

This topic is 2330 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is a very specific question, so maybe I can't provide you with enough information to help me solve the problem.

It's an issue of triggers and events.

I have triggers that have a condition and events to fire off.
I have a Trigger Handler that sends events to active triggers.
The triggers check the event against their condition and if the condition is met, it fires off its events.

My world consists of a bunch of rooms. Each room can have triggers in it that are moved into the TriggerHandler when the player enters.

I have trap rooms that have an area trigger that closes all exits. These rooms also have kill count triggers that opens the doors when all enemies are killed.

It all works splendidly.

The problem reveals itself when the player dies or saves the game in a closed trap room. Now the doors are closed when the player returns, and so they can't enter.
I figure I could maybe solve the death issue by having a PlayerDiedTrigger that opens all doors in the room and resets the triggers.

Saving feels more difficult. There are other doors that need their states saved, so I have to save whether they are closed or not. Not only that, but I have to save the state of the triggers too (I don't want the player to have to redo the trap rooms they've cleared), so even if I manage to reset the doors with some ugly myShouldResetWhenLoaded flag, the trigger that closes the doors has already been triggered.

I can probably figure something out, but it feels as if any solution I come up with is ugly as hell. I don't expect anyone to know an exact solution, but maybe someone could point me in the right direction?

Share this post


Link to post
Share on other sites
Ah, maybe the missing piece of information is that upon loading a saved game or dying, the player is returned to the entrance of the dungeon.

So if the player saves the game in a room where the exits have been sealed, there's no longer any way in there and the dungeon is unsolvable. And if I write code to force the doors to open somehow, the area trigger that seals the exits is no longer active, so the player would have bypassed the trap room without having to fight.

I'm starting to consider just putting a isTrapRoom-flag in the room and solve it that way, but I have a feeling that'll lead me on a path where rooms have a bazillion update and activation functions depending on their combination of isTrapRoom, isShop, isInside, isUpsideDown, isDirty, isDangerousToGoats and smellsOfElderberries flags...

Share this post


Link to post
Share on other sites
I still don't see what the problem is. What's wrong with saving the states of both the triggers and the doors?


[edit] Never mind, I see. Answer pending.


[edit 2] What I would do is simply not save the states of doors [i]or[/i] door lock triggers at all. This way, when the player re-enters the dungeon, either via death or save/load, the dungeon returns to its original state with regard to trap doors. Monsters and items can still be saved off, though, so it's possible for the player to partially complete a dungeon and then revisit it entirely, but not abuse the system by just respawning a lot and gobbling up dupe items/monster XP.

Share this post


Link to post
Share on other sites
And if you kind of cheat in this.... if the player saves in the locked doors room, when he loads he returns a little before entering the room, behaving like a checkpoint

It's something a lot of games do and is actually [i]easier [/i]than saving inside....

[Edit]

Oh sorry, didn't pay attention to the "return to the entrance" part...

ApochPiQ way of doing it is good. You stay kind of "saved" in the instance until you finish it

Edit 2:

Thinking of it by a moment.... if you are using a database, you could have 2-3 columns:

enteredDoorLock
passedDoorLock

This way you can check if the player already entered in the locked room, and if he passed it. Thus restoring the dungeon "should be a brezze"

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1311636080' post='4840253']
What I would do is simply not save the states of doors [i]or[/i] door lock triggers at all. This way, when the player re-enters the dungeon, either via death or save/load, the dungeon returns to its original state with regard to trap doors. Monsters and items can still be saved off, though, so it's possible for the player to partially complete a dungeon and then revisit it entirely, but not abuse the system by just respawning a lot and gobbling up dupe items/monster XP.
[/quote]

That would probably work for the trap rooms specifically, but there are also doors which are opened by keys that the player picks up. The dungeons can grow quite large, and forcing the players to find the keys for all the doors every time they die seems rather... brutal. So the state of some doors must be saved.

There's always the option of special-casing the doors, I guess, and not saving the state of the trap doors, but then I instead run the risk of having a billion different door types in the end, instead of a billion different room types.

It feels like there must be a more general way of doing this without changing the game design around.

[quote name='Mauricio Cinelli' timestamp='1311636444' post='4840256']
Thinking of it by a moment.... if you are using a database, you could have 2-3 columns:

enteredDoorLock
passedDoorLock

This way you can check if the player already entered in the locked room, and if he passed it. Thus restoring the dungeon "should be a brezze"
[/quote]

If I understand correctly (I'm not using a database and have no experience with doing so), that means I must tag the room as locked instead of relying on a more general system of triggers and events. I'm leaning towards your solution, but I'm not very happy with it, as it'll mean that if I want to create other types of rooms later, that means a bunch of special cases for each one, instead of just adding other triggers.
Then again, I could luck out and realize that the trap rooms are the only special cases, in which case I'm wasting my time thinking about this too much. :rolleyes:

Share this post


Link to post
Share on other sites
what happens if the guy never finish the dungeon?

I mean, he started, picked like 10 keys, died and didn't play this dungeon again.

These keys disappear after using them?
The player keep them forever?

It's two different situations with different approaches

[Edit]

Is it a single player game?

Share this post


Link to post
Share on other sites
But isn't a door-unlocked-by-key a different concept than door-locked-by-trap?

I see no reason why they should behave the same from a code or design standpoint; instead, I'd say that you classify door behavior based precisely on how gameplay rules say it should work. If the door is key-activated, store its state. If a door is trap-activated, don't.

More generally, you really only have two "types" of doors here: those that retain their locked state, and those that reset. Those binary choices cover all possibilities of how door-lock-state-serialization should work, so in the specific case where your code needs to decide whether or not to save a door's lock state, you only have to worry about two categories. Then, as you add different types of door to the mix, they always fall into one of these two buckets, so as far as lock-state-saving goes, nothing ever gets more complicated.

Obviously if you favor a lot of inheritance this doesn't work nicely, because you have IDoorSavesLockState and IDoorCanBeDamaged and IDoorWhatever and ten million other things. This is where composition and tagging become far superior approaches to describing the behavior of game objects.

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1311638517' post='4840277']
But isn't a door-unlocked-by-key a different concept than door-locked-by-trap?

I see no reason why they should behave the same from a code or design standpoint; instead, I'd say that you classify door behavior based precisely on how gameplay rules say it should work. If the door is key-activated, store its state. If a door is trap-activated, don't.

More generally, you really only have two "types" of doors here: those that retain their locked state, and those that reset. Those binary choices cover all possibilities of how door-lock-state-serialization should work, so in the specific case where your code needs to decide whether or not to save a door's lock state, you only have to worry about two categories. Then, as you add different types of door to the mix, they always fall into one of these two buckets, so as far as lock-state-saving goes, nothing ever gets more complicated.

Obviously if you favor a lot of inheritance this doesn't work nicely, because you have IDoorSavesLockState and IDoorCanBeDamaged and IDoorWhatever and ten million other things. This is where composition and tagging become far superior approaches to describing the behavior of game objects.
[/quote]

Sure. And in the code side you can have some generic events and triggers for these categories. But will inheritance don't work if one door inherits only one type of door? I don't see much problems.. but i might be wrong

Share this post


Link to post
Share on other sites
Suppose my game design calls for a door which:

[list][*]Can be opened with a key[*]Can be destroyed by weapons[*]Can be opened via a specific magic spell[*]Can lock itself again based on triggering a trap[*]Changes color occasionally[/list]

Then I need another door that has all of those, except it is immune to magic.

Then there's a third door in the game which can [i]only[/i][b] [/b]be opened with magic or keys, but not destroyed by weapons.

And maybe I also want a door for the final boss chamber that doesn't open until I reach a certain point in the story.


As soon as you describe your objects and their capabilities in terms of inheritance, you create a maintenance hell. Extending the class hierarchy to support all those different combinations of behavior is going to [b]suck[/b].

Hence: use composition or tagging (aka data-driven modeling).

Share this post


Link to post
Share on other sites
[quote name='Mauricio Cinelli' timestamp='1311638058' post='4840270']
what happens if the guy never finish the dungeon?

I mean, he started, picked like 10 keys, died and didn't play this dungeon again.

These keys disappear after using them?
The player keep them forever?

It's two different situations with different approaches

[Edit]

Is it a single player game?
[/quote]

The player must beat all the dungeons to complete the game, and the keys are only valid inside the dungeon they belong. That's not an issue as far as I can see.
And yes, it's single player.

[quote name='ApochPiQ' timestamp='1311638517' post='4840277']
But isn't a door-unlocked-by-key a different concept than door-locked-by-trap?

I see no reason why they should behave the same from a code or design standpoint; instead, I'd say that you classify door behavior based precisely on how gameplay rules say it should work. If the door is key-activated, store its state. If a door is trap-activated, don't.

More generally, you really only have two "types" of doors here: those that retain their locked state, and those that reset. Those binary choices cover all possibilities of how door-lock-state-serialization should work, so in the specific case where your code needs to decide whether or not to save a door's lock state, you only have to worry about two categories. Then, as you add different types of door to the mix, they always fall into one of these two buckets, so as far as lock-state-saving goes, nothing ever gets more complicated.

Obviously if you favor a lot of inheritance this doesn't work nicely, because you have IDoorSavesLockState and IDoorCanBeDamaged and IDoorWhatever and ten million other things. This is where composition and tagging become far superior approaches to describing the behavior of game objects.
[/quote]

The two types of doors share the majority of their code. The only difference is their visual representation, and a check upon collision. The trap doors are also not really defined as being locked by traps (any door could be closed by any trigger or event) but rather as not being unlockable by keys. They simply block the player's path until they manage to fire off the correct event. But it's only in the case of trap rooms where they'll run the risk of making the dungeon unsolvable.

You're correct about the door saving being simple enough I guess, but the triggers are a lot messier for me to wrap my head around. For trap rooms specifically I could probably just not save them, but I'll definitely have to save other trigger elsewhere in the dungeon. The "two bucket" concept works here too, but seems a lot messier.

I'll sleep on iy now and return if I still can't solve it tomorrow. Thank you. :)

Share this post


Link to post
Share on other sites
[quote name='ApochPiQ' timestamp='1311640587' post='4840293']
Suppose my game design calls for a door which:

[list][*]Can be opened with a key[*]Can be destroyed by weapons[*]Can be opened via a specific magic spell[*]Can lock itself again based on triggering a trap[*]Changes color occasionally[/list]

Then I need another door that has all of those, except it is immune to magic.

Then there's a third door in the game which can [i]only[/i][b] [/b]be opened with magic or keys, but not destroyed by weapons.

And maybe I also want a door for the final boss chamber that doesn't open until I reach a certain point in the story.


As soon as you describe your objects and their capabilities in terms of inheritance, you create a maintenance hell. Extending the class hierarchy to support all those different combinations of behavior is going to [b]suck[/b].

Hence: use composition or tagging (aka data-driven modeling).
[/quote]

Can't agree more with you, and I see your point about inheritance now. Yeah, it become hell as more things gets put together.

The use of composition or tagging is indeed the best option.[img]http://public.gamedev.net/public/style_emoticons/default/laugh.gif[/img]

Share this post


Link to post
Share on other sites
I think I've come up with a solution that works for me.
I use a isTrap-flag for the room. Upon entering such a room, all doors are opened and the triggers are reset. Upon clearing a trap room, the isTrapFlag is set to false, so nothing is reset the next time you enter.
So I guess it closely resembles the database idea. Thanks people! :)

Share this post


Link to post
Share on other sites
[quote name='Exorph' timestamp='1311690504' post='4840548']
I think I've come up with a solution that works for me.
I use a isTrap-flag for the room. Upon entering such a room, all doors are opened and the triggers are reset. Upon clearing a trap room, the isTrapFlag is set to false, so nothing is reset the next time you enter.
So I guess it closely resembles the database idea. Thanks people! :)
[/quote]

Nice, just make sure you have another flag or something that says that you have already cleared that room, so the trap won't "execute" again, if you die or something....

Good luck. Hope we could help you.

Share this post


Link to post
Share on other sites
[quote name='Mauricio Cinelli' timestamp='1311691099' post='4840555']
Nice, just make sure you have another flag or something that says that you have already cleared that room, so the trap won't "execute" again, if you die or something....
[/quote]

Am I missing something?
As far as I can tell, by doing it my way a trap room is only going to execute if you haven't already cleared it.

Enter room -> trap is reset and executes -> kill enemies -> doors are opened -> trap flag is removed -> enter again -> room is no longer a trap and nothing happens

Enter room -> trap is reset and executes -> die -> return -> trap is reset and executes

Share this post


Link to post
Share on other sites
[quote name='Exorph' timestamp='1311695002' post='4840594']
[quote name='Mauricio Cinelli' timestamp='1311691099' post='4840555']
Nice, just make sure you have another flag or something that says that you have already cleared that room, so the trap won't "execute" again, if you die or something....
[/quote]

Am I missing something?
As far as I can tell, by doing it my way a trap room is only going to execute if you haven't already cleared it.

Enter room -> trap is reset and executes -> kill enemies -> doors are opened -> trap flag is removed -> enter again -> room is no longer a trap and nothing happens

Enter room -> trap is reset and executes -> die -> return -> trap is reset and executes
[/quote]



Oh, i see. Your way is fine... i didn't understand you were to REMOVE the flag from the room.

guess this way it'll work fine. SOrry for my confusion

Share this post


Link to post
Share on other sites
No problem, my head has been spinning around this problem for two days straight now and I was just worried I was missing something obvious.
It seems like it's been solved now, and I can finally move on to new tasks. :D

Share this post


Link to post
Share on other sites

This topic is 2330 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this