Allocate memories instead of constant buffer, DRASTICALLY reduces entity

size
main
parent 60787202cb
commit 656d40ce29

@ -551,6 +551,8 @@ void done_with_request(int id)
#endif // WINDOWS
#endif // DESKTOP
Memory *memories_free_list = 0;
TextChunk *text_chunk_free_list = 0;
// s.size must be less than MAX_SENTENCE_LENGTH, or assert fails
@ -965,11 +967,29 @@ bool is_fighting(Entity *player)
void push_memory(Entity *e, Memory new_memory)
{
new_memory.tick_happened = gs.tick;
if(!BUFF_HAS_SPACE(&e->memories))
Memory *memory_allocated = 0;
if(memories_free_list)
{
memory_allocated = memories_free_list;
MD_StackPop(memories_free_list);
}
else
{
memory_allocated = MD_PushArray(persistent_arena, Memory, 1);
}
*memory_allocated = new_memory;
int count = 0;
for(Memory *cur = e->memories_first; cur; cur = cur->next) count += 1;
while(count >= REMEMBERED_MEMORIES)
{
BUFF_REMOVE_FRONT(&e->memories);
Memory *freed = e->memories_first;
MD_DblRemove(e->memories_first, e->memories_last, freed);
MD_StackPush(memories_free_list, freed);
count -= 1;
}
BUFF_APPEND(&e->memories, new_memory);
MD_DblPushBack(e->memories_first, e->memories_last, memory_allocated);
if(!new_memory.context.i_said_this)
{
@ -1594,12 +1614,7 @@ void reset_level()
MD_String8 speech = MD_S8Lit("This is some very important testing dialog. Too important to count. Very very very very important. Super caliafradgalisticexpelaladosis");
memcpy(test_memory.speech, speech.str, speech.size);
test_memory.speech_length = (int)speech.size;
RANGE_ITER(0, 15)
BUFF_APPEND(&it->memories, test_memory);
//RANGE_ITER(0, 20)
//BUFF_APPEND(&it->remembered_perceptions, ((Perception) { .type = PlayerDialog, .player_dialog = SENTENCE_CONST("Testing dialog") }));
//BUFF_APPEND(&it->held_items, ITEM_Chalice);
push_memory(it, test_memory);
}
}
#endif
@ -1826,7 +1841,31 @@ void ser_entity(SerState *ser, Entity *e)
ser_float(ser, &e->opened_amount);
ser_bool(ser, &e->gave_away_sword);
SER_BUFF(ser, Memory, &e->memories);
if(ser->serializing)
{
Memory *cur = e->memories_first;
bool more_memories = cur != 0;
ser_bool(ser, &more_memories);
while(more_memories)
{
ser_Memory(ser, cur);
cur = cur->next;
more_memories = cur != 0;
ser_bool(ser, &more_memories);
}
}
else
{
bool more_memories;
ser_bool(ser, &more_memories);
while(more_memories)
{
Memory *new_chunk = MD_PushArray(ser->arena, Memory, 1);
ser_Memory(ser, new_chunk);
MD_DblPushBack(e->memories_first, e->memories_last, new_chunk);
ser_bool(ser, &more_memories);
}
}
ser_bool(ser, &e->direction_of_spiral_pattern);
ser_float(ser, &e->dialog_panel_opacity);
@ -3454,23 +3493,20 @@ void translate_words_by(PlacedWordList words, Vec2 translation)
MD_String8 last_said_sentence(Entity *npc)
{
assert(npc->is_npc);
int last_speech_index = -1;
BUFF_ITER_I(Memory, &npc->memories, i)
MD_String8 to_return = (MD_String8){0};
Memory *cur = npc->memories_last;
for(Memory *cur = npc->memories_last; cur; cur = cur->prev)
{
if(it->context.author_npc_kind == npc->npc_kind)
if(cur->context.author_npc_kind == npc->npc_kind)
{
last_speech_index = i;
to_return = MD_S8(cur->speech, cur->speech_length);
break;
}
}
if(last_speech_index == -1)
{
return (MD_String8){0};
}
else
{
return MD_S8(npc->memories.data[last_speech_index].speech, npc->memories.data[last_speech_index].speech_length);
}
return to_return;
}
typedef enum
@ -3522,7 +3558,7 @@ Dialog get_dialog_elems(Entity *talking_to, bool character_names)
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
assert(talking_to->is_npc);
Dialog to_return = { 0 };
BUFF_ITER(Memory, &talking_to->memories)
for(Memory *it = talking_to->memories_first; it; it = it->next)
{
if(!it->context.dont_show_to_player)
{

@ -118,6 +118,9 @@ typedef struct
// memories are subjective to an individual NPC
typedef struct Memory
{
struct Memory *prev;
struct Memory *next;
uint64_t tick_happened; // can sort memories by time for some modes of display
// 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
ActionKind action_taken;
@ -250,17 +253,16 @@ typedef struct Entity
bool is_npc;
bool being_hovered;
bool perceptions_dirty;
TextChunk *errorlist_first;
TextChunk *errorlist_last;
#ifdef DESKTOP
int times_talked_to; // for better mocked response string
#endif
bool opened;
float opened_amount;
bool gave_away_sword;
BUFF(Memory, REMEMBERED_MEMORIES) memories;
Memory *memories_first;
Memory *memories_last;
bool direction_of_spiral_pattern;
float dialog_panel_opacity;
int words_said;
@ -499,7 +501,7 @@ MD_String8 generate_chatgpt_prompt(MD_Arena *arena, Entity *e, CanTalkTo can_tal
//MD_S8ListPush(scratch.arena, &list, make_json_node(scratch.arena, MSG_SYSTEM, MD_S8ListJoin(scratch.arena, first_system_string, &(MD_StringJoin){0})));
MD_S8ListPush(scratch.arena, &list, make_json_node(scratch.arena, MSG_SYSTEM, MD_S8ListJoin(scratch.arena, first_system_string, &(MD_StringJoin){0})));
BUFF_ITER(Memory, &e->memories)
for(Memory *it = e->memories_first; it; it = it->next)
{
MessageType sent_type = -1;
MD_String8List cur_list = {0};
@ -639,11 +641,11 @@ MD_String8 generate_chatgpt_prompt(MD_Arena *arena, Entity *e, CanTalkTo can_tal
// last thought explanation and re-prompt
{
MD_String8 last_thought_string = {0};
BUFF_ITER(Memory, &e->memories)
for(Memory *cur = e->memories_first; cur; cur = cur->next)
{
if(it->internal_monologue_length > 0)
if(cur->internal_monologue_length > 0)
{
last_thought_string = MD_S8(it->internal_monologue, it->internal_monologue_length);
last_thought_string = MD_S8(cur->internal_monologue, cur->internal_monologue_length);
}
}
PushWithLint(scratch.arena, &latest_state, "Your last thought was: %.*s\n", MD_S8VArg(last_thought_string));

Loading…
Cancel
Save