SL2 Analyzer
Read a FromSoftware .sl2 save and report what is in it
Loading...
Searching...
No Matches
sl2.progress Namespace Reference

Functions

 find_boss_souls (goods)
 Pull the likely boss / lord souls out of a goods list.
 
 load_boss_soul_map (base_dir, subdir)
 
 load_boss_route (base_dir, subdir)
 
 attach_defeated_bosses (ch, base_dir)
 Attach a bosses defeat floor to a non-DS2 character from the boss souls / remembrances it still holds, plus endgame progression.
 
 find_key_goods (goods)
 Pull key / progression items out of a goods list (DS1 keeps keys here).
 

Variables

dict GENERIC_SOULS
 Ordinary soul consumables that are NOT boss souls.
 
dict DS1_PROGRESSION
 DS1 progression goods that gate the world but do not read as "keys".
 
dict BOSS_SOUL_DB_DIR
 Per-game folder holding a boss-soul → boss-name table (boss_souls.json).
 
dict _BOSS_SOUL_CACHE = {}
 Load a game's boss-soul → boss-name table.
 
dict _BOSS_ROUTE_CACHE = {}
 Load a game's route graph (boss_route.json): boss name → [gate area, [bosses that must die first]].
 
dict BOSS_PREREQ
 Endgame-only progression prereqs: a proven-dead boss (key) implies its mandatory predecessors (values) are dead too, tagged gate.
 
dict MANDATORY_BOSSES
 Bosses that CANNOT be skipped to finish the game, so reaching NG+ proves every one of them dead at least once (tag clear).
 
 DS3_LORDS
 The four Lords of Cinder, boss name → the name on the Firelink throne.
 
