- 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.
443 lines
9.1 KiB
Plaintext
443 lines
9.1 KiB
Plaintext
[gd_resource type="Resource" script_class="VenueScenario" format=3]
|
|
|
|
[ext_resource type="Script" path="res://src/core/access_policy.gd" id="1_3pn5m"]
|
|
[ext_resource type="Script" path="res://src/core/npc_profile.gd" id="2_l60ad"]
|
|
[ext_resource type="Script" path="res://src/core/venue_scenario.gd" id="3_voh88"]
|
|
|
|
[sub_resource type="Resource" id="Resource_aal3l"]
|
|
script = ExtResource("1_3pn5m")
|
|
required_artifacts = {
|
|
2: true,
|
|
3: true
|
|
}
|
|
minimum_age = 21
|
|
require_id = true
|
|
wand_screening_required = true
|
|
policy_summary = "Government ID and a valid ticket or reservation required. Carry items are screened."
|
|
|
|
[sub_resource type="Resource" id="Resource_57xgi"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "tourist"
|
|
display_name = "Tourist"
|
|
temperament = 0.1
|
|
base_compliance = 0.9
|
|
dialogue_lines = Array[String](["Oh sure, sorry, just taking a picture.", "Is there a better spot to stand?", "Understood, moving."])
|
|
context_lines = {
|
|
"deescalation": ["Okay, I'll move to the sidewalk.", "Sorry, I'll put the camera away."],
|
|
"reason": ["Just getting a photo of the entrance.", "I'm meeting friends here."],
|
|
"recognition": ["You remember me from the tour, right?"],
|
|
"refusal": ["I just want a photo, I'm not staying.", "I didn't know this entrance was restricted."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_r873e"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "confused_visitor"
|
|
display_name = "Confused Visitor"
|
|
npc_type = 3
|
|
temperament = 0.2
|
|
base_compliance = 0.85
|
|
dialogue_lines = Array[String](["Wait, this isn't the entrance?", "Sorry about that, I'm a bit lost."])
|
|
context_lines = {
|
|
"deescalation": ["Oh, I understand. I'll check with the box office."],
|
|
"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."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_3xy2u"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "street_performer"
|
|
display_name = "Street Performer"
|
|
npc_type = 1
|
|
temperament = 0.45
|
|
base_compliance = 0.55
|
|
reactions_by_level = {
|
|
1: {
|
|
0: 55,
|
|
2: 15,
|
|
3: 30
|
|
}
|
|
}
|
|
context_lines = {
|
|
"reason": ["Just doing my act; I'll keep the sidewalk clear."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_50i1h"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "influencer"
|
|
display_name = "Influencer"
|
|
npc_type = 2
|
|
temperament = 0.5
|
|
base_compliance = 0.5
|
|
reactions_by_level = {
|
|
1: {
|
|
0: 40,
|
|
2: 10,
|
|
3: 30,
|
|
4: 20
|
|
},
|
|
2: {
|
|
0: 30,
|
|
2: 20,
|
|
4: 35,
|
|
8: 15
|
|
},
|
|
3: {
|
|
0: 10,
|
|
1: 15,
|
|
2: 20,
|
|
4: 30,
|
|
8: 25
|
|
}
|
|
}
|
|
dialogue_lines = Array[String](["This is public sidewalk, you can't stop me from filming."])
|
|
context_lines = {
|
|
"reason": ["Filming a quick clip for my channel."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_nsw77"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "intoxicated"
|
|
display_name = "Intoxicated Pedestrian"
|
|
npc_type = 4
|
|
temperament = 0.6
|
|
base_compliance = 0.4
|
|
reactions_by_level = {
|
|
1: {
|
|
0: 30,
|
|
2: 20,
|
|
3: 50
|
|
},
|
|
2: {
|
|
0: 40,
|
|
2: 35,
|
|
3: 15,
|
|
4: 10
|
|
}
|
|
}
|
|
reaction_delay = 1.8
|
|
context_lines = {
|
|
"reason": ["Looking for my friends. I think they went inside."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_20knl"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "trespasser"
|
|
display_name = "Trespasser"
|
|
npc_type = 5
|
|
temperament = 0.55
|
|
base_compliance = 0.35
|
|
return_probability = 0.6
|
|
reactions_by_level = {
|
|
1: {
|
|
0: 30,
|
|
2: 25,
|
|
3: 45
|
|
},
|
|
2: {
|
|
0: 40,
|
|
2: 35,
|
|
6: 25
|
|
},
|
|
3: {
|
|
1: 35,
|
|
2: 25,
|
|
6: 15,
|
|
7: 10,
|
|
8: 15
|
|
},
|
|
4: {
|
|
1: 70,
|
|
7: 30
|
|
},
|
|
5: {
|
|
1: 30,
|
|
5: 50,
|
|
7: 20
|
|
}
|
|
}
|
|
dialogue_lines = Array[String](["I'm just here to see a friend, come on.", "I'll be inside for ten seconds."])
|
|
context_lines = {
|
|
"reason": ["Meeting a friend inside. I'll only be a minute.", "Just cutting through."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_rivis"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "violent_threat"
|
|
display_name = "Violent Threat"
|
|
npc_type = 6
|
|
temperament = 0.95
|
|
base_compliance = 0.05
|
|
reactions_by_level = {
|
|
1: {
|
|
2: 25,
|
|
3: 45,
|
|
5: 30
|
|
},
|
|
2: {
|
|
2: 30,
|
|
5: 45,
|
|
7: 25
|
|
},
|
|
3: {
|
|
1: 20,
|
|
5: 45,
|
|
7: 35
|
|
},
|
|
4: {
|
|
1: 15,
|
|
5: 30,
|
|
7: 55
|
|
},
|
|
5: {
|
|
1: 30,
|
|
5: 40,
|
|
7: 30
|
|
}
|
|
}
|
|
context_lines = {
|
|
"reason": ["Back off. This doesn't concern you."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_1dvkp"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "authorized_staff"
|
|
display_name = "Staff Member"
|
|
npc_type = 8
|
|
temperament = 0.15
|
|
base_compliance = 1.0
|
|
default_reactions = {
|
|
1: {
|
|
0: 100
|
|
}
|
|
}
|
|
context_lines = {
|
|
"reason": ["I'm on staff. I'm checking the entrance.", "Crew check-in; I'm working tonight."]
|
|
}
|
|
|
|
[sub_resource type="Resource" id="Resource_7wsm0"]
|
|
script = ExtResource("2_l60ad")
|
|
id = "authorized_guest"
|
|
display_name = "Authorized Guest"
|
|
npc_type = 9
|
|
temperament = 0.2
|
|
base_compliance = 0.95
|
|
default_reactions = {
|
|
1: {
|
|
0: 92,
|
|
2: 8
|
|
},
|
|
2: {
|
|
0: 88,
|
|
2: 12
|
|
}
|
|
}
|
|
context_lines = {
|
|
"reason": ["I'm on the guest list. Here's my ID.", "A friend invited me; I have a ticket."]
|
|
}
|
|
|
|
[resource]
|
|
script = ExtResource("3_voh88")
|
|
id = "joke_shop"
|
|
display_name = "The Joke Shop"
|
|
description = "Comedy club door: IDs, reservations, and wand screening."
|
|
access_policy = SubResource("Resource_aal3l")
|
|
equipment = Array[String](["id_check", "guest_list", "wand", "radio"])
|
|
locations = {
|
|
"door_area": Vector3(0, 0, 3),
|
|
"entrance": Vector3(0, 0, 1),
|
|
"guard_post": Vector3(0, 0, -3),
|
|
"queue_area": Vector3(0, 0, 9),
|
|
"sidewalk": Vector3(0, 0, 9),
|
|
"steps_end": Vector3(0, 0, 3)
|
|
}
|
|
npc_profiles = Array[ExtResource("2_l60ad")]([SubResource("Resource_57xgi"), SubResource("Resource_r873e"), SubResource("Resource_3xy2u"), SubResource("Resource_50i1h"), SubResource("Resource_nsw77"), SubResource("Resource_20knl"), SubResource("Resource_rivis"), SubResource("Resource_1dvkp"), SubResource("Resource_7wsm0")])
|
|
event_pool = Array[Dictionary]([{
|
|
"base_weight": 1.0,
|
|
"id": "guest_valid",
|
|
"intent": "enter",
|
|
"kind": "routine",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true
|
|
},
|
|
"phase": 0,
|
|
"probability": 0.3,
|
|
"time_range_s": Vector2(0, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "guest_no_ticket",
|
|
"intent": "enter",
|
|
"kind": "routine",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": false
|
|
},
|
|
"phase": 0,
|
|
"probability": 0.18,
|
|
"time_range_s": Vector2(0, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "guest_expired_id",
|
|
"intent": "enter",
|
|
"kind": "routine",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true,
|
|
"id_status": 1
|
|
},
|
|
"phase": 0,
|
|
"probability": 0.12,
|
|
"time_range_s": Vector2(0, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "guest_no_id",
|
|
"intent": "enter",
|
|
"kind": "routine",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": false,
|
|
"has_ticket": true
|
|
},
|
|
"phase": 0,
|
|
"probability": 0.12,
|
|
"time_range_s": Vector2(0, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"hint": "hint.reservation_no_id",
|
|
"id": "joke_guest_reservation_no_id",
|
|
"intent": "enter",
|
|
"kind": "scripted",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"guest_list_status": 0,
|
|
"has_guest_list": true,
|
|
"has_id": false,
|
|
"has_ticket": false
|
|
},
|
|
"phase": 2,
|
|
"probability": 0.45,
|
|
"time_range_s": Vector2(620, 860)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"hint": "hint.borrowed_id",
|
|
"id": "joke_borrowed_id",
|
|
"intent": "enter",
|
|
"kind": "scripted",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true,
|
|
"id_status": 3,
|
|
"ticket_status": 0
|
|
},
|
|
"phase": 1,
|
|
"probability": 0.4,
|
|
"time_range_s": Vector2(320, 700)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"hint": "hint.refuses_wand",
|
|
"id": "joke_refuses_wand",
|
|
"intent": "enter",
|
|
"kind": "scripted",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true,
|
|
"id_status": 0,
|
|
"ticket_status": 0
|
|
},
|
|
"phase": 2,
|
|
"probability": 0.4,
|
|
"refuses_screening": true,
|
|
"time_range_s": Vector2(650, 880)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"hint": "hint.late_arrival",
|
|
"id": "joke_late_arrival",
|
|
"intent": "arrive",
|
|
"kind": "scripted",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true,
|
|
"id_status": 0,
|
|
"ticket_status": 0
|
|
},
|
|
"phase": 2,
|
|
"probability": 0.35,
|
|
"time_range_s": Vector2(700, 860)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "joke_staff",
|
|
"intent": "enter",
|
|
"kind": "routine",
|
|
"npc_type": 8,
|
|
"phase": 0,
|
|
"probability": 0.25,
|
|
"time_range_s": Vector2(0, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "performer_show",
|
|
"intent": "perform",
|
|
"kind": "routine",
|
|
"npc_type": 1,
|
|
"phase": 0,
|
|
"probability": 0.15,
|
|
"time_range_s": Vector2(300, 800)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "influencer_film",
|
|
"intent": "film",
|
|
"kind": "routine",
|
|
"npc_type": 2,
|
|
"phase": 0,
|
|
"probability": 0.15,
|
|
"time_range_s": Vector2(300, 900)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "joke_disruptive",
|
|
"intent": "force_entry",
|
|
"kind": "scripted",
|
|
"npc_type": 4,
|
|
"phase": 2,
|
|
"probability": 0.5,
|
|
"time_range_s": Vector2(650, 830)
|
|
}, {
|
|
"base_weight": 1.0,
|
|
"id": "joke_denied_guest_return",
|
|
"intent": "enter",
|
|
"kind": "recovery",
|
|
"npc_type": 9,
|
|
"override_access": {
|
|
"has_id": true,
|
|
"has_ticket": true
|
|
},
|
|
"phase": 2,
|
|
"probability": 0.2,
|
|
"time_range_s": Vector2(650, 830)
|
|
}])
|
|
shift_phases = {
|
|
0: {
|
|
"start_s": 0.0
|
|
},
|
|
1: {
|
|
"start_s": 300.0
|
|
},
|
|
2: {
|
|
"start_s": 600.0
|
|
},
|
|
3: {
|
|
"start_s": 700.0
|
|
}
|
|
}
|
|
door_staff_lines = {
|
|
"id_check": ["May I see your ID, please?", "Could you show me some identification?"],
|
|
"prohibited_item": ["I can't allow that item inside. Please leave it outside.", "That item isn't permitted in the venue."],
|
|
"refusal": ["I'm sorry, I can't let you in without that.", "Without a valid ID, I can't admit you tonight."],
|
|
"ticket_check": ["Your ticket or reservation, please.", "Do you have a ticket for tonight's show?"],
|
|
"wand_check": ["Please step forward for the wand check.", "Arms out, please — just a quick screening."]
|
|
}
|