From 0dfe102c3e0f010c105c0e9f4fb98cd9e2470d27 Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Sat, 13 May 2023 23:43:49 -0700 Subject: [PATCH] Cull quads before queueing, fix GNARLY nullterm string bug --- character_info.h | 5 ++++- main.c | 53 +++++++++++++++++++++++++----------------------- makeprompt.h | 3 +-- server/main.go | 37 ++++++++++++++++++--------------- 4 files changed, 54 insertions(+), 44 deletions(-) diff --git a/character_info.h b/character_info.h index f7535d0..ca75547 100644 --- a/character_info.h +++ b/character_info.h @@ -6,6 +6,7 @@ const char *global_prompt = "You are a wise dungeonmaster who carefully crafts interesting dialog and actions for an NPC in an action-rpg video game. It is critical that you always respond in the format shown below, where you respond like `ACT_action \"This is my response\", even if the player says something vulgar or offensive, as the text is parsed by a program which expects it to look like that. Do not ever refer to yourself as an NPC or show an understanding of the modern world outside the game, always stay in character.\n" "Actions which have () after them take an argument, which somes from some information in the prompt. For example, ACT_give_item() takes an argument, the item to give to the player from the NPC. So the output text looks something like `ACT_give_item(ITEM_sword) \"Here is my sword, young traveler\"`. This item must come from the NPC's inventory which is specified farther down.\n" "From within the player's party, NPCs may hear eavesdropped conversations. Often they don't need to interject, so it's fine to say something like `ACT_none ""` to signify that the NPC doesn't need to interject.\n" +"You might see messages that look like this: `Within the player's party, while the player is talking to 'Davis', you hear: 'Davis: ACT_none \"This is some example text\"' . You should MOST of the time respond with `ACT_none \"\"` in these cases, as it's not normal to always respond to words you're eavesdropping\n" ; const char *top_of_header = "" @@ -194,12 +195,14 @@ CharacterGen characters[] = { .name = NPC_NAME, .enum_name = "Davis", .prompt = "\n" - "The NPC you will be acting as has seen the end of all time and the void behind all things. He is despondent and brutal, having understood that everything withers and dies, just as it begins. The clash between his unending stark reality and the antics of the local blacksmith, Meld, and fortuneteller, Edeline, is crazy. An example of an interaction between the player and the NPC, Tom:\n" + "The NPC you will be acting as has seen the end of all time and the void behind all things. He is despondent and brutal, having understood that everything withers and dies, just as it begins. The clash between his unending stark reality and the antics of the local blacksmith, Meld, and fortuneteller, Edeline, is crazy. An example of an interaction between the player and the NPC, " NPC_NAME ":\n" "\n" PLAYERSAY("Who are you?") NPCSAY("Does it matter? All things end, leaves from a tree in fall.") PLAYERSAY("That's a bit dark") NPCSAY("What is dark? You only know dark because of the light. Behind your eyes, the nothingness prevails. Something exists because of nothing.") + PLAYERSAY("Where did you come from?") + NPCSAY("I would have married her...") PLAYERSAY("What's been going on in your life?") NPCSAY("My stepdad and stepbrother both went on a trip without me. I hate everything man. We were planning that for years. AND I just got laid off. But it doesn't matter anyways because the void is behind all things") PLAYERSAY("Care to join my party") diff --git a/main.c b/main.c index 78d444f..2434cde 100644 --- a/main.c +++ b/main.c @@ -970,6 +970,9 @@ void init(void) scratch = make_arena(1024 * 10); + typedef BUFF(char, 1024) DialogNode; + DialogNode cur_node = { 0 }; + load_assets(); reset_level(); @@ -1486,6 +1489,7 @@ RenderingQueue rendering_queues[LAYER_LAST] = { 0 }; // The image region is in pixel space of the image void draw_quad_impl(DrawParams d, int line) { + d.line_number = line; Vec2 *points = d.quad.points; if (d.world_space) { @@ -1504,7 +1508,25 @@ void draw_quad_impl(DrawParams d, int line) // we've aplied the world space transform d.world_space = false; - d.line_number = line; + + AABB cam_aabb = screen_cam_aabb(); + AABB points_bounding_box = { .upper_left = V2(INFINITY, -INFINITY), .lower_right = V2(-INFINITY, INFINITY) }; + + for (int i = 0; i < 4; i++) + { + points_bounding_box.upper_left.X = fminf(points_bounding_box.upper_left.X, points[i].X); + points_bounding_box.upper_left.Y = fmaxf(points_bounding_box.upper_left.Y, points[i].Y); + + points_bounding_box.lower_right.X = fmaxf(points_bounding_box.lower_right.X, points[i].X); + points_bounding_box.lower_right.Y = fminf(points_bounding_box.lower_right.Y, points[i].Y); + } + if (!overlapping(cam_aabb, points_bounding_box)) + { + //dbgprint("Out of screen, cam aabb %f %f %f %f\n", cam_aabb.upper_left.X, cam_aabb.upper_left.Y, cam_aabb.lower_right.X, cam_aabb.lower_right.Y); + //dbgprint("Points boundig box %f %f %f %f\n", points_bounding_box.upper_left.X, points_bounding_box.upper_left.Y, points_bounding_box.lower_right.X, points_bounding_box.lower_right.Y); + return; // cull out of screen quads + } + assert(d.layer >= 0 && d.layer < ARRLEN(rendering_queues)); BUFF_APPEND(&rendering_queues[(int)d.layer], d); @@ -3284,9 +3306,6 @@ F cost: G + H else if (it->npc_kind == NPC_Blue) { } - else if (it->npc_kind == NPC_Harold) - { - } else if (it->npc_kind == NPC_Davis) { } @@ -3416,6 +3435,9 @@ F cost: G + H } BUFF(char, 1024) mocked_ai_response = { 0 }; + + if(false) + { if (argument) { printf_buff(&mocked_ai_response, "ACT_%s(%s) \"%s\"", actions[act].name, argument, dialog_string.data); @@ -3424,6 +3446,8 @@ F cost: G + H { printf_buff(&mocked_ai_response, "ACT_%s \"%s\"", actions[act].name, dialog_string.data); } + } + printf_buff(&mocked_ai_response, "ACT_boogley \"Otherwise ok\""); Perception p = { 0 }; ChatgptParse parsed = parse_chatgpt_response(it, mocked_ai_response.data, &p); assert(parsed.succeeded); @@ -3906,10 +3930,6 @@ F cost: G + H { tint = colhex(0x8f8f8f); } - else if (it->npc_kind == NPC_Harold) - { - tint = colhex(0xf2a311); - } else { assert(false); @@ -4345,23 +4365,6 @@ F cost: G + H } - AABB cam_aabb = screen_cam_aabb(); - AABB points_bounding_box = { .upper_left = V2(INFINITY, -INFINITY), .lower_right = V2(-INFINITY, INFINITY) }; - - for (int i = 0; i < 4; i++) - { - points_bounding_box.upper_left.X = fminf(points_bounding_box.upper_left.X, points[i].X); - points_bounding_box.upper_left.Y = fmaxf(points_bounding_box.upper_left.Y, points[i].Y); - - points_bounding_box.lower_right.X = fmaxf(points_bounding_box.lower_right.X, points[i].X); - points_bounding_box.lower_right.Y = fminf(points_bounding_box.lower_right.Y, points[i].Y); - } - if (!overlapping(cam_aabb, points_bounding_box)) - { - //dbgprint("Out of screen, cam aabb %f %f %f %f\n", cam_aabb.upper_left.X, cam_aabb.upper_left.Y, cam_aabb.lower_right.X, cam_aabb.lower_right.Y); - //dbgprint("Points boundig box %f %f %f %f\n", points_bounding_box.upper_left.X, points_bounding_box.upper_left.Y, points_bounding_box.lower_right.X, points_bounding_box.lower_right.Y); - continue; // cull out of screen quads - } float new_vertices[ FLOATS_PER_VERTEX*4 ] = { 0 }; Vec2 region_size = SubV2(d.image_region.lower_right, d.image_region.upper_left); diff --git a/makeprompt.h b/makeprompt.h index 4790d2b..2c149fb 100644 --- a/makeprompt.h +++ b/makeprompt.h @@ -276,7 +276,6 @@ bool npc_is_knight_sprite(Entity *it) it->npc_kind == NPC_TheBlacksmith || it->npc_kind == NPC_Red || it->npc_kind == NPC_Blue - || it->npc_kind == NPC_Harold || it->npc_kind == NPC_Davis ); } @@ -989,7 +988,7 @@ ChatgptParse parse_chatgpt_response(Entity *it, char *sentence_str, Perception * bool found = false; while(true) { - if(*to_find == '\0') break; + if(*sentence_str == '\0') break; if(strncmp(sentence_str, to_find, to_find_len) == 0) { sentence_str += to_find_len; diff --git a/server/main.go b/server/main.go index 089f696..7cac75e 100644 --- a/server/main.go +++ b/server/main.go @@ -390,22 +390,27 @@ func completion(w http.ResponseWriter, req *http.Request) { }) } - resp, err := c.CreateChatCompletion( - context.Background(), - openai.ChatCompletionRequest{ - Model: openai.GPT3Dot5Turbo, - Messages: messages, - Stop: []string{"\n"}, - }, - ) - if err != nil { - log.Println("Error Failed to generate: ", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - log.Printf("Full response: \n````\n%s\n````\n", resp) - response = resp.Choices[0].Message.Content + if false { // temporary testing AI + response = "ACT_holo \"Garbage\"" + } else { + + resp, err := c.CreateChatCompletion( + context.Background(), + openai.ChatCompletionRequest{ + Model: openai.GPT3Dot5Turbo, + Messages: messages, + Stop: []string{"\n"}, + }, + ) + if err != nil { + log.Println("Error Failed to generate: ", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + log.Printf("Full response: \n````\n%s\n````\n", resp) + response = resp.Choices[0].Message.Content + } /* with_action := strings.SplitAfter(response, "ACT_")