Xeverous / filter_spirit

Advanced item filter generator for Path of Exile that uses it's own DSL and online item price APIs
GNU General Public License v3.0
36 stars 7 forks source link

support for filter variants #7

Open Xeverous opened 5 years ago

Xeverous commented 5 years ago

We need a feature which will allow to generate filters with multiple variants/strictness levels from 1 template.


Current idea: decorate blocks (something akin to Python's decorators) and then specify which blocks should be present in each variant.

@chome_items
SocketGroup "RGB" {
        @chrome_items.small {
                Width 2
                Height <= 2 {
                        SetBorderColor color_chromatic_small
                        Show
                }

                Width 1
                Height <= 4 {
                        SetBorderColor color_chromatic_small
                        Show
                }

                SetBorderColor color_chromatic_big
                Show
        }
}

Edit: cleaner goals - a list of what is must-have:

  1. The feature must support all 3 states (generate with Show, generate with Hide, do not generate). In a lot of cases you want the 3rd one - the difference is that items not explicitly hidden may be caught by later blocks - this means that syntax like @Strict(Show) @UberStrict(Hide) is not enough, because (example):
    • You want to hide armourer scraps and whetstones, simply because you don't pick up them and they have no other use.
    • You don't want to hide hammers when you resign from hammer recipe. You want to just not generate a block for them so they can still be catched by chromatic or chaos recipe blocks.
  2. A lot of variants will use exactly the same block, with the only differences being disabling sound effect and changing Show to Hide. The feature should allow to avoid code duplication.
  3. The feature should not require additional files. 1 filter template file => multiple filter variants. We can already generate multiple filters by choosing different league for item price data.
  4. There should a way to specify the file name, since we can not put multiple filters in the same output file. Need ideas for the syntax.
  5. The feature should be independent from theming, which is just a selection of colors/sounds etc. When having X different variants and Y different themes, you should be able to generate all X * Y different filters.
  6. The feature should not impose requirement that each subsequent variant is a subset of another. It should be possible to have different variants, where each one has an independent set of blocks.
  7. Any syntax should be declarative, not imperative.
Alekhoff commented 4 years ago

Just to add a note on how strictness filtering is done in other filters:

Usually you have a base version of said filter which acts as "league start" filter into early maps, this will most likely show way to much loot, but that is need in a league start situation as bad items can still be worth something and you need some gear for your char. It also likely contains a detailed leveling section which is only need for your first character in the league(later characters will have mostly twinked leveling gear, which means you don't really pick up any gear on your way to maps.)

Now when you get into mid tier maps your most likely gonna switch to some stricter filters; the way this is done the easiest is: (I will use StupidFatHobbits filters as an example, as i base my filter on his)

This is an example from the "normal" filter

Show
    BaseType "Vaal Axe" "Coronal Maul" "Exquisite Blade"
    Rarity = Rare
    SetFontSize 34
    SetBorderColor 128 0 0

This is from the Strict version:

Hide
    BaseType "Vaal Axe" "Coronal Maul" "Exquisite Blade"
    Rarity = Rare
    SetFontSize 34
    SetBorderColor 128 0 0

So what you really want is an easy way to toggle the Show/Hide when compiling the filter, this could for example be done by having a tag in front of Show in filter_spirit. Something like this maybe?

BaseType ["Vaal Axe", "Coronal Maul", "Exquisite Blade"]{
    SetBackgroundColor color_rare_t3
    SetFontSize font_t5
    SetBorderColor color_rare_border_t3
    @Strict(Hide) Show
}

When you then complie in filter_spirit you could do something like this:

filter_spirit_cli.exe -g -version=Strict "location/to/filter_spirit/file.txt" "location/to/filter/filter.filter"

Which then would change all the lines that has the @Strict(x) with was on the line before. So in the example above it would simply change "Show" to "Hide".

You could also have that function add an action if there the line is empty without the @Strict command beeing called. Like this:

BaseType ["Vaal Axe", "Coronal Maul", "Exquisite Blade"]{
    SetBackgroundColor color_rare_t3
    SetFontSize font_t5
    SetBorderColor color_rare_border_t3
    @Strict(DisableDropSound True)
    @Strict(Hide) Show
}

Which when compiled with the "-version=Strict" [option] shown above would change the block from "Show" to "Hide" and add the "DisableDropSound" "True" to the block as well.

What do you think about this idea for implementing strictness versioning?

You also want to be able to add the PlayDefaultDropSound = False to any block that is tagged with

Xeverous commented 4 years ago

I don't like this approach, for these reasons:

The second strictness approach appeals more to me, because:


I have updated the issue intial comment to better outline what is the goal of the feature. This should help in designing it and give a direction for propositions.

Xeverous commented 4 years ago

Another idea: each block could be marked with a tag and then one could form multiple variants from tags:

@lab
BaseType "Offering to the Goddess" {

...

normal = { +currency, +shards, +lab, +rares, +crafting, ... }
strict = { +currency, +lab, -rares, ... }

pros:

cons:

Xeverous commented 4 years ago

A bit of thinking and I actually prefer your idea of @Strict(Hide) Show - I see the potential to satisfy all conditions:

We only need an idea of better syntax, something that will allow to write one Show/Hide keyword for multiple variants.

Alekhoff commented 4 years ago

Been away for Christmas, but i really like that you came back to this idea. It makes it so there will be minimal effort to convert current filters to work with it.

I think it could work really well i this instance, just need to figure out a good syntax.

Xeverous commented 4 years ago

Adding label and pinning for awarness. We need more ideas for the variant support, perhaps someone with experience in other languages could help.

We basically need:

The current idea of something like @strict(..code...) can satisfy first 3 points, but gets messy when:

Xeverous commented 4 years ago

I'm still uncertain on this and GGG just relased a big filters improvement annoucement - https://www.pathofexile.com/forum/view-thread/2771031

However, I have been fiddling with the grammar to also support loading/debugging real filters and started to think about rewriting FS grammar so that it is as close to real filters as possible. I won't remove $,{} etc but mostly I want to get rid of the stuff like color = RGB(255, 255, 255) so that one can actually just write color = 255 255 255.

The only ambiguity I have found is when someone would write x = 123 123 123 y or x = "base1" "base2" y - the parser would not know whether that y is a variable describing some opacity/base or a part of further y = ... code. It can be worked around with a rule that requires a line break before any next definition, which I think is fine since most people will probably be used to 1-thing-per-line. So far the only drawback of introducing line breaks into the grammar is that it will no longer be possible to write Class "abc" "def" ... "xyz" where the names are split across multiple lines. This however could use another workaround - programming languages which have something that is per-line allow to use \ at the end of it to indicate that the line is continued below. This would looks in FS this way:

BaseType "abc" "def" \
    "xyz" \
    "zzzz" \
    "last base type name"
Xeverous commented 3 years ago

Ok, this took a while, but it is finally done.

I won't explain it here in detail (just read documentation) but I think it's the best implementation possible that satisfies all of my goals for finely-grained strictness editing. I have even added some reasoning to the documentation.