Repository navigation
Refuse to remove a member who carries an item the adventure needs - #213
Merged
Merged
Conversation
… tests In a playtest of a game built on osrlib, the player removed a member who carried the music box the main quest needed, without give_to. The box left the game with the member, and the quest could no longer be finished. osrlib knows which items an adventure depends on, so the session will refuse that removal, and every game gets the check. This commit adds the contract and the tests. The handler doesn't emit the code yet, so the chunk's tests are marked xfail for chunk: quest-item-guard. The contract: - RemoveMember without give_to is refused with party.remove.carries_quest_item when the leaving member carries an item the adventure depends on. With give_to, the item moves to that member, so the command isn't refused. - The adventure depends on an item when its catalog id is named by a HasItemCondition or an ItemAcquiredPattern anywhere in the adventure. The sites are the gate of a door or a transition, a trigger's pattern and conditions, and a quest's activation, each objective's when, and each objective's reveal_when. - Ids match the way has_item matches them. Mundane items, magic items, and the adventure's own items count, equipped or in the pack. A spent stack doesn't count. The member can be alive, dead, turned to stone, or asleep. Another member who carries the same item doesn't lift the refusal. - A completed quest protects nothing, and neither does a trigger that has fired and isn't repeatable. A quest that is still open protects the items in all its clauses, even an objective that is already complete. A gate always protects its item. - The check is the last of the RemoveMember refusals. Its params are the member's id as character and, as item, the catalog id of the first such item in Inventory.all_instances order. - A refusal costs nothing: no draws, no time, no log entry, and no change. The RemoveMember docstring lists the code last in its Rejections section and says when to use give_to. The rejection-code docs gate is marked xfail until the handler emits the code. The tests of removals the check must still allow pass today and carry no marker. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
RemoveMember without give_to now refuses with party.remove.carries_quest_item when the leaving member carries an item the adventure depends on. The handler runs the check last, after every other refusal, before it changes anything or draws anything. The adventure depends on an item when a HasItemCondition or an ItemAcquiredPattern names it in a door or transition gate, in a trigger that can still fire, or in any clause of a quest that isn't completed. The rejection names the member as character and the first matching item in Inventory.all_instances order as item. A spent stack doesn't count. The rejection code has a description, the changelog has a bullet, and the LLM referee guide mentions the refusal. The chunk's xfail markers stay for the lead to remove. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
The tests for party.remove.carries_quest_item pass, so their expected-to-fail markers and the one on the rejection-code docs gate come off. Claude-Session: https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RemoveMemberwithoutgive_tonow refuses to remove a member who carries an item the adventure depends on, with the new codeparty.remove.carries_quest_item. Before, the item left the game with the member, and a quest that needed it could no longer be finished.The adventure depends on an item when a
has_itemcondition or an item-acquired trigger pattern names it in one of these places:The rejection's
characteranditemparams name the member and the first such item they carry. Naming a member ingive_tomoves the item to them, so the removal goes through. A refusal costs no draws, no time, and no change.The Snoring King found this in a playtest of 2.2.0, when removing a member lost the music box its main quest needs.
https://claude.ai/code/session_01V7ErtnsmhaP7aLwcfmzohD