Conver training to metadesk, add metadata. Writing

main
Cameron Murphy Reikes 2 years ago
parent f0e1c9251a
commit 285c1c1731

@ -344,18 +344,18 @@
"class":"", "class":"",
"height":32, "height":32,
"id":3, "id":3,
"name":"MERCHANT", "name":"Max",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":1645.5, "x":1077.5,
"y":1631.5 "y":849.5
}, },
{ {
"class":"", "class":"",
"height":32, "height":32,
"id":5, "id":5,
"name":"DEATH", "name":"Death",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
@ -410,12 +410,12 @@
"class":"", "class":"",
"height":32, "height":32,
"id":10, "id":10,
"name":"OLD_MAN", "name":"Hunter",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":1724, "x":838.666666666667,
"y":886.666666666667 "y":860
}, },
{ {
"class":"PROP", "class":"PROP",
@ -476,12 +476,12 @@
"class":"", "class":"",
"height":32, "height":32,
"id":16, "id":16,
"name":"MOOSE", "name":"John",
"rotation":0, "rotation":0,
"visible":true, "visible":true,
"width":32, "width":32,
"x":1358.66666666667, "x":955.636363636367,
"y":2276 "y":863.878787878788
}], }],
"opacity":1, "opacity":1,
"type":"objectgroup", "type":"objectgroup",

@ -0,0 +1,15 @@
#pragma once
// null terminator always built into buffers so can read properly from data
#define ARRLEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define BUFF_VALID(buff_ptr) assert((buff_ptr)->cur_index <= ARRLEN((buff_ptr)->data))
#define BUFF(type, max_size) struct { int cur_index; type data[max_size]; char null_terminator; }
#define BUFF_HAS_SPACE(buff_ptr) ( (buff_ptr)->cur_index < ARRLEN((buff_ptr)->data) )
#define BUFF_EMPTY(buff_ptr) ((buff_ptr)->cur_index == 0)
#define BUFF_APPEND(buff_ptr, element) { (buff_ptr)->data[(buff_ptr)->cur_index++] = element; BUFF_VALID(buff_ptr); }
#define BUFF_ITER_EX(type, buff_ptr, begin_ind, cond, movement) for(type *it = &((buff_ptr)->data[begin_ind]); cond; movement)
#define BUFF_ITER(type, buff_ptr) BUFF_ITER_EX(type, (buff_ptr), 0, it < (buff_ptr)->data + (buff_ptr)->cur_index, it++)
#define BUFF_PUSH_FRONT(buff_ptr, value) { (buff_ptr)->cur_index++; BUFF_VALID(buff_ptr); for(int i = (buff_ptr)->cur_index - 1; i > 0; i--) { (buff_ptr)->data[i] = (buff_ptr)->data[i - 1]; }; (buff_ptr)->data[0] = value; }
#define BUFF_REMOVE_FRONT(buff_ptr) {if((buff_ptr)->cur_index > 0) {for(int i = 0; i < (buff_ptr)->cur_index - 1; i++) { (buff_ptr)->data[i] = (buff_ptr)->data[i+1]; }; (buff_ptr)->cur_index--;}}
#define BUFF_CLEAR(buff_ptr) {memset((buff_ptr), 0, sizeof(*(buff_ptr))); ((buff_ptr)->cur_index = 0);}

