yairm210 / Unciv

Open-source Android/Desktop remake of Civ V
Mozilla Public License 2.0
8.26k stars 1.55k forks source link

"Provides [amount] [stockpiled resource] <in [tileFilter] tiles>" not working in non-[Fresh water] tiles #11707

Closed SpacedOutChicken closed 1 month ago

SpacedOutChicken commented 2 months ago

Is there an existing issue for this?

Game Version

4.11.17

Describe the bug

I've attempted to design an improvement that provides a stockpiled resource but which behaves differently in tiles that aren't adjacent to fresh water. I used this unique: "Provides [1] [Stuff] <in [non-[Fresh water]] tiles>" So far, it isn't working. The improvement provides the same Stuff in both Fresh water and non-Fresh water tiles.

Steps to Reproduce

This mod contains the improvement of "Stuff maker" that includes the above unique. ResourceTile.zip

Screenshots

No response

Link to save file

No response

Operating System

Windows

Additional Information

My ultimate intention is to actually make an improvement that costs the resource in tiles that aren't next to Fresh water. For that, I've written it as "Provides [-1] [H2O] <in [non-[Fresh water]] tiles>" but I ran into the same problem.

yairm210 commented 2 months ago

There's a "tile checkfilter" command, can you use that to check the filters?

SpacedOutChicken commented 2 months ago

I don't know how to use the console. Is there a guide for doing so?

yairm210 commented 2 months ago

https://yairm210.github.io/Unciv/Modders/Scenarios/#console

SpacedOutChicken commented 2 months ago

I've got the console open, but I can't make any sense of what I'm seeing. What should I be putting into the check, and what results should I be expecting?

Sorry if this is a dumb question.

SomeTroglodyte commented 2 months ago

tile checkfilter "non-[Fresh water]" I'd guess (select the tile to test outside the console first), as that is the part declared to be a "tileFilter" in the Uniques dox. Needs quotes and proper casing to be meaningful. I'd bet it's the lowercase 'w' - or otherwise the parser not understanding nested brackets.

Seems to me "Fresh water" vs "Fresh Water" vs "non-[Fresh Water]" vs "non-fresh water" is still not handled well... But how else can we reliably differentiate a water source from "supports a consumer"?

yairm210 commented 2 months ago

There was a problem in the checkfilter command, now fixed That aside, checked, your exact unique is working absolutely fine for me I confuse

SpacedOutChicken commented 2 months ago

When you build the improvement with the "Provides [1] [Stuff] <in [non-[Fresh water]] tiles>" unique in Fresh water tiles, does it still provide the stockpiled resource? Based on how I'm reading the unique, it shouldn't be doing that, but when I test it on my end, it's still doing exactly that. The "Stuff maker" makes the same stuff in Fresh water as it does in non-[Fresh water] and it's not supposed to be doing that.

yairm210 commented 2 months ago

Nope, it's working, and I even have a test to reproduce it


    @Test
    fun CityResourcesFromImprovementWithConditional() {
        // given
        val resource = game.createResource(UniqueType.CityResource.text)
        val resourceImprovement = game.createTileImprovement("Provides [2] [${resource.name}] <in [non-[Fresh water]] tiles>")
        game.getTile(1,1).addTerrainFeature("Oasis")

        // when
        game.getTile(1,1).setImprovement(resourceImprovement.name)

        // then
        val resourceAmountInCapital = city.getAvailableResourceAmount(resource.name)
        assert(resourceAmountInCapital == 0)
    }
yairm210 commented 2 months ago

And without the oasis it provides the resources


    @Test
    fun CityResourcesFromImprovementWithConditional() {
        // given
        val resource = game.createResource(UniqueType.CityResource.text)
        val resourceImprovement = game.createTileImprovement("Provides [2] [${resource.name}] <in [non-[Fresh water]] tiles>")

        // when
        game.getTile(1,1).setImprovement(resourceImprovement.name)

        // then
        val resourceAmountInCapital = city.getAvailableResourceAmount(resource.name)
        assert(resourceAmountInCapital == 2)
    }
