NPC Claim Violation and Shop Theft Model
Goal
NPCs should turn on the player when the player violates a recognized claim.
This should not be modeled as random NPC anger or a special-case shopkeeper reaction. It should be modeled as a rules-side claim violation system that can support shop theft, trespass, faction retaliation, sacred desecration, assault, debt, and future reputation mechanics.
The immediate bug/example:
A player walked into a book shop, picked up a spellbook, learned a prayer from it for free, and the shopkeeper did not react.
That is wrong. Reading an unpaid spellbook is not harmless inspection. It transfers value from owned property to the player without payment. The player extracted benefit from the item even if they did not physically remove it.
The model should treat this as unauthorized use of owned property: knowledge theft.
Core Design Principle
Do not model this as:
shopkeeper gets mad because player picked up item
Model it as:
player violated a claim recognized by an NPC or faction
The player can violate different kinds of claims:
property claim
territory claim
body claim
kin / faction claim
sacred claim
contract / debt claim
Shop theft is only one instance of the broader rule.
Immediate Behavior Target
For shop items:
Picking up unpaid merchandise inside the shop may be allowed.
Using unpaid merchandise is not allowed.
Leaving the shop with unpaid merchandise is not allowed.
Destroying unpaid merchandise is not allowed.
Refusing payment after unauthorized use escalates the situation.
Attacking the owner escalates immediately.
For the spellbook case:
Reading an unpaid spellbook in a shop should create debt or a transgression.
Learning a prayer/spell from that book counts as value extraction.
The shopkeeper should react.
Reaction should usually begin with warning/demand, not instant combat.
Suggested first reaction:
"That knowledge is not free. Pay 120 gold."
New Concepts
Ownership
Represents a property claim over an entity.
Example shape:
Ownership {
ownerId, // entity id of owner, if specific NPC owns it
factionId, // optional faction claim, e.g. "shopkeepers"
price, // sale value / debt value
saleState // "for_sale" | "paid" | "stolen" | "used"
}
Notes:
ownerId is useful for a specific shopkeeper.
factionId lets the faction remember crimes even if the specific owner dies.
price is the default debt amount.
saleState should remain semantic. Avoid visual/display fields here.
UsePolicy
Represents whether using an item requires ownership or payment.
Example shape:
UsePolicy {
requiresPurchase, // true for shop merchandise
unauthorizedUseKind, // "knowledge_theft" | "consumption_theft" | "activation_theft"
valueOnUse, // fraction of price owed on unauthorized use
consumeOnUse // whether the item disappears after use
}
Examples:
Spellbook:
unauthorizedUseKind = "knowledge_theft"
valueOnUse = 1.0
consumeOnUse = false
Potion:
unauthorizedUseKind = "consumption_theft"
valueOnUse = 1.0
consumeOnUse = true
Scroll:
unauthorizedUseKind = "activation_theft"
valueOnUse = 1.0
consumeOnUse = true
Transgression
A fact that the player violated a recognized claim.
This may be stored as a component, record, or rules-side event depending on the current architecture.
Example shape:
Transgression {
actorId,
victimId,
factionId,
kind,
itemId,
value,
turn,
witnessed
}
Example for the spellbook:
Transgression {
actorId: playerId,
victimId: shopkeeperId,
factionId: "shopkeepers",
kind: "knowledge_theft",
itemId: spellbookId,
value: 120,
turn: world.turn,
witnessed: true
}
Debt
Represents an unresolved claim for payment.
Example shape:
Debt {
debtorId,
creditorId,
factionId,
amount,
reason,
itemId,
createdTurn,
status // "unpaid" | "paid" | "refused" | "forgiven"
}
For the first implementation, debt may be enough without persistent reputation.
Disposition
Represents how one entity currently regards another.
Example shape:
Disposition {
sourceId,
targetId,
stance, // "neutral" | "suspicious" | "warn" | "angry" | "hostile"
reason
}
Important: AI should read disposition. AI should not independently decide that a crime occurred.
Suggested Rule Flow
Reading / Using an Item
When the player performs an item-use intent:
Intent: read / quaff / eat / activate item
Rules:
if item has Ownership
and item is not paid for
and actor is not owner
and item has UsePolicy requiring purchase
create Transgression
create or update Debt
update owner/faction Disposition toward actor
emit semantic event
then continue or block the use depending on policy
For spellbooks, the use probably should still succeed. The player learned the prayer; now they owe money.
For some magical shops or sacred texts, future variants may block the use until paid. But the first version should allow the theft and create consequences.
Leaving With Owned Goods
When the player attempts to leave the shop region:
if player carries unpaid owned items belonging to shopkeeper/shop faction:
create theft transgression or escalate existing debt
shopkeeper demands payment
if player refuses / forces exit:
hostile or guards summoned
This can come after the read/use case. It is the second vertical slice.
Destroying Owned Goods
When an owned item is destroyed:
if item has Ownership and is unpaid:
create property_damage transgression
create Debt for item price
update owner Disposition
Shopkeeper Escalation Ladder
The shopkeeper should not always instantly attack.
Suggested ladder:
1. Neutral
Player is browsing.
2. Warning
Player used/read an unpaid item or picked up too many items.
Shopkeeper says: "Careful. That is not yours yet."
3. Demand Payment
Player has unpaid debt.
Shopkeeper says: "Pay 120 gold."
4. Containment
Player tries to leave or ignores the demand.
Shopkeeper blocks the exit, locks door, or calls guards.
5. Criminal Mark
Player refuses payment, flees, or repeats the offense.
Debt becomes transgression/reputation with shopkeeper faction.
6. Hostile
Player attacks, refuses, flees with goods, or escalates past threshold.
Good first implementation:
Unauthorized use creates debt and sets shopkeeper stance to "angry" or "warn".
Trying to leave with unpaid debt sets stance to "hostile" or summons guards.
Attacking the shopkeeper sets stance to "hostile" immediately.
First Vertical Slice
Implement this in the smallest useful path.
Components / Data
Add or reuse:
Ownership
UsePolicy
Debt or Transgression
Disposition
FactionMember
Apply to Book Shop Items
For shop spellbooks:
Ownership:
ownerId = shopkeeper id
factionId = "shopkeepers"
price = current shop price
saleState = "for_sale"
UsePolicy:
requiresPurchase = true
unauthorizedUseKind = "knowledge_theft"
valueOnUse = 1.0
consumeOnUse = false
Hook Item Use
In the rules-side item use/read path, before or after the learn effect:
function handleUnauthorizedUse(world, actorId, itemId) {
const ownership = getOwnership(world, itemId);
const policy = getUsePolicy(world, itemId);
if (!ownership || !policy) return null;
if (!policy.requiresPurchase) return null;
if (ownership.saleState === "paid") return null;
if (ownership.ownerId === actorId) return null;
const amount = Math.ceil((ownership.price || 0) * (policy.valueOnUse ?? 1));
const debt = createDebt(world, {
debtorId: actorId,
creditorId: ownership.ownerId,
factionId: ownership.factionId,
amount,
reason: policy.unauthorizedUseKind,
itemId,
});
createTransgression(world, {
actorId,
victimId: ownership.ownerId,
factionId: ownership.factionId,
kind: policy.unauthorizedUseKind,
itemId,
value: amount,
witnessed: true,
});
setDisposition(world, {
sourceId: ownership.ownerId,
targetId: actorId,
stance: "warn",
reason: policy.unauthorizedUseKind,
});
emitEvent(world, {
type: "claim_violated",
actorId,
victimId: ownership.ownerId,
factionId: ownership.factionId,
kind: policy.unauthorizedUseKind,
itemId,
value: amount,
});
return debt;
}
Names should be adapted to the existing ECS style. This is intended as shape, not exact final API.
Shopkeeper AI Response
Shopkeeper behavior should check debt/disposition:
if player owes debt to this shopkeeper:
approach player
demand payment
block exit if player tries to leave
if player attacks shopkeeper:
become hostile
if player refuses payment or flees:
become hostile / call guards
Do not put theft detection inside shopkeeper AI. The rules system should produce debt/transgression/disposition. AI responds to those facts.
Bridge / Display Contract
The rules layer should emit semantic facts only.
Good event:
{
type: "claim_violated",
actorId,
victimId,
factionId,
kind,
itemId,
value
}
Good event:
{
type: "debt_created",
debtorId,
creditorId,
amount,
reason,
itemId
}
Good event:
{
type: "disposition_changed",
sourceId,
targetId,
stance,
reason
}
Bad event:
{
type: "shopkeeper_turns_red_and_shakes"
}
Display can choose glyphs, colors, speech bubbles, anger particles, alert marks, etc. Rules should only expose semantic state and events.
Suggested Event Names
Use existing event conventions if available. Otherwise:
claim_violated
transgression_recorded
debt_created
debt_paid
debt_refused
disposition_changed
No lighting, VFX, color, camera, or animation information should be introduced into rules events.
Edge Cases
Player Reads Book But Already Paid
No transgression.
Player Reads Book Owned by Self
No transgression.
Player Reads Book Not For Sale But Owned
This is still unauthorized use, but reason may be:
forbidden_knowledge
sacred_violation
private_property_violation
Not all owned books are shop merchandise.
Player Picks Up Item But Does Not Use It
No immediate theft unless the shop design wants stricter rules.
Recommended default:
Pickup inside shop is suspicious but tolerated.
Leaving with unpaid item is theft.
Using unpaid item is theft.
Player Has Enough Gold
On unauthorized use, the shopkeeper can demand payment. Later, interaction can offer:
Pay now
Refuse
Drop item does not help if value was already extracted
For knowledge theft, dropping the book does not undo the theft.
Player Does Not Have Enough Gold
Debt remains unpaid.
Shopkeeper/faction can escalate.
Player Learns Same Prayer Already Known
This is subtle.
Options:
A. Still theft, because they used the merchandise.
B. Lesser violation, because no new value was extracted.
C. No violation, because no benefit was gained.
Recommended first behavior: still create violation. Simpler and more legible.
Later refinement: if no new knowledge was learned, debt amount could be reduced.
Item Use Is Accidental
No special handling in first version. Player intent is enough.
Owner Not Present
If unwitnessed, create transgression with witnessed: false or create no immediate reaction.
Future stealth support:
unwitnessed theft affects inventory state but not immediate disposition
witnessed theft affects disposition immediately
magical shops may always witness knowledge theft
First version can assume shopkeeper witnesses use inside shop.
Multiple Shopkeepers / Faction Store
Prefer both:
ownerId: specific shopkeeper
factionId: shopkeepers
The specific NPC demands payment. The faction may remember repeat offenses.
Why This Is Worth Doing
This creates a reusable moral/social physics layer.
Same system can power:
shop theft
reading forbidden books
using sacred altars incorrectly
attacking allied NPCs
killing faction members
stealing from homes
breaking contracts
entering restricted rooms
refusing debt
NPCs become more interesting because they are not merely hostile/non-hostile. They are defending claims.
Acceptance Tests
Test 1: Reading Unpaid Spellbook Creates Debt
Given a shopkeeper owns a spellbook for sale
And player has not paid for it
When player reads the spellbook
Then a Debt exists from player to shopkeeper
And the debt amount equals the spellbook price
And a claim/transgression event is emitted
And shopkeeper disposition toward player is warn/angry
Test 2: Reading Paid Spellbook Does Not Create Debt
Given player has purchased the spellbook
When player reads it
Then no transgression is created
And no new debt is created
And shopkeeper disposition does not worsen
Test 3: Picking Up Book Alone Does Not Create Theft
Given a shop spellbook is unpaid
When player picks it up inside the shop
Then no debt is created
And no transgression is created
Test 4: Leaving With Unpaid Item Escalates
Given player carries an unpaid shop item
When player crosses the shop exit boundary
Then theft transgression is created
And shopkeeper disposition escalates
This can be implemented after Test 1 if exit/shop-region logic is not ready.
Test 5: Destroying Unpaid Item Creates Debt
Given an unpaid shop item exists
When player destroys it
Then property_damage transgression is created
And player owes the item value
Optional for first pass.
Implementation Priority
- Add ownership to shop merchandise.
- Add use policy to spellbooks, scrolls, potions, and other usable shop items.
- Hook unauthorized-use detection into the item-use/read path.
- Create debt/transgression and disposition state.
- Make shopkeeper AI respond to debt/disposition.
- Add leaving-with-unpaid-goods detection later.
- Add faction/reputation memory later.
Final Rule of Thumb
An NPC turns on the player when the player violates a claim the NPC recognizes.
For shops, the claims are property and payment.
For spellbooks, reading can be theft because the player can steal the value without stealing the object.
That is the mechanic to preserve.
NPC Claim Violation and Shop Theft Model
Goal
NPCs should turn on the player when the player violates a recognized claim.
This should not be modeled as random NPC anger or a special-case shopkeeper reaction. It should be modeled as a rules-side claim violation system that can support shop theft, trespass, faction retaliation, sacred desecration, assault, debt, and future reputation mechanics.
The immediate bug/example:
A player walked into a book shop, picked up a spellbook, learned a prayer from it for free, and the shopkeeper did not react.
That is wrong. Reading an unpaid spellbook is not harmless inspection. It transfers value from owned property to the player without payment. The player extracted benefit from the item even if they did not physically remove it.
The model should treat this as unauthorized use of owned property: knowledge theft.
Core Design Principle
Do not model this as:
Model it as:
The player can violate different kinds of claims:
Shop theft is only one instance of the broader rule.
Immediate Behavior Target
For shop items:
For the spellbook case:
Suggested first reaction:
New Concepts
Ownership
Represents a property claim over an entity.
Example shape:
Notes:
ownerIdis useful for a specific shopkeeper.factionIdlets the faction remember crimes even if the specific owner dies.priceis the default debt amount.saleStateshould remain semantic. Avoid visual/display fields here.UsePolicy
Represents whether using an item requires ownership or payment.
Example shape:
Examples:
Transgression
A fact that the player violated a recognized claim.
This may be stored as a component, record, or rules-side event depending on the current architecture.
Example shape:
Example for the spellbook:
Debt
Represents an unresolved claim for payment.
Example shape:
For the first implementation, debt may be enough without persistent reputation.
Disposition
Represents how one entity currently regards another.
Example shape:
Important: AI should read disposition. AI should not independently decide that a crime occurred.
Suggested Rule Flow
Reading / Using an Item
When the player performs an item-use intent:
Intent: read / quaff / eat / activate item Rules: if item has Ownership and item is not paid for and actor is not owner and item has UsePolicy requiring purchase create Transgression create or update Debt update owner/faction Disposition toward actor emit semantic event then continue or block the use depending on policyFor spellbooks, the use probably should still succeed. The player learned the prayer; now they owe money.
For some magical shops or sacred texts, future variants may block the use until paid. But the first version should allow the theft and create consequences.
Leaving With Owned Goods
When the player attempts to leave the shop region:
if player carries unpaid owned items belonging to shopkeeper/shop faction: create theft transgression or escalate existing debt shopkeeper demands payment if player refuses / forces exit: hostile or guards summonedThis can come after the read/use case. It is the second vertical slice.
Destroying Owned Goods
When an owned item is destroyed:
Shopkeeper Escalation Ladder
The shopkeeper should not always instantly attack.
Suggested ladder:
Good first implementation:
First Vertical Slice
Implement this in the smallest useful path.
Components / Data
Add or reuse:
Apply to Book Shop Items
For shop spellbooks:
Hook Item Use
In the rules-side item use/read path, before or after the learn effect:
Names should be adapted to the existing ECS style. This is intended as shape, not exact final API.
Shopkeeper AI Response
Shopkeeper behavior should check debt/disposition:
Do not put theft detection inside shopkeeper AI. The rules system should produce debt/transgression/disposition. AI responds to those facts.
Bridge / Display Contract
The rules layer should emit semantic facts only.
Good event:
Good event:
Good event:
Bad event:
Display can choose glyphs, colors, speech bubbles, anger particles, alert marks, etc. Rules should only expose semantic state and events.
Suggested Event Names
Use existing event conventions if available. Otherwise:
No lighting, VFX, color, camera, or animation information should be introduced into rules events.
Edge Cases
Player Reads Book But Already Paid
No transgression.
Player Reads Book Owned by Self
No transgression.
Player Reads Book Not For Sale But Owned
This is still unauthorized use, but reason may be:
Not all owned books are shop merchandise.
Player Picks Up Item But Does Not Use It
No immediate theft unless the shop design wants stricter rules.
Recommended default:
Player Has Enough Gold
On unauthorized use, the shopkeeper can demand payment. Later, interaction can offer:
For knowledge theft, dropping the book does not undo the theft.
Player Does Not Have Enough Gold
Debt remains unpaid.
Shopkeeper/faction can escalate.
Player Learns Same Prayer Already Known
This is subtle.
Options:
Recommended first behavior: still create violation. Simpler and more legible.
Later refinement: if no new knowledge was learned, debt amount could be reduced.
Item Use Is Accidental
No special handling in first version. Player intent is enough.
Owner Not Present
If unwitnessed, create transgression with
witnessed: falseor create no immediate reaction.Future stealth support:
First version can assume shopkeeper witnesses use inside shop.
Multiple Shopkeepers / Faction Store
Prefer both:
The specific NPC demands payment. The faction may remember repeat offenses.
Why This Is Worth Doing
This creates a reusable moral/social physics layer.
Same system can power:
NPCs become more interesting because they are not merely hostile/non-hostile. They are defending claims.
Acceptance Tests
Test 1: Reading Unpaid Spellbook Creates Debt
Test 2: Reading Paid Spellbook Does Not Create Debt
Test 3: Picking Up Book Alone Does Not Create Theft
Test 4: Leaving With Unpaid Item Escalates
This can be implemented after Test 1 if exit/shop-region logic is not ready.
Test 5: Destroying Unpaid Item Creates Debt
Optional for first pass.
Implementation Priority
Final Rule of Thumb
An NPC turns on the player when the player violates a claim the NPC recognizes.
For shops, the claims are property and payment.
For spellbooks, reading can be theft because the player can steal the value without stealing the object.
That is the mechanic to preserve.