HintMachine / hintMachine

HintMachine is a program giving hints for your Archipelago games.
MIT License
9 stars 11 forks source link

New Game: Luck be a Landlord #19

Closed nbrochu closed 8 months ago

nbrochu commented 8 months ago

In this PR

image

Dinopony commented 8 months ago

Tested, it works perfectly, but I find the quest a bit too easy to spam by just playing bad & fast, since the first rent is kind of easy to pay.

I think raising the bar to 3 rents would make no real difference (since it would just push the problem further), we'd rather need a metric that encourages going into the late game and which works optimally while trying to win the game instead of losing on purpose.

I was thinking of a "Money spent" quest, where you would just have to track the money value using a HintQuestCumulative with DESCENDING order (this way, only a decrease in money value impacts the quest progress). It would encourage as a side effect to pick some "risky" symbols which lose you money before giving you more, which is a cool thing even though it doesn't really matter in the end. Since late-game rents cost significantly more than early-game ones, it makes the late game a bit more rewarding for the quest while keeping it straightforward enough.

nbrochu commented 8 months ago

OK I can try a different approach with Money Spent and see how it works

nbrochu commented 8 months ago

@Dinopony Has the DESCENDING direction been tested? It explodes horribly here when I try to use it. All my memory reading looks fine when debugging, but it freaks out when I pass the value to UpdateValue. I'm not sure how it's supposed to work when the initial value is max long... Pretend memoryReading is 1 here. It will literally set the current value to Max long - 1, which of course proceeds to unlock all hints in the world image

nbrochu commented 8 months ago

Wouldn't it be safer to start with an empty _lastMemoryReading, then set the value and early return on the first call to UpdateValue, and finally proceed as normal on further calls?

nbrochu commented 8 months ago

Also, isn't this even more cheesable than Rents Payments Made? If I have a lot of coins and reset the run, the value will drop to 0, causing sizeable progress to be granted for free

Dinopony commented 8 months ago

@nbrochu Indeed, as you have noticed the starting value is the problem here. We set the last memory reading to MaxValue initially because in an ASCENDING context, it makes the program "ignore" the first reading as some form of setup, so that it increases relatively to that first reading instead of relatively to zero. We should find a cleaner way to standardize this mechanism so it works both directions with one of those two approaches:

You can try either solution and it should make the DESCENDING case work as expected.

As for the "quit game to lose money" cheese, this indeed something that has to be considered and properly tested. Isn't there a boolean somewhere flipped to 1 when in-game, and 0 when outside of a game? If not, maybe look for a "next rent cost" variable in RAM, and only update quest If money value decreased exactly by the rent cost?

Dinopony commented 8 months ago

And if you're not too comfortable with editing the core classes, I can do the fix tomorrow. There's no pressure for you to contribute beyond game connectors, your work is already very welcome and appreciated 👍

nbrochu commented 8 months ago

I successfully changed the quest to Coins Spent instead of Rent Payments Made. I settled on a starter value of 375. It's definitely not a uniform unlock rate anymore (slow start but speeds up as you push further into a run) but you probably expected that when proposing that quest.

image

I also reworked some stuff in HintQuestCumulative. Changes to UpdateValue should be fine. I went with the nullable approach.

You will probably question ForceLastMemoryReading 😄 It's my simple way to work around run restart cheese. I don't think _lastMemoryReading should be publicly settable, but at the same time, there are some use cases where being able to force it to be a specific value helps. For this game, when the coin value is 1 or 0, I set _lastMemoryReading but skip calling UpdateValue. This fully circumvents the cheese. Upside is it's dead simple (I like simple approaches); downside is the first coin of a run is not counted. Up to you to decide if you are OK with that.

nbrochu commented 8 months ago

Other possibility: I go back to Rent Payments Made but don't count the first 2.

Dinopony commented 8 months ago

The modification for the nullable part is perfect 👍 As for the ForceLastMemoryReading, I think it might become necessary at some point but I don't feel like we need it right now. I don't like the result right now since it won't work if the player pays their rent while having 0 or 1 coin left at the end (quest update won't occur).


Instead, I did a little research and got a pointer path for the price of the current rent price:

image

The last one (highlighted) seems the best one, since it shares some common ground with the pointer you already have for the current gold value. During gameplay, this value seems to update (i.e. increase) before current golds are updated, which means it would require some complex mechanism to store the previous rent and so on... in the end I don't like it because I like simple and elegant solutions, just like you 😉


But, if we want to avoid game restarts to reset gold, we can check a variable which starts at 0 on game start and increases by 1 on each spin (essentially, a "Spin counter"). If gold decreased but spin counter decreased as well, it means the player restarted a new game. If it stayed equal or increased, it means we are in the normal flow of a game.

Here are pointer paths to that spin counter : image

I feel like using this would be pretty simple and gives a good hint on the global flow of the game, to notice if the player is actually playing or "breaking" that flow.

nbrochu commented 8 months ago

Alright, take three! I think this is good to go. I'm using the spin count to ignore the next value when a break in continuity is detected.

cc @Dinopony

Dinopony commented 8 months ago

It looks like it's working well indeed, finally we can celebrate! 😄