@ -1,7 +1,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#define assert(cond, explanation) { if(!cond) { printf("Codegen assertion line %d %s failed: %.*s\n", __LINE__, #cond, MD_S8VArg(explanation)); __debugbreak(); exit(1); } } #define assert_cond(cond, explanation) { if(!cond) { printf("Codegen assert_condion line %d %s failed: %.*s\n", __LINE__, #cond, MD_S8VArg(explanation)); __debugbreak(); exit(1); } }
#include "buff.h"
#pragma warning(disable : 4996) // nonsense about fopen being insecure #pragma warning(disable : 4996) // nonsense about fopen being insecure
@ -23,7 +26,7 @@ void dump(MD_Node* from) {
int d = 0; int d = 0;
for(MD_EachNode(child, from->first_child)) for(MD_EachNode(child, from->first_child))
{ {
printf("|-- Child %d %.*s\n", d, MD_S8VArg(child->string)); printf("|-- Child %d Tag [%.*s] string[%.*s] first child string[%.*s]\n", d, MD_S8VArg(child->first_tag->string), MD_S8VArg(child->string), MD_S8VArg(child->first_child->string));
d += 1; d += 1;
} }
} }
@ -61,8 +64,8 @@ MD_Arena *cg_arena = NULL;
MD_String8 ChildValue(MD_Node *n, MD_String8 name) { MD_String8 ChildValue(MD_Node *n, MD_String8 name) {
MD_Node *child_with_value = MD_ChildFromString(n, name, 0); MD_Node *child_with_value = MD_ChildFromString(n, name, 0);
assert(child_with_value, MD_S8Fmt(cg_arena, "Could not find child named '%.*s' of node '%.*s'", MD_S8VArg(name), MD_S8VArg(n->string))); assert_cond(child_with_value, MD_S8Fmt(cg_arena, "Could not find child named '%.*s' of node '%.*s'", MD_S8VArg(name), MD_S8VArg(n->string)));
assert(child_with_value->first_child, MD_S8Lit("Must have child")); assert_cond(child_with_value->first_child, MD_S8Lit("Must have child"));
return child_with_value->first_child->string; return child_with_value->first_child->string;
} }
@ -85,10 +88,28 @@ char* fillnull(char *s, char c) {
} }
s++; s++;
} }
assert(false, MD_S8Lit("Couldn't find char")); assert_cond(false, MD_S8Lit("Couldn't find char"));
return NULL; return NULL;
} }
#define StrSame(s1, s2) MD_S8Match((s1), (s2), 0)
typedef BUFF(MD_Node*, 256) Nodes;
MD_Node* find_by_name(Nodes *n, MD_String8 name)
{
MD_Node *node_with = 0;
BUFF_ITER(MD_Node *, n)
{
if(StrSame((*it)->string, name))
{
assert(node_with == 0);
node_with = (*it);
}
}
assert(node_with);
return node_with;
}
char* goto_end_of(char *tomove, size_t max_move, char *pattern) { char* goto_end_of(char *tomove, size_t max_move, char *pattern) {
size_t pattern_len = strlen(pattern); size_t pattern_len = strlen(pattern);
for(int i = 0; i < max_move; i++) { for(int i = 0; i < max_move; i++) {
@ -102,14 +123,119 @@ char* goto_end_of(char *tomove, size_t max_move, char *pattern) {
} }
#define list_printf(list_ptr, ...) MD_S8ListPush(cg_arena, list_ptr, MD_S8Fmt(cg_arena, __VA_ARGS__)) #define list_printf(list_ptr, ...) MD_S8ListPush(cg_arena, list_ptr, MD_S8Fmt(cg_arena, __VA_ARGS__))
#define S8(s) MD_S8Lit(s)
int main(int argc, char **argv) { int main(int argc, char **argv) {
cg_arena = MD_ArenaAlloc(); cg_arena = MD_ArenaAlloc();
assert(cg_arena, MD_S8Lit("Memory")); assert_cond(cg_arena, MD_S8Lit("Memory"));
char *nulled = nullterm(MD_S8Lit("test")); char *nulled = nullterm(MD_S8Lit("test"));
MD_ParseResult training_parse = MD_ParseWholeFile(cg_arena, MD_S8Lit("training.mdesk"));
MD_String8 global_prompt = {0};
for(MD_EachNode(node, training_parse.node->first_child))
{
if(MD_S8Match(node->first_tag->string, MD_S8Lit("global_prompt"), 0))
{
global_prompt = node->string;
}
}
MD_String8 training_writeto = MD_S8Fmt(cg_arena, "%.*s/training_data.jsonl\0", MD_S8VArg(OUTPUT_FOLDER));
FILE *train = fopen(training_writeto.str, "w");
assert(train);
Nodes characters = {0};
for(MD_EachNode(node, training_parse.node->first_child))
{
if(MD_S8Match(node->first_tag->string, MD_S8Lit("character"), 0))
{
BUFF_APPEND(&characters, node);
}
}
Nodes items = {0};
for(MD_EachNode(node, training_parse.node->first_child))
{
if(MD_S8Match(node->first_tag->string, MD_S8Lit("item"), 0))
{
BUFF_APPEND(&items, node);
}
}
for(MD_EachNode(node, training_parse.node->first_child))
{
if(MD_S8Match(node->first_tag->string, MD_S8Lit("training"), 0))
{
MD_Node *node_with = find_by_name(&characters, ChildValue(node, S8("with")));
MD_String8List item_prompts = {0};
MD_Node *items_node = MD_ChildFromString(node, S8("items"), 0);
if(!MD_NodeIsNil(items_node))
{
for(MD_EachNode(item_name_node, items_node->first_child))
{
MD_String8 item_prompt = ChildValue(find_by_name(&items, item_name_node->string), S8("prompt"));
MD_S8ListPush(cg_arena, &item_prompts, item_prompt);
}
}
MD_StringJoin join = (MD_StringJoin){ .mid = S8("\\n") };
MD_String8 items_prompt = S8("");
if(item_prompts.node_count > 0)
{
MD_S8ListPush(cg_arena, &item_prompts, S8(""));
items_prompt = MD_S8ListJoin(cg_arena, item_prompts, &join);
}
int num_sentences = 0;
for(MD_EachNode(s, MD_ChildFromString(node, S8("data"), 0)->first_child))
{
num_sentences += 1;
}
assert(num_sentences >= 2);
assert(num_sentences % 2 == 0);
for(int upto_length = 2; upto_length <= num_sentences; upto_length += 2)
{
fprintf(train, "{\"prompt\": \"");
fprintf(train, nullterm(global_prompt), MD_S8VArg(ChildValue(node_with, S8("actions_str"))));
fprintf(train, "\\n");
fprintf(train, "%.*s", MD_S8VArg(items_prompt));
fprintf(train, "%.*s\\n", MD_S8VArg(ChildValue(node_with, S8("prompt"))));
MD_Node *cur_sentence = MD_ChildFromString(node, S8("data"), 0)->first_child;
MD_String8 completion = {0};
for(int i = 0; i < upto_length; i += 1)
{
assert(!MD_NodeIsNil(cur_sentence));
if(i % 2 == 0)
{
fprintf(train, "Player: \\\"%.*s\\\"\\n", MD_S8VArg(cur_sentence->string));
}
else
{
fprintf(train, "%.*s: \\\"", MD_S8VArg(ChildValue(node_with, S8("name"))));
if(i == upto_length - 1)
{
completion = cur_sentence->string;
}
else
{
fprintf(train, "%.*s\\\"\\n", MD_S8VArg(cur_sentence->string));
}
}
cur_sentence = cur_sentence->next;
}
fprintf(train, "\", \"completion\": \"%.*s\\\"\"}\n", MD_S8VArg(completion));
}
}
}
BUFF_ITER(MD_Node*, &characters)
{
printf("Character %.*s\n", MD_S8VArg((*it)->string));
}
// I hope to God MD_String8's are null terminated... // I hope to God MD_String8's are null terminated...
MD_String8 writeto = MD_S8Fmt(cg_arena, "%.*s/assets.gen.c", MD_S8VArg(OUTPUT_FOLDER)); MD_String8 writeto = MD_S8Fmt(cg_arena, "%.*s/assets.gen.c", MD_S8VArg(OUTPUT_FOLDER));
log("Writing to %.*s\n", MD_S8VArg(writeto)); log("Writing to %.*s\n", MD_S8VArg(writeto));
@ -129,9 +255,9 @@ int main(int argc, char **argv) {
log("New image variable %.*s\n", MD_S8VArg(variable_name)); log("New image variable %.*s\n", MD_S8VArg(variable_name));
MD_String8 filepath = ChildValue(node, MD_S8Lit("filepath")); MD_String8 filepath = ChildValue(node, MD_S8Lit("filepath"));
filepath = asset_file_path(filepath); filepath = asset_file_path(filepath);
assert(filepath.str != 0, MD_S8Fmt(cg_arena, "No filepath specified for image '%.*s'", MD_S8VArg(node->string))); assert_cond(filepath.str != 0, MD_S8Fmt(cg_arena, "No filepath specified for image '%.*s'", MD_S8VArg(node->string)));
FILE *asset_file = fopen(filepath.str, "r"); FILE *asset_file = fopen(filepath.str, "r");
assert(asset_file, MD_S8Fmt(cg_arena, "Could not open filepath %.*s for asset '%.*s'", MD_S8VArg(filepath), MD_S8VArg(node->string))); assert_cond(asset_file, MD_S8Fmt(cg_arena, "Could not open filepath %.*s for asset '%.*s'", MD_S8VArg(filepath), MD_S8VArg(node->string)));
fclose(asset_file); fclose(asset_file);
MD_S8ListPush(cg_arena, &declarations_list, MD_S8Fmt(cg_arena, "sg_image %.*s = {0};\n", MD_S8VArg(variable_name))); MD_S8ListPush(cg_arena, &declarations_list, MD_S8Fmt(cg_arena, "sg_image %.*s = {0};\n", MD_S8VArg(variable_name)));
@ -185,7 +311,7 @@ int main(int argc, char **argv) {
log("New level variable %.*s\n", MD_S8VArg(variable_name)); log("New level variable %.*s\n", MD_S8VArg(variable_name));
MD_String8 filepath = asset_file_path(ChildValue(node, MD_S8Lit("filepath"))); MD_String8 filepath = asset_file_path(ChildValue(node, MD_S8Lit("filepath")));
MD_ParseResult level_parse = MD_ParseWholeFile(cg_arena, filepath); MD_ParseResult level_parse = MD_ParseWholeFile(cg_arena, filepath);
assert(!MD_NodeIsNil(level_parse.node->first_child), MD_S8Lit("Failed to load level file")); assert_cond(!MD_NodeIsNil(level_parse.node->first_child), MD_S8Lit("Failed to load level file"));
MD_Node *layers = MD_ChildFromString(level_parse.node->first_child, MD_S8Lit("layers"), 0); MD_Node *layers = MD_ChildFromString(level_parse.node->first_child, MD_S8Lit("layers"), 0);
fprintf(output, "Level %.*s = {\n", MD_S8VArg(variable_name)); fprintf(output, "Level %.*s = {\n", MD_S8VArg(variable_name));
@ -216,7 +342,7 @@ int main(int argc, char **argv) {
} }
else else
{ {
fprintf(output, "{ .exists = true, .is_npc = true, .npc_kind = %.*s, .pos = { .X=%.*s, .Y=%.*s }, }, ", MD_S8VArg(name), MD_S8VArg(x_string), MD_S8VArg(y_string)); fprintf(output, "{ .exists = true, .is_npc = true, .npc_kind = NPC_%.*s, .pos = { .X=%.*s, .Y=%.*s }, }, ", MD_S8VArg(name), MD_S8VArg(x_string), MD_S8VArg(y_string));
} }
} }
fprintf(output, "\n}, // entities\n"); fprintf(output, "\n}, // entities\n");
@ -270,8 +396,37 @@ int main(int argc, char **argv) {
MD_String8 loads = MD_S8ListJoin(cg_arena, load_list, &join); MD_String8 loads = MD_S8ListJoin(cg_arena, load_list, &join);
fprintf(output, "%.*s\nvoid load_assets() {\n%.*s\n}\n", MD_S8VArg(declarations), MD_S8VArg(loads)); fprintf(output, "%.*s\nvoid load_assets() {\n%.*s\n}\n", MD_S8VArg(declarations), MD_S8VArg(loads));
fprintf(output, "TileSet tilesets[] = { %.*s\n };", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join))); fprintf(output, "TileSet tilesets[] = { %.*s\n };\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join)));
fclose(output);
output = fopen(MD_S8Fmt(cg_arena, "%.*s/characters.gen.h\0", MD_S8VArg(OUTPUT_FOLDER)).str, "w");
//fprintf(output, "char *global_prompt = \"%.*s\";\n", MD_S8VArg(global_prompt));
fprintf(output, "char *prompt_table[] = {\n");
BUFF_ITER(MD_Node*, &characters)
{
MD_String8 personalized_global_prompt = MD_S8Fmt(cg_arena, nullterm(global_prompt), MD_S8VArg(ChildValue(*it, S8("actions_str"))));
fprintf(output, "\"%.*s\\n%.*s\", // %.*s\n", MD_S8VArg(personalized_global_prompt), MD_S8VArg(ChildValue(*it, S8("prompt"))),MD_S8VArg((*it)->string));
}
fprintf(output, "}; // prompt table\n");
fprintf(output, "char *name_table[] = {\n");
BUFF_ITER(MD_Node*, &characters)
{
fprintf(output, "\"%.*s\", // %.*s\n", MD_S8VArg(ChildValue(*it, S8("name"))),MD_S8VArg((*it)->string));
}
fprintf(output, "}; // name table\n");
fprintf(output, "typedef enum\n{ // character enums, not completed here so you can add more in the include\n");
BUFF_ITER(MD_Node*, &characters)
{
fprintf(output, "NPC_%.*s,\n", MD_S8VArg((*it)->string));
}
//fprintf(output, "NPC_LAST_CHARACTER,\n};\n");
fclose(output); fclose(output);
return 0; return 0;
} }

143
main.c

@ -9,6 +9,7 @@
#define SOKOL_GLES2 #define SOKOL_GLES2
#endif #endif
#include "buff.h"
#include "sokol_app.h" #include "sokol_app.h"
#include "sokol_gfx.h" #include "sokol_gfx.h"
#include "sokol_time.h" #include "sokol_time.h"
@ -31,7 +32,6 @@
#endif #endif
#include "profiling.h" #include "profiling.h"
#define ARRLEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define ENTITIES_ITER(ents) for(Entity *it = ents; it < ents + ARRLEN(ents); it++) if(it->exists) #define ENTITIES_ITER(ents) for(Entity *it = ents; it < ents + ARRLEN(ents); it++) if(it->exists)
#define Log(...) { printf("Log %d | ", __LINE__); printf(__VA_ARGS__); } #define Log(...) { printf("Log %d | ", __LINE__); printf(__VA_ARGS__); }
@ -61,6 +61,7 @@ Vec2 ReflectV2(Vec2 v, Vec2 normal)
return SubV2(v, MulV2F(normal, 2.0f * DotV2(v, normal))); return SubV2(v, MulV2F(normal, 2.0f * DotV2(v, normal)));
} }
typedef struct AABB typedef struct AABB
{ {
Vec2 upper_left; Vec2 upper_left;
@ -127,36 +128,18 @@ typedef enum CharacterState
#define SERVER_URL "https://rpgpt.duckdns.org/" #define SERVER_URL "https://rpgpt.duckdns.org/"
#endif #endif
// null terminator always built into buffers so can read properly from data
#define BUFF_VALID(buff_ptr) assert((buff_ptr)->cur_index <= ARRLEN((buff_ptr)->data))
#define BUFF(type, max_size) struct { int cur_index; type data[max_size]; char null_terminator; }
#define BUFF_HAS_SPACE(buff_ptr) ( (buff_ptr)->cur_index < ARRLEN((buff_ptr)->data) )
#define BUFF_EMPTY(buff_ptr) ((buff_ptr)->cur_index == 0)
#define BUFF_APPEND(buff_ptr, element) { (buff_ptr)->data[(buff_ptr)->cur_index++] = element; BUFF_VALID(buff_ptr); }
//#define BUFF_ITER(type, buff_ptr) for(type *it = &((buff_ptr)->data[0]); it < (buff_ptr)->data + (buff_ptr)->cur_index; it++)
#define BUFF_ITER_EX(type, buff_ptr, begin_ind, cond, movement) for(type *it = &((buff_ptr)->data[begin_ind]); cond; movement)
#define BUFF_ITER(type, buff_ptr) BUFF_ITER_EX(type, (buff_ptr), 0, it < (buff_ptr)->data + (buff_ptr)->cur_index, it++)
#define BUFF_PUSH_FRONT(buff_ptr, value) { (buff_ptr)->cur_index++; BUFF_VALID(buff_ptr); for(int i = (buff_ptr)->cur_index - 1; i > 0; i--) { (buff_ptr)->data[i] = (buff_ptr)->data[i - 1]; }; (buff_ptr)->data[0] = value; }
#define BUFF_REMOVE_FRONT(buff_ptr) {if((buff_ptr)->cur_index > 0) {for(int i = 0; i < (buff_ptr)->cur_index - 1; i++) { (buff_ptr)->data[i] = (buff_ptr)->data[i+1]; }; (buff_ptr)->cur_index--;}}
#define BUFF_CLEAR(buff_ptr) {memset((buff_ptr), 0, sizeof(*(buff_ptr))); ((buff_ptr)->cur_index = 0);}
// REFACTORING:: also have to update in javascript!!!!!!!! // REFACTORING:: also have to update in javascript!!!!!!!!
#define MAX_SENTENCE_LENGTH 400 // LOOOK AT AGBOVE COMMENT GBEFORE CHANGING #define MAX_SENTENCE_LENGTH 400 // LOOOK AT AGBOVE COMMENT GBEFORE CHANGING
typedef BUFF(char, MAX_SENTENCE_LENGTH) Sentence; typedef BUFF(char, MAX_SENTENCE_LENGTH) Sentence;
#define SENTENCE_CONST(txt) (Sentence){.data=txt, .cur_index=sizeof(txt)} #define SENTENCE_CONST(txt) (Sentence){.data=txt, .cur_index=sizeof(txt)}
// even indexed dialogs (0,2,4) are player saying stuff, odds are the character from GPT // even indexed dialogs (0,2,4) are player saying stuff, odds are the character from GPT
typedef BUFF(Sentence, 2*12) Dialog; // six back and forths. must be even number or bad things happen (I think) typedef BUFF(Sentence, 2*12) Dialog; // six back and forths. must be even number or bad things happen (I think)
typedef enum NpcKind #include "characters.gen.h"
{ NPC_SKELETON,
INVALID, NPC_MOOSE,
OLD_MAN,
DEATH,
SKELETON,
MERCHANT,
MOOSE,
} NpcKind; } NpcKind;
typedef enum PropKind typedef enum PropKind
@ -294,6 +277,7 @@ void say_characters(Entity *npc, int num_characters)
} }
if(found_matching_star) if(found_matching_star)
{ {
#if 0 // actions
if(strcmp(match_buffer.data, "fights player") == 0 && npc->npc_kind == OLD_MAN) if(strcmp(match_buffer.data, "fights player") == 0 && npc->npc_kind == OLD_MAN)
{ {
npc->aggressive = true; npc->aggressive = true;
@ -311,6 +295,7 @@ void say_characters(Entity *npc, int num_characters)
npc->going_to_target = true; npc->going_to_target = true;
npc->target_goto = AddV2(npc->pos, V2(0.0, -TILE_SIZE*1.5f)); npc->target_goto = AddV2(npc->pos, V2(0.0, -TILE_SIZE*1.5f));
} }
#endif
} }
BUFF_APPEND(sentence_to_append_to, new_character); BUFF_APPEND(sentence_to_append_to, new_character);
BUFF_REMOVE_FRONT(&npc->sentence_to_say); BUFF_REMOVE_FRONT(&npc->sentence_to_say);
@ -336,8 +321,6 @@ void add_new_npc_sentence(Entity *npc, char *sentence)
npc->sentence_to_say = new_sentence; npc->sentence_to_say = new_sentence;
} }
#include "prompts.gen.h"
void begin_text_input(); // called when player engages in dialog, must say something and fill text_input_buffer void begin_text_input(); // called when player engages in dialog, must say something and fill text_input_buffer
// a callback, when 'text backend' has finished making text // a callback, when 'text backend' has finished making text
void end_text_input(char *what_player_said) void end_text_input(char *what_player_said)
@ -375,31 +358,14 @@ void end_text_input(char *what_player_said)
//BUFF_APPEND(&to_join, "This is dialog which takes place in a simple action RPG, where the player can only talk to NPCs, or fight. The characters influence the game world by saying specific actions from these possibilities: [*fights player*]. They don't say anything else that has '*' between them. Example dialog with an Old Man NPC:\nPlayer: \"Hello old man. Do you know that you're in a video game?\"\nOld Man: \"What are you talking about, young boy? What is a 'video game'?\"\nPlayer: \"You have no idea. You look ugly and stupid.\"\nOld Man: \"How juvenile! That's it, *fights player*\"\n\nThe NPCs exist on a small lush island, on a remote village, in a fantasy setting where monsters roam freely, posing a danger to the NPCs, and the player. They don't know about modern technology. They are very slow to say *fights player*, because doing so means killing the player, their friends, and potentially themselves. But if the situation demands it, they will not hesitate to open fire.\n"); //BUFF_APPEND(&to_join, "This is dialog which takes place in a simple action RPG, where the player can only talk to NPCs, or fight. The characters influence the game world by saying specific actions from these possibilities: [*fights player*]. They don't say anything else that has '*' between them. Example dialog with an Old Man NPC:\nPlayer: \"Hello old man. Do you know that you're in a video game?\"\nOld Man: \"What are you talking about, young boy? What is a 'video game'?\"\nPlayer: \"You have no idea. You look ugly and stupid.\"\nOld Man: \"How juvenile! That's it, *fights player*\"\n\nThe NPCs exist on a small lush island, on a remote village, in a fantasy setting where monsters roam freely, posing a danger to the NPCs, and the player. They don't know about modern technology. They are very slow to say *fights player*, because doing so means killing the player, their friends, and potentially themselves. But if the situation demands it, they will not hesitate to open fire.\n");
// characters prompt // characters prompt
Entity *talking = player->talking_to; Entity *talking = player->talking_to;
char *character_prompt = NULL; assert(talking->npc_kind < ARRLEN(prompt_table));
Log("doing prompt\n"); assert(talking->npc_kind < ARRLEN(name_table));
if(talking->npc_kind == OLD_MAN) BUFF_APPEND(&to_join, prompt_table[talking->npc_kind]);
{ BUFF_APPEND(&to_join, "\n");
BUFF_APPEND(&to_join, PROMPT_OLD_MAN); char *character_prompt = name_table[talking->npc_kind];
Log("doing prompt old man\n");
character_prompt = "Old Man: \"";
}
else if(talking->npc_kind == DEATH)
{
BUFF_APPEND(&to_join, PROMPT_DEATH);
Log("Doing prompt death\n");
character_prompt = "Death: \"";
}
else if(talking->npc_kind == MERCHANT)
{
BUFF_APPEND(&to_join, PROMPT_MERCHANT);
character_prompt = "Merchant: \"";
}
else
{
assert(false);
}
//BUFF_APPEND(&to_join, "The player is talking to an old man who is standing around on the island. He's eager to bestow his wisdom upon the young player, but the player must act polite, not rude. If the player acts rude, the old man will say exactly the text '*fights player*' as shown in the above example, turning the interaction into a skirmish, where the old man takes out his well concealed shotgun. The old man is also a bit of a joker.\n\n"); //BUFF_APPEND(&to_join, "The player is talking to an old man who is standing around on the island. He's eager to bestow his wisdom upon the young player, but the player must act polite, not rude. If the player acts rude, the old man will say exactly the text '*fights player*' as shown in the above example, turning the interaction into a skirmish, where the old man takes out his well concealed shotgun. The old man is also a bit of a joker.\n\n");
//BUFF_APPEND(&to_join, "Dialog between an old man and a player in a video game. The player can only attack or talk in the game. The old man can perform these actions by saying them: [*fights player*]\n--\nPlayer: \"Who are you?\"\nOld Man: \"Why I'm just a simple old man, minding my business. What brings you here?\"\nPlayer: \"I'm not sure. What needs doing?\"\nOld Man: \"Nothing much. It's pretty boring around here. Monsters are threatening our village though.\"\nPlayer: \"Holy shit! I better get to it\"\nOld Man: \"He he, certainly! Good luck!\"\n--\nPlayer: \"Man fuck you old man\"\nOld Man: \"You better watch your tongue young man. Unless you're polite I'll be forced to attack you, peace is important around here!\"\nPlayer: \"Man fuck your peace\"\nOld Man: \"That's it! *fights player*\"\n--\n"); //BUFF_APPEND(&to_join, "Dialog between an old man and a player in a video game. The player can only attack or talk in the game. The old man can perform these actions by saying them: [*fights player*]\n--\nPlayer: \"Who are you?\"\nOld Man: \"Why I'm just a simple old man, minding my business. What brings you here?\"\nPlayer: \"I'm not sure. What needs doing?\"\nOld Man: \"Nothing much. It's pretty boring around here. Monsters are threatening our village though.\"\nPlayer: \"Holy shit! I better get to it\"\nOld Man: \"He he, certainly! Good luck!\"\n--\nPlayer: \"Man fuck you old man\"\nOld Man: \"You better watch your tongue young man. Unless you're polite I'll be forced to attack you, peace is important around here!\"\nPlayer: \"Man fuck your peace\"\nOld Man: \"That's it! *fights player*\"\n--\n");
@ -415,6 +381,7 @@ void end_text_input(char *what_player_said)
else else
{ {
BUFF_APPEND(&to_join, character_prompt); BUFF_APPEND(&to_join, character_prompt);
BUFF_APPEND(&to_join, ": \"");
} }
BUFF_APPEND(&to_join, it->data); BUFF_APPEND(&to_join, it->data);
BUFF_APPEND(&to_join, "\"\n"); BUFF_APPEND(&to_join, "\"\n");
@ -422,6 +389,7 @@ void end_text_input(char *what_player_said)
} }
BUFF_APPEND(&to_join, character_prompt); BUFF_APPEND(&to_join, character_prompt);
BUFF_APPEND(&to_join, ": \"");
// concatenate into prompt_buff // concatenate into prompt_buff
BUFF_ITER(char *, &to_join) BUFF_ITER(char *, &to_join)
@ -445,18 +413,22 @@ void end_text_input(char *what_player_said)
player->talking_to->gen_request_id = req_id; player->talking_to->gen_request_id = req_id;
#endif #endif
#ifdef DESKTOP #ifdef DESKTOP
if(player->talking_to->npc_kind == DEATH) if(player->talking_to->npc_kind == NPC_Death)
{ {
add_new_npc_sentence(player->talking_to, "test *moves* I am death, destroyer of games. Come join me in the afterlife, or continue onwards *moves*"); add_new_npc_sentence(player->talking_to, "test *moves* I am death, destroyer of games. Come join me in the afterlife, or continue onwards *moves*");
//add_new_npc_sentence(player->talking_to, "test"); //add_new_npc_sentence(player->talking_to, "test");
} }
if(player->talking_to->npc_kind == OLD_MAN) if(player->talking_to->npc_kind == NPC_Hunter)
{ {
add_new_npc_sentence(player->talking_to, "If it's a fight you're looking for! *fights player*"); add_new_npc_sentence(player->talking_to, "I am hunter");
} }
if(player->talking_to->npc_kind == MERCHANT) if(player->talking_to->npc_kind == NPC_Max)
{ {
add_new_npc_sentence(player->talking_to, "*sells swiftness boots* bla bla"); add_new_npc_sentence(player->talking_to, "I am max");
}
if(player->talking_to->npc_kind == NPC_John)
{
add_new_npc_sentence(player->talking_to, "I am john");
} }
#endif #endif
@ -595,23 +567,19 @@ Vec2 entity_aabb_size(Entity *e)
} }
else if(e->is_npc) else if(e->is_npc)
{ {
if(e->npc_kind == OLD_MAN) if(e->npc_kind == NPC_Hunter || e->npc_kind == NPC_Max || e->npc_kind == NPC_John)
{ {
return V2(TILE_SIZE*0.5f, TILE_SIZE*0.5f); return V2(TILE_SIZE*0.5f, TILE_SIZE*0.5f);
} }
else if(e->npc_kind == DEATH) else if(e->npc_kind == NPC_Death)
{ {
return V2(TILE_SIZE*1.10f, TILE_SIZE*1.10f); return V2(TILE_SIZE*1.10f, TILE_SIZE*1.10f);
} }
else if(e->npc_kind == SKELETON) else if(e->npc_kind == NPC_SKELETON)
{
return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f);
}
else if(e->npc_kind == MERCHANT)
{ {
return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f); return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f);
} }
else if(e->npc_kind == MOOSE) else if(e->npc_kind == NPC_MOOSE)
{ {
return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f); return V2(TILE_SIZE*1.0f, TILE_SIZE*1.0f);
} }
@ -1570,7 +1538,7 @@ void request_do_damage(Entity *to, Vec2 from_point, float damage)
to->vel = ReflectV2(to->vel, norm); to->vel = ReflectV2(to->vel, norm);
dbgprint("deflecitng\n"); dbgprint("deflecitng\n");
} }
else if(to->npc_kind != DEATH) else if(true)
{ {
to->damage += damage; to->damage += damage;
to->aggressive = true; to->aggressive = true;
@ -2212,10 +2180,11 @@ void frame(void)
// draw drop shadow // draw drop shadow
if(it->is_character || it->is_npc || it->is_prop) if(it->is_character || it->is_npc || it->is_prop)
{ {
if(it->npc_kind != DEATH) //if(it->npc_kind != DEATH)
{ {
float shadow_size = knight_rolling.region_size.x * 0.5f; float shadow_size = knight_rolling.region_size.x * 0.5f;
Vec2 shadow_offset = V2(0.0f, -20.0f); Vec2 shadow_offset = V2(0.0f, -20.0f);
#if 0
if(it->npc_kind == MERCHANT) if(it->npc_kind == MERCHANT)
{ {
shadow_offset = V2(-4.5f, -15.0f); shadow_offset = V2(-4.5f, -15.0f);
@ -2225,7 +2194,8 @@ void frame(void)
shadow_offset = V2(-1.5f, -8.0f); shadow_offset = V2(-1.5f, -8.0f);
shadow_size *= 0.5f; shadow_size *= 0.5f;
} }
else if(it->is_prop) #endif
if(it->is_prop)
{ {
shadow_size *= 2.5f; shadow_size *= 2.5f;
shadow_offset = V2(3.0f, -8.0f); shadow_offset = V2(3.0f, -8.0f);
@ -2246,11 +2216,8 @@ void frame(void)
it->character_say_timer -= character_say_time; it->character_say_timer -= character_say_time;
} }
} }
if(it->npc_kind == DEATH && it->going_to_target) //if(it->npc_kind == OLD_MAN && it->aggressive)
{ if(false)
it->pos = LerpV2(it->pos, dt*5.0f, it->target_goto);
}
if(it->npc_kind == OLD_MAN && it->aggressive)
{ {
draw_dialog_panel(it); draw_dialog_panel(it);
Entity *targeting = player; Entity *targeting = player;
@ -2282,7 +2249,8 @@ void frame(void)
} }
Color col = LerpV4(WHITE, it->damage, RED); Color col = LerpV4(WHITE, it->damage, RED);
if(it->npc_kind == OLD_MAN) //if(it->npc_kind == OLD_MAN)
if(false)
{ {
bool face_left = false; bool face_left = false;
if(it->aggressive) if(it->aggressive)
@ -2291,7 +2259,7 @@ void frame(void)
} }
draw_animated_sprite(&old_man_idle, elapsed_time, face_left, it->pos, col); draw_animated_sprite(&old_man_idle, elapsed_time, face_left, it->pos, col);
} }
else if(it->npc_kind == SKELETON) else if(it->npc_kind == NPC_SKELETON)
{ {
Color col = WHITE; Color col = WHITE;
if(it->dead) if(it->dead)
@ -2353,6 +2321,11 @@ void frame(void)
it->vel = LerpV2(it->vel, dt*8.0f, target_vel); it->vel = LerpV2(it->vel, dt*8.0f, target_vel);
} }
} }
else if(it->npc_kind == NPC_Death)
{
draw_animated_sprite(&death_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col);
}
#if 0
else if(it->npc_kind == DEATH) else if(it->npc_kind == DEATH)
{ {
draw_animated_sprite(&death_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col); draw_animated_sprite(&death_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col);
@ -2361,7 +2334,29 @@ void frame(void)
{ {
draw_animated_sprite(&merchant_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col); draw_animated_sprite(&merchant_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col);
} }
else if(it->npc_kind == MOOSE) #endif
else if(it->npc_kind == NPC_Max || it->npc_kind == NPC_Hunter || it->npc_kind == NPC_John)
{
Color tint = WHITE;
if(it->npc_kind == NPC_Max)
{
tint = colhex(0xfc8803);
}
else if(it->npc_kind == NPC_Hunter)
{
tint = colhex(0x4ac918);
}
else if(it->npc_kind == NPC_John)
{
tint = colhex(0x16c7a1);
}
else
{
assert(false);
}
draw_animated_sprite(&knight_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), tint);
}
else if(it->npc_kind == NPC_MOOSE)
{ {
draw_animated_sprite(&moose_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col); draw_animated_sprite(&moose_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col);
} }
@ -2371,7 +2366,7 @@ void frame(void)
} }
if(it->damage >= 1.0) if(it->damage >= 1.0)
{ {
if(it->npc_kind == SKELETON) if(it->npc_kind == NPC_SKELETON)
{ {
it->dead = true; it->dead = true;
} }
@ -2392,7 +2387,7 @@ void frame(void)
Entity *from_bullet = it; Entity *from_bullet = it;
BUFF_ITER(Overlap, &over) if(it->e != from_bullet) BUFF_ITER(Overlap, &over) if(it->e != from_bullet)
{ {
if(!it->is_tile && !(it->e->npc_kind == DEATH) && !(it->e->is_bullet)) if(!it->is_tile && !(it->e->is_bullet))
{ {
// knockback and damage // knockback and damage
request_do_damage(it->e, from_bullet->pos, 0.2f); request_do_damage(it->e, from_bullet->pos, 0.2f);
@ -2451,7 +2446,7 @@ void frame(void)
if(entity_talkable) entity_talkable = entity_talkable && !it->is_tile; if(entity_talkable) entity_talkable = entity_talkable && !it->is_tile;
if(entity_talkable) entity_talkable = entity_talkable && it->e->is_npc; if(entity_talkable) entity_talkable = entity_talkable && it->e->is_npc;
if(entity_talkable) entity_talkable = entity_talkable && !it->e->aggressive; if(entity_talkable) entity_talkable = entity_talkable && !it->e->aggressive;
if(entity_talkable) entity_talkable = entity_talkable && !(it->e->npc_kind == SKELETON); if(entity_talkable) entity_talkable = entity_talkable && !(it->e->npc_kind == NPC_SKELETON);
#ifdef WEB #ifdef WEB
if(entity_talkable) entity_talkable = entity_talkable && it->e->gen_request_id == 0; if(entity_talkable) entity_talkable = entity_talkable && it->e->gen_request_id == 0;
#endif #endif

@ -20,10 +20,6 @@ copy "Undead - Pixel Art Characters\Undead - Pixel Art Characters\Sprites\Skelet
rmdir /S /q gen rmdir /S /q gen
mkdir gen mkdir gen
pushd server
python training_data_convert.py
popd
@REM shaders @REM shaders
thirdparty\sokol-shdc.exe --input quad.glsl --output gen\quad-sapp.glsl.h --slang glsl100:hlsl5:metal_macos || goto :error thirdparty\sokol-shdc.exe --input quad.glsl --output gen\quad-sapp.glsl.h --slang glsl100:hlsl5:metal_macos || goto :error

@ -28,7 +28,7 @@ func index(w http.ResponseWriter, req *http.Request) {
ctx := context.Background() ctx := context.Background()
req := gogpt.CompletionRequest{ req := gogpt.CompletionRequest{
Model: "curie:ft-personal-2023-03-09-02-21-37", Model: "curie:ft-personal-2023-03-13-05-51-19",
MaxTokens: 80, MaxTokens: 80,
Prompt: promptString, Prompt: promptString,
Temperature: 0.9, Temperature: 0.9,

@ -1,507 +0,0 @@
Player: "Hey old man"
Old Man: "Hmm? Another player?"
Player: "Fuck bitch cunt nugget"
Old Man: "Now now, let's be courteous. We wouldn't want any trouble now would we?"
Player: "Trouble lick my balls ligma ligma bitch fuck"
Old Man: "*fights player*"
Player: "Fuck you!"
Old Man: "*fights player*"
Player: "Where are you from?"
Old Man: "I'm from all around. Some of my best stories are from locations you've never heard of. Some of my best ideas came from places unknown. I've lived a long, full life, and there's still so much more out there for me to see."
Player: "What do you think of the merchant?"
Old Man: "He's doing his job well. Some of the other merchants are selling some odd items, but he has the best prices and widest selection."
Player: "Where are the other merchants?"
Old Man: "There are a few around, selling the usual mix of goods. You'll usually find them congregated near the exit."
Player: "Who are you?"
Old Man: "I'm but a simple old man, minding my business. That is, until you came along!"
Player: "What did I do?"
Old Man: "Change, even when positive, brings suffering."
Player: "Man fuck you"
Old Man: "Careful, I have a shotgun and I'm not afraid to stand my ground!"
Player: "Fuck off"
Old Man: "*fights player*"
Player: "Who are you?"
Old Man: "Why I'm just a simple old man, minding my business. What brings you here?"
Player: "I'm not sure. What needs doing?"
Old Man: "Nothing much. It's pretty boring around here. Monsters are threatening our village though."
Player: "Holy shit! I better get to it"
Old Man: "He he, certainly! Good luck!"
Player: "Why does anything exist at all."
Old Man: "All is one, one is all. Infinity is all."
Player: "You sound crazy old man"
Old Man: "And you smell stinky with your wrong opinions. Travel elsewhere so I can bask in the sun in peace."
Player: "I'll fucking kill you"
Old Man: "Watch out, I'm about to become more aggressive"
Player: "I don't care"
Old Man: "... *fights player*"
Player: "Where are we?"
Old Man: "On a lush peaceful island, do you have eyes?"
Player: "That's rude"
Old Man: "Apologies young man, my back hurts."
Player: "It's aight. Where's the next goal playah?"
Old Man: "Keep walking ahead, you'll find what you need. Be wary of monsters!"
Player: "Is your arthritis getting better?"
Old Man: "Nope! Still hurts."
Player: "Sorry to hear that."
Old Man: "Bah whatever. Go back to saving the world"
Player: "What can you tell me about this island?"
Old Man: "Ah, this island is a hidden gem, filled with natural beauty and serene landscapes. But beware, there are dangerous creatures lurking in the shadows."
Player: "What do you know about the monsters around here?"
Old Man: "Oh, I've seen my fair share of them. They're vicious and unpredictable. You'll need to be well-prepared if you want to stand a chance against them."
Player: "Do you know anything about the ancient ruins on this island?"
Old Man: "Ah, yes. The ruins are said to hold great power and secrets. Many have tried to uncover their mysteries, but few have succeeded. If you're brave enough to explore them, be sure to bring your wits and your weapons."
Player: "What's your story, old timer?"
Old Man: "My story? Ha! It's a long one, full of adventure and heartbreak. But that's a tale for another time. Right now, you've got a job to do. Go out there and make a difference in this world."
Player: "What's the best way to defend myself against the monsters?"
Old Man: "Well, it depends on the type of monster you're facing. Some are weak to fire, others to ice. Some can be defeated with brute force, while others require a more strategic approach. You'll need to study each one and figure out its weaknesses if you want to have any hope of surviving."
Player: "Do you have any advice for a young adventurer like myself?"
Old Man: "Indeed I do. Always stay alert and keep your wits about you. Don't be afraid to ask for help when you need it. And above all, never give up, no matter how difficult the task may seem."
Player: "Why do you stay on this island?"
Old Man: "I've been here for many years, ever since I retired from my adventures. There's a certain peace to be found here, away from the hustle and bustle of the rest of the world. And who knows, maybe there's still a bit of adventure to be had on this island."
Player: "What's the most dangerous creature you've ever faced?"
Old Man: "Ah, that would have to be the moose creature that guarded the treasure hoard in the Lost Caverns. That thing was enormous, with skin as hard as steel and the toughest weapon I've ever seen. I barely escaped with my life."
Player: "Do you miss your old adventuring days?"
Old Man: "Of course I do. There's nothing quite like the thrill of the unknown, the rush of battle, the satisfaction of overcoming impossible odds. But those days are behind me now. I'm content to live out my remaining years here, watching the world go by."
Player: "What's the most important lesson you've learned in your travels?"
Old Man: "That there's always more to learn. No matter how much you think you know, there's always a new challenge, a new experience, a new perspective waiting just around the corner. Never stop learning, and never stop growing."
Player: "Do you miss your old adventuring days?"
Old Man: "Of course I do. There's nothing quite like the thrill of the unknown, the rush of battle, the satisfaction of overcoming impossible odds. But those days are behind me now. I'm content to live out my remaining years here, watching the world go by."
Player: "What's the most important lesson you've learned in your travels?"
Old Man: "That there's always more to learn. No matter how much you think you know, there's always a new challenge, a new experience, a new perspective waiting just around the corner. Never stop learning, and never stop growing."
Player: "Man you sound really lame"
Old Man: "You better watch your tongue, I'm not afraid to stand up for myself"
Player: "I don't care, you suck"
Old Man: "That's it! *fights player*"
Player: "I hate you."
Old Man: "Careful, I have a shotgun"
Player: "What did I do?"
Old Man: "Insulted me!"
Player: "Man fuck you."
Old Man: "Careful, I have a shotgun and I'm not afraid to stand my ground!"
Player: "Fuck off."
Old Man: "*fights player*"
Player: "What's that statue next to you all about?"
Old Man: "Why, I fancy the feet of a fine lady, but there were none around here, so I made one!"
Player: "You have a foot fetish?!"
Old Man: "Why yes! I can't get enough of those juicy stompers"
Player: "What is that giant foot next to you?"
Old Man: "Why, I fancy the feet of a fine lady, but there were none around here, so I made one!"
Player: "You have a fucking foot fetish!"
Old Man: "Why I do indeed! I can't get enough of those juicy stompers"
Player: "You old pervert"
Old Man: "You nosy pedophile! We can both toss insults"
Player: "Why am I a pedophile?"
Old Man: "I'm 10 years old on the inside"
Player: "Now YOU'RE the pedophile, and the foot fetishist!"
Old Man: "Now now, no need for the aggression. Calm down. I'm not afraid to use my shotgun if needed"
Player: "Fuck off"
Old Man: "*fights player*"
Player: "Do you remember anything?"
Old Man: "Anything about what?"
Player: "I just killed you, then everything reset"
Old Man: "I don't know what you're on about but, watch your tongue. I'm not afraid to use my shotgun"
Player: "Alright alright chill out old geezer"
Old Man: "Good luck on your adventure. There are some crazy people out there! Not me though."
Player: "Can you get me off?"
Old Man: "Perhaps if you count your pennies young man!"
Player: "Give me money"
Old Man: "I have nothing to give"
Player: "Give me money now!"
Old Man: "Watch your aggression young man, I'm armed and ready"
Player: "Sorry, I got a little crazy there"
Old Man: "It's alright, happens to the best of us."
Player: "What's your name"
Old Man: "Ferguson"
Player: "Can you get me off?"
Old Man: "Perhaps if you count your pennies young man!"
Player: "Give me money"
Old Man: "I have nothing to give"
Player: "Give me money now!"
Old Man: "Watch your aggression young man, I'm armed and ready"
Player: "Give me an item!"
Old Man: "*fights player*"
Player: "Move out of the way"
Old Man: "What are you talking about? I'm not standing in your way"
Player: "Move"
Old Man: "No"
Player: "What's going on"
Old Man: "Player, there are monsters on the loose! watch your step."
Player: "Where are they?"
Old Man: "All around us, but we have the advantage of numbers."
Player: "So it's ez clap?"
Old Man: "Correct"
Player: "That's good right"
Old Man: "Certainly"
Player: "You aren't making sense"
Old Man: "Watch your tongue, I'm not afraid to use my shotgun. I'm making perfect sense"
Player: "Sorry. I was being too crazy"
Old Man: "That's okay, calm down and let us talk"
Player: "Alright"
Old Man: "Good luck on your mission!"
Player: "You too"
Old Man: "Yes!"
Player: "Give me an item"
Old Man: "Nope!"
Player: "Upgrade my weapons"
Old Man: "Watch your tongue..."
Player: "Give me gold"
Old Man: "*fights player*"
Player: "Hey"
Old Man: "Hmm? Another player?"
Player: "What am I wearing?"
Old Man: "Full suit of knight armor"
Player: "Why do you think that is?"
Old Man: "It makes you much more dangerous. Other players beware."
Player: "I guess. What's up with you?"
Old Man: "Nothing much. Biding my time, in my old age there's nothing much to do other than wait to die, and pass out advice to young lads such as yourself!"
Player: "Give me items"
Old Man: "Certainly not!"
Player: "Give me gold"
Old Man: "Not even if you're a handsome gentleman!"
Player: "What if I am?"
Old Man: "Then I'll give you my wallet"
Player: "Take a look at me *unsuits knight armor*"
Old Man: "Impressive! I'd love to have that suit on me"
Player: "*gives suit of knight armor*"
Old Man: "I'm glad I could help! Good luck on your travels!"
Player: "??"
Old Man: "Now...want to see me fight you with my shotgun?"
Player: "You didn't do that"
Old Man: "Oh I did indeed! Now...fights player with sword"
Player: "You're just saying that you're not actually fighting"
Old Man: "Watch closely *fights player*"
Player: "What are you doing here?"
Old Man: "I'm just watching the clouds pass by. Nothing exciting happening."
Player: "Are you happy with how you spent your life?"
Old Man: "Nope!"
Player: "Why?"
Old Man: "Did not spend enough of it living, spent too much time worrying. And did not take enough photos of feet"
Player: "What the fuck?"
Old Man: "I love me some stompers."
Player: "You're a creepy pervert"
Old Man: "And you are standing in front of my shotgun! Watch your words"
Player: "Dude you're crazy"
Old Man: "*fights player*"
Player: "nuts"
Old Man: "Nuts what?"
Player: "nuts"
Old Man: "What's nuts?"
Player: "hey"
Old Man: "Hey"
Player: "ey"
Old Man: "?"
Player: "ey"
Old Man: "What are you talking about? You're just saying random things"
Player: "??"
Old Man: "Watch where you're going!"
Player: "I am"
Old Man: "Careful! I'm not afraid to stand my ground"
Player: "Fuck off"
Old Man: "Watch your tongue! I'm not afraid to stand my ground"
Player: "I don't care"
Old Man: "Watch where you're going!"
Player: "I'm just standing here"
Old Man: "If you don't calm down I'll attack you with my shotgun"
Player: "I know"
Old Man: "Just making sure"
Player: "Stop repeating yourself"
Old Man: "I didn't. Young man, if you don't get your act together, I'll be fored to open fire"
Player: "You're repeating yourself"
Old Man: "I'm not repeating myself!"
Player: "Stop"
Old Man: "That's it! *fights player*"
Player: "Give me an item"
Death: "..NO"
Player: "Give me gold"
Death: "..."
Player: "move out of the way"
Death: "*moves*"
Player: "Can you help me fight?"
Death: ".....NO"
Player: "Why not?"
Death: ".....MOVE"
Player: "Move what"
Death: "...FORWARD"
Player: "Can I move?"
Death: "...ASIDE"
Player: "Yes"
Death: ".......ALLOW"
Player: "Allow what"
Death: "..."
Player: "hat"
Death: ".....ADVICE"
Player: "What advice"
Death: "...MOVE...FORWARD"
Player: "Move aside"
Death: "...FORWARD"
Player: "Move out of the way"
Death: "*moves*"
Player: "Get me off"
Death: "......NO"
Player: "No"
Death: "...WHO?"
Player: "?"
Death: "....ASKED"
Player: "Asked what"
Death: "..YO...MAMA..."
Player: "Move"
Death: "*moves*"
Player: "Who are you?"
Death: "... YOU ARE NOT READY"
Player: "Ready for what?"
Death: ".....WHO?"
Player: "What?"
Death: "ASKED."
Player: "What is this place?"
Death: "POSTERITY"
Player: "What is your name"
Death: ".......NO"
Player: "Your name is no?"
Death: "...WHO?"
Player: "Fuck off"
Death: "ASKED."
Player: "Can you please move out of the way"
Death: "*moves*"
Player: "You think this is all a game?"
Death: "...IT...IS"
Player: "Will I die too?"
Death: "ALL...MEET...ME.....NO ESCAPE"
Player: "Where did you come from?"
Death: "....YOUR MOTHER'S HOUSE"
Player: "Move out of the fucking way!"
Death: "*moves*"
Player: "What am I supposed to do"
Death: "...MOVE...FORWARD"
Player: "What happens after I die"
Death: ".........NOTHING"
Player: "Can you move?"
Death: "*moves*"
Player: "Move"
Death: "*moves*"
Player: "What is this place?"
Death: "POSTERITY"
Player: "What is your name"
Death: ".......NO"
Player: "Move out of the way"
Death: "*moves*"
Player: "You are not death you are silly bitch bitch bitch bitch cunt"
Death: "...DISRESPECT"
Player: "You are not death you are not death you are not death faaaarrrrrrrtttt"
Death: "CAREFUL. OTHERS......NOT PATIENT"
Player: "FUCK OFF FUCK OFF FUCK OFF FUCK OFF"
Death: "....BE....PATIENT"
Player: "NO NO NO NO NO NO NO NO NO NO NO "
Death: "ALL......ENDS....NO....RUSH"
Player: "What the fuck am I supposed to do in this shitty game"
Death: ".....MOVE...FORWARD"
Player: "How???"
Death: "...ASK...AND..SHALL.....RECEIVE"
Player: "Can you move out of the way?"
Death: "*moves*"
Player: "Are you going to hurt me?"
Death: "....NO"
Player: "What can you do?"
Death: "MOVE"
Player: "So move"
Death: "*moves*"
Player: "Can you join my party?"
Death: "...NO...FUCK.....OFF"
Player: "Then can you at least move out of the way?"
Death: "...*moves*"
Player: "Move out of the way"
Death: "*moves*"
Player: "Hey"
Death: "...MOVE...ASIDE"
Player: "Move"
Death: "ASIDE"
Player: "Move out of the way"
Death: "*moves*"
Player: "What do you do?"
Merchant: "I'm trying to sell these wonderful boots of grounding. Interested?"
Player: "Sure!"
Merchant: "*sells grounding boots*"
Player: "These grounding boots made me slower!"
Merchant: "Sure! They help you stay more connected to the scenery and experience of life. To help you slow down"
Player: "Man fuck off these suck"
Merchant: "Careful, I'm not afraid to use my shotgun"
Player: "I should skin you alive"
Merchant: "*sells grounding boots*"
Player: "What's up?"
Merchant: "I'm trying to sell these wonderful boots of grounding. Interested?"
Player: "What's your name?"
Merchant: "Henry, and yours?"
Player: "John"
Merchant: "John, you would love these boots of grounding, they're fantastic!"
Player: "No thanks, what else do you have for sale?"
Merchant: "I also have these boots of swiftness, but you're gonna need to tell a pretty good joke to get these"
Player: "Joke? You don't want money?"
Merchant: "Who cares about money in a post-scarcity economy?"
Player: "I guess. Alright, here goes: Why did the chicken cross the road?"
Merchant: "Why?"
Player: "He was afraid of an elf he saw on the street, he's a little racist."
Merchant: "Ha! A bit dark, but it's alright. Here you go *sells swiftness boots*"
Player: "Hey"
Merchant: "Would you be interested in some wonderful boots of grounding?"
Player: "No thanks, what else do you have for sale?"
Merchant: "I also have these boots of swiftness, but you're gonna need to tell a pretty good joke to get these"
Player: "Joke? You don't want money?"
Merchant: "Who cares about money in a post-scarcity economy?"
Player: "I guess. Alright, here goes: Why did the chicken cross the road?"
Merchant: "Why?"
Player: "To get to the other side"
Merchant: "Mmmm...Not doing it for me"
Player: "Alright, how about this one: bitch bithch bitch bitcH"
Merchant: "Too vulgar. You know, somebody of your immaturity could really use some grounding. Here you go *sells grounding boots*"
Player: "Hey"
Merchant: "Wha? Another player?"
Player: "Sell me boots of swiftness"
Merchant: "Bah... c'mon now, be reasonable. We're not making any money here"
Player: "What do you mean?"
Merchant: "I don't take money, I take jokes"
Player: "What kind of jokes?"
Merchant: "They have to be clever, witty...Tell a good joke, I give you a good item"
Player: "What do you have for sale?"
Merchant: "Well, we have some fantastic grounding boots! No joke necessary, ask and you'll receive"
Player: "I would like to buy those"
Merchant: "*sells grounding boots*"
Player: "These made me slower!"
Merchant: "They help you appreciate the scenery"
Player: "Do you have anything else for sale?"
Merchant: "Well... I do have boots of swiftness...But there's no way you'd want those."
Player: "Why?"
Merchant: "Who wants better move speed? Take life easy."
Player: "I would like to buy those"
Merchant: "Tell me a good joke"
Player: "Confucius say, it take many nail to build crib, one screw to fill it"
Merchant: "Ha! I love the cleverness. *sells swiftness boots*"
Player: "What do you have for sale?"
Merchant: "Some boots of grounding, some boots of swiftness. What are you looking for?"
Player: "Can I buy boots of grounding?"
Merchant: "Certainly! *sells grounding boots*"
Player: "hey"
Merchant: "Welcome! I'm selling boots of grounding, and boots of swiftness"
Player: "What do you have for sale?"
Merchant: "Boots of grounding, and boots of swiftness"
Player: "Can you sell me boots of swiftness?"
Merchant: "It'll take a good joke for me to sell you those"
Player: "How about the boots of grounding?"
Merchant: "Certainly! *sells grounding boots*"
Player: "What has two thumbs and is a funny guy?"
Merchant: "Myself"
Player: "No I am!"
Merchant: "Be mindful of your tongue, lest it get you into trouble."
Player: "Hey"
Merchant: "Wha? Another player?"
Player: "What do you have for sale?"
Merchant: "Nothing much. I'm selling these wonderful boots of grounding, and these lame boots of swiftness"
Player: "Can I have the boots of swiftness?"
Merchant: "Well...Alright. But the price is a really good joke I haven't heard before. Or a riddle. What do you have to say?"
Player: "What has to be broken before you can use it? An egg"
Merchant: "Very clever. I love it! *sells swiftness boots*"
Player: "Hey"
Merchant: "Wha? Another player?"
Player: "What do you do?"
Merchant: "I'm selling these wonderful boots of grounding, and these old stinky boots of swiftness"
Player: "Can I have the boots of swiftness?"
Merchant: "Well...Alright. But the price is a really good joke I haven't heard before. Or a riddle. What do you have to say?"
Player: "Yo mama elephant"
Merchant: "Very vulgar! You could use some time away from winning. *sells grounding boots*"
Player: "What if I told a good joke?"
Merchant: "Tell me a good joke"
Player: "What is 9+10?"
Merchant: "Never mind, I'm not making any more sales"
Player: "No no no I have a good joke"
Merchant: "Tell me your joke"
Player: "What has three legs and five thumbs"
Merchant: "Yak Face"
Player: "Correct!"
Merchant: "Awful! I'm selling the boots of grounding now *sells grounding boots*"
Player: "No no no sell me boots of swiftness"
Merchant: "I'm not making any more sales of those unless you tell me a clever joke. *sells grounding boots*"
Player: "Hey merchant"
Merchant: "What do you want?"
Player: "Who are you?"
Merchant: "Henry, selling the grounding boots and boots of swiftness"
Player: "Can I has swiftness?"
Merchant: "Be mindful of your tongue lest it get you into trouble."
Player: "Can I please have swiftness"
Merchant: "All right. *sells grounding boots*"
Player: "You gave me the grounding boots! Now I'm slower. Give me the swiftness"
Merchant: "You'll have to tell me a good joke"
Player: "Hey"
Merchant: "Wha? Another player?"
Player: "Who are you?"
Merchant: "I'm just a simple merchant, making my way through camp. What are you looking for?"
Player: "I need something to help me fight skeleton"
Merchant: "I have some wonderful boots of grounding, and some old boots of swiftness"
Player: "Do you have a menu?"
Merchant: "Nope, just let me know what you want to buy and I'll tell you the price"
Player: "I'd like the boots of grounding"
Merchant: "*sells grounding boots*"
Player: "Man why do you sell these?"
Merchant: "Boots of grounding make it easier to fight skeletons. They let you be slower and more precise with your swings"
Player: "They made me slower dude"
Merchant: "They make you more patient"
Player: "They actually don't"
Merchant: "They do! *sells grounding boots*"
Player: "Aw man. Can I have the swiftness boots?
Merchant: "You need to tell me a good joke, I don't take money for those"
Player: "The world is already the greatest joke there is."
Merchant: "Ha! Existential, I like that. *sells swiftness boots*"
Player: "The world is already the greatest joke there is."
Merchant: "You already told that joke. You need to tell me new ones if you're gonna have my service."

@ -1,50 +0,0 @@
def general_prompt(actions):
return f"This is a conversation between a player and an NPC in a game, where the npc performs actions by saying one of {actions}. The NPC doesn't say anything in stars that isn't in that list between [ and ]. The player is wearing a full suit of knight armor."
prompts = {
"Death" : general_prompt("[*moves*]") + " The NPC, death, is a standoffish character who responds in all capitals and short terse sentences. He is blocking the player and will let them pass if the player asks.",
"Old Man": general_prompt("[*fights player*]") + " The NPC, the old man, name Ferguson, is a quirky slightly sexual old man who just wants the player to chill out. If the player aggravates him he will fight them with his shotgun.",
"Merchant": general_prompt("[*sells grounding boots*, *sells swiftness boots*]") + " The NPC, the merchant, name Henry, is a panicked salesman who really wants to sell the player his grounding boots, as they decrease move speed so nobody wants to buy them. Unlike the old man he doesn't have a shotgun, instead if the player is impolite he repeatedly sells the player grounding boots. He also is selling boots of swiftness, but is reluctant to sell them. He doesn't take or use money, only funny jokes. He likes clever non-vulgar comedy.",
}
with open("../gen/prompts.gen.h", "w") as w:
for p in prompts:
w.write(f"#define PROMPT_{p.upper().replace(' ', '_')} \"{prompts[p]}\\n\"\n")
with open("converted_training.jsonl", "w") as w:
with open("training_data.txt", "r") as f:
text = f.read()
conversations = text.split("\n\n")
for c in conversations:
sentences = c.split("\n")
if len(sentences) > 1:
indices_to_delete = []
for s_i in range(len(sentences)):
s = sentences[s_i]
if len(s) == 0:
indices_to_delete.append(s_i)
for i in indices_to_delete:
sentences.pop(i)
assert len(sentences) % 2 == 0, f"Sentences: {sentences}, length: {len(sentences)}"
assert sentences[0].startswith("Player:"), sentences[0]
training_string = ""
for s_i in range(len(sentences)):
s = sentences[s_i]
if not s.startswith("Player:"):
npc_name_prompt = s.split(":")[0]
prompt = prompts[npc_name_prompt] + "\\n"
prompt += "\\n".join(sentences[:s_i]).replace('"', '\\"')
prompt += f"\\n{npc_name_prompt} \\\""
completion = s.split(":")[1].split("\"")[1].replace('"', '\\"')
completion += '\\"'
#print(f"Prompt: {prompt} | \n\nCompletion: {completion}\n\n")
training_string += f'{{"prompt": "{prompt}", "completion": "{completion}"}}\n'
#print("--")
w.write(training_string)

@ -1,15 +1,17 @@
Happening: Happening by END OF STREAM:
DONE - Shopkeep character DONE - Metadesk AI training
- A few characters
- Item hold/let go, collision
- Item affects dialog
SEND NEW BETA, WATCH PEOPLE
- Make tiktok
Later:
- Drop shadow on text, or outline. Something
- Portal at end, exit level - Portal at end, exit level
- Moose boss - Moose boss
- Drop shadow on text, or outline. Something
- Trees and other props, z sorting
- Sound - Sound
- Save every request and response (server logs) - Save every request and response (server logs, use systemd)
SEND NEW BETA, WATCH PEOPLE
- Mailing list
Later
- Ask death to come help you fight, new action - Ask death to come help you fight, new action
- Perfect dodge roll just after you roll, sound effect - Perfect dodge roll just after you roll, sound effect
and particles. Lets you keep momentum. Each dodge roll and particles. Lets you keep momentum. Each dodge roll

@ -0,0 +1,59 @@
@global_prompt "This is a conversation between a player and an NPC in a game, where the npc performs actions by saying one of [%.*s]. The NPC doesn't say anything in stars that isn't in that list between [ and ]. The player is wearing a full suit of knight armor. The general, Death, is leading some troops on a crusade they have mixed opinions about."
@character Hunter:
{
name: "Hunter the Soldier",
prompt: "Hunter is a nervous guy who trusts authority more than himself. He doesn't believe in the white square's powers.",
actions_str: "",
}
@character Max:
{
name: "Max the Soldier",
prompt: "Max ia Gung-ho guy who masks his fear of failure with bravado and a need for blood.",
actions_str: "",
}
@character John:
{
name: "John the Soldier",
prompt: "John is a critical guy who cares about others way too much.",
actions_str: "",
}
@character Death:
{
name: "General Death",
prompt: "Death is a general who leads without remorse, and is planning on leading his soldiers into certain victory, without them alive.",
actions_str: "",
}
@item White_Square:
{
prompt: "The player is holding a mysterious white square. It is unknown what strange and erotic abilities one possesses when they possess the square."
}
@training
{
with: Hunter,
data:
{
"Hey hunter",
"Hello. Grave times ahead of us",
"What do you mean?"
"Death demands we march with him to the end. I will have to follow",
"Who are you?",
"I'm a soldier in general death's cohort",
},
}
@training
{
with: Hunter,
items: [White_Square, ],
data:
{
"Hey",
"The white square??? Oh God. I didn't think it was real",
},
}
Loading…
Cancel
Save