Factor out duplicated information across action and context in memory

main
Cameron Murphy Reikes 7 months ago
parent c928a09255
commit 6641f6488b

@ -4,7 +4,7 @@
{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: "THIS DAMNED FOOL DOESN'T UNDERSTAND RESPECT", to: Raphael} {enum: Daniel, dialog: "THIS DAMNED FOOL DOESN'T UNDERSTAND RESPECT", to: Raphael}
{enum: Raphael, dialog: "Easy man, easy. I ain't much for helpin' folk but you're outta control.", to: Daniel} {enum: Raphael, dialog: "Easy man, easy. I ain't much for helpin' folk but you're outta control.", to: Daniel}
@ -32,14 +32,14 @@
{enum: Daniel, dialog: "ANOTHER QUESTION??? YOU HAD THIS COMING TO YOU!", to: PreviousPlayer1, action: ACT_fire_shotgun} {enum: Daniel, dialog: "ANOTHER QUESTION??? YOU HAD THIS COMING TO YOU!", to: PreviousPlayer1, action: ACT_fire_shotgun}
{enum: Raphael, dialog: "Oh God! What have you done??", to: Daniel} {enum: Raphael, dialog: "Oh God! What have you done??", to: Daniel}
{enum: Daniel, dialog: "Exactly what I'll do to you if you don't keep your mouth shut", to: Raphael, action: ACT_put_shotgun_away} {enum: Daniel, dialog: "Exactly what I'll do to you if you don't keep your mouth shut", to: Raphael, action: ACT_put_shotgun_away}
{enum: Raphael, dialog: "Y-y-y-yes sir.", to: Daniel, action: ACT_end_conversation, action_argument: "Daniel"} {enum: Raphael, dialog: "Y-y-y-yes sir.", to: Daniel, action: ACT_end_conversation, action.argument: "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"}
] ]

Binary file not shown.

@ -4,7 +4,7 @@
// @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.
const char *global_prompt = const char *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"

