osrlib.crawl.exploration.HANDLERS, and the sibling maps in encounter.py and battle.py, are public and documented, but crawl/session.py merges them into a module-level global _HANDLERS_CACHE on the first dispatch, so replacing an entry after the first execute silently does nothing. The HANDLERS docstring now says so (#87), which is the most a docstring can do for a half-public extension point. A module-level mutable cache is also an odd thing in a library whose contract is that all state lives in the session.
Two acceptable outcomes:
- Handler registration becomes an API: a registry object or a method on
GameSession that a front end or a content pack calls before play, with the merged table held on the session, not the module.
- The maps become private,
execute is the only documented way in, and the cache moves onto the session instance.
Either way, remove the module global. Acceptance: a test that a handler registered through the chosen path is dispatched, and that two sessions with different registrations do not see each other's handlers.
osrlib.crawl.exploration.HANDLERS, and the sibling maps inencounter.pyandbattle.py, are public and documented, butcrawl/session.pymerges them into a module-level global_HANDLERS_CACHEon the first dispatch, so replacing an entry after the firstexecutesilently does nothing. TheHANDLERSdocstring now says so (#87), which is the most a docstring can do for a half-public extension point. A module-level mutable cache is also an odd thing in a library whose contract is that all state lives in the session.Two acceptable outcomes:
GameSessionthat a front end or a content pack calls before play, with the merged table held on the session, not the module.executeis the only documented way in, and the cache moves onto the session instance.Either way, remove the module global. Acceptance: a test that a handler registered through the chosen path is dispatched, and that two sessions with different registrations do not see each other's handlers.