Breaking more package cycles for locks, keys and notes
Chests, doors and the item content stopped naming level classes. An early autoload answers for the dungeons on file, and 17 more backward dependencies went away.
The second slice of breaking the package cycles is landed. Locks, keys, doors and notes in the actors package no longer name classes from the levels package. The count of backward dependencies went from 140 to 123, and the ones from actors into levels went from 69 to 52. Nothing in the game looks or sounds different, so there is no film.
Like the first slice, this comes from my decision on 18 October to do the cycles before the audio work. There are still 123 edges left, so this isn’t finished.
What belongs to actors?
Five files in the dungeon folder, lock, locks, lock_picking, key_ring and keypad, are used by chests and the party as much as by doors. So I made them actors’ files, with five more rules in packages.json. Nothing moved on disk. A chest in actors carries a Lock the same way a door does, and that no longer crosses a package line.
How does the content ask about dungeons?
The item content still needed to know about the dungeons on file. Each dungeon sheet can have keys drawn on it, which have lock groups, and notes described on it. All of those become items. The actors package can’t name the classes that hold them, so I added four questions to LevelQueries: dungeon_keys(), dungeon_lock_groups(), note_text(item_id) and item_sources(). With no answer they return an empty dictionary, an empty string or an empty list.
Telling a door from a chest was the other place the content named a levels class. Now every DungeonDoor joins a group called doors when it’s ready, and LevelQueries.is_door(node) asks the group. The effects and the registry hold the door untyped. It’s the same trick as the monster husk and the no_step group in the first slice.
Why did the answers need an autoload?
In the first slice the answers were installed when a level started, because the questions were about a level that exists. These are different. The dungeons’ keys and notes are content, and content is read when the game starts, before any level exists. So the installer had to run earlier than the first content read.
DungeonAnswers is a 36-line @tool script registered in project.godot as the autoload DungeonFiles, listed before ItemContent. Its _init() calls install(), which sets the four answers as Callables of static functions: DungeonKeys.all, DungeonKeys.groups, DungeonNotes.text_of and its own item_sources. They are never lambdas and never set from _static_init(), because those two crashed Godot 4.7 in the first slice. It’s @tool because the editor makes autoloads too, and the editor check has to stay clean. The result is that the keys and notes are generated items from the first read, the same as before.
ItemDb.generators() builds its own rows and then appends whatever LevelQueries.item_sources() returns. It also asks dungeon_lock_groups() instead of naming DungeonKeys in two places.
Also done
- Seventeen edges went in all: party 3, item 1, chest 1, conditions 1, effects 2,
item_db3,lock_content1,live_content1, notes 1 and registry 3. No other pair of packages changed. tests/level_querieswent from 32 to 53 checks. They cover the no-answer value of each new question, the answers afterinstall()andis_door.- The 40 tests whose names matched the words I ran all passed. The actors package’s 104 tests had no failures. Of the levels package’s 131, one failed,
world_frames, the same frame-time check that was already failing. lock_critcan no longer see the levels package at all.