Audit and fix NPC, door-staff and UI dialogue
Full build / Import + headless tests (push) Successful in 40s
Full build / Full desktop build + optional release (push) Skipped

- Route the Reason verb through authored reason contexts and give every shared archetype an in-character answer.
- Add Hollywood wristband and TV Studio ticket/credential door-staff lines.
- Clarify radio cancellation, Ask terminology, start hints and campaign-reset copy.
- Record the dialogue audit and length findings in docs/ui-copy.md; add regression tests.
This commit is contained in:
Gig Line Dev committed 2026-11-02 14:44:01 +01:00
1 parent daf0926d91
commit 98c31fe44c
15 files changed
+232 -30

No files matched your search

+44
View File
@@ -22,6 +22,7 @@ static func shared_profiles() -> Array[NpcProfile]:
tourist.temperament = 0.1
tourist.base_compliance = 0.9
tourist.context_lines = {
"reason": ["Just getting a photo of the entrance.", "I'm meeting friends here."],
"refusal": ["I just want a photo, I'm not staying.", "I didn't know this entrance was restricted."],
"deescalation": ["Okay, I'll move to the sidewalk.", "Sorry, I'll put the camera away."],
"recognition": ["You remember me from the tour, right?"],
@@ -40,6 +41,7 @@ static func shared_profiles() -> Array[NpcProfile]:
confused.temperament = 0.2
confused.base_compliance = 0.85
confused.context_lines = {
"reason": ["I thought this was the box office.", "I'm looking for the event entrance."],
"refusal": ["I'm sure the event is here. Let me check my phone."],
"deescalation": ["Oh, I understand. I'll check with the box office."],
}
@@ -55,6 +57,9 @@ static func shared_profiles() -> Array[NpcProfile]:
delivery.npc_type = Rules.NpcType.DELIVERY
delivery.temperament = 0.25
delivery.base_compliance = 0.8
delivery.context_lines = {
"reason": ["Drop-off for the venue. Where should I leave it?"],
}
delivery.dialogue_lines = ["Where should I leave this?"]
profiles.append(delivery)
@@ -64,6 +69,9 @@ static func shared_profiles() -> Array[NpcProfile]:
performer.npc_type = Rules.NpcType.PERFORMER
performer.temperament = 0.45
performer.base_compliance = 0.55
performer.context_lines = {
"reason": ["Just doing my act; I'll keep the sidewalk clear."],
}
performer.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.COMPLY: 55,
@@ -100,6 +108,9 @@ static func shared_profiles() -> Array[NpcProfile]:
Rules.Reaction.COMPLY: 10,
},
}
influencer.context_lines = {
"reason": ["Filming a quick clip for my channel."],
}
influencer.dialogue_lines = [
"This is public sidewalk, you can't stop me from filming.",
]
@@ -113,6 +124,9 @@ static func shared_profiles() -> Array[NpcProfile]:
intoxicated.temperament = 0.6
intoxicated.base_compliance = 0.4
intoxicated.reaction_delay = 1.8
intoxicated.context_lines = {
"reason": ["Looking for my friends. I think they went inside."],
}
intoxicated.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.COMPLY: 30,
@@ -135,6 +149,9 @@ static func shared_profiles() -> Array[NpcProfile]:
trespasser.temperament = 0.55
trespasser.base_compliance = 0.35
trespasser.return_probability = 0.6
trespasser.context_lines = {
"reason": ["Meeting a friend inside. I'll only be a minute.", "Just cutting through."],
}
trespasser.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.IGNORE: 45,
@@ -177,6 +194,9 @@ static func shared_profiles() -> Array[NpcProfile]:
mental_crisis.base_compliance = 0.3
mental_crisis.return_probability = 0.4
mental_crisis.reaction_delay = 2.4
mental_crisis.context_lines = {
"reason": ["I just need a quiet minute.", "I'm waiting for someone."],
}
mental_crisis.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.IGNORE: 55,
@@ -214,6 +234,9 @@ static func shared_profiles() -> Array[NpcProfile]:
violent_threat.npc_type = Rules.NpcType.VIOLENT_THREAT
violent_threat.temperament = 0.95
violent_threat.base_compliance = 0.05
violent_threat.context_lines = {
"reason": ["Back off. This doesn't concern you."],
}
violent_threat.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.THREATEN: 30,
@@ -250,6 +273,9 @@ static func shared_profiles() -> Array[NpcProfile]:
protester.temperament = 0.5
protester.base_compliance = 0.4
protester.return_probability = 0.25
protester.context_lines = {
"reason": ["We're demonstrating on the public sidewalk.", "This is a peaceful protest."],
}
protester.reactions_by_level = {
Rules.Level.SIMPLE_DETERRENCE: {
Rules.Reaction.ARGUE: 35,
@@ -290,6 +316,9 @@ static func shared_profiles() -> Array[NpcProfile]:
staff.npc_type = Rules.NpcType.AUTHORIZED_STAFF
staff.temperament = 0.15
staff.base_compliance = 1.0
staff.context_lines = {
"reason": ["I'm on staff. I'm checking the entrance.", "Crew check-in; I'm working tonight."],
}
staff.default_reactions = { Rules.Level.SIMPLE_DETERRENCE: { Rules.Reaction.COMPLY: 100 } }
profiles.append(staff)
@@ -299,6 +328,9 @@ static func shared_profiles() -> Array[NpcProfile]:
guest.npc_type = Rules.NpcType.AUTHORIZED_GUEST
guest.temperament = 0.2
guest.base_compliance = 0.95
guest.context_lines = {
"reason": ["I'm on the guest list. Here's my ID.", "A friend invited me; I have a ticket."],
}
guest.default_reactions = {
Rules.Level.SIMPLE_DETERRENCE: { Rules.Reaction.COMPLY: 92, Rules.Reaction.ARGUE: 8 },
Rules.Level.FORMAL_WARNING: { Rules.Reaction.COMPLY: 88, Rules.Reaction.ARGUE: 12 },
@@ -322,6 +354,12 @@ static func hollywood_building() -> VenueScenario:
scenario.access_policy = policy
scenario.equipment = ["wristband_policy", "flashlight", "radio"]
scenario.door_staff_lines = {
"wristband_check": [
"Wristband, please.",
"I need to see your event wristband.",
],
}
scenario.locations = {
"guard_post": Vector3(0, 0, -3),
"entrance": Vector3(0, 0, 1.0),
@@ -589,6 +627,12 @@ static func tv_studio() -> VenueScenario:
scenario.access_policy = policy
scenario.equipment = ["wristband_policy", "guest_list", "radio", "flashlight"]
scenario.door_staff_lines = {
"ticket_check": [
"Ticket, credential, or guest-list confirmation, please.",
"I need your ticket or guest-list confirmation.",
],
}
scenario.locations = {
"guard_post": Vector3(0, 0, -3),
"entrance": Vector3(0, 0, 1.0),