SpacedOutChicken commented 2 months ago

I don't know what's going on, but I swear that it's not working on my end. I'm using 4.11.19-patch1 and it's still not doing for me what it's doing for you.

Can someone else test this, and see if the problem is just on my machine?

SpacedOutChicken commented 2 months ago

I tried it out on Android, currently running version 4.12.0, to see if the problem exists there as well, and it looks like it is. I converted Stuff to a city-level resource to see if that would change anything, and I built one improvement right next to an oasis with the other next to no Fresh water. The result: still getting two Stuff in the city. You can check my code here: https://github.com/SpacedOutChicken/Lodo-s-testbed Screenshot_20240616_144228_Unciv I don't intend to be an annoying asshole, but I've been able to consistently get the bug on my phone and my PC, so let me ask: are you sure it's working on your end? Is there anything about the test you ran that might not catch the behavior we're looking for?

yairm210 commented 2 months ago

I'll test this more hermetically I have no doubt that there is a real problem, I'll see how I can replicate - I think I'll use your mod and game save

SpacedOutChicken commented 2 months ago

Here are a pair of saved games you can use. One with the Stuff Maker next to a river, the other with a Stuff Maker next to a lake. StuffMakerRiver.json StuffMakerLakes.json

SomeTroglodyte commented 2 months ago

I don't intend to be an annoying asshole

Thanks! When I read that in my mail, I laughed out - "they seldom do" came to mind immediately. Sorry, it's not you, just the word combinations... Sorry again, won't debug myself unless y'all ask nicely, because I get lost in all that stockpile code, it's unfamiliar and I quickly scratch my scalp into a bloody mess "how is all that supposed to work???" :where's that rips-hair-out-not-that-i-have-any-left emoji: - Yair is the better person for this. By far. With strawberries on top.

SpacedOutChicken commented 1 month ago

I did a little tinkering and found a few filters that do work: non-[Coastal] and non-[Open terrain] both work, providing the resource everywhere except the specified areas, but non-[Fresh water] still doesn't work properly.

SpacedOutChicken commented 1 month ago

I did a little more testing and I found something that does what I want: <in tiles not adjacent to [Fresh water]>, or <in tiles adjacent to [Fresh water]> for the inverse. I gave a tile the unique of "Consumes [1] [Stuff] <in tiles not adjacent to [Fresh water]>" and it did exactly what I was hoping it would do, draining the resource in any tile not next to a river or an oasis. With that in mind, should I close this issue, or is the original situation still a problem that deserves to be fixed?

yairm210 commented 1 month ago

So the filter does work...? I'm just plain confused Let's leave it open for now, worst case it will auto close

SpacedOutChicken commented 1 month ago

Sorry for the confusion. The original format that I was trying to use, <in [non-[Fresh water] tiles>, still doesn't work, but maybe it's not supposed to. Using <in tiles not adjacent to [Fresh water]> works just fine. I found a different unique conditional that gives me the effect I wanted, so I'm okay if the original unique I had in mind just wasn't meant for what I needed.

SpacedOutChicken commented 1 month ago

Alright, I did some more tinkering, and I finally figured out what's going on here. If you write your conditional as <in [Fresh water] tiles>, it does not check to see if the terrain is next to Fresh water. Instead, it checks to see if the terrain itself has the exact "Fresh water" unique. In other words, if you phrase the conditional that way, it doesn't work if it's next to an Oasis; it has to be directly on TOP of the Oasis, or directly on top of the Lakes, or whatever exact tile is the Fresh water source, and of course it doesn't work on Rivers because you can't build on Rivers, you can only build next to them.

On the other hand, if you say <in tiles adjacent to [Fresh water]>, then building next to an Oasis or next to a River will do the trick, because you're building next to the thing with the "Fresh water" unique. In other words, there was never a bug. There was simply a misunderstanding on my part of what the conditionals are checking for. Of course, it doesn't help that tiles next to Fresh water say "Fresh water" on the map description, but that's a small matter.

yairm210 commented 1 month ago

...Aha