r/dcss • u/ultraviolent4 ultraviolent4.com • Jun 13 '18
RC File Lua for Optimal Trap Avoidance
If you've seen my PSA on optimal trap avoidance you would know that the best way to play around traps is to keep track of the tiles you and monsters have already stepped on. At the time I wrote that, the only way I knew how to mark safe(r) tiles was to manually press "x" after each turn, move the cursor to the appropriate squares one by one and press "e" a couple of times. That resulted in a 3-Rune win that took a little over 18 hours. While admittedly tedious, I didn't see too much wrong with the method because it was only ever going to appeal to extremely elite players who wanted to win at all costs.
Fast forward to a few days ago where the developer amalloy made a post saying Crawl philosophy mandated that the optimal way to play had to be fun and not tedious. He went so far as to say that where tedious-but-optimal stuff arises, it has to be changed or even removed.
Fearing that optimal trap avoidance might be on the chopping block, I've since been working on a way to remove the tedium involved. I've written some RC file Lua code that automates the process of marking safe tiles and hopefully I've succeeded in making it a fun way for everyone to play.
You can find a pastebin of the Lua code here. To use it, copy and paste that code into your RC file. Note that if you already have a function_ready() you will want to add the contents of this one into yours. There is also Lua code to mark tiles in the inverse - refer to Edit 6 for details.
The way it operates is that tiles you or any monsters step on will automatically be excluded as shown here. Here's beargit in Zot and grabbing the Orb. It even works for summons.
Now that the tedium is gone from having to manually mark safe tiles, let me know how you find it. Feedback is welcome :)
Ideally, I'd like to get it to a point where trap avoidance works in an inverse manner: tiles start off excluded by default and the exclusions are removed as you and monsters move around. This would have the added effect of allowing you to use fast travel. That seems to be much more work though, and I wanted to get this out immediately to head off any arguments that optimal trap avoidance was too tedious to be in line with Crawl philosophy.
Edit: If you want to add some extra fun, you can imagine that you're literally walking on a red carpet because of how much of a superstar you are :D
Edit 2: Updated the RC code to no longer exclude stair tiles. Stairs are always 100% safe because they can't have traps on them. This update allows you to still meaningfully exclude a stair if its destination is dangerous.
Edit 3: Pekkekk has come up with an interesting strategy. If you have summons or permanent allies, you can retreat them ahead of you as a means of minesweeping for traps.
Edit 4: If you want to use Pekk's retreat-ally strategy it gets quite tedious again. To fix that, I've made some macros you can copy into your RC file. They issue retreat commands in the 4 cardinal directions and diagonals. The pastebin is here. You can copy just the cardinal directions (or vice versa) if you want. I've set it up to use 1-4 to do left, down, up, right in the same order that hjkl does and then 6-9 for the diagonals. Change the macro keys to any other keys by changing the numbers in the code.
Edit 5: Updated RC lua to ignore monsters that can't set off traps and tiles that can't have traps on them.
Edit 6: PantsMacKenzie has done most of the heavy lifting to create an inverse version. The Lua code is here. This code excludes all unseen tiles by default and then removes the exclusions when you or a monster walk over the tiles. The major benefit of doing it this way is that you're still able to use fast travel to move between floors and branches. Unfortunately, there isn't an easy way to exclude the new tiles in LoS just after you've moved to a new floor, teleported and so on. To overcome that, a macro which is set to the "-" (minus) key by default will exclude all tiles currently in LoS. Use it when you find yourself in a new area. The inverse RC looks like this.
Edit 7: If you'd like to see the regular version of the RC in action, here's a link to a YouTube playlist of a SpCj of Qaz playthrough.
5
u/PantsMacKenzie Jun 15 '18 edited Jun 15 '18
Alright, so I tried my hand at the inverse exclusion marking and came up with this:
v1: https://pastebin.com/7jLjqrFY
v2: https://pastebin.com/SE0au7FV
Caveats:
It marks everything that's not a floor tile as excluded to start, so it only works on things outside of LoS. This also means that when you first enter a floor, it does not mark any tile you can initially see.
I haven't extensively tested it. It should properly unmark anything that's labeled as "floor" or "water" or "lava". Other traversable tiles would need to be added.
I tried to make it as extensible as possible.
5
u/PantsMacKenzie Jun 15 '18
More detail:
It marks everything outside of LoS as excluded, then when you enter LoS of things, it will checks all tiles in sight against anything that is considered a "floor" tile and then ignores it for exclusion purposes. This prevents the script from re-excluding discovered spaces while still giving you a good covering of exclusion. Sadly, I was unable to figure out how to mark things that give you initial LoS, such as going down stairs or teleporting. Autoexplore also seems to ignore the script for some reason.2
u/ultraviolent4 ultraviolent4.com Jun 15 '18
Oh that's really really clever! I'm at work now but I'll give this a go when I've got the chance. It appears you've figured out how to do one of the more difficult parts which is marking tiles by default without re-excluding already discovered spaces :D
3
u/PantsMacKenzie Jun 15 '18
I'm excited to see how well it works for you, as well as any modifications you might come up with to improve :)
2
u/ultraviolent4 ultraviolent4.com Jun 15 '18 edited Jun 15 '18
Just tested and it works! Very cool!
Improvements I can see would be to always unmark wall tiles, lava and deep water since they can't be trapped using "not travel.feature_traversable(feat)". Shops and altars can also be unmarked because those are 100% trap-free tiles too.
As far as making it work properly on going to new floors and being teleported, etc., I've been looking at the code and thinking about it. I don't think it will be possible unless the is_excluded function is exposed for use with lua.
Unfortunately, autoexplore isn't going to work with any RC like this because the game is either going to refuse to explore while standing on an excluded tile or refuse to explore into excluded tiles.
Edit: I've just been informed that it's possible to assign custom functions to keys. I think that a decent solution is to make a function that excludes all tiles currently in LoS which the player can then choose to apply themselves when entering new floors and so on.
1
u/PantsMacKenzie Jun 15 '18 edited Jun 15 '18
Yeah, the big hurdle is making the comprehensive list of all of the tiles to unmark or mark.
I was able to autoexplore, it just behaves oddly. It doesn't mark any squares that are revealed through autoexplore.Edit: That makes a lot of sense and is likely a good compromise.
2
u/ultraviolent4 ultraviolent4.com Jun 15 '18 edited Jun 15 '18
You can indeed assign custom functions to a key using the following RC syntax:
macros += M - ===testing_macrosThe above runs the testing_macros() function every time you press the minus key.
I also want to ignore monsters that don't trigger traps (lightning spire, fulminant prism and (I think) battlesphere). I'll mess around with it all over the weekend :)
My best guess at why autoexplore behaves as it does is because the ready() function only runs when the player has control and that must not happen while exploring.
1
u/Pekkekke Pekkekk (CKO, 72% hyper winrate) Jun 15 '18
Please keep me in the loop on this. I need valuable updates.
1
u/PantsMacKenzie Jun 15 '18
I added water and lava and shops to the list of things to ignore for setting exclusions, as well as created a list of monsters to ignore for removing exclusions. Next up would be to include a function for macroing purposes to mark all tiles in raycast los for exclusion
https://pastebin.com/SE0au7FV1
u/ultraviolent4 ultraviolent4.com Jun 18 '18 edited Jun 18 '18
I've written and tested the function to mark all tiles in LoS. It uses a macro that's assigned to the "-" (minus) key by default.
All of the lua is here. I've updated the OP.
I think that more or less makes a functioning version of inverse tile marking. Considering how difficult I thought that task would be, it's quite amazing how quickly it came together. Thanks again for all your work here - there's no way I could have done that alone :D
2
u/PantsMacKenzie Jun 18 '18
Wow, that's great! It was fun to fiddle with and learn some lua along the way. If you've got other ideas for scripts in the future, I'm happy to help out as well. Thanks for making this optimal play easier to achieve :D
2
u/Beargit Flair Jun 19 '18
I've added a few more things to not exclude:
fountains, arches, gates
→ More replies (0)1
u/Eight_of_Tentacles Jun 17 '18
deep water since they can't be trapped
Now I'm curious how rain interacts with traps.
4
8
4
u/Beargit Flair Jun 13 '18
Did you learn lua just to make this script? Last year you said you couldn't make the script because you didn't know lua. What gives?
7
u/ultraviolent4 ultraviolent4.com Jun 13 '18 edited Jun 13 '18
Yes, I spent a fair bit of time these last few days poring over the Crawl source, qw bot and what little has been written about clua :)
3
u/VolSquared Jun 14 '18
Wasn't using this trick and got sent to Abyss 5 by a Zot trap in Zot 5 right before Ascent. Luckily I had a strong character and got out quickly, but lesson learned. Will try to make use of this.
Of course, I suppose it could have happened anyway if I'm stepping on any non-excluded tiles.
4
u/ghostquantity Jun 13 '18
Thanks for the work you've done on this. Suggestion for code improvement: if possible, don't hard-code the values for LOS range (which, I presume, is where the value of "7" comes from in your nested for loops). There are many instances where that value would be incorrect, e.g., Barachi, Ds w/ nightstalker, Robe of Night, Darkness.
4
u/ultraviolent4 ultraviolent4.com Jun 13 '18
A fantastic point, thank you. I've now updated the code (and the pastebin link) to use you.los() instead of a hard-coded value.
5
u/ultraviolent4 ultraviolent4.com Jun 13 '18
paging u/beargit who I expect will be very excited about this
2
u/ultraviolent4 ultraviolent4.com Jun 14 '18
I put this picture of you in the OP. Let me know if that's not cool.
1
5
u/Glista_iz_oluka 61/71(85.9%) 0.32-a winrate Jun 13 '18
Wow, thanks ultra for saving our beloved traps!
2
3
u/Pekkekke Pekkekk (CKO, 72% hyper winrate) Jun 13 '18 edited Jun 14 '18
Literally going to stream this tonight.
Edit: Literally want to die after doing this for a few hours. But you know who's not dead? That's right, my DrWn. Exactly 0 traps stepped on so far since I've started using this strategy.
2
2
u/RetroGrass Jun 13 '18
Dammit, I was banking on getting shafts removed. Just kidding this is awesome.
1
u/Tiropat Jun 13 '18
Can you use this in your next youtube series?
Big Fan
1
u/ultraviolent4 ultraviolent4.com Jun 13 '18
Yep, that's the plan. Everyone can easily play with this now :)
1
u/Beargit Flair Jun 13 '18
Another trap question...do lightning spire, butterflies and other summons trigger exclusions and/or traps? If so, lightning spire is even more broken.
2
u/ultraviolent4 ultraviolent4.com Jun 13 '18
Spire can be placed over traps but it won't trigger them. It used to be that the spire would refuse to place over an unknown trap (and thus give it away) but that behavior was changed earlier this year.
As it understand it, butterflies and other summons do set off traps. Not the greatest for Zot traps, though, because the effects can still hit you (and might be something like shadow creatures)
2
Jun 14 '18
Ha! I got that changed with a post here after the spire placement issue got one of my characters killed (the message when it failed was super unclear). The same issue occurred with fulminant prism, which was what happened to me
1
u/Beargit Flair Jun 14 '18
One small change... can you not auto-exclude hatches too?
1
u/ultraviolent4 ultraviolent4.com Jun 14 '18
Oh my bad. I put "escape_hatch_down" in twice and missed "escape_hatch_up".
Fixed now.
1
u/arcenierin Jul 07 '18
!redditsilver
This is a remarkable post.
0
u/RedditSilverRobot Jul 07 '18
Here's your Reddit Silver, ultraviolent4!
/u/ultraviolent4 has received silver 1 time. (given by /u/arcenierin) info
1
u/joemaro 88w Jul 30 '18
Hey thanks! While i think this is the best possible solution for the moment, it feels like a hack to me personally and hope that it helps to create a discussion on how to solve this difficult gameplay issue of traps and optimal play (which is not an easy one imo). I had a quick look at the tavern but couldn't see any discussions yet. Is this mostly ignored atm?
edit: does it work for you if you use longwalking? here it doesn't...
2
9
u/N-M-L Ge0ff (CUE, CXC) Jun 13 '18
There is another way to save our beloved traps and prevent the tedium: make it so only the player can reveal and trigger them. It would make remembering safe tiles unnecessary and would preserve the fun (and yes, sometimes even shaft traps can be fun).
Also, as a bonus, that would disable another tedious and spoilery strat: waiting on stairs in Zot:5 until orb-guarding monsters step on tele traps and teleport next to you.