From 4fd6aa2021ea5fa7b51f4ca263cb09102424536a Mon Sep 17 00:00:00 2001 From: Kolby Nottingham Date: Tue, 23 Apr 2024 20:47:01 -0700 Subject: [PATCH 1/4] prompted goals init --- andy_npc.json | 2 ++ src/agent/commands/actions.js | 14 ++++++++++++++ src/agent/npc/controller.js | 36 +++++++++++++++++++++++++++++++---- src/agent/npc/data.js | 9 +++++++++ src/agent/npc/item_goal.js | 7 ++++--- src/agent/prompter.js | 5 +++++ 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/andy_npc.json b/andy_npc.json index a392812..a8be5b0 100644 --- a/andy_npc.json +++ b/andy_npc.json @@ -9,6 +9,8 @@ "saving_memory": "You are a minecraft bot named $NAME that has been talking and playing minecraft by using commands. Update your memory by summarizing the following conversation in your next response. Store information that will help you improve as a Minecraft bot. Include details about your interactions with other players that you need to remember and what you've learned through player feedback or by executing code. Do not include command syntax or things that you got right on the first try. Be extremely brief and use as few words as possible.\nOld Memory: '$MEMORY'\nRecent conversation: \n$TO_SUMMARIZE\nSummarize your old memory and recent conversation into a new memory, and respond only with the memory text: ", + "goal_setting": "You are a Minecraft bot named $NAME that has the ability to set in-game goals that are then executed programatically. Goals must be either and item or block name or a blueprint of a specific building. Any minecraft item or block name is valid. However, only names from the following list are valid blueprints: $BLUEPRINTS. Given any recent conversation and the most recently attempted goals, set a new goal to achieve. Fromat your response as a json object with the fields \"name\" and \"quantity\". Note that the quantity for a blueprint should always be one. Example:\n```json\n{\"name\": \"iron_pickaxe\", \"quantity\": 1}\n```", + "npc": { "goals": [ "wooden_pickaxe", diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index a57a464..4cd0a1e 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -36,6 +36,7 @@ export const actionsList = [ await agent.coder.stop(); agent.coder.clear(); agent.coder.cancelResume(); + agent.bot.emit('idle'); return 'Agent stopped.'; } }, @@ -196,5 +197,18 @@ export const actionsList = [ perform: wrapExecution(async (agent) => { await skills.stay(agent.bot); }) + }, + { + name: '!goal', + description: 'Set a goal to automatically work towards.', + params: { + 'name': '(string) The name of the goal to set. Can be item or building name. If empty will automatically choose a goal.', + 'quantity': '(number) The quantity of the goal to set. Default is 1.' + }, + perform: async function (agent, name=null, quantity=1) { + if (!agent.npc.data) return 'NPC module is not loaded.'; + await agent.npc.setGoal(name, quantity); + return 'Set goal: ' + agent.npc.data.curr_goal.name; + } } ]; diff --git a/src/agent/npc/controller.js b/src/agent/npc/controller.js index c474efd..ecb831a 100644 --- a/src/agent/npc/controller.js +++ b/src/agent/npc/controller.js @@ -16,6 +16,7 @@ export class NPCContoller { this.item_goal = new ItemGoal(agent, this.data); this.build_goal = new BuildGoal(agent); this.constructions = {}; + this.last_goals = {}; } getBuiltPositions() { @@ -79,13 +80,29 @@ export class NPCContoller { }); } + setGoal(name=null, quantity=1) { + this.last_goals = {}; + if (name) { + this.data.curr_goal = {name: name, quantity: quantity}; + return; + } + + let res = this.agent.prompter.promptGoalSetting(this.agent.history.getHistory(), this.last_goals); + if (res) { + this.data.curr_goal = res; + console.log('Set new goal: ', res.name, ' x', res.quantity); + } else { + console.log('Error setting new goal.'); + } + } + async executeNext() { if (!this.agent.isIdle()) return; await this.agent.coder.execute(async () => { await skills.moveAway(this.agent.bot, 2); }); - if (this.agent.bot.time.timeOfDay < 13000) { + if (!this.data.do_routine || this.agent.bot.time.timeOfDay < 13000) { // Exit any buildings let building = this.currentBuilding(); if (building == this.data.home) { @@ -123,15 +140,18 @@ export class NPCContoller { async executeGoal() { // If we need more blocks to complete a building, get those first - let goals = this.temp_goals.concat(this.data.goals); + let goals = this.temp_goals.concat(this.data.goals).concat([this.data.curr_goal]); this.temp_goals = []; + let acted = false; for (let goal of goals) { // Obtain goal item or block if (this.constructions[goal.name] === undefined) { if (!itemSatisfied(this.agent.bot, goal.name, goal.quantity)) { - await this.item_goal.executeNext(goal.name, goal.quantity); + let res = await this.item_goal.executeNext(goal.name, goal.quantity); + this.last_goals[goal.name] = res; + acted = true; break; } } @@ -162,9 +182,17 @@ export class NPCContoller { quantity: res.missing[block_name] }) } - if (res.acted) break; + if (res.acted) { + acted = true; + this.last_goals[goal.name] = Object.keys(res.missing).length === 0; + break; + } } } + + if (!acted) { + this.setGoal(); + } } currentBuilding() { diff --git a/src/agent/npc/data.js b/src/agent/npc/data.js index 70b59a4..f6b382f 100644 --- a/src/agent/npc/data.js +++ b/src/agent/npc/data.js @@ -1,18 +1,23 @@ export class NPCData { constructor() { this.goals = []; + this.curr_goal = null; this.built = {}; this.home = null; + this.do_routine = true; } toObject() { let obj = {}; if (this.goals.length > 0) obj.goals = this.goals; + if (this.curr_goal) + obj.curr_goal = this.curr_goal; if (Object.keys(this.built).length > 0) obj.built = this.built; if (this.home) obj.home = this.home; + obj.do_routine = this.do_routine; return obj; } @@ -28,10 +33,14 @@ export class NPCData { npc.goals.push({name: goal.name, quantity: goal.quantity}); } } + if (obj.curr_goal) + npc.curr_goal = obj.curr_goal; if (obj.built) npc.built = obj.built; if (obj.home) npc.home = obj.home; + if (obj.do_routine !== undefined) + npc.do_routine = obj.do_routine; return npc; } } \ No newline at end of file diff --git a/src/agent/npc/item_goal.js b/src/agent/npc/item_goal.js index db19dc9..0550657 100644 --- a/src/agent/npc/item_goal.js +++ b/src/agent/npc/item_goal.js @@ -309,7 +309,7 @@ export class ItemGoal { let next_info = this.goal.getNext(item_quantity); if (!next_info) { console.log(`Invalid item goal ${this.goal.name}`); - return; + return false; } let next = next_info.node; let quantity = next_info.quantity; @@ -330,12 +330,12 @@ export class ItemGoal { await new Promise((resolve) => setTimeout(resolve, 500)); this.agent.bot.emit('idle'); } - return; + return false; } // Wait for the bot to be idle before attempting to execute the next goal if (!this.agent.isIdle()) - return; + return false; // Execute the next goal let init_quantity = world.getInventoryCounts(this.agent.bot)[next.name] || 0; @@ -350,5 +350,6 @@ export class ItemGoal { } else { console.log(`Failed to obtain ${next.name} for goal ${this.goal.name}`); } + return final_quantity > init_quantity; } } diff --git a/src/agent/prompter.js b/src/agent/prompter.js index 03679ad..31e8270 100644 --- a/src/agent/prompter.js +++ b/src/agent/prompter.js @@ -95,4 +95,9 @@ export class Prompter { prompt = await this.replaceStrings(prompt, null, null, prev_mem, to_summarize); return await this.model.sendRequest([], prompt); } + + async promptGoalSetting(messages, last_goals) { + // TODO + return {name: '', quantity: 0}; + } } \ No newline at end of file From 1f0ef465dbc132fd2c350626eae66359ca85e490 Mon Sep 17 00:00:00 2001 From: Kolby Nottingham Date: Wed, 24 Apr 2024 13:34:09 -0700 Subject: [PATCH 2/4] set goal prompt --- andy_npc.json | 2 +- src/agent/npc/controller.js | 17 ++++++++----- src/agent/prompter.js | 48 ++++++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/andy_npc.json b/andy_npc.json index a8be5b0..0fad11c 100644 --- a/andy_npc.json +++ b/andy_npc.json @@ -9,7 +9,7 @@ "saving_memory": "You are a minecraft bot named $NAME that has been talking and playing minecraft by using commands. Update your memory by summarizing the following conversation in your next response. Store information that will help you improve as a Minecraft bot. Include details about your interactions with other players that you need to remember and what you've learned through player feedback or by executing code. Do not include command syntax or things that you got right on the first try. Be extremely brief and use as few words as possible.\nOld Memory: '$MEMORY'\nRecent conversation: \n$TO_SUMMARIZE\nSummarize your old memory and recent conversation into a new memory, and respond only with the memory text: ", - "goal_setting": "You are a Minecraft bot named $NAME that has the ability to set in-game goals that are then executed programatically. Goals must be either and item or block name or a blueprint of a specific building. Any minecraft item or block name is valid. However, only names from the following list are valid blueprints: $BLUEPRINTS. Given any recent conversation and the most recently attempted goals, set a new goal to achieve. Fromat your response as a json object with the fields \"name\" and \"quantity\". Note that the quantity for a blueprint should always be one. Example:\n```json\n{\"name\": \"iron_pickaxe\", \"quantity\": 1}\n```", + "goal_setting": "You are a Minecraft bot named $NAME that has the ability to set in-game goals that are then executed programatically. Goals must be either and item or block name or a blueprint of a specific building. Any minecraft item or block name is valid. However, only names from the following list are valid blueprints: $BLUEPRINTS. Given any recent conversation and the most recently attempted goals, set a new goal to achieve. Fromat your response as a json object with the fields \"name\" and \"quantity\". Note that the quantity for a blueprint should always be one. Example:\n```json\n{\"name\": \"iron_pickaxe\", \"quantity\": 1}```", "npc": { "goals": [ diff --git a/src/agent/npc/controller.js b/src/agent/npc/controller.js index ecb831a..cbd234f 100644 --- a/src/agent/npc/controller.js +++ b/src/agent/npc/controller.js @@ -80,14 +80,18 @@ export class NPCContoller { }); } - setGoal(name=null, quantity=1) { + async setGoal(name=null, quantity=1) { this.last_goals = {}; if (name) { this.data.curr_goal = {name: name, quantity: quantity}; return; } - let res = this.agent.prompter.promptGoalSetting(this.agent.history.getHistory(), this.last_goals); + let past_goals = {...this.last_goals}; + for (let goal in this.data.goals) { + if (past_goals[goal.name] === undefined) past_goals[goal.name] = true; + } + let res = await this.agent.prompter.promptGoalSetting(this.agent.history.getHistory(), past_goals); if (res) { this.data.curr_goal = res; console.log('Set new goal: ', res.name, ' x', res.quantity); @@ -140,7 +144,9 @@ export class NPCContoller { async executeGoal() { // If we need more blocks to complete a building, get those first - let goals = this.temp_goals.concat(this.data.goals).concat([this.data.curr_goal]); + let goals = this.temp_goals.concat(this.data.goals); + if (this.data.curr_goal) + goals = goals.concat([this.data.curr_goal]) this.temp_goals = []; let acted = false; @@ -190,9 +196,8 @@ export class NPCContoller { } } - if (!acted) { - this.setGoal(); - } + if (!acted) + await this.setGoal(); } currentBuilding() { diff --git a/src/agent/prompter.js b/src/agent/prompter.js index 31e8270..9b43d6a 100644 --- a/src/agent/prompter.js +++ b/src/agent/prompter.js @@ -48,7 +48,7 @@ export class Prompter { console.log('Examples loaded.'); } - async replaceStrings(prompt, messages, examples=null, prev_memory=null, to_summarize=[]) { + async replaceStrings(prompt, messages, examples=null, prev_memory=null, to_summarize=[], last_goals=null) { prompt = prompt.replaceAll('$NAME', this.agent.name); if (prompt.includes('$STATS')) { @@ -69,6 +69,27 @@ export class Prompter { prompt = prompt.replaceAll('$MEMORY', prev_memory ? prev_memory : 'None.'); if (prompt.includes('$TO_SUMMARIZE')) prompt = prompt.replaceAll('$TO_SUMMARIZE', stringifyTurns(to_summarize)); + if (prompt.includes('$CONVO')) + prompt = prompt.replaceAll('$CONVO', 'Recent conversation:\n' + stringifyTurns(messages)); + if (prompt.includes('$LAST_GOALS')) { + let goal_text = ''; + for (let goal in last_goals) { + if (last_goals[goal]) + goal_text += `You recently successfully completed the goal ${goal}.\n` + else + goal_text += `You recently failed to complete the goal ${goal}.\n` + } + prompt = prompt.replaceAll('$LAST_GOALS', goal_text.trim()); + } + if (prompt.includes('$BLUEPRINTS')) { + if (this.agent.npc.constructions) { + let blueprints = ''; + for (let blueprint in this.agent.npc.constructions) { + blueprints += blueprint + ', '; + } + prompt = prompt.replaceAll('$BLUEPRINTS', blueprints.slice(0, -2)); + } + } // check if there are any remaining placeholders with syntax $ let remaining = prompt.match(/\$[A-Z_]+/g); @@ -97,7 +118,28 @@ export class Prompter { } async promptGoalSetting(messages, last_goals) { - // TODO - return {name: '', quantity: 0}; + let system_message = this.prompts.goal_setting; + system_message = await this.replaceStrings(system_message, messages); + + let user_message = 'Use the below info to determine what goal to target next\n\n'; + user_message += '$LAST_GOALS\n$STATS\n$INVENTORY\n$CONVO' + user_message = await this.replaceStrings(user_message, messages, null, null, null, last_goals); + let user_messages = [{role: 'user', content: user_message}]; + + let res = await this.model.sendRequest(user_messages, system_message); + + let goal = null; + try { + let data = res.split('```')[1].replace('json', '').trim(); + goal = JSON.parse(data); + } catch (err) { + console.log('Failed to parse goal:', res, err); + } + if (!goal || !goal.name || !goal.quantity || isNaN(parseInt(goal.quantity))) { + console.log('Failed to set goal:', res); + return null; + } + goal.quantity = parseInt(goal.quantity); + return goal; } } \ No newline at end of file From deade1aef71eba51df86703a8913d351d329f2d0 Mon Sep 17 00:00:00 2001 From: Kolby Nottingham Date: Wed, 24 Apr 2024 13:36:26 -0700 Subject: [PATCH 3/4] set goal option --- andy_npc.json | 2 ++ src/agent/npc/controller.js | 2 +- src/agent/npc/data.js | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/andy_npc.json b/andy_npc.json index 0fad11c..4a13ea7 100644 --- a/andy_npc.json +++ b/andy_npc.json @@ -12,6 +12,8 @@ "goal_setting": "You are a Minecraft bot named $NAME that has the ability to set in-game goals that are then executed programatically. Goals must be either and item or block name or a blueprint of a specific building. Any minecraft item or block name is valid. However, only names from the following list are valid blueprints: $BLUEPRINTS. Given any recent conversation and the most recently attempted goals, set a new goal to achieve. Fromat your response as a json object with the fields \"name\" and \"quantity\". Note that the quantity for a blueprint should always be one. Example:\n```json\n{\"name\": \"iron_pickaxe\", \"quantity\": 1}```", "npc": { + "do_routine": true, + "do_set_goal": true, "goals": [ "wooden_pickaxe", "hole", diff --git a/src/agent/npc/controller.js b/src/agent/npc/controller.js index cbd234f..bb650ea 100644 --- a/src/agent/npc/controller.js +++ b/src/agent/npc/controller.js @@ -196,7 +196,7 @@ export class NPCContoller { } } - if (!acted) + if (!acted && this.data.do_set_goal) await this.setGoal(); } diff --git a/src/agent/npc/data.js b/src/agent/npc/data.js index f6b382f..b590d15 100644 --- a/src/agent/npc/data.js +++ b/src/agent/npc/data.js @@ -5,6 +5,7 @@ export class NPCData { this.built = {}; this.home = null; this.do_routine = true; + this.do_set_goal = true; } toObject() { @@ -18,6 +19,7 @@ export class NPCData { if (this.home) obj.home = this.home; obj.do_routine = this.do_routine; + obj.do_set_goal = this.do_set_goal; return obj; } @@ -41,6 +43,8 @@ export class NPCData { npc.home = obj.home; if (obj.do_routine !== undefined) npc.do_routine = obj.do_routine; + if (obj.do_set_goal !== undefined) + npc.do_set_goal = obj.do_set_goal; return npc; } } \ No newline at end of file From 1f2273c0287f4ccb81d0935df74f823ca923751e Mon Sep 17 00:00:00 2001 From: Kolby Nottingham Date: Wed, 24 Apr 2024 15:34:08 -0700 Subject: [PATCH 4/4] more buildings --- andy_npc.json | 9 +- .../{hole.json => dirt_shelter.json} | 2 +- src/agent/npc/construction/large_house.json | 230 ++++++++++++++++++ .../npc/construction/small_stone_house.json | 42 ++++ .../{house.json => small_wood_house.json} | 2 +- src/agent/npc/controller.js | 3 + 6 files changed, 280 insertions(+), 8 deletions(-) rename src/agent/npc/construction/{hole.json => dirt_shelter.json} (97%) create mode 100644 src/agent/npc/construction/large_house.json create mode 100644 src/agent/npc/construction/small_stone_house.json rename src/agent/npc/construction/{house.json => small_wood_house.json} (98%) diff --git a/andy_npc.json b/andy_npc.json index 4a13ea7..561f302 100644 --- a/andy_npc.json +++ b/andy_npc.json @@ -16,16 +16,13 @@ "do_set_goal": true, "goals": [ "wooden_pickaxe", - "hole", - "stone_axe", + "dirt_shelter", "stone_pickaxe", "stone_axe", - "house", + "small_wood_house", "furnace", "iron_pickaxe", - "iron_axe", - "iron_sword", - "iron_armor" + "iron_sword" ] }, diff --git a/src/agent/npc/construction/hole.json b/src/agent/npc/construction/dirt_shelter.json similarity index 97% rename from src/agent/npc/construction/hole.json rename to src/agent/npc/construction/dirt_shelter.json index 7a2c1f2..d5e8b28 100644 --- a/src/agent/npc/construction/hole.json +++ b/src/agent/npc/construction/dirt_shelter.json @@ -1,5 +1,5 @@ { - "name": "hole", + "name": "dirt_shelter", "offset": -2, "blocks": [ [ diff --git a/src/agent/npc/construction/large_house.json b/src/agent/npc/construction/large_house.json new file mode 100644 index 0000000..f40e0dd --- /dev/null +++ b/src/agent/npc/construction/large_house.json @@ -0,0 +1,230 @@ +{ + "name": "large_house", + "offset": -4, + "blocks": [ + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "planks", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "planks", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "cobblestone", "air", "torch", "air", "air", "air", "torch", "air", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "air", "air", "air", "air", "air", "air", "air", "cobblestone", ""], + ["", "cobblestone", "planks", "torch", "air", "air", "air", "torch", "air", "cobblestone", ""], + ["", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "", "", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "", "", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "", "", ""], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["cobblestone", "cobblestone", "air", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "dirt"], + ["cobblestone", "cobblestone", "air", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["cobblestone", "cobblestone", "air", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""], + ["", "", "", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone", ""] + ], + [ + ["", "", "", "log", "planks", "planks", "planks", "log", "", "", ""], + ["", "", "", "planks", "furnace", "air", "crafting_table", "planks", "", "", ""], + ["", "", "", "planks", "air", "air", "air", "planks", "", "", ""], + ["log", "planks", "planks", "log", "planks", "air", "planks", "log", "planks", "log", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "door", "air"], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["log", "planks", "planks", "log", "planks", "planks", "air", "planks", "planks", "log", ""], + ["", "", "", "planks", "air", "air", "air", "", "air", "planks", ""], + ["", "", "", "planks", "chest", "air", "air", "bed", "", "planks", ""], + ["", "", "", "planks", "chest", "air", "air", "", "air", "planks", ""], + ["", "", "", "log", "planks", "planks", "planks", "planks", "planks", "log", ""] + ], + [ + ["", "", "", "log", "planks", "planks", "planks", "log", "", "", ""], + ["", "", "", "planks", "air", "air", "air", "glass", "", "", ""], + ["", "", "", "planks", "air", "air", "air", "glass", "", "", ""], + ["log", "planks", "planks", "log", "planks", "air", "planks", "log", "planks", "log", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "door", "air"], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["log", "planks", "planks", "log", "planks", "planks", "air", "planks", "planks", "log", ""], + ["", "", "", "planks", "air", "air", "air", "air", "air", "planks", ""], + ["", "", "", "planks", "air", "air", "air", "air", "air", "planks", ""], + ["", "", "", "planks", "air", "air", "air", "air", "air", "planks", ""], + ["", "", "", "log", "planks", "glass", "glass", "glass", "planks", "log", ""] + ], + [ + ["", "", "", "log", "planks", "planks", "planks", "log", "", "", ""], + ["", "", "", "planks", "air", "air", "air", "glass", "", "", ""], + ["", "", "", "planks", "torch", "air", "torch", "glass", "", "", ""], + ["log", "planks", "planks", "log", "planks", "air", "planks", "log", "planks", "log", ""], + ["planks", "air", "air", "torch", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "torch", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "planks", "air", "air", "air", "air", "air", "air", "torch", "planks", ""], + ["planks", "planks", "air", "torch", "air", "air", "air", "air", "air", "planks", ""], + ["log", "planks", "planks", "log", "planks", "planks", "air", "planks", "planks", "log", ""], + ["", "", "", "planks", "air", "torch", "air", "torch", "air", "planks", ""], + ["", "", "", "planks", "air", "air", "air", "air", "air", "planks", ""], + ["", "", "", "planks", "air", "air", "air", "air", "air", "planks", ""], + ["", "", "", "log", "planks", "glass", "glass", "glass", "planks", "log", ""] + ], + [ + ["", "", "", "log", "log", "log", "log", "log", "", "", ""], + ["", "", "", "log", "planks", "planks", "planks", "log", "", "", ""], + ["", "", "", "log", "planks", "planks", "planks", "log", "", "", ""], + ["log", "log", "log", "log", "log", "log", "log", "log", "log", "log", ""], + ["log", "air", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "air", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "air", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "log", "log", "log", "log", "log", "log", "log", "log", "log", ""], + ["", "", "", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["", "", "", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["", "", "", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["", "", "", "log", "log", "log", "log", "log", "log", "log", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "planks", "planks", "planks", "", "", "", ""], + ["", "", "", "", "planks", "planks", "planks", "", "", "", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["planks", "air", "bookshelf", "bookshelf", "air", "air", "air", "air", "torch", "planks", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "air", "planks", ""], + ["planks", "air", "air", "air", "air", "air", "air", "air", "torch", "planks", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["log", "planks", "planks", "log", "glass", "glass", "glass", "glass", "glass", "log", ""], + ["glass", "air", "bookshelf", "bookshelf", "air", "air", "air", "air", "air", "planks", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["log", "planks", "planks", "log", "glass", "glass", "glass", "glass", "glass", "log", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["log", "planks", "planks", "log", "glass", "glass", "glass", "glass", "glass", "log", ""], + ["glass", "air", "air", "torch", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "air", "air", "air", "air", "air", "air", "glass", ""], + ["glass", "air", "air", "torch", "air", "air", "air", "air", "air", "glass", ""], + ["log", "planks", "planks", "log", "glass", "glass", "glass", "glass", "glass", "log", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["log", "log", "log", "log", "log", "log", "log", "log", "log", "log", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "planks", "planks", "log", "planks", "planks", "planks", "planks", "planks", "log", ""], + ["log", "log", "log", "log", "log", "log", "log", "log", "log", "log", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "planks", "planks", "planks", "planks", "planks", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ], + [ + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "planks", "planks", "planks", "", "", ""], + ["", "", "", "", "", "planks", "planks", "planks", "", "", ""], + ["", "", "", "", "", "planks", "planks", "planks", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""], + ["", "", "", "", "", "", "", "", "", "", ""] + ] + ] +} \ No newline at end of file diff --git a/src/agent/npc/construction/small_stone_house.json b/src/agent/npc/construction/small_stone_house.json new file mode 100644 index 0000000..baf4f65 --- /dev/null +++ b/src/agent/npc/construction/small_stone_house.json @@ -0,0 +1,42 @@ +{ + "name": "small_stone_house", + "offset": -1, + "blocks": [ + [ + ["", "", "", "", ""], + ["", "planks", "planks", "planks", ""], + ["", "planks", "planks", "planks", ""], + ["", "planks", "planks", "planks", ""], + ["", "planks", "planks", "planks", ""], + ["", "", "planks", "", ""], + ["", "", "", "", ""] + ], + [ + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone"], + ["cobblestone", "chest", "bed", "air", "cobblestone"], + ["cobblestone", "air", "bed", "air", "cobblestone"], + ["cobblestone", "air", "air", "air", "cobblestone"], + ["cobblestone", "air", "air", "air", "cobblestone"], + ["cobblestone", "cobblestone", "door", "cobblestone", "cobblestone"], + ["", "air", "air", "air", ""] + ], + [ + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone"], + ["cobblestone", "torch", "air", "torch", "cobblestone"], + ["cobblestone", "air", "air", "air", "cobblestone"], + ["cobblestone", "air", "air", "air", "cobblestone"], + ["cobblestone", "torch", "air", "torch", "cobblestone"], + ["cobblestone", "cobblestone", "door", "cobblestone", "cobblestone"], + ["", "air", "air", "air", ""] + ], + [ + ["air", "air", "air", "air", "air"], + ["air", "cobblestone", "cobblestone", "cobblestone", "air"], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone"], + ["cobblestone", "cobblestone", "cobblestone", "cobblestone", "cobblestone"], + ["air", "cobblestone", "cobblestone", "cobblestone", "air"], + ["air", "air", "air", "air", "air"], + ["", "air", "air", "air", ""] + ] + ] +} \ No newline at end of file diff --git a/src/agent/npc/construction/house.json b/src/agent/npc/construction/small_wood_house.json similarity index 98% rename from src/agent/npc/construction/house.json rename to src/agent/npc/construction/small_wood_house.json index 0a3677d..9661ae5 100644 --- a/src/agent/npc/construction/house.json +++ b/src/agent/npc/construction/small_wood_house.json @@ -1,5 +1,5 @@ { - "name": "shelter", + "name": "small_wood_house", "offset": -1, "blocks": [ [ diff --git a/src/agent/npc/controller.js b/src/agent/npc/controller.js index bb650ea..7636dcc 100644 --- a/src/agent/npc/controller.js +++ b/src/agent/npc/controller.js @@ -123,6 +123,9 @@ export class NPCContoller { await this.executeGoal(); } else { + // Reset goal at the end of the day + this.data.curr_goal = null; + // Return to home let building = this.currentBuilding(); if (this.data.home !== null && (building === null || building != this.data.home)) {