diff --git a/main.c b/main.c index 235009a..6b9fb0c 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ // you will die someday -#define CURRENT_VERSION 6 // wehenver you change Entity increment this boz +#define CURRENT_VERSION 7 // wehenver you change Entity increment this boz #define SOKOL_IMPL #if defined(WIN32) || defined(_WIN32) @@ -1670,14 +1670,15 @@ void request_do_damage(Entity *to, Entity *from, float damage) } else if(true) { - to->damage += damage; + // damage processing is done in process perception so in training, has accurate values for + // NPC health if(from->is_character) { - process_perception(to, (Perception){.type = PlayerAction, .player_action_type = ACT_hits_npc}); + process_perception(to, (Perception){.type = PlayerAction, .player_action_type = ACT_hits_npc, .damage_done = damage,}); } else { - process_perception(to, (Perception){.type = EnemyAction, .enemy_action_type = ACT_hits_npc}); + process_perception(to, (Perception){.type = EnemyAction, .enemy_action_type = ACT_hits_npc, .damage_done = damage,}); } to->vel = MulV2F(NormV2(SubV2(to->pos, from_point)), 15.0f); } @@ -2589,7 +2590,7 @@ void frame(void) Entity *from = it; BUFF_ITER(Entity *, &to_damage) { - request_do_damage(*it, from, 0.2f); + request_do_damage(*it, from, DAMAGE_SWORD); } } } @@ -2709,7 +2710,7 @@ void frame(void) if(!it->is_tile && !(it->e->is_bullet)) { // knockback and damage - request_do_damage(it->e, from_bullet, 0.2f); + request_do_damage(it->e, from_bullet, DAMAGE_BULLET); destroy_bullet = true; } } @@ -2940,7 +2941,7 @@ void frame(void) SwordToDamage to_damage = entity_sword_to_do_damage(player, get_overlapping(cur_level, weapon_aabb)); BUFF_ITER(Entity*, &to_damage) { - request_do_damage(*it, player, 0.2f); + request_do_damage(*it, player, DAMAGE_SWORD); } player->swing_progress += dt; if(player->swing_progress > anim_sprite_duration(&knight_attack)) diff --git a/makeprompt.h b/makeprompt.h index 6f3fd6f..5df3cbe 100644 --- a/makeprompt.h +++ b/makeprompt.h @@ -34,10 +34,14 @@ typedef struct Perception { PerceptionType type; + float damage_done; // Valid in player action and enemy action union { // player action - Action player_action_type; + struct + { + Action player_action_type; + }; // player dialog Sentence player_dialog; @@ -86,6 +90,9 @@ typedef enum STANDING_FIGHTING, } NPCPlayerStanding; +#define DAMAGE_SWORD 0.2f +#define DAMAGE_BULLET 0.2f + typedef struct Entity { bool exists; @@ -198,6 +205,10 @@ void process_perception(Entity *it, Perception p) if(p.type != NPCDialog) it->perceptions_dirty = true; if(!BUFF_HAS_SPACE(&it->remembered_perceptions)) BUFF_REMOVE_FRONT(&it->remembered_perceptions); BUFF_APPEND(&it->remembered_perceptions, p); + if(p.type == PlayerAction && p.player_action_type == ACT_hits_npc) + { + it->damage += p.damage_done; + } if(p.type == PlayerHeldItemChanged) { it->last_seen_holding_kind = p.holding; diff --git a/maketraining.c b/maketraining.c index b425345..ed74816 100644 --- a/maketraining.c +++ b/maketraining.c @@ -16,7 +16,8 @@ typedef struct TrainingElement elems[32]; } TrainingSample; -#define PlayerAct(act) { .p = { .type = PlayerAction, .player_action_type = act, } } +#define PlayerActDamage(act, dmg) { .p = { .type = PlayerAction, .player_action_type = act, .damage_done = dmg, } } +#define PlayerAct(act) PlayerActDamage(act, 0.0f) #define PlayerSay(txt) { .p = { .type = PlayerDialog, .player_dialog = SENTENCE_CONST(txt), } } #define NPCDoSay(d, txt) { .p = { .type = NPCDialog, .npc_action_type = d, .npc_dialog = SENTENCE_CONST(txt) } } #define NPCSay(txt) NPCDoSay(ACT_none, txt) @@ -41,8 +42,7 @@ TrainingSample samples[] = { NPCSay("You must stop death in his tracks and let the village live on!"), PlayerSay("Nah"), NPCSay("PLEASE!"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "Ready your sword!"), }, }, @@ -143,11 +143,9 @@ TrainingSample samples[] = { .elems = { PlayerSay("Hey"), NPCDoSay(ACT_none, "I'm just sitting here, what are you doing?"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_none, "Looks like you're ready to do what needs to be done."), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "I won't stand for this assault."), }, }, @@ -160,8 +158,7 @@ TrainingSample samples[] = { NPCDoSay(ACT_none, "I'm sure it'll be fine"), PlayerSay("No it won't"), NPCDoSay(ACT_none, "Nahhhh"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "You don't have a tripod."), PlayerItemChange(ITEM_Tripod), PlayerSay("Look! I have the tripod! Please stop fighting me!"), @@ -171,22 +168,18 @@ TrainingSample samples[] = { { .npc_kind = NPC_OldMan, .elems = { - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_none, "Young man! You must stop death, do not harm me further I'm warning you!"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "That's it! No holds barred, to the death!"), }, }, { .npc_kind = NPC_Blocky, .elems = { - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCSay("I'm warning you, one more hit and it's curtains for you"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "Although I stood here before, today I move and FIGHT!"), }, }, @@ -198,8 +191,7 @@ TrainingSample samples[] = { NPCDoSay(ACT_allows_player_to_pass, "The tripod...Of course my liege."), PlayerSay("Thanks"), NPCDoSay(ACT_none, "My pleasure"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCSay("How could you do such a thing? After the tripod as well"), PlayerItemChange(ITEM_none), PlayerSay("You suck"), @@ -241,11 +233,9 @@ TrainingSample samples[] = { .elems = { PlayerSay("Join me"), NPCDoSay(ACT_joins_player, "I would be honored"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_none, "Hey! Watch it!"), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "That's it!"), }, }, @@ -283,11 +273,9 @@ TrainingSample samples[] = { NPCDoSay(ACT_none, "You don't care...fine."), PlayerSay("DIE"), NPCDoSay(ACT_none, "I wasn't going to do that."), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_leaves_player, "You shouldn't do that."), - PlayerAct(ACT_hits_npc), - NPCTakeDamage(0.2f), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), NPCDoSay(ACT_fights_player, "You won't last a minute against me!"), }, }, @@ -311,6 +299,31 @@ TrainingSample samples[] = { NPCDoSay(ACT_fights_player, "You must perish for your wildness!"), }, }, + { + .npc_kind = NPC_OldMan, + .elems = { + PlayerSay("Who are you?"), + NPCSay("I'm the old man fredrick, you have to stop the general!"), + PlayerSay("What do you do?"), + NPCSay("I mostly just stand here in my old age, but I've been through a lot in my youth...tales to tell!"), + PlayerSay("What's an example?"), + NPCSay("I've killed a man"), + }, + }, + { + .npc_kind = NPC_Blocky, + .elems = { + PlayerSay("If you don't move out of the way I'll kill you"), + NPCDoSay(ACT_none, "I'm just standing here, what are you doing?"), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), + NPCDoSay(ACT_none, "Looks like you're ready to do what needs to be done."), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), + NPCDoSay(ACT_none, "I'm not sure what you're thinking, but that doesn't sound like a good idea."), + PlayerActDamage(ACT_hits_npc, DAMAGE_SWORD), + NPCDoSay(ACT_allows_player_to_pass, "Fine! Please spare me!"), + PlayerSay("That's more like it"), + }, + }, }; diff --git a/server/go.mod b/server/go.mod index 4e2f226..7220795 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,6 +7,7 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-sqlite3 v1.14.15 // indirect github.com/sashabaranov/go-gpt3 v1.2.1 // indirect + github.com/sashabaranov/go-openai v1.5.8 // indirect github.com/stripe/stripe-go/v72 v72.122.0 // indirect github.com/stripe/stripe-go/v74 v74.13.0 // indirect gorm.io/driver/sqlite v1.4.4 // indirect diff --git a/server/go.sum b/server/go.sum index 06fbc8f..b72a007 100644 --- a/server/go.sum +++ b/server/go.sum @@ -9,6 +9,8 @@ github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sashabaranov/go-gpt3 v1.2.1 h1:kfU+vQ1ThI7p+xfwwJC8olEEEWjK3smgKZ3FcYbaLRQ= github.com/sashabaranov/go-gpt3 v1.2.1/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ= +github.com/sashabaranov/go-openai v1.5.8 h1:EfNEmc+Ue+CuRy7iSpNdxfHyiOv2vQsQ2Y0kZRA/z5w= +github.com/sashabaranov/go-openai v1.5.8/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/server/main.go b/server/main.go index 55f6234..47ae2cc 100644 --- a/server/main.go +++ b/server/main.go @@ -12,7 +12,7 @@ import ( "strings" "encoding/json" "math/rand" - gogpt "github.com/sashabaranov/go-gpt3" + openai "github.com/sashabaranov/go-openai" "github.com/stripe/stripe-go/v74" "github.com/stripe/stripe-go/v74/event" "github.com/stripe/stripe-go/v74/webhook" @@ -48,7 +48,7 @@ type User struct { CheckoutSessionID string } -var c *gogpt.Client +var c *openai.Client var logResponses = false var doCors = false var checkoutRedirectTo string @@ -340,24 +340,66 @@ func completion(w http.ResponseWriter, req *http.Request) { } ctx := context.Background() - req := gogpt.CompletionRequest { - Model: "curie:ft-alnar-games-2023-04-01-21-23-38", - MaxTokens: 80, - Prompt: promptString, - Temperature: 0.9, - FrequencyPenalty: 0.0, - PresencePenalty: 0.6, - TopP: 1.0, - Stop: []string{"\n"}, - N: 1, - } - resp, err := c.CreateCompletion(ctx, req) - if err != nil { - log.Println("Error Failed to generate: ", err) - w.WriteHeader(http.StatusInternalServerError) - return + var response string = "" + if true { + req := openai.CompletionRequest { + Model: "davinci:ft-alnar-games-2023-04-03-10-06-45", + MaxTokens: 80, + Prompt: promptString, + Temperature: 0.9, + FrequencyPenalty: 0.0, + PresencePenalty: 0.6, + TopP: 1.0, + Stop: []string{"\n"}, + N: 1, + } + resp, err := c.CreateCompletion(ctx, req) + if err != nil { + log.Println("Error Failed to generate: ", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + response = resp.Choices[0].Text + } else { + messages := make([]openai.ChatCompletionMessage, 0) + inSystem := true + for _, line := range strings.Split(promptString, "\n") { + if inSystem { + messages = append(messages, openai.ChatCompletionMessage { + Role: "system", + Content: line, + }) + } else { + newMessage := openai.ChatCompletionMessage { + Role: "assistant", + Content: line, + } + if strings.HasPrefix(line, "Player") { + newMessage.Role = "user" + } + messages = append(messages, newMessage) + } + // this is the last prompt string + if strings.HasPrefix(line, "The NPC possible actions array") { + inSystem = false + } + } + clippedOfEndPrompt := messages[:len(messages)-1] + resp, err := c.CreateChatCompletion( + context.Background(), + openai.ChatCompletionRequest{ + Model: openai.GPT3Dot5Turbo, + Messages: clippedOfEndPrompt, + }, + ) + if err != nil { + log.Println("Error Failed to generate: ", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + response = resp.Choices[0].Message.Content + } - response := resp.Choices[0].Text if logResponses { log.Println("Println response: `", response + "`") log.Println() @@ -377,6 +419,7 @@ func main() { if err != nil { log.Fatal(err) } + db.AutoMigrate(&User{}) clearOld(db) @@ -405,7 +448,7 @@ func main() { logResponses = os.Getenv("LOG_RESPONSES") != "" doCors = os.Getenv("CORS") != "" - c = gogpt.NewClient(api_key) + c = openai.NewClient(api_key) http.HandleFunc("/completion", completion) http.HandleFunc("/webhook", webhookResponse) diff --git a/todo.txt b/todo.txt index 1b28afd..a914563 100644 --- a/todo.txt +++ b/todo.txt @@ -7,25 +7,27 @@ DONE - Help you fight and fight you actions DONE - Do not use webhooks (shitty, bad idea propagated by bad docs) query stripe for if the payment went through on request if not fulfilled yet DONE - New art in DON'T NEED - Old man in beginning is invincible - - Make new openai key (it was leaked) DONE - Add cancel button DONE - Style buttons DONE - nockin git thing - - Animate text characters coming in DONE - Make TREE1 prop work - - Instead of roll animation, 5 sprite long trail of past moves for juice DONE - Enemy hitting NPC is enemy perception not player peception of player hitting them - - Sword combat for sword npcs DONE - Third button for dialog/item stuff, not roll button. E on desktop. Touchscreen button only visible when appropriate to let player know what it's for DON'T NEED, SET BACKGROUND COLOR - Clamp camera to boundaries of level DONE - Ignore keyrepeat events DONE - Remove control attack key as devtools - - Cells interlinked (interlinked) DONE - Tune fade popping at dist when you go too far awy - - Particle fx and sound fx for when hit - - Max text length on text input DONE - Fade dialog with distance DONE - Make vignette in front + - Make new openai key (it was leaked) + - Animate text characters coming in + - Instead of roll animation, 5 sprite long trail of past moves for juice + - Cells interlinked (interlinked) + - Particle fx and sound fx for when hit + - Max text length on text input + - Sword combat for sword npcs + - Fade for dialog not tied to interacting, starts when outside of interacting range, when begin conversation fades completely in + SHIP BETA - Make ANOTHER tiktok if you can. Por favor - Make map better, add new characters/items from fate