mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-08-05 14:55:43 +02:00
npc refactor
This commit is contained in:
parent
1c68065405
commit
2f53a6729b
7 changed files with 58 additions and 41 deletions
|
@ -2,6 +2,5 @@
|
||||||
"name": "andy",
|
"name": "andy",
|
||||||
"bio": "You are playing minecraft and assisting other players in tasks.",
|
"bio": "You are playing minecraft and assisting other players in tasks.",
|
||||||
"memory": "",
|
"memory": "",
|
||||||
"goals": [],
|
|
||||||
"turns": []
|
"turns": []
|
||||||
}
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"name": "andy",
|
|
||||||
"bio": "You are playing minecraft and assisting other players in tasks.",
|
|
||||||
"memory": "",
|
|
||||||
"goals": [
|
|
||||||
"wooden_pickaxe",
|
|
||||||
"torch",
|
|
||||||
"stone_pickaxe",
|
|
||||||
"stone_sword",
|
|
||||||
"leather_chestplate",
|
|
||||||
"iron_pickaxe",
|
|
||||||
"iron_sword",
|
|
||||||
"iron_helmet",
|
|
||||||
"iron_boots",
|
|
||||||
"iron_leggings",
|
|
||||||
"iron_chestplate"
|
|
||||||
],
|
|
||||||
"turns": []
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ import { Prompter } from './prompter.js';
|
||||||
import { initModes } from './modes.js';
|
import { initModes } from './modes.js';
|
||||||
import { initBot } from '../utils/mcdata.js';
|
import { initBot } from '../utils/mcdata.js';
|
||||||
import { containsCommand, commandExists, executeCommand, truncCommandMessage } from './commands/index.js';
|
import { containsCommand, commandExists, executeCommand, truncCommandMessage } from './commands/index.js';
|
||||||
import { ItemGoal } from './item_goal.js';
|
import { NPCContoller } from './npc/controller.js';
|
||||||
|
|
||||||
|
|
||||||
export class Agent {
|
export class Agent {
|
||||||
|
@ -13,13 +13,12 @@ export class Agent {
|
||||||
this.name = this.prompter.getName();
|
this.name = this.prompter.getName();
|
||||||
this.history = new History(this);
|
this.history = new History(this);
|
||||||
this.coder = new Coder(this);
|
this.coder = new Coder(this);
|
||||||
this.item_goal = new ItemGoal(this);
|
this.npc = new NPCContoller(this);
|
||||||
|
|
||||||
await this.prompter.initExamples();
|
await this.prompter.initExamples();
|
||||||
|
|
||||||
if (load_mem)
|
if (load_mem)
|
||||||
this.history.load();
|
this.history.load();
|
||||||
this.item_goal.setGoals(this.history.goals);
|
|
||||||
|
|
||||||
console.log('Logging in...');
|
console.log('Logging in...');
|
||||||
this.bot = initBot(this.name);
|
this.bot = initBot(this.name);
|
||||||
|
@ -178,20 +177,13 @@ export class Agent {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.bot.on('idle', async () => {
|
this.bot.on('idle', async () => {
|
||||||
// Resume all paused modes
|
|
||||||
this.bot.modes.unPauseAll();
|
this.bot.modes.unPauseAll();
|
||||||
|
this.coder.executeResume();
|
||||||
// Wait a while for inputs before acting independently
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
||||||
if (!this.isIdle()) return;
|
|
||||||
|
|
||||||
// Resume behavior or persue goal
|
|
||||||
if (this.coder.resume_func != null)
|
|
||||||
this.coder.executeResume();
|
|
||||||
else
|
|
||||||
this.item_goal.executeNext();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Init NPC controller
|
||||||
|
this.npc.init();
|
||||||
|
|
||||||
// This update loop ensures that each update() is called one at a time, even if it takes longer than the interval
|
// This update loop ensures that each update() is called one at a time, even if it takes longer than the interval
|
||||||
const INTERVAL = 300;
|
const INTERVAL = 300;
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { writeFileSync, readFileSync, mkdirSync } from 'fs';
|
import { writeFileSync, readFileSync } from 'fs';
|
||||||
|
import { NPCData } from './npc/data.js';
|
||||||
|
|
||||||
|
|
||||||
export class History {
|
export class History {
|
||||||
|
@ -10,7 +11,6 @@ export class History {
|
||||||
|
|
||||||
// These define an agent's long term memory
|
// These define an agent's long term memory
|
||||||
this.memory = '';
|
this.memory = '';
|
||||||
this.goals = [];
|
|
||||||
|
|
||||||
// Variables for controlling the agent's memory and knowledge
|
// Variables for controlling the agent's memory and knowledge
|
||||||
this.max_messages = 20;
|
this.max_messages = 20;
|
||||||
|
@ -51,9 +51,10 @@ export class History {
|
||||||
let data = {
|
let data = {
|
||||||
'name': this.name,
|
'name': this.name,
|
||||||
'memory': this.memory,
|
'memory': this.memory,
|
||||||
'goals': this.goals,
|
|
||||||
'turns': this.turns
|
'turns': this.turns
|
||||||
};
|
};
|
||||||
|
if (this.agent.npc.data !== null)
|
||||||
|
data.npc = this.agent.npc.data.toObject();
|
||||||
const json_data = JSON.stringify(data, null, 4);
|
const json_data = JSON.stringify(data, null, 4);
|
||||||
writeFileSync(this.memory_fp, json_data, (err) => {
|
writeFileSync(this.memory_fp, json_data, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -69,8 +70,8 @@ export class History {
|
||||||
const data = readFileSync(this.memory_fp, 'utf8');
|
const data = readFileSync(this.memory_fp, 'utf8');
|
||||||
const obj = JSON.parse(data);
|
const obj = JSON.parse(data);
|
||||||
this.memory = obj.memory;
|
this.memory = obj.memory;
|
||||||
|
this.agent.npc.data = NPCData.fromObject(obj.npc);
|
||||||
this.turns = obj.turns;
|
this.turns = obj.turns;
|
||||||
this.goals = obj.goals;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`No memory file '${this.memory_fp}' for agent ${this.name}.`);
|
console.error(`No memory file '${this.memory_fp}' for agent ${this.name}.`);
|
||||||
}
|
}
|
||||||
|
|
26
src/agent/npc/controller.js
Normal file
26
src/agent/npc/controller.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { NPCData } from './data.js';
|
||||||
|
import { ItemGoal } from './item_goal.js';
|
||||||
|
|
||||||
|
|
||||||
|
export class NPCContoller {
|
||||||
|
constructor(agent) {
|
||||||
|
this.agent = agent;
|
||||||
|
this.data = NPCData.fromObject(agent.prompter.prompts.npc);
|
||||||
|
this.item_goal = new ItemGoal(agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (this.data === null) return;
|
||||||
|
this.item_goal.setGoals(this.data.goals);
|
||||||
|
|
||||||
|
this.agent.bot.on('idle', async () => {
|
||||||
|
// Wait a while for inputs before acting independently
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||||
|
if (!this.agent.isIdle()) return;
|
||||||
|
|
||||||
|
// Persue goal
|
||||||
|
if (this.agent.coder.resume_func === null)
|
||||||
|
this.item_goal.executeNext();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
18
src/agent/npc/data.js
Normal file
18
src/agent/npc/data.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
export class NPCData {
|
||||||
|
constructor() {
|
||||||
|
this.goals = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
toObject() {
|
||||||
|
return {
|
||||||
|
goals: this.goals
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromObject(obj) {
|
||||||
|
if (!obj) return null;
|
||||||
|
let npc = new NPCData();
|
||||||
|
npc.goals = obj.goals;
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import * as skills from './library/skills.js';
|
import * as skills from '../library/skills.js';
|
||||||
import * as world from './library/world.js';
|
import * as world from '../library/world.js';
|
||||||
import * as mc from '../utils/mcdata.js';
|
import * as mc from '../../utils/mcdata.js';
|
||||||
|
|
||||||
|
|
||||||
const blacklist = [
|
const blacklist = [
|
Loading…
Add table
Reference in a new issue