str DS3_CINDER_ITEM = "Cinders of a Lord"
 The one item id (any lord's) that sits in the inventory between killing a Lord of Cinder and offering the ashes at the throne.
 

Detailed Description

Progress inference shared by every game: boss souls held, key items, the
NG+ mandatory-clear floor, and the denominators each progress section prints.

Function Documentation

◆ find_boss_souls()

sl2.progress.find_boss_souls (   goods)

Pull the likely boss / lord souls out of a goods list.

Definition at line 58 of file progress.py.

◆ load_boss_soul_map()

sl2.progress.load_boss_soul_map (   base_dir,
  subdir 
)

Definition at line 90 of file progress.py.

◆ load_boss_route()

sl2.progress.load_boss_route (   base_dir,
  subdir 
)

Definition at line 112 of file progress.py.

◆ attach_defeated_bosses()

sl2.progress.attach_defeated_bosses (   ch,
  base_dir 
)

Attach a bosses defeat floor to a non-DS2 character from the boss souls / remembrances it still holds, plus endgame progression.

A held boss soul is a boss killed — you cannot own the soul otherwise — so each maps to its boss with soul evidence, and its mandatory endgame predecessors get gate (see BOSS_PREREQ), the same certain-when-true signals DS2 uses. If the character is in NG+ (ng_plus > 0) every MANDATORY_BOSSES entry is proven dead too (clear). A boss whose soul was consumed, not gated and not mandatory, is invisible here (the render note says so). DS2 sets its own richer bosses via augment and is skipped.

Definition at line 229 of file progress.py.

◆ find_key_goods()

sl2.progress.find_key_goods (   goods)

Pull key / progression items out of a goods list (DS1 keeps keys here).

Definition at line 272 of file progress.py.

Variable Documentation

◆ GENERIC_SOULS

dict sl2.progress.GENERIC_SOULS

Ordinary soul consumables that are NOT boss souls.

A boss soul in your pack means the boss is dead; a "Soul of a Lost Undead" just means you killed something ordinary.

Definition at line 12 of file progress.py.

◆ DS1_PROGRESSION

dict sl2.progress.DS1_PROGRESSION
Initial value:
1= {
2 "Lordvessel",
3 "Peculiar Doll",
4 "Broken Pendant",
5 "Rite of Kindling",
6 "Crest of Artorias",
7}

DS1 progression goods that gate the world but do not read as "keys".

Crest of Artorias opens the sealed Darkroot door, so it gates as hard as a key.

Definition at line 48 of file progress.py.

◆ BOSS_SOUL_DB_DIR

dict sl2.progress.BOSS_SOUL_DB_DIR
Initial value:
1= {
2 "dsr": "db_ds1",
3 "ptde": "db_ds1",
4 "ds3": "db_ds3",
5 "er": "db_er",
6 "sdt": "db_sdt",
7}

Per-game folder holding a boss-soul → boss-name table (boss_souls.json).

DS2 runs its own richer multi-source inference; these cover the games whose only proof-of-kill floor is the boss souls / remembrances the character still holds. Sekiro's table maps its Memory items, which are the same kind of token — and the only one in the series whose spending leaves a trace (see sdt_memories_spent).

Definition at line 77 of file progress.py.

◆ _BOSS_SOUL_CACHE

dict sl2.progress._BOSS_SOUL_CACHE = {}
protected

Load a game's boss-soul → boss-name table.

Cached per (base_dir, subdir).

Definition at line 87 of file progress.py.

◆ _BOSS_ROUTE_CACHE

dict sl2.progress._BOSS_ROUTE_CACHE = {}
protected

Load a game's route graph (boss_route.json): boss name → [gate area, [bosses that must die first]].

GAME STRUCTURE, not a save read — it exists to answer "what can I fight now", which no flag can. The area name is a key of that game's own bonfire table, so "the area was reached" is decided by that area's lit bonfires; the predecessor list is only the HARD gates (the arena or key you cannot get past otherwise), never a suggested order. Cached per (base_dir, subdir). Returns {} if the game has no table.

Definition at line 109 of file progress.py.

◆ BOSS_PREREQ

dict sl2.progress.BOSS_PREREQ

Endgame-only progression prereqs: a proven-dead boss (key) implies its mandatory predecessors (values) are dead too, tagged gate.

Each key lists ALL its predecessors (already flattened), so one closure pass suffices. DELIBERATELY ENDGAME-ONLY, mirroring DS2's DS2_BOSS_PREREQ rule: only strictly-linear, cannot-skip mandatory chains qualify — a mid-game gate would risk a false kill (the core rule). Sourced from each game's fixed endgame route.

DS3: the four Lords of Cinder plus Iudex Gundyr are all mandatory to fight Soul of Cinder, and Vordt/Dancer gate the only path forward (High Wall → … → Lothric Castle). Aldrich sits past Pontiff Sulyvahn in Irithyll. ER: Morgott (Leyndell) → Fire Giant (Forge) → Maliketh (Farum Azula) → Godfrey/ Hoarah Loux (Ashen Leyndell) is the fixed mandatory endgame chain; each requires every earlier one. Morgott's own prereqs are player-choice great runes, so it gates nothing specific.

Definition at line 138 of file progress.py.

◆ MANDATORY_BOSSES

dict sl2.progress.MANDATORY_BOSSES
Initial value:
1= {
2 "dsr": [
3 "Bell Gargoyles",
4 "Chaos Witch Quelaag",
5 "Iron Golem",
6 "Dragon Slayer Ornstein",
7 "Executioner Smough",
8 "Great Grey Wolf Sif",
9 "The Four Kings",
10 "Seath the Scaleless",
11 "Gravelord Nito",
12 "Bed of Chaos",
13 "Gwyn, Lord of Cinder",
14 ],
15}

Bosses that CANNOT be skipped to finish the game, so reaching NG+ proves every one of them dead at least once (tag clear).

DS1 (dsr/ptde) is linear from Anor Londo on: both bells (Gargoyles, Quelaag), Sen's/Anor Londo (Iron Golem, O&S), the four Lord Souls (Nito, Bed of Chaos, Four Kings — needs Sif's ring — and Seath) and Gwyn are all mandatory. Deliberately endgame-safe, the same core-rule caution as the gate maps — no mid-game boss whose route can be skipped is listed. (DS2 handles this itself in ds2_infer_bosses, seeding only its final boss Nashandra, because DS2's mid-game is skippable — Shrine of Winter opens on Soul Memory alone.)

Definition at line 183 of file progress.py.

◆ DS3_LORDS

sl2.progress.DS3_LORDS
Initial value:
1= OrderedDict(
2 [
3 ("Abyss Watchers", "Abyss Watchers"),
4 ("Yhorm the Giant", "Yhorm the Giant"),
5 ("Aldrich, Devourer of Gods", "Aldrich"),
6 ("Lothric, Younger Prince", "Twin Princes"),
7 ]
8)

The four Lords of Cinder, boss name → the name on the Firelink throne.

A closed set: all four must be placed before the Kiln opens, so "N of 4" is a real denominator rather than an open-ended list.

Definition at line 256 of file progress.py.

◆ DS3_CINDER_ITEM

str sl2.progress.DS3_CINDER_ITEM = "Cinders of a Lord"

The one item id (any lord's) that sits in the inventory between killing a Lord of Cinder and offering the ashes at the throne.

Definition at line 268 of file progress.py.