@ -1892,10 +1892,8 @@ Entity *get_targeted(Entity *from, NpcKind targeted)
Memory make_memory(ActionOld a, MemoryContext context) Memory make_memory(ActionOld a, MemoryContext context)
{ {
Memory new_memory = {0}; Memory new_memory = {0};
new_memory.speech = a.speech; new_memory.action = a;
new_memory.action_taken = a.kind;
new_memory.context = context; new_memory.context = context;
new_memory.action_argument = a.argument;
return new_memory; return new_memory;
} }
@ -1998,7 +1996,7 @@ String8 is_action_valid(Arena *arena, Entity *from, ActionOld a)
} }
if (arg_valid == false) if (arg_valid == false)
{ {
error_message = FmtWithLint(arena, "Your action_argument for who the action `%s` be directed at, %.*s, is either invalid (you can't operate on nobody) or it's not an NPC that's near you right now.", actions[a.kind].name, TextChunkVArg(npc_data(&gs, a.argument.targeting)->name)); error_message = FmtWithLint(arena, "Your action.argument for who the action `%s` be directed at, %.*s, is either invalid (you can't operate on nobody) or it's not an NPC that's near you right now.", actions[a.kind].name, TextChunkVArg(npc_data(&gs, a.argument.targeting)->name));
} }
} }
@ -2091,8 +2089,6 @@ bool perform_action(GameState *gs, Entity *from, ActionOld a)
if (a.speech.text_length > 0) if (a.speech.text_length > 0)
from->dialog_fade = 2.5f; from->dialog_fade = 2.5f;
context.talking_to_kind = a.talking_to_kind;
String8 is_valid = is_action_valid(scratch.arena, from, a); String8 is_valid = is_action_valid(scratch.arena, from, a);
bool proceed_propagating = true; bool proceed_propagating = true;
if (is_valid.size > 0) if (is_valid.size > 0)
@ -4902,9 +4898,9 @@ String8 last_said_sentence(Entity *npc)
for (Memory *cur = npc->memories_last; cur; cur = cur->prev) for (Memory *cur = npc->memories_last; cur; cur = cur->prev)
{ {
if (cur->context.author_npc_kind == npc->npc_kind && cur->speech.text_length > 0) if (cur->context.author_npc_kind == npc->npc_kind && cur->action.speech.text_length > 0)
{ {
to_return = TextChunkString8(cur->speech); to_return = TextChunkString8(cur->action.speech);
break; break;
} }
} }
@ -6336,7 +6332,7 @@ void frame(void)
if (words_over_limit > 0) if (words_over_limit > 0)
{ {
String8 new_err = FmtWithLint(frame_arena, "Your speech is %d words over the maximum limit, you must be more succinct and remove at least that many words", words_over_limit); String8 new_err = FmtWithLint(frame_arena, "Your speech is %d words over the maximum limit, you must be more succinct and remove at least that many words", words_over_limit);
append_to_errors(it, make_memory(out, (MemoryContext){.i_said_this = true, .author_npc_kind = it->npc_kind, .talking_to_kind = out.talking_to_kind}), new_err); append_to_errors(it, make_memory(out, (MemoryContext){.i_said_this = true, .author_npc_kind = it->npc_kind,}), new_err);
} }
else else
{ {
@ -6796,7 +6792,7 @@ void frame(void)
if (mocking_the_ai_response) if (mocking_the_ai_response)
{ {
String8 ai_response = {0}; String8 ai_response = {0};
if (it->memories_last->context.talking_to_kind == it->npc_kind) if (it->memories_last->action.talking_to_kind == it->npc_kind)
// if (it->memories_last->context.author_npc_kind != it->npc_kind) // if (it->memories_last->context.author_npc_kind != it->npc_kind)
{ {
const char *action = 0; const char *action = 0;
@ -7205,10 +7201,10 @@ void frame(void)
cur_pos.y -= aabb_size(bounds).y; cur_pos.y -= aabb_size(bounds).y;
for (Memory *cur = to_view->memories_first; cur; cur = cur->next) for (Memory *cur = to_view->memories_first; cur; cur = cur->next)
if (cur->speech.text_length > 0) if (cur->action.speech.text_length > 0)
{ {
String8 to_text = cur->context.talking_to_kind != NPC_nobody ? S8Fmt(frame_arena, " to %.*s ", TextChunkVArg(npc_data(&gs, cur->context.talking_to_kind)->name)) : S8Lit(""); String8 to_text = cur->action.talking_to_kind != NPC_nobody ? S8Fmt(frame_arena, " to %.*s ", TextChunkVArg(npc_data(&gs, cur->action.talking_to_kind)->name)) : S8Lit("");
String8 text = S8Fmt(frame_arena, "%s%.*s%.*s: %.*s", to_view->npc_kind == cur->context.author_npc_kind ? "(Me) " : "", TextChunkVArg(npc_data(&gs, cur->context.author_npc_kind)->name), S8VArg(to_text), cur->speech.text_length, cur->speech); String8 text = S8Fmt(frame_arena, "%s%.*s%.*s: %.*s", to_view->npc_kind == cur->context.author_npc_kind ? "(Me) " : "", TextChunkVArg(npc_data(&gs, cur->context.author_npc_kind)->name), S8VArg(to_text), cur->action.speech.text_length, cur->action.speech);
AABB bounds = draw_text((TextParams){false, text, cur_pos, WHITE, 1.0}); AABB bounds = draw_text((TextParams){false, text, cur_pos, WHITE, 1.0});
cur_pos.y -= aabb_size(bounds).y; cur_pos.y -= aabb_size(bounds).y;
} }
@ -7220,8 +7216,8 @@ void frame(void)
int mem_idx = 0; int mem_idx = 0;
for (Memory *cur = to_view->memories_first; cur; cur = cur->next) for (Memory *cur = to_view->memories_first; cur; cur = cur->next)
{ {
String8 to_text = cur->context.talking_to_kind != NPC_nobody ? S8Fmt(frame_arena, " to %.*s ", TextChunkVArg(npc_data(&gs, cur->context.talking_to_kind)->name)) : S8Lit(""); String8 to_text = cur->action.talking_to_kind != NPC_nobody ? S8Fmt(frame_arena, " to %.*s ", TextChunkVArg(npc_data(&gs, cur->action.talking_to_kind)->name)) : S8Lit("");
String8 speech = TextChunkString8(cur->speech); String8 speech = TextChunkString8(cur->action.speech);
if (speech.size == 0) if (speech.size == 0)
speech = S8Lit("<said nothing>"); speech = S8Lit("<said nothing>");
String8 text = S8Fmt(frame_arena, "%s%.*s%.*s: %.*s", to_view->npc_kind == cur->context.author_npc_kind ? "(Me) " : "", TextChunkVArg(npc_data(&gs, cur->context.author_npc_kind)->name), S8VArg(to_text), S8VArg(speech)); String8 text = S8Fmt(frame_arena, "%s%.*s%.*s: %.*s", to_view->npc_kind == cur->context.author_npc_kind ? "(Me) " : "", TextChunkVArg(npc_data(&gs, cur->context.author_npc_kind)->name), S8VArg(to_text), S8VArg(speech));

@ -122,8 +122,6 @@ typedef struct
{ {
bool i_said_this; // don't trigger npc action on own self memory modification bool i_said_this; // don't trigger npc action on own self memory modification
NpcKind author_npc_kind; NpcKind author_npc_kind;
NpcKind talking_to_kind;
bool heard_physically; // if not physically, the source was directly
} MemoryContext; } MemoryContext;
// memories are subjective to an individual NPC // memories are subjective to an individual NPC
@ -132,12 +130,8 @@ typedef struct Memory
struct Memory *prev; struct Memory *prev;
struct Memory *next; struct Memory *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 ActionOld action;
ActionKind action_taken;
ActionArgument action_argument;
MemoryContext context; MemoryContext context;
TextChunk speech;
} Memory; } Memory;
// text chunk must be a literal, not a pointer // text chunk must be a literal, not a pointer
@ -578,11 +572,11 @@ String8List dump_memory_as_json(Arena *arena, GameState *gs, Memory *it)
#define AddFmt(...) PushWithLint(arena, &current_list, __VA_ARGS__) #define AddFmt(...) PushWithLint(arena, &current_list, __VA_ARGS__)
AddFmt("{"); AddFmt("{");
AddFmt("\"speech\":\"%.*s\",", TextChunkVArg(it->speech)); AddFmt("\"speech\":\"%.*s\",", TextChunkVArg(it->action.speech));
AddFmt("\"action\":\"%s\",", actions[it->action_taken].name); AddFmt("\"action\":\"%s\",", actions[it->action.kind].name);
String8 arg_str = action_argument_string(scratch.arena, gs, it->action_argument); String8 arg_str = action_argument_string(scratch.arena, gs, it->action.argument);
AddFmt("\"action_argument\":\"%.*s\",", S8VArg(arg_str)); AddFmt("\"action.argument\":\"%.*s\",", S8VArg(arg_str));
AddFmt("\"target\":\"%.*s\"}", TextChunkVArg(npc_data(gs, it->context.talking_to_kind)->name)); AddFmt("\"target\":\"%.*s\"}", TextChunkVArg(npc_data(gs, it->action.talking_to_kind)->name));
#undef AddFmt #undef AddFmt
ReleaseScratch(scratch); ReleaseScratch(scratch);
@ -597,55 +591,55 @@ String8List memory_description(Arena *arena, GameState *gs, Entity *e, Memory *i
bool no_longer_wants_to_converse = false; // add the no longer wants to converse text after any speech, it makes more sense reading it bool no_longer_wants_to_converse = false; // add the no longer wants to converse text after any speech, it makes more sense reading it
#define HUMAN(kind) S8VArg(npc_to_human_readable(gs, e, kind)) #define HUMAN(kind) S8VArg(npc_to_human_readable(gs, e, kind))
if (it->action_taken != ACT_none) if (it->action.kind != ACT_none)
{ {
switch (it->action_taken) switch (it->action.kind)
{ {
case ACT_none: case ACT_none:
break; break;
case ACT_join: case ACT_join:
AddFmt("%.*s joined %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action_argument.targeting)); AddFmt("%.*s joined %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.argument.targeting));
break; break;
case ACT_leave: case ACT_leave:
AddFmt("%.*s left their party\n", HUMAN(it->context.author_npc_kind)); AddFmt("%.*s left their party\n", HUMAN(it->context.author_npc_kind));
break; break;
case ACT_aim_shotgun: case ACT_aim_shotgun:
AddFmt("%.*s aimed their shotgun at %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action_argument.targeting)); AddFmt("%.*s aimed their shotgun at %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.argument.targeting));
break; break;
case ACT_fire_shotgun: case ACT_fire_shotgun:
AddFmt("%.*s fired their shotgun at %.*s, brutally murdering them.\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action_argument.targeting)); AddFmt("%.*s fired their shotgun at %.*s, brutally murdering them.\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.argument.targeting));
break; break;
case ACT_put_shotgun_away: case ACT_put_shotgun_away:
AddFmt("%.*s holstered their shotgun, no longer threatening anybody\n", HUMAN(it->context.author_npc_kind)); AddFmt("%.*s holstered their shotgun, no longer threatening anybody\n", HUMAN(it->context.author_npc_kind));
break; break;
case ACT_approach: case ACT_approach:
AddFmt("%.*s approached %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action_argument.targeting)); AddFmt("%.*s approached %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.argument.targeting));
break; break;
case ACT_end_conversation: case ACT_end_conversation:
no_longer_wants_to_converse = true; no_longer_wants_to_converse = true;
break; break;
case ACT_assign_gameplay_objective: case ACT_assign_gameplay_objective:
AddFmt("%.*s assigned a definitive game objective to %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->context.talking_to_kind)); AddFmt("%.*s assigned a definitive game objective to %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.talking_to_kind));
break; break;
case ACT_award_victory: case ACT_award_victory:
AddFmt("%.*s awarded victory to %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->context.talking_to_kind)); AddFmt("%.*s awarded victory to %.*s\n", HUMAN(it->context.author_npc_kind), HUMAN(it->action.talking_to_kind));
break; break;
} }
} }
if (it->speech.text_length > 0) if (it->action.speech.text_length > 0)
{ {
String8 target_string = S8Lit("the world"); String8 target_string = S8Lit("the world");
if (it->context.talking_to_kind != NPC_nobody) if (it->action.talking_to_kind != NPC_nobody)
{ {
if (it->context.talking_to_kind == e->npc_kind) if (it->action.talking_to_kind == e->npc_kind)
target_string = S8Lit("you"); target_string = S8Lit("you");
else else
target_string = TextChunkString8(npc_data(gs, it->context.talking_to_kind)->name); target_string = TextChunkString8(npc_data(gs, it->action.talking_to_kind)->name);
} }
if(!e->is_world) if(!e->is_world)
{ {
if(it->context.talking_to_kind == e->npc_kind) if(it->action.talking_to_kind == e->npc_kind)
{ {
AddFmt("(Speaking directly you) "); AddFmt("(Speaking directly you) ");
} }
@ -654,7 +648,7 @@ String8List memory_description(Arena *arena, GameState *gs, Entity *e, Memory *i
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", TextChunkVArg(npc_data(gs, 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)", TextChunkVArg(npc_data(gs, e->npc_kind)->name)); AddFmt(" (you are %.*s)", TextChunkVArg(npc_data(gs, e->npc_kind)->name));
@ -664,13 +658,13 @@ String8List memory_description(Arena *arena, GameState *gs, Entity *e, Memory *i
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));
} }
} }
#undef HUMAN #undef HUMAN
@ -749,7 +743,7 @@ String8 generate_chatgpt_prompt(Arena *arena, GameState *gs, Entity *e, CanTalkT
AddFmt("Errors you made: \n"); AddFmt("Errors you made: \n");
for(RememberedError *cur = e->errorlist_first; cur; cur = cur->next) for(RememberedError *cur = e->errorlist_first; cur; cur = cur->next)
{ {
if(cur->offending_self_output.speech.text_length > 0 || cur->offending_self_output.action_taken != ACT_none) if(cur->offending_self_output.action.speech.text_length > 0 || cur->offending_self_output.action.kind != ACT_none)
{ {
String8 offending_json_output = S8ListJoin(scratch.arena, dump_memory_as_json(scratch.arena, gs, &cur->offending_self_output), &(StringJoin){0}); String8 offending_json_output = S8ListJoin(scratch.arena, dump_memory_as_json(scratch.arena, gs, &cur->offending_self_output), &(StringJoin){0});
AddFmt("When you output, `%.*s`, ", S8VArg(offending_json_output)); AddFmt("When you output, `%.*s`, ", S8VArg(offending_json_output));
@ -843,7 +837,7 @@ String8 parse_chatgpt_response(Arena *arena, GameState *gs, Entity *e, String8 a
{ {
speech_str = get_field(message_obj, S8Lit("speech")); speech_str = get_field(message_obj, S8Lit("speech"));
action_str = get_field(message_obj, S8Lit("action")); action_str = get_field(message_obj, S8Lit("action"));
action_argument_str = get_field(message_obj, S8Lit("action_argument")); action_argument_str = get_field(message_obj, S8Lit("action.argument"));
target_str = get_field(message_obj, S8Lit("target")); target_str = get_field(message_obj, S8Lit("target"));
} }
if(error_message.size == 0 && action_str.size == 0) if(error_message.size == 0 && action_str.size == 0)

Loading…
Cancel
Save