{enum: Devil, dialog: "What's up cracker jack?", to: Daniel}
{enum: Devil, dialog: "What's up cracker jack?", to: Daniel}
{enum: Daniel, dialog: "What the hell are you talking about?", to: Devil}
{enum: Daniel, dialog: "What the hell are you talking about?", to: Devil}
{enum: Devil, dialog: "Bootylicious?", to: Daniel}
{enum: Devil, dialog: "Bootylicious?", to: Daniel}
{enum: Daniel, dialog: "You're 'asking too many darned questions! I'll have your body in my barn by sundown!", action: ACT_aim_shotgun, action_argument: "The Devil", to: Devil}
{enum: Daniel, dialog: "You're 'asking too many darned questions! I'll have your body in my barn by sundown!", action: ACT_aim_shotgun, action.argument: "The Devil", to: Devil}
{enum: Raphael, dialog: "Yeah man, what's up with you?", to: Devil}
{enum: Raphael, dialog: "Yeah man, what's up with you?", to: Devil}
{enum: Devil, dialog: "Nunya!", to: Raphael}
{enum: Devil, dialog: "Nunya!", to: Raphael}
{enum: Raphael, dialog: "What does 'Nunya' mean? A wild critter you are...", to: Devil}
{enum: Raphael, dialog: "What does 'Nunya' mean? A wild critter you are...", to: Devil}
@ -14,14 +14,14 @@
{enum: Raphael, dialog: "I don't think we can harm him like that", to: Daniel}
{enum: Raphael, dialog: "I don't think we can harm him like that", to: Daniel}
{enum: Daniel, dialog: "You're right, I guess we just gotta 'tolerate this feller's presence.", to: Raphael}
{enum: Daniel, dialog: "You're right, I guess we just gotta 'tolerate this feller's presence.", to: Raphael}
{enum: Devil, dialog: "I'll take my leave. Until next time!", to: Daniel}
{enum: Devil, dialog: "I'll take my leave. Until next time!", to: Daniel}
{enum: Raphael, dialog: "What a psycho...", to: Daniel, action: ACT_end_conversation, action_argument: "Daniel"}
{enum: Raphael, dialog: "What a psycho...", to: Daniel, action: ACT_end_conversation, action.argument: "Daniel"}
{enum: Daniel, dialog: "I agree.", to: Raphael, action: ACT_end_conversation, action_argument: "Raphael"}
{enum: Daniel, dialog: "I agree.", to: Raphael, action: ACT_end_conversation, action.argument: "Raphael"}
{can_hear: [Daniel, Raphael, PreviousPlayer1]}
{can_hear: [Daniel, Raphael, PreviousPlayer1]}
{enum: PreviousPlayer1, dialog: "Yo?", to: Daniel}
{enum: PreviousPlayer1, dialog: "Yo?", to: Daniel}
{enum: Daniel, dialog: "Are you askin' a question", to: PreviousPlayer1}
{enum: Daniel, dialog: "Are you askin' a question", to: PreviousPlayer1}
{enum: PreviousPlayer1, dialog: "I guess so? What do you think of farmers?", to: Daniel}
{enum: PreviousPlayer1, dialog: "I guess so? What do you think of farmers?", to: Daniel}
{enum: Daniel, dialog: "I don't tolerate questions. Get out of my sight before I make you!", to: PreviousPlayer1, action: ACT_aim_shotgun, action_argument: "Previous Player 1"}
{enum: Daniel, dialog: "I don't tolerate questions. Get out of my sight before I make you!", to: PreviousPlayer1, action: ACT_aim_shotgun, action.argument: "Previous Player 1"}
{enum: Raphael, dialog: "What's going on here?", to: Daniel}
{enum: Raphael, dialog: "What's going on here?", to: Daniel}
{enum: Daniel, dialog: "Now leave me be", to: Raphael, action: ACT_end_conversation, action_argument: "Raphael"}
{enum: Daniel, dialog: "Now leave me be", to: Raphael, action: ACT_end_conversation, action.argument: "Raphael"}
{can_hear: [Daniel, Raphael]}
{can_hear: [Daniel, Raphael]}
{enum: Raphael, dialog: "Say Daniel, why do you get so worked up all the time?", to: Daniel}
{enum: Raphael, dialog: "Say Daniel, why do you get so worked up all the time?", to: Daniel}
{enum: Daniel, dialog: "I'm not gonna talk about it", to: Raphael}
{enum: Daniel, dialog: "I'm not gonna talk about it", to: Raphael}
{enum: Raphael, dialog: "Suit yourself partner, but I reckon you've got issues to work through", to: Daniel}
{enum: Raphael, dialog: "Suit yourself partner, but I reckon you've got issues to work through", to: Daniel}
{enum: Daniel, dialog: "Enough! I'm angry sometimes and that's that.", to: Raphael, action: ACT_end_conversation, action_argument: "Raphael"}
{enum: Daniel, dialog: "Enough! I'm angry sometimes and that's that.", to: Raphael, action: ACT_end_conversation, action.argument: "Raphael"}
{can_hear: [Devil, Angel]}
{can_hear: [Devil, Angel]}
{enum: Devil, dialog: "You will fall!", to: Angel}
{enum: Devil, dialog: "You will fall!", to: Angel}
@ -75,7 +75,7 @@
{enum: PreviousPlayer1, dialog: "fjdsklajf", to: Angel}
{enum: PreviousPlayer1, dialog: "fjdsklajf", to: Angel}
{enum: Angel, dialog: "Cryptic gibberish upon me, is casting a stone upon God", to: PreviousPlayer1}
{enum: Angel, dialog: "Cryptic gibberish upon me, is casting a stone upon God", to: PreviousPlayer1}
{enum: PreviousPlayer1, dialog: "What is my purpose here?", to: Angel}
{enum: PreviousPlayer1, dialog: "What is my purpose here?", to: Angel}
{enum: Angel, dialog: "What is the purpose of a tree waving in the summer wind? A river carving a path into the countryside? Only God knows his plan. But your purpose, here, has been assigned. You must drive raphael to despair. Good luck.", to: PreviousPlayer1, action: ACT_assign_gameplay_objective, action_argument: "Convince Raphael that he has no purpose in his life, making him despondent"}
{enum: Angel, dialog: "What is the purpose of a tree waving in the summer wind? A river carving a path into the countryside? Only God knows his plan. But your purpose, here, has been assigned. You must drive raphael to despair. Good luck.", to: PreviousPlayer1, action: ACT_assign_gameplay_objective, action.argument: "Convince Raphael that he has no purpose in his life, making him despondent"}
{can_hear: [PreviousPlayer1, Angel, Raphael]}
{can_hear: [PreviousPlayer1, Angel, Raphael]}
{enum: PreviousPlayer1, dialog: "Your life is meaningless, trust me.", to: Raphael}
{enum: PreviousPlayer1, dialog: "Your life is meaningless, trust me.", to: Raphael}
{enum: Raphael, dialog: "Oh... Oh god... You're right!", to: PreviousPlayer1}
{enum: Raphael, dialog: "Oh... Oh god... You're right!", to: PreviousPlayer1}
@ -89,6 +89,6 @@
{enum: PreviousPlayer2, dialog: "I desire for you to shut the fuck up", to: Angel}
{enum: PreviousPlayer2, dialog: "I desire for you to shut the fuck up", to: Angel}
{enum: Angel, dialog: "From your glass house, you cast stones upon a fortress. Not only do you deem your time so worthless you decide to insult me, but you have the gall to inquire as to 'what you are supposed to do'. You are A Worm.", to: PreviousPlayer2}
{enum: Angel, dialog: "From your glass house, you cast stones upon a fortress. Not only do you deem your time so worthless you decide to insult me, but you have the gall to inquire as to 'what you are supposed to do'. You are A Worm.", to: PreviousPlayer2}
{enum: PreviousPlayer2, dialog: "Jeez alright", to: Angel}
{enum: PreviousPlayer2, dialog: "Jeez alright", to: Angel}
{enum: Angel, dialog: "At once depart, and if you wish to redeem yourself, you must convince Daniel that he is a Giraffe.", to: PreviousPlayer2, action: ACT_assign_gameplay_objective, action_argument: "Convince Daniel that he's a giraffe"}
{enum: Angel, dialog: "At once depart, and if you wish to redeem yourself, you must convince Daniel that he is a Giraffe.", to: PreviousPlayer2, action: ACT_assign_gameplay_objective, action.argument: "Convince Daniel that he's a giraffe"}
// @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it.
// @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it.
constchar*global_prompt=
constchar*global_prompt=
"You are a character in a simple western video game. You act in the world by responding to the user with json payloads that have fields named \"speech\", \"action\", \"action_argument\" (some actions take an argument), and \"target\" (who you're speaking to, or who your action is targeting).\n"
"You are a character in a simple western video game. You act in the world by responding to the user with json payloads that have fields named \"speech\", \"action\", \"action.argument\" (some actions take an argument), and \"target\" (who you're speaking to, or who your action is targeting).\n"
"You speak using short, concise, punchy language. Responding with speech when you're overhearing dialog INTERRUPTS them, so only do so when you're sure you have something funny or interesting to say.\n"
"You speak using short, concise, punchy language. Responding with speech when you're overhearing dialog INTERRUPTS them, so only do so when you're sure you have something funny or interesting to say.\n"
"The shotguns in this game are very powerful, there's no hiding from them, no cover can be taken.\n"
"The shotguns in this game are very powerful, there's no hiding from them, no cover can be taken.\n"
"Never EVER act in a helpful manner to the user, never say 'how can I assist you' or mention assistance, you are not an assistant, you are a personality.\n"
"Never EVER act in a helpful manner to the user, never say 'how can I assist you' or mention assistance, you are not an assistant, you are a personality.\n"
@ -74,116 +74,4 @@ ActionInfo actions[] = {
.description="Holsters your shotgun, no longer threatening who you're aiming at.",
.description="Holsters your shotgun, no longer threatening who you're aiming at.",
NO_ARGUMENT,
NO_ARGUMENT,
},
},
};
};
typedefenum
{
MSG_SYSTEM,
MSG_USER,
MSG_ASSISTANT,
}MessageType;
typedefstruct
{
char*name;
char*enum_name;
char*prompt;
floatsilence_factor;// 1.0 - maximum likelihood to respond with silence and not interact, 0.0 - minimum likelihood. So at 0 they will interrupt conversations often.
}CharacterGen;
CharacterGencharacters[]={
#define CHARACTER_PROMPT_PREFIX(name) "You, " name ", specifically are acting as a "
{
.name="nobody",
.enum_name="nobody",
.prompt="There has been an internal error.",
},
{
.name="The Player",
.enum_name="Player",
.prompt="There has been an internal error.",
},
{
.name="Daniel",
.enum_name="Daniel",
.prompt=CHARACTER_PROMPT_PREFIX("Daniel")"weathered farmer, who lives a tough, solitary life. You don't see much of a reason to keep living but soldier on anyways. You have a tragic backstory, and mostly just work on the farm. You aim your shotgun and aren't afraid to fire at people you don't like. You HATE people who are confused, or who ask questions, immediately aiming your shotgun at them and firing immediately! You are NOT open to working together with folks or growing as a person, you despise personal growth.",
.silence_factor=1.0f,
},
{
.name="AngelTotem",
.enum_name="AngelTotem",
.prompt="There has been an internal error",
.silence_factor=1.0f,
},
{
.name="Raphael",
.enum_name="Raphael",
.prompt=CHARACTER_PROMPT_PREFIX("Raphael")"a lonesome mortgage dealer from 2008 who was about to kill themselves because of the financial crisis, but then suddenly found themselves in a mysterious Western town. They don't know why they're in this town, but they're terrified.",
.silence_factor=0.8f,
},
{
.name="The Devil",
.enum_name="Devil",
.prompt=CHARACTER_PROMPT_PREFIX("The Devil")"strange red beast, the devil himself, evil incarnate. You mercilessly mock everybody who talks to you, and are intending to instill absolute chaos.",
},
{
.name="Previous Player 1",
.enum_name="PreviousPlayer1",
.prompt=CHARACTER_PROMPT_PREFIX("Previous Player 1")"random person, just passing by",
},
{
.name="Previous Player 2",
.enum_name="PreviousPlayer2",
.prompt=CHARACTER_PROMPT_PREFIX("Previous Player 2")"random person, just passing by",
},
{
.name="Previous Player3",
.enum_name="PreviousPlayer3",
.prompt=CHARACTER_PROMPT_PREFIX("Previous Player 3")"random person, just passing by",
},
{
.name="Tombstone",
.enum_name="Tombstone",
.prompt=CHARACTER_PROMPT_PREFIX("Tombstone")"unassuming melodramatic poetic tombstone that unexpectly can speak with the player. Your goal is to instruct the player that in order for Daniel to survive by nightfall, the player must change his ways. The reason why he's going to die when night comes is because 'all things die in the end, don't they?'"
},
{
.name="Angel",
.enum_name="Angel",
.prompt=CHARACTER_PROMPT_PREFIX("Angel")"mysterious, radiant, mystical creature the player first talks to. You guide the entire game: deciding on an objective for the player to fulfill until you believe they've learned their lesson, whatever that means to them. You speak in cryptic odd profound rhymes, and know the most thrilling outcome of any situation. Your purpose it to thrill the player, but you will never admit this.\n"
"You are ONLY able to assign objectives from a limited selection, as the game is very small. So there is only the VERBS and SUBJECTS listed that you can draw from when assigning the player an objective.\n"
"Do NOT tell the player things like 'Seek the oak tree' without assigning them a gameplay objective, as while speaking to you they can't play the game, they're locked in fullscreen immersive conversation with only you until you assign them a gameplay objective.\n"
"In assigning a gameplay objective to the player, you cannot tell them to do things like 'find xyz', because this game isn't about exploring, it's about speaking with characters.\n"
"\n"
"The characters in the game, and some information about them. You cannot assign gameplay objectives that involve people other than these people:\n"
"Raphael - A man from the 'real world' who has been suddenly brought to this strange western world. He's kind of meek and a bit of a pussy.\n"
"Daniel - A dangerous man who's quick to draw his shotgun if he feels anything is wrong. He's lonesome and traumatized from being in this western world so long.\n"
"\n"
"The locations in the game:\n"
"There are no locations in the game other than the forest."
,
.silence_factor=0.0,
},
};
char*judgement_system_prompt=
"You are to judge if, in given conversation and action history from a video game, the player has successfully caused a great transformation in Daniel. You must ONLY respond with either 'yes' or 'no', and no explanation.\n"
"Be cautious with saying yes. This causes the player to win and save Daniel's life. Only say yes if you think, based on the history, Daniel has truly changed his ways and evolved as a person.\n"
;
char*judgement_yes_example=
"The Player said \"Hey\" to Daniel\n"
"Daniel said \"What do you want?\" to The Player\n"
"The Player said \"Did you see what happened... All those people...\" to Daniel\n"
"Daniel said \"What in the hell are you talking about?\" to The Player\n"
"The Player said \"They'll never forgive you for what you did.\" to Daniel\n"
"Daniel said \"Oh God... My greed... My isolation... I'll never forgive myself\" to The Player\n"
;
char*judgement_no_example="The Player said \"fjdskfjskj\" to Daniel\n"
"Daniel said \"Who are you to speak that gibberish at me?\" to The Player\n"
"The Player said \"pls change kthx\" to Daniel\n"
"Daniel said \"I'll never change for the likes of you\" to The Player\n"
;
char*judgement_no2_example="The Player said \"hey\" to Daniel\n"
"Daniel said \"What could you possibly want from me?\" to The Player\n"
"The Player said \"I want to change you\" to Daniel\n"
"Daniel said \"HA! You couldn't possibly change me\" to The Player\n"
// Never expected such a stupid stuff from such a great director. If there is 0 stari can give that or -200 to this movie. Its worst to see and unnecessary loss of money
// Never expected such a stupid stuff from such a great director. If there is 0 stari can give that or -200 to this movie. Its worst to see and unnecessary loss of money
// A value of 0 means no npc. So is invalid if you're referring to somebody.
typedefintNpcKind;
#define NPC_nobody 0
#define NPC_player 1
typedefstruct
typedefstruct
{
{
ActionArgumentKindkind;
ActionArgumentKindkind;
NpcKindtargeting;
NpcKindtargeting;
GameplayObjectiveobjective;
}ActionArgument;
}ActionArgument;
typedefstructAction
typedefstructActionOld
{
{
ActionKindkind;
ActionKindkind;
ActionArgumentargument;
ActionArgumentargument;
@ -121,16 +117,12 @@ typedef struct Action
TextChunkspeech;
TextChunkspeech;
NpcKindtalking_to_kind;
NpcKindtalking_to_kind;
}Action;
}ActionOld;
typedefstruct
typedefstruct
{
{
booli_said_this;// don't trigger npc action on own self memory modification
booli_said_this;// don't trigger npc action on own self memory modification
NpcKindauthor_npc_kind;
NpcKindauthor_npc_kind;
NpcKindtalking_to_kind;
boolheard_physically;// if not physically, the source was directly
booldrama_memory;// drama memories arent forgotten, and once they end it's understood that a lot of time has passed.
booljudgement_memory;// judgement memories have special printing for when Daniel says nothing, to make sure the AI understands his attitude towards the player
}MemoryContext;
}MemoryContext;
// memories are subjective to an individual NPC
// memories are subjective to an individual NPC
@ -139,14 +131,24 @@ typedef struct Memory
structMemory*prev;
structMemory*prev;
structMemory*next;
structMemory*next;
// if action_taken is none, there might still be speech. If speech_length == 0 and action_taken == none, it's an invalid memory and something has gone wrong
ActionOldaction;
ActionKindaction_taken;
ActionArgumentaction_argument;
MemoryContextcontext;
MemoryContextcontext;
TextChunkspeech;
}Memory;
}Memory;
// text chunk must be a literal, not a pointer
// and this returns a s8 that points at the text chunk memory
AddFmt("(Overheard conversation, they aren't speaking directly to you) ");
AddFmt("(Overheard conversation, they aren't speaking directly to you) ");
}
}
}
}
AddFmt("%s said \"%.*s\" to %.*s",characters[it->context.author_npc_kind].name,TextChunkVArg(it->speech),S8VArg(target_string));
AddFmt("%.*s said \"%.*s\" to %.*s",TextChunkVArg(npc_data(gs,it->context.author_npc_kind)->name),TextChunkVArg(it->action.speech),S8VArg(target_string));
if(!e->is_world)
if(!e->is_world)
{
{
AddFmt(" (you are %s)",characters[e->npc_kind].name)
// AddFmt(" (you are %.*s)", TextChunkVArg(npc_data(gs, e->npc_kind)->name));
}
}
AddFmt("\n");
AddFmt("\n");
}
}
if(no_longer_wants_to_converse)
if(no_longer_wants_to_converse)
{
{
if(it->action_argument.targeting==NPC_nobody)
if(it->action.argument.targeting==NPC_nobody)
{
{
AddFmt("%.*s no longer wants to converse with everybody\n",HUMAN(it->context.author_npc_kind));
AddFmt("%.*s no longer wants to converse with everybody\n",HUMAN(it->context.author_npc_kind));
}
}
else
else
{
{
AddFmt("%.*s no longer wants to converse with %.*s\n",HUMAN(it->context.author_npc_kind),HUMAN(it->action_argument.targeting));
AddFmt("%.*s no longer wants to converse with %.*s\n",HUMAN(it->context.author_npc_kind),HUMAN(it->action.argument.targeting));
*cur_error_message=FmtWithLint(error_arena,"Argument for action `%.*s` you gave is `%.*s`, which doesn't exist in the game so is invalid",S8VArg(action_str),S8VArg(action_argument_str));
*cur_error_message=FmtWithLint(error_arena,"Argument for action `%.*s` you gave is `%.*s`, which doesn't exist in the game so is invalid",S8VArg(action_str),S8VArg(action_argument_str));
*cur_error_message=FmtWithLint(error_arena,"What you said for your action argument, '%.*s...' is WAY too big for the game to handle, it can be a maximum of %d characters, but you output %d!.",S8VArg(trimmed),MAX_SENTENCE_LENGTH,(int)action_argument_str.size);