PoE Dynamic Loot Filter (or DLF) is a tool to modify your loot filter seamlessly in real-time while playing Path of Exile.
Join our Discord for help, to give suggestions, or just to discuss DLF!
There are only two requirements for DLF to run (see below for more details):
Once you have the requirements, follow these steps to setup DLF:
dynamic_loot_filter.ahk
to launch PoE DLF (setup is integrated into the GUI).F7
).F8
). Path of Exile will automatically be brought to the foreground.F9
) - your changes are now immediately visible in-game!Normally, in order to make a change to our filter, we need to:
With DLF, this can all be done in a couple seconds. No exaggeration here.
Common highly valuable uses include:
PoE DLF has minimal requirements and setup to make it as widely accessible as possible. You need the following:
switch prog: command not found
when running DLF,
update your version.python
: it should launch Python 3.X)python
doesn't work, but one of python3
or py
work, then you're also okay!Firstly, since we are programmatically reading, analyzing, and writing filter files, note that this is all done locally
FilterBlade formats its loot filters in a certain way, and PoE DLF leverages that format to parse the input filter into
a structure that it can understand and manipulate. For example, FilterBlade places type
and tier
tags on the first
line of their rules, so the tier 1 currency rule can be found by looking for the tags type->currency
and tier->t1
.
Whenever the user wants to make a change to the filter, the corresponding rules are modified, and the filter is re-saved. User profiles are also updated to save the changes the user has made to the filter, so the user can re-download a filter (if they want to make a change on the FilterBlade site), and all their DLF changes will be maintained. Users can also maintain separate profiles (e.g. for different characters, for SSF/Trade leagues, etc) if desired.
All filter parsing, modification, and saving is done by a Python backend. An AHK frontend GUI presents the program's functionality in a clean and efficient manner to the user, and the AHK GUI then relays commands to the Python backend to execute.
Rule matching is a somewhat complicated - the python backend has to reproduce Path of Exile's entire rule-item matching algorithm. In general, it works pretty well, but note that some aspects of it have been shortcut slightly, as they're not super important and the system takes a lot of work to get perfectly. Also, note that at new league starts, there may be significant bugs because of new items and loot filter attributes that are added to the game.
End of user Readme: non-developers may safely ignore everything below.
> python backend_cli.py <function_name> <function_parameters...> <profile_name (if required)>
The profile_name
parameter is required in all cases except for:
is_first_launch
set_hotkey <hotkey_identifier: str> <hotkey_string: str>
get_all_hotkeys
get_all_profile_names
Feature suggestions and bug reports are now tracked in GitHub issues. I will just leave items that do not have a corresponding GitHub issue here for now.
The AHK frontend calls the Python backend via:
> python backend_cli.py <function_name> <function_parameters...> <profile_name (if required)>
The Python backend communicates output values to AHK by writing them to the file
backend_cli.output
. It writes an exit code to backend_cli.exit_code
: -1
indicates
in-progress, 0
indicates exit success, and 1
indicates exit with error
(backend_cli.log
contains error details).
See backend_cli.py
for the detailed documentation of all available function calls.
Currently Supported Functions:
is_first_launch
set_hotkey <hotkey_identifier: str> <hotkey_string: str>
get_all_hotkeys
get_all_profile_names
create_new_profile <new_profile_name>
rename_profile <original_profile_name> <new_profile_name>
delete_profile <profile_name>
set_active_profile
check_filters_exist
import_downloaded_filter
load_input_filter
run_batch
get_rule_matching_item
set_rule_visibility <type_tag: str> <tier_tag: str> <visibility: {show, hide, disable}>
set_currency_to_tier <currency_name: str> <tier: int>
get_all_currency_tiers
set_currency_tier_min_visible_stack_size <tier: int or string> <stack_size: int or "hide_all">
get_currency_tier_min_visible_stack_size <tier: int or string>
get_all_currency_tier_min_visible_stack_sizes
(For test suite use: get_tier_of_currency <currency_name: str>
)
set_splinter_min_visible_stack_size <base_type: str> <stack_size: int>
get_splinter_min_visible_stack_size <base_type: str>
get_all_splinter_min_visible_stack_sizes
set_chaos_recipe_enabled_for <item_slot: str> <enable_flag: int>
is_chaos_recipe_enabled_for <item_slot: str>
get_all_chaos_recipe_statuses
set_hide_maps_below_tier <tier: int>
get_hide_maps_below_tier
get_all_essence_tier_visibilities
set_hide_essences_above_tier <tier: int>
get_hide_essences_above_tier
get_all_div_card_tier_visibilities
set_hide_div_cards_above_tier <tier: int>
get_hide_div_cards_above_tier
get_all_unique_item_tier_visibilities
set_hide_unique_items_above_tier <tier: int>
get_hide_unique_items_above_tier
get_all_unique_map_tier_visibilities
set_hide_unique_maps_above_tier <tier: int>
get_hide_unique_maps_above_tier
set_lowest_visible_oil <oil_name: str>
get_lowest_visible_oil
show_basetype <base_type: str> <rare_only_flag: int> <min_ilvl: int> <max_ilvl: int>
disable_basetype <base_type: str> <rare_only_flag: int> <min_ilvl: int> <max_ilvl: int>
get_all_visible_basetypes
set_flask_visibility <base_type: str> <visibility_flag: int> <(optional) high_ilvl_flag: int>
get_flask_visibility <base_type: str>
get_all_visible_flasks
add_remove_socket_rule <socket_string: str> <(optional) item_slot: str> <add_flag: bool>
get_all_added_socket_rules
set_gem_min_quality <quality: int in [1, 21]>
get_gem_min_quality
set_flask_min_quality <quality: int in [1, 21]>
get_flask_min_quality
set_rgb_item_max_size <size: {none, small, medium, large}>
get_rgb_item_max_size