1. Dialog Structure
Each dialog is created using the following function:
exports['koja-dialogs']:CreateDialog({
id = "<unique_dialog_id>",
npc = "<npc_model>",
coords = vector4(<x>, <y>, <z>, <heading>),
name = "<npc_display_name>",
message = "<initial_npc_message>",
tag = "<display_tag_above_npc>",
animations = {
{ type = "<animation_type>", dict = "<animation_dict>", anim = "<animation_name>" },
{ type = "<animation_type>", dict = "<animation_dict>", anim = "<animation_name>" }
},
actions = {
{
label = "<button_label>",
player_message = "<message_player_says>",
onclick = {
message = "<npc_response_after_selection>",
actions = {
{ ... } -- nested actions for more dialogue branches
},
open = {
window = "<window_type>", -- "shop", "market" or "crafting"
data = {
-- depends on window type
}
}
},
close = <boolean> -- close dialog after clicking?
},
-- more actions
}
})
Fields to highlight:
id (string): Unique identifier for the dialog.
npc (string): Model name of the NPC (e.g., "g_m_m_chicold_01"
).
coords (vector4): Position in the world: vector4(x, y, z, heading)
.
name (string): Display name for the NPC in the dialog header.
message (string): The NPC’s initial message when the dialog opens.
tag (string): A label shown above the NPC (e.g., “Dealer”, “Distributor”, “OG”).
animations (table): List of animation objects:
type
(string): Custom label for the animation (e.g., "idle"
, "active"
).
dict
(string): The Animation Dictionary to load.
anim
(string): The Animation Name.
actions (table): Array of player-action objects:
label
(string): Text displayed on the button.
player_message
(string): The player’s dialogue line.
onclick
(table):
message
(string): NPC’s response after clicking.
actions
(table): (Optional) Array of nested actions for further dialogue.
open
(table): (Optional) UI window to open, with:
window
(string): "shop"
, "market"
, or "crafting"
.
data
(table): Data structure depending on the window type.
close
(boolean): Whether to close the dialog after this action.
2. Shop Window
The Shop window displays a list of items (e.g., weapons) that the player can purchase. Its data block looks like this:
open = {
window = "shop",
data = {
products = {
{
respname = "<resource_name_in_inventory>", -- e.g. "weapon_pistol"
price = <price_in_game_currency>, -- e.g. 14250
label = "<display_label>", -- e.g. "Pistol"
desc = "<description_text>" -- e.g. "weapon"
},
-- additional products
}
}
}
Example: Dialog with Shop Window (dealer-1)
exports['koja-dialogs']:CreateDialog({
id = "dealer-1",
npc = "g_m_m_chicold_01",
coords = vector4(492.8855, -1356.6151, 29.3423 - 1, 41.8399),
name = "Masked Guy",
message = "Oi, what are you looking at?",
tag = "Dealer",
animations = {
{ type = "idle", dict = "rcmjosh1", anim = "idle" },
{ type = "active", dict = "missfbi3_party_d", anim = "stand_talk_loop_a_male1" }
},
actions = {
{
label = "Buy Drugs",
player_message = "I want to buy some drugs",
onclick = {
message = "I'm not selling drugs, I'm selling guns.",
actions = {
{
label = "Ask about guns",
player_message = "What guns do you have?",
onclick = {
message = "I'll show you now.",
open = {
window = "shop",
data = {
products = {
{
respname = "weapon_pistol",
price = 14250,
label = "Pistol",
desc = "weapon"
}
}
}
}
}
},
{
label = "Go away",
player_message = "Oh, I think I'll go now...",
close = true
}
}
},
close = false
},
{
label = "Who are you?",
player_message = "What are you doing here?",
onclick = {
message = "Why do you want to know? Are you from the police?",
actions = {
{
label = "Say no",
player_message = "No!",
onclick = {
message = "I'll show you now.",
}
},
{
label = "Go away",
player_message = "Oh, I think I'll go now...",
close = true
}
}
},
close = true
},
{
label = "Goodbye",
player_message = "Goodbye!",
onclick = {
message = "Take care!",
actions = {}
},
close = true
}
}
})
Notes:
Clicking Buy Drugs responds that the NPC only sells guns.
In that branch, Ask about guns opens the Shop window showing available weapons.
If Go away is chosen, the dialog closes.
3. Market Window
The Market window is used for trading resources (e.g., narcotics). Its data structure is identical to Shop, but the context is resource exchange:
open = {
window = "market",
data = {
products = {
{
respname = "<resource_name>", -- e.g. "packed_weed"
price = <price_per_unit>, -- e.g. 50
label = "<display_label>", -- e.g. "Weed"
desc = "<category_description>" -- e.g. "Narcotics"
},
-- additional products
}
}
}
Example: Dialog with Market Window (dealer-2)
exports['koja-dialogs']:CreateDialog({
id = "dealer-2",
npc = "g_m_importexport_01",
coords = vector4(492.9131, -1461.6570, 29.2863 - 1, 139.3608),
name = "Rodrigues",
message = "Hey you! Come here.",
tag = "Distributor",
animations = {
{ type = "idle_a", dict = "amb@world_human_leaning@male@wall@back@foot_up@idle_a", anim = "idle_a" },
{ type = "active", dict = "missfbi3_party_d", anim = "stand_talk_loop_a_male1" }
},
actions = {
{
label = "What Happened?",
player_message = "Hey, what do you want?",
onclick = {
message = "You sold the dope?",
actions = {
{
label = "Yes",
player_message = "Yeah, can I sell it to you?",
onclick = {
message = "Right now? All right, give me the dope and I'll give you the cash.",
actions = {
{
label = "Give the dope",
player_message = "Here.",
onclick = {
message = "Yeah, that's it buddy.",
open = {
window = "market",
data = {
products = {
{
respname = "packed_weed",
price = 50,
label = "Weed",
desc = "Narcotics"
}
}
}
}
}
}
}
}
},
{
label = "No, I'll go do it now!",
player_message = "Not yet, please wait!",
close = true
}
}
},
close = false
}
}
})
Notes:
The dialog asks if the player sold the drugs (“You sold the dope?”).
If Yes, Give the dope opens the Market window for finalizing the transaction.
4. Crafting Window
The Crafting window combines raw materials into finished goods. It uses data.items
, built through buildRequired()
:
open = {
window = "crafting",
data = {
items = exports['koja-dialogs']:buildRequired({
{
respname = "<result_item_resource_name>", -- e.g. "packed_weed"
label = "<result_item_label>", -- e.g. "Packed Weed"
category = "<item_category>", -- e.g. "Narcotics"
required = {
{ respname = "<ingredient1>", label = "<ingredient1_label>", amount = <quantity1> },
{ respname = "<ingredient2>", label = "<ingredient2_label>", amount = <quantity2> }
-- additional ingredients
}
},
-- additional recipes
})
}
}
Example: Dialog with Crafting Window (dealer-3)
exports['koja-dialogs']:CreateDialog({
id = "dealer-3",
npc = "g_m_m_mexboss_02",
coords = vector4(466.9149, -1590.3712, 32.8233 - 1, 317.4886),
name = "Martin",
message = "Oh! My favourite worker.",
tag = "OG",
animations = {
{ type = "idle_a", dict = "amb@world_human_leaning@male@wall@back@foot_up@idle_a", anim = "idle_a" },
{ type = "active", dict = "missfbi3_party_d", anim = "stand_talk_loop_a_male1" }
},
actions = {
{
label = "Hello!",
player_message = "Hey Martin, can I pack my weed in your place?",
onclick = {
message = "Sure, come in.",
actions = {
{
label = "Pack weed",
player_message = "Yeah, can I sell it to you?",
onclick = {
message = "Right now? All right, give me the dope and I'll give you the cash.",
actions = {
{
label = "Give the dope",
player_message = "Here.",
onclick = {
message = "Yeah, that's it buddy.",
open = {
window = "crafting",
data = {
items = exports['koja-dialogs']:buildRequired({
{
respname = "packed_weed",
label = "Packed Weed",
category = "Narcotics",
required = {
{ respname = "weed", label = "Weed", amount = 5 },
{ respname = "plastic_bag", label = "Plastic Bag", amount = 1 }
}
}
})
}
}
}
}
}
}
},
{
label = "I'll come back!",
player_message = "Not yet, please wait!",
close = true
}
}
},
close = false
}
}
})
Notes:
Player initiates with Hello! asking to pack weed.
After confirmation, Pack weed leads to Give the dope, which opens the Crafting window.
buildRequired()
builds the internal format for recipes.
5. Summary of Fields and Window Differences
Field / Context
Shop
Market
Crafting
data.items
(uses buildRequired
)
{ respname = "weapon_pistol", price = 14250, label = "Pistol", desc = "weapon" }
{ respname = "packed_weed", price = 50, label = "Weed", desc = "Narcotics" }
{ respname = "packed_weed", label = "Packed Weed", category = "Narcotics", required = { { respname = "weed", amount = 5 }, { respname = "plastic_bag", amount = 1 } } }
Buying weapons or other items from an NPC
Selling or buying raw resources (e.g., narcotics)