mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-06-09 18:55:56 +02:00
Merge branch 'main' of https://github.com/icwhite/mindcraft
This commit is contained in:
commit
c43dc879d2
11 changed files with 13285 additions and 137 deletions
|
@ -53,16 +53,19 @@ def analyze_json_file(file_path):
|
|||
try:
|
||||
with open(file_path, 'r') as f:
|
||||
data = json.load(f)
|
||||
if 'turns' in data and isinstance(data['turns'], list):
|
||||
for turn in reversed(data['turns']): # Check turns from the end
|
||||
if turn.get('role') == 'system' and isinstance(turn.get('content'), str):
|
||||
code = turn["content"].split(":")[-1].strip()
|
||||
if code in ["2", "1"]: # Check for success codes
|
||||
return True
|
||||
elif 0 < float(code) < 1: # Check for other success indicators
|
||||
return code
|
||||
if "turns" in data:
|
||||
for turn in data["turns"]:
|
||||
if turn.get("role") == "system" and "content" in turn:
|
||||
if isinstance(turn["content"], str) and "Task ended with score : " in turn["content"]:
|
||||
score_found = True
|
||||
if "Task ended with score : 1" in turn["content"]:
|
||||
return 1
|
||||
elif "Task ended with score : 0" in turn["content"]:
|
||||
return 0
|
||||
else:
|
||||
return False
|
||||
score = float(turn["content"].split(":")[-1].strip())
|
||||
return score
|
||||
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
print(f"Error: File not found: {file_path}")
|
||||
|
@ -82,12 +85,12 @@ def extract_result(folder_path):
|
|||
if not json_files:
|
||||
return None
|
||||
else:
|
||||
outcome = False
|
||||
score = None
|
||||
for json_file in json_files:
|
||||
outcome = analyze_json_file(json_file)
|
||||
if outcome:
|
||||
return True
|
||||
return False
|
||||
score = analyze_json_file(json_file)
|
||||
if score is not None:
|
||||
return score
|
||||
return 0
|
||||
|
||||
def aggregate_results(local_folders):
|
||||
"""
|
||||
|
@ -110,7 +113,7 @@ def aggregate_results(local_folders):
|
|||
result = extract_result(folder_path)
|
||||
if result is not None:
|
||||
total += 1
|
||||
successful += float(result)
|
||||
successful += result
|
||||
except Exception as e:
|
||||
print(f"Error processing {folder_name}: {e}")
|
||||
|
||||
|
@ -161,28 +164,6 @@ def update_keys_json():
|
|||
with open("keys.json", 'w', encoding='utf-8') as file:
|
||||
json.dump(data, file, indent=4)
|
||||
|
||||
def check_task_completion(agents):
|
||||
"""Check memory.json files of all agents to determine task success/failure."""
|
||||
for agent in agents:
|
||||
memory_path = f"bots/{agent}/memory.json"
|
||||
try:
|
||||
with open(memory_path, 'r') as f:
|
||||
memory = json.load(f)
|
||||
|
||||
# Check the last system message in turns
|
||||
for turn in reversed(memory['turns']):
|
||||
if turn['role'] == 'system' and 'code' in turn['content']:
|
||||
# Extract completion code
|
||||
if 'code : 2' in turn['content']:
|
||||
return True # Task successful
|
||||
elif 'code : 4' in turn['content']:
|
||||
return False # Task failed
|
||||
|
||||
except (FileNotFoundError, json.JSONDecodeError) as e:
|
||||
print(f"Error reading memory for agent {agent}: {e}")
|
||||
continue
|
||||
return False # Default to failure if no conclusive result found
|
||||
|
||||
def set_environment_variable_tmux_session(session_name, key, value):
|
||||
"""Set an environment variable for the current process."""
|
||||
subprocess.run(["tmux", "send-keys", "-t", session_name, f"export {key}={value}", "C-m"])
|
||||
|
@ -202,7 +183,8 @@ def launch_parallel_experiments(task_path,
|
|||
max_messages=15,
|
||||
num_examples=2,
|
||||
no_pruning=False,
|
||||
block_conversation=False):
|
||||
block_conversation=False,
|
||||
run_in_tmux=True):
|
||||
|
||||
with open(task_path, 'r', encoding='utf-8') as file:
|
||||
content = file.read()
|
||||
|
@ -211,8 +193,6 @@ def launch_parallel_experiments(task_path,
|
|||
task_ids = json_data.keys()
|
||||
|
||||
task_type = json_data[list(task_ids)[0]]["type"]
|
||||
|
||||
|
||||
# split the task_ids into num_parallel groups
|
||||
task_ids = list(task_ids)
|
||||
task_ids_split = [task_ids[i::num_parallel] for i in range(num_parallel)]
|
||||
|
@ -224,7 +204,10 @@ def launch_parallel_experiments(task_path,
|
|||
elif task_type == "construction":
|
||||
world_name = "Superflat"
|
||||
|
||||
if run_in_tmux:
|
||||
servers = create_server_files("./server_data/", num_parallel, world_name=world_name)
|
||||
else:
|
||||
servers = [(f"./server_data_{i}/", 55916 + i) for i in range(num_parallel)]
|
||||
date_time = datetime.now().strftime("%m-%d_%H-%M")
|
||||
experiments_folder = f"experiments/{exp_name}_{date_time}"
|
||||
exp_name = f"{exp_name}_{date_time}"
|
||||
|
@ -259,7 +242,8 @@ def launch_parallel_experiments(task_path,
|
|||
max_messages=max_messages,
|
||||
num_examples=num_examples,
|
||||
no_pruning=no_pruning,
|
||||
block_conversation=block_conversation)
|
||||
block_conversation=block_conversation,
|
||||
run_in_tmux=run_in_tmux)
|
||||
time.sleep(5)
|
||||
|
||||
total_num_tasks = len(task_ids)
|
||||
|
@ -307,7 +291,8 @@ def launch_server_experiment(task_path,
|
|||
max_messages=15,
|
||||
num_examples=2,
|
||||
no_pruning=False,
|
||||
block_conversation=False):
|
||||
block_conversation=False,
|
||||
run_in_tmux=True):
|
||||
|
||||
"""
|
||||
Launch a Minecraft server and run experiments on it.
|
||||
|
@ -360,13 +345,13 @@ def launch_server_experiment(task_path,
|
|||
agent_profiles_str += f'\"{agent}\", '
|
||||
agent_profiles_str += f"\"{agent_profiles[-1]}\"]'"
|
||||
print(agent_profiles_str)
|
||||
if run_in_tmux:
|
||||
print("run in tmux is true")
|
||||
launch_world(server_path, session_name="server_" + session_name, agent_names=agent_names, port=server_port)
|
||||
|
||||
subprocess.run(['tmux', 'new-session', '-d', '-s', session_name], check=True)
|
||||
|
||||
|
||||
|
||||
# set environment variables
|
||||
if run_in_tmux:
|
||||
set_environment_variable_tmux_session(session_name, "MINECRAFT_PORT", server_port)
|
||||
set_environment_variable_tmux_session(session_name, "MINDSERVER_PORT", mindserver_port)
|
||||
set_environment_variable_tmux_session(session_name, "PROFILES", agent_profiles_str)
|
||||
|
@ -376,23 +361,91 @@ def launch_server_experiment(task_path,
|
|||
if insecure_coding:
|
||||
set_environment_variable_tmux_session(session_name, "INSECURE_CODING", "true")
|
||||
make_ops(agent_names, session_name)
|
||||
else:
|
||||
agent_profiles_str = "["
|
||||
for agent in agent_profiles[:-1]:
|
||||
agent_profiles_str += f"\"{agent}\", "
|
||||
agent_profiles_str += f"\"{agent_profiles[-1]}\"]"
|
||||
# print(agent_profiles_str)
|
||||
os.environ["PROFILES"] = agent_profiles_str
|
||||
os.environ["MAX_MESSAGES"] = str(max_messages)
|
||||
os.environ["NUM_EXAMPLES"] = str(num_examples)
|
||||
os.environ["LOG_ALL"] = "true"
|
||||
|
||||
run_script(task_path,
|
||||
task_ids,
|
||||
num_exp,
|
||||
experiments_folder,
|
||||
agent_names,
|
||||
server_path,
|
||||
s3=s3,
|
||||
s3_path=s3_path,
|
||||
session_name=session_name,
|
||||
run_in_tmux=run_in_tmux)
|
||||
|
||||
# add the bots as op
|
||||
# op_script_content = "sleep 5\n\op @p" * 20
|
||||
# op_script_file = f"./tmp/op_script_{session_name}.sh"
|
||||
# make_script_file_and_run(op_script_content, "server_" + session_name, op_script_file)
|
||||
blocked_actions = []
|
||||
if not no_pruning:
|
||||
if task_type == "cooking":
|
||||
blocked_actions = BLOCKED_ACTIONS_COOKING
|
||||
elif task_type == "techtree":
|
||||
blocked_actions = BLOCKED_ACTIONS_CRAFTING
|
||||
elif task_type == "construction":
|
||||
blocked_actions = BLOCKED_ACTIONS_CONSTRUCTION
|
||||
if block_conversation:
|
||||
blocked_actions += ["!endConversation", "!startConversation"]
|
||||
set_environment_variable_tmux_session(session_name, "BLOCKED_ACTIONS", blocked_actions)
|
||||
# blocked_actions = []
|
||||
# if not no_pruning:
|
||||
# if task_type == "cooking":
|
||||
# blocked_actions = BLOCKED_ACTIONS_COOKING
|
||||
# elif task_type == "techtree":
|
||||
# blocked_actions = BLOCKED_ACTIONS_CRAFTING
|
||||
# elif task_type == "construction":
|
||||
# blocked_actions = BLOCKED_ACTIONS_CONSTRUCTION
|
||||
# if block_conversation:
|
||||
# blocked_actions += ["!endConversation", "!startConversation"]
|
||||
# set_environment_variable_tmux_session(session_name, "BLOCKED_ACTIONS", blocked_actions)
|
||||
|
||||
|
||||
|
||||
# script_content = ""
|
||||
# for task_id in task_ids:
|
||||
# # Create a separate folder for each task_id
|
||||
# task_folder = os.path.join(experiments_folder, str(task_id))
|
||||
# os.makedirs(task_folder, exist_ok=True)
|
||||
# assert os.path.exists(task_folder), f"Directory {task_folder} was not created"
|
||||
# print(f"Created directory: {task_folder}")
|
||||
|
||||
# cmd = f"node main.js --task_path \'{task_path}\' --task_id {task_id}"
|
||||
# cp_cmd = f"cp {agent_names[0]}.json {server_path}bots/{agent_names[0]}/profile.json"
|
||||
# for _ in range(num_exp):
|
||||
# script_content += f"{cmd}\n"
|
||||
# script_content += "sleep 2\n"
|
||||
# for agent in agent_names:
|
||||
# agent_file_path = os.path.join(task_folder, f"{agent}_{_}.json")
|
||||
# script_content += f"echo 'Saving to {agent_file_path}'\n"
|
||||
# cp_cmd = f"cp bots/{agent}/memory.json {agent_file_path}"
|
||||
# script_content += f"echo '{cp_cmd}'\n"
|
||||
# script_content += f"{cp_cmd}\n"
|
||||
# script_content += "sleep 1\n"
|
||||
# if s3:
|
||||
# s3_cmd = f"aws s3 cp {agent_file_path} s3://{s3_path}/{task_id}/{agent}_{_}.json"
|
||||
# script_content += f"echo 'Uploading {agent_file_path} to S3'\n"
|
||||
# script_content += f"echo '{s3_cmd}'\n"
|
||||
# script_content += f"{s3_cmd}\n"
|
||||
# script_content += "sleep 1\n"
|
||||
# script_content += f"sleep 10\n"
|
||||
# if s3:
|
||||
# for agent in agent_names:
|
||||
# script_content += f"aws s3 cp bots/{agent} s3://{s3_path}/bots/{agent} --recursive\n"
|
||||
|
||||
# # Create a temporary shell script file
|
||||
# script_file = f"./tmp/experiment_script_{session_name}.sh"
|
||||
# make_script_file_and_run(script_content, script_file, session_name=session_name, run_in_tmux=True)
|
||||
|
||||
def run_script(task_path,
|
||||
task_ids,
|
||||
num_exp,
|
||||
experiments_folder,
|
||||
agent_names,
|
||||
server_path,
|
||||
s3=False,
|
||||
s3_path="mindcraft-experiments",
|
||||
session_name="0",
|
||||
run_in_tmux=True,):
|
||||
script_content = ""
|
||||
for task_id in task_ids:
|
||||
# Create a separate folder for each task_id
|
||||
|
@ -426,7 +479,8 @@ def launch_server_experiment(task_path,
|
|||
|
||||
# Create a temporary shell script file
|
||||
script_file = f"./tmp/experiment_script_{session_name}.sh"
|
||||
make_script_file_and_run(script_content, session_name, script_file)
|
||||
make_script_file_and_run(script_content, script_file, session_name=session_name, run_in_tmux=run_in_tmux)
|
||||
|
||||
|
||||
def make_ops(agent_names, session_name):
|
||||
"""Make the agents operators in the Minecraft world."""
|
||||
|
@ -458,7 +512,10 @@ def check_agent_ops(agent_names, ops_file="ops.json"):
|
|||
return False
|
||||
return True
|
||||
|
||||
def make_script_file_and_run(script_content, session_name, file_name):
|
||||
def make_script_file_and_run(script_content,
|
||||
file_name,
|
||||
session_name="0",
|
||||
run_in_tmux=True):
|
||||
script_dir = os.path.dirname(file_name)
|
||||
os.makedirs(script_dir, exist_ok=True)
|
||||
assert os.path.exists(script_dir), f"Script directory {script_dir} was not created"
|
||||
|
@ -472,9 +529,10 @@ def make_script_file_and_run(script_content, session_name, file_name):
|
|||
script_file_run = "bash " + file_name
|
||||
|
||||
# Execute the shell script using subprocess
|
||||
if run_in_tmux:
|
||||
subprocess.run(["tmux", "send-keys", "-t", session_name, script_file_run, "C-m"])
|
||||
|
||||
# subprocess.run(["tmux", "send-keys", "-t", session_name, f"/op {agent_names[0]}", "C-m"])
|
||||
else:
|
||||
subprocess.run(script_file_run.split())
|
||||
|
||||
def make_profiles(agent_names, models, apis, template_profile="profiles/collab_profile.json", url="http://127.0.0.1:8000/v1"):
|
||||
assert len(agent_names) == len(models)
|
||||
|
@ -645,6 +703,7 @@ def main():
|
|||
# edit_server_properties_file("../server_data/", 55917)
|
||||
|
||||
parser = argparse.ArgumentParser(description='Run Minecraft AI agent experiments')
|
||||
parser.add_argument('--no_launch_world', action='store_true', help='Do not launch the Minecraft world')
|
||||
parser.add_argument('--task_path', default="multiagent_crafting_tasks.json", help='Path to the task file')
|
||||
parser.add_argument('--num_agents', default=2, type=int, help='Number of agents to run')
|
||||
parser.add_argument('--num_exp', default=1, type=int, help='Number of experiments to run')
|
||||
|
@ -666,13 +725,14 @@ def main():
|
|||
|
||||
args = parser.parse_args()
|
||||
print(args)
|
||||
|
||||
if not args.no_launch_world:
|
||||
try:
|
||||
subprocess.run(['tmux', 'kill-server'], check=True)
|
||||
except:
|
||||
print("No tmux session to kill")
|
||||
|
||||
# delete all server files
|
||||
if not args.no_launch_world:
|
||||
clean_up_server_files(args.num_parallel)
|
||||
if args.add_keys:
|
||||
update_keys_json()
|
||||
|
@ -692,7 +752,8 @@ def main():
|
|||
max_messages=args.max_messages,
|
||||
num_examples=args.num_examples,
|
||||
no_pruning=args.no_pruning,
|
||||
block_conversation=args.block_conversation)
|
||||
block_conversation=args.block_conversation,
|
||||
run_in_tmux=not args.no_launch_world)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -12,14 +12,12 @@ export class ConstructionTaskValidator {
|
|||
let valid = false;
|
||||
let score = 0;
|
||||
let result = this.blueprint.check(this.agent.bot);
|
||||
if (result.mismatches.length === 0) {
|
||||
if (result.mismatches.y_amount === 0) {
|
||||
valid = true;
|
||||
console.log('Task is complete');
|
||||
}
|
||||
let total_blocks = result.mismatches.length + result.matches.length;
|
||||
score = (result.matches.length / total_blocks) * 100;
|
||||
console.log(`Agent name is ${this.agent.name}`);
|
||||
console.log(`Task is ${score}% complete \n\n`);
|
||||
let total_blocks = result.mismatches.y_amount + result.matches.y_amount;
|
||||
score = (result.matches.y_amount / total_blocks) * 100;
|
||||
return {
|
||||
"valid": valid,
|
||||
"score": score
|
||||
|
@ -37,10 +35,10 @@ export class ConstructionTaskValidator {
|
|||
export function resetConstructionWorld(bot, blueprint) {
|
||||
console.log('Resetting world...');
|
||||
const starting_position = blueprint.levels[0].coordinates;
|
||||
const length = blueprint.levels[0].placement.length + 5;
|
||||
const height = blueprint.levels.length + 5;
|
||||
const width = blueprint.levels[0].placement[0].length + 5;
|
||||
const command = `/fill ${starting_position[0]} ${starting_position[1]} ${starting_position[2]} ${starting_position[0] + width} ${starting_position[1] + height} ${starting_position[2] + length} air`;
|
||||
const y_amount = blueprint.levels[0].placement.y_amount + 5;
|
||||
const height = blueprint.levels.y_amount + 5;
|
||||
const width = blueprint.levels[0].placement[0].y_amount + 5;
|
||||
const command = `/fill ${starting_position[0]} ${starting_position[1]} ${starting_position[2]} ${starting_position[0] + width} ${starting_position[1] + height} ${starting_position[2] + y_amount} air`;
|
||||
bot.chat(command);
|
||||
console.log('World reset');
|
||||
}
|
||||
|
@ -50,7 +48,7 @@ export function checkLevelBlueprint(agent, levelNum) {
|
|||
const bot = agent.bot;
|
||||
try {
|
||||
const result = blueprint.checkLevel(bot, levelNum);
|
||||
if (result.mismatches.length === 0) {
|
||||
if (result.mismatches.y_amount === 0) {
|
||||
return `Level ${levelNum} is correct`;
|
||||
} else {
|
||||
let explanation = blueprint.explainLevelDifference(bot, levelNum);
|
||||
|
@ -69,7 +67,7 @@ export function checkBlueprint(agent) {
|
|||
const blueprint = agent.task.blueprint;
|
||||
const bot = agent.bot;
|
||||
const result = blueprint.check(bot);
|
||||
if (result.mismatches.length === 0) {
|
||||
if (result.mismatches.y_amount === 0) {
|
||||
return "Blueprint is correct";
|
||||
} else {
|
||||
let explanation = blueprint.explainBlueprintDifference(bot);
|
||||
|
@ -97,11 +95,11 @@ export class Blueprint {
|
|||
var placement_string = "[\n";
|
||||
for (let row of placement) {
|
||||
placement_string += "[";
|
||||
for (let i = 0; i < row.length - 1; i++) {
|
||||
for (let i = 0; i < row.y_amount - 1; i++) {
|
||||
let item = row[i];
|
||||
placement_string += `${item}, `;
|
||||
}
|
||||
let final_item = row[row.length - 1];
|
||||
let final_item = row[row.y_amount - 1];
|
||||
placement_string += `${final_item}],\n`;
|
||||
}
|
||||
placement_string += "]";
|
||||
|
@ -118,7 +116,7 @@ export class Blueprint {
|
|||
explainBlueprintDifference(bot) {
|
||||
var explanation = "";
|
||||
const levels = this.data.levels;
|
||||
for (let i = 0; i < levels.length; i++) {
|
||||
for (let i = 0; i < levels.y_amount; i++) {
|
||||
let level_explanation = this.explainLevelDifference(bot, i);
|
||||
explanation += level_explanation + "\n";
|
||||
}
|
||||
|
@ -129,7 +127,7 @@ export class Blueprint {
|
|||
const mismatches = results.mismatches;
|
||||
const levelData = this.data.levels[levelNum];
|
||||
|
||||
if (mismatches.length === 0) {
|
||||
if (mismatches.y_amount === 0) {
|
||||
return `Level ${levelData.level} is complete`;
|
||||
}
|
||||
var explanation = `Level ${levelData.level} `;
|
||||
|
@ -153,7 +151,7 @@ export class Blueprint {
|
|||
const levels = this.data.levels;
|
||||
const mismatches = [];
|
||||
const matches = [];
|
||||
for (let i = 0; i < levels.length; i++) {
|
||||
for (let i = 0; i < levels.y_amount; i++) {
|
||||
const result = this.checkLevel(bot, i);
|
||||
mismatches.push(...result.mismatches);
|
||||
matches.push(...result.matches);
|
||||
|
@ -173,9 +171,9 @@ export class Blueprint {
|
|||
const mismatches = [];
|
||||
const matches = [];
|
||||
|
||||
for (let zOffset = 0; zOffset < placement.length; zOffset++) {
|
||||
for (let zOffset = 0; zOffset < placement.y_amount; zOffset++) {
|
||||
const row = placement[zOffset];
|
||||
for (let xOffset = 0; xOffset < row.length; xOffset++) {
|
||||
for (let xOffset = 0; xOffset < row.y_amount; xOffset++) {
|
||||
const blockName = row[xOffset];
|
||||
|
||||
const x = startCoords[0] + xOffset;
|
||||
|
@ -240,15 +238,15 @@ export class Blueprint {
|
|||
|
||||
// Update bounds
|
||||
minX = Math.min(minX, baseX);
|
||||
maxX = Math.max(maxX, baseX + placement[0].length - 1);
|
||||
maxX = Math.max(maxX, baseX + placement[0].y_amount - 1);
|
||||
minY = Math.min(minY, baseY);
|
||||
maxY = Math.max(maxY, baseY);
|
||||
minZ = Math.min(minZ, baseZ);
|
||||
maxZ = Math.max(maxZ, baseZ + placement.length - 1);
|
||||
maxZ = Math.max(maxZ, baseZ + placement.y_amount - 1);
|
||||
|
||||
// Loop through the 2D placement array
|
||||
for (let z = 0; z < placement.length; z++) {
|
||||
for (let x = 0; x < placement[z].length; x++) {
|
||||
for (let z = 0; z < placement.y_amount; z++) {
|
||||
for (let x = 0; x < placement[z].y_amount; x++) {
|
||||
const blockType = placement[z][x];
|
||||
if (blockType) {
|
||||
const setblockCommand = `/setblock ${baseX + x} ${baseY} ${baseZ + z} ${blockType}`;
|
||||
|
@ -289,15 +287,15 @@ export class Blueprint {
|
|||
|
||||
// Update bounds
|
||||
minX = Math.min(minX, baseX) - 30;
|
||||
maxX = Math.max(maxX, baseX + placement[0].length - 1) + 30;
|
||||
maxX = Math.max(maxX, baseX + placement[0].y_amount - 1) + 30;
|
||||
minY = Math.min(minY, baseY);
|
||||
maxY = Math.max(maxY, baseY);
|
||||
minZ = Math.min(minZ, baseZ) - 30;
|
||||
maxZ = Math.max(maxZ, baseZ + placement.length - 1) + 30;
|
||||
maxZ = Math.max(maxZ, baseZ + placement.y_amount - 1) + 30;
|
||||
|
||||
// Loop through the 2D placement array
|
||||
for (let z = 0; z < placement.length; z++) {
|
||||
for (let x = 0; x < placement[z].length; x++) {
|
||||
for (let z = 0; z < placement.y_amount; z++) {
|
||||
for (let x = 0; x < placement[z].y_amount; x++) {
|
||||
const blockType = placement[z][x];
|
||||
if (blockType) {
|
||||
const setblockCommand = `/setblock ${baseX + x} ${baseY} ${baseZ + z} air`;
|
||||
|
@ -350,8 +348,8 @@ export function proceduralGeneration(m = 20,
|
|||
complexity = 4,
|
||||
startCoord = [148,-60,-170]) {
|
||||
// Build 3D space
|
||||
const matrix = Array.from({length: p}, () =>
|
||||
Array.from({length: m}, () =>
|
||||
const matrix = Array.from({y_amount: p}, () =>
|
||||
Array.from({y_amount: m}, () =>
|
||||
Array(n).fill('air')
|
||||
)
|
||||
);
|
||||
|
@ -359,7 +357,7 @@ export function proceduralGeneration(m = 20,
|
|||
// todo: extrapolate into another param? then have set materials be dynamic?
|
||||
let roomMaterials = ["stone", "terracotta", "quartz_block", "copper_block", "purpur_block"]
|
||||
|
||||
if (complexity < roomMaterials.length) {
|
||||
if (complexity < roomMaterials.y_amount) {
|
||||
roomMaterials = roomMaterials.slice(0, complexity + 1);
|
||||
}
|
||||
|
||||
|
@ -510,9 +508,9 @@ export function proceduralGeneration(m = 20,
|
|||
// Takes in a room and randomly converts some faces to be windows
|
||||
function addWindowsAsSquares(matrix, x, y, z, newLength, newWidth, newDepth, material) {
|
||||
// Matrix dimensions
|
||||
const matrixDepth = matrix.length;
|
||||
const matrixLength = matrix[0].length;
|
||||
const matrixWidth = matrix[0][0].length;
|
||||
const matrixDepth = matrix.y_amount;
|
||||
const matrixLength = matrix[0].y_amount;
|
||||
const matrixWidth = matrix[0][0].y_amount;
|
||||
const windowX = Math.ceil(minRoomWidth / 2)
|
||||
const windowY = Math.ceil(minRoomLength / 2)
|
||||
const windowZ = Math.ceil(minRoomDepth / 2)
|
||||
|
@ -593,9 +591,9 @@ export function proceduralGeneration(m = 20,
|
|||
|
||||
function addWindowsAsPlane(matrix, x, y, z, newLength, newWidth, newDepth, material) {
|
||||
// Ensure the new dimensions are within bounds
|
||||
const maxX = matrix[0].length;
|
||||
const maxY = matrix[0][0].length;
|
||||
const maxZ = matrix.length;
|
||||
const maxX = matrix[0].y_amount;
|
||||
const maxY = matrix[0][0].y_amount;
|
||||
const maxZ = matrix.y_amount;
|
||||
|
||||
// Each face has a 30% chance of becoming a window
|
||||
if (Math.random() < 0.8) {
|
||||
|
@ -643,21 +641,21 @@ export function proceduralGeneration(m = 20,
|
|||
|
||||
|
||||
//still a little buggy
|
||||
function addStairs(matrix, x, y, z, length, width, material) {
|
||||
function addStairs(matrix, x, y, z, y_amount, width, material) {
|
||||
let currentZ = z;
|
||||
let currentX = x + 1;
|
||||
let currentY = y + 1;
|
||||
let direction = 0;
|
||||
let stepCount = 0;
|
||||
const maxSteps = length * width; // Safety limit
|
||||
const maxSteps = y_amount * width; // Safety limit
|
||||
|
||||
while (currentZ >= 0 && currentX < x + length - 1 && currentY < y + width - 1 && stepCount < maxSteps) {
|
||||
while (currentZ >= 0 && currentX < x + y_amount - 1 && currentY < y + width - 1 && stepCount < maxSteps) {
|
||||
// Place stair block
|
||||
matrix[currentZ][currentX][currentY] = material || 'stone';
|
||||
|
||||
// Clear 3 blocks above for headroom
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
if (currentZ + i < matrix.length) {
|
||||
if (currentZ + i < matrix.y_amount) {
|
||||
matrix[currentZ + i][currentX][currentY] = 'air';
|
||||
}
|
||||
}
|
||||
|
@ -665,8 +663,8 @@ export function proceduralGeneration(m = 20,
|
|||
// Move to next position based on direction
|
||||
if (direction === 0) {
|
||||
currentX++;
|
||||
if (currentX >= x + length - 1) {
|
||||
currentX = x + length - 2;
|
||||
if (currentX >= x + y_amount - 1) {
|
||||
currentX = x + y_amount - 2;
|
||||
direction = 1;
|
||||
} else {
|
||||
currentZ--;
|
||||
|
@ -700,7 +698,7 @@ export function proceduralGeneration(m = 20,
|
|||
// Consider a random probability of adding a carpet
|
||||
if (Math.random() < probability) {
|
||||
// Choose a random color for the carpet
|
||||
let randomColor = colors[Math.floor(Math.random() * colors.length)];
|
||||
let randomColor = colors[Math.floor(Math.random() * colors.y_amount)];
|
||||
// Add carpet one z position above the floor with a random color
|
||||
matrix[z + 1][x][y] = `${randomColor}_carpet`;
|
||||
}
|
||||
|
@ -773,7 +771,7 @@ export function proceduralGeneration(m = 20,
|
|||
|
||||
for (let attempt = 0; attempt < 150; attempt++) {
|
||||
|
||||
const material = roomMaterials[Math.floor(Math.random() * roomMaterials.length)];
|
||||
const material = roomMaterials[Math.floor(Math.random() * roomMaterials.y_amount)];
|
||||
|
||||
|
||||
// dimensions of room
|
||||
|
@ -790,7 +788,7 @@ export function proceduralGeneration(m = 20,
|
|||
newZ = 0; // Ground floor
|
||||
|
||||
if (validateAndBuildBorder(matrix, newX, newY, newZ, newLength, newWidth, newDepth, m, n, p, material)) {
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
|
||||
|
@ -820,14 +818,14 @@ export function proceduralGeneration(m = 20,
|
|||
|
||||
embellishments(carpetStyle, windowStyle, matrix, newX, newY, newZ, newLength, newWidth, newDepth, material)
|
||||
|
||||
// addLadder(matrix, lastRoom.x + Math.floor(lastRoom.length / 2),
|
||||
// addLadder(matrix, lastRoom.x + Math.floor(lastRoom.y_amount / 2),
|
||||
// lastRoom.y + Math.floor(lastRoom.width / 2),
|
||||
// newZ); // Adding the ladder
|
||||
|
||||
addStairs(matrix, newX, newY, newZ, newLength, newWidth, material)
|
||||
|
||||
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
break;
|
||||
|
@ -847,7 +845,7 @@ export function proceduralGeneration(m = 20,
|
|||
addDoor(matrix, lastRoom.x, lastRoom.y + Math.floor(lastRoom.width / 2), lastRoom.z, material);
|
||||
|
||||
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
break;
|
||||
|
@ -855,7 +853,7 @@ export function proceduralGeneration(m = 20,
|
|||
break;
|
||||
|
||||
case 'right':
|
||||
newX = lastRoom.x + lastRoom.length - 1;
|
||||
newX = lastRoom.x + lastRoom.y_amount - 1;
|
||||
newY = lastRoom.y;
|
||||
newZ = lastRoom.z;
|
||||
if (validateAndBuildBorder(matrix, newX, newY, newZ, newLength, newWidth, newDepth, m, n, p, material)) {
|
||||
|
@ -863,12 +861,12 @@ export function proceduralGeneration(m = 20,
|
|||
embellishments(carpetStyle, windowStyle, matrix, newX, newY, newZ, newLength, newWidth, newDepth, material)
|
||||
|
||||
|
||||
addDoor(matrix, lastRoom.x + lastRoom.length - 1,
|
||||
addDoor(matrix, lastRoom.x + lastRoom.y_amount - 1,
|
||||
lastRoom.y + Math.floor(lastRoom.width / 2),
|
||||
lastRoom.z, material);
|
||||
|
||||
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
break;
|
||||
|
@ -884,12 +882,12 @@ export function proceduralGeneration(m = 20,
|
|||
embellishments(carpetStyle, windowStyle, matrix, newX, newY, newZ, newLength, newWidth, newDepth, material)
|
||||
|
||||
|
||||
addDoor(matrix, lastRoom.x + Math.floor(lastRoom.length / 2),
|
||||
addDoor(matrix, lastRoom.x + Math.floor(lastRoom.y_amount / 2),
|
||||
lastRoom.y + lastRoom.width - 1,
|
||||
lastRoom.z, material);
|
||||
|
||||
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
break;
|
||||
|
@ -905,12 +903,12 @@ export function proceduralGeneration(m = 20,
|
|||
embellishments(carpetStyle, windowStyle, matrix, newX, newY, newZ, newLength, newWidth, newDepth, material)
|
||||
|
||||
|
||||
addDoor(matrix, lastRoom.x + Math.floor(lastRoom.length / 2),
|
||||
addDoor(matrix, lastRoom.x + Math.floor(lastRoom.y_amount / 2),
|
||||
lastRoom.y,
|
||||
lastRoom.z, material);
|
||||
|
||||
|
||||
lastRoom = {x: newX, y: newY, z: newZ, length: newLength, width: newWidth, depth: newDepth};
|
||||
lastRoom = {x: newX, y: newY, z: newZ, y_amount: newLength, width: newWidth, depth: newDepth};
|
||||
roomPlaced = true;
|
||||
placedRooms++;
|
||||
break;
|
||||
|
@ -978,7 +976,7 @@ function printMatrix(matrix) {
|
|||
*/
|
||||
function matrixToBlueprint(matrix, startCoord) {
|
||||
// Validate inputs
|
||||
if (!Array.isArray(matrix) || !Array.isArray(startCoord) || startCoord.length !== 3) {
|
||||
if (!Array.isArray(matrix) || !Array.isArray(startCoord) || startCoord.y_amount !== 3) {
|
||||
console.log(matrix)
|
||||
throw new Error('Invalid input format');
|
||||
}
|
||||
|
@ -1003,6 +1001,85 @@ function matrixToBlueprint(matrix, startCoord) {
|
|||
};
|
||||
}
|
||||
|
||||
async function getBlockName(bot, coordinate) {
|
||||
const blockAtLocation = bot.blockAt(new Vec3(coordinate.x, coordinate.y, coordinate.z));
|
||||
const blockName = blockAtLocation ? bot.registry.blocks[blockAtLocation.type].name : "air";
|
||||
return blockName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a world location to a blueprint. takes some time to ensure that the chunks are loaded before conversion.
|
||||
* @param startCoord - [x,y,z] that signifies the start of the blueprint
|
||||
* @param y_amount - how many spaces you want to register from the start coordinate in the y dimension
|
||||
* @param x_amount - how many spaces in the x direction on minecraft
|
||||
* @param z_amount - how many spaces from the start coordinate in the z direction in minecraft
|
||||
* @param bot - the mineflayer agent (ex. andy)
|
||||
* @returns - a Blueprint object of the converted blueprint
|
||||
*/
|
||||
export async function worldToBlueprint(startCoord, y_amount, x_amount, z_amount, bot) {
|
||||
await bot.waitForChunksToLoad();
|
||||
|
||||
const materials = {};
|
||||
|
||||
const levels = [];
|
||||
for (let y = 0; y < y_amount; y++) {
|
||||
const placement = [];
|
||||
const coordinates = [startCoord.x, startCoord.y + y, startCoord.z];
|
||||
for (let z = 0; z < z_amount; z++) {
|
||||
const row = [];
|
||||
for (let x = 0; x < x_amount; x++) {
|
||||
const worldCoord = {
|
||||
x: startCoord.x + x,
|
||||
y: startCoord.y + y,
|
||||
z: startCoord.z + z
|
||||
};
|
||||
await bot.waitForChunksToLoad(worldCoord);
|
||||
const blockName = await getBlockName(bot, worldCoord);
|
||||
row.push(blockName);
|
||||
if (blockName !== 'air') {
|
||||
materials[blockName] = (materials[blockName] || 0) + 1;
|
||||
}
|
||||
}
|
||||
placement.push(row);
|
||||
}
|
||||
levels.push({
|
||||
level: y,
|
||||
coordinates: coordinates,
|
||||
placement: placement
|
||||
})
|
||||
}
|
||||
console.log(levels);
|
||||
const blueprint_data = {
|
||||
materials: materials,
|
||||
levels: levels
|
||||
}
|
||||
return blueprint_data
|
||||
}
|
||||
|
||||
export function blueprintToTask(blueprint_data, num_agents) {
|
||||
let initialInventory = {}
|
||||
for (let j = 0; j < num_agents; j++) {
|
||||
initialInventory[JSON.stringify(j)] = {};
|
||||
}
|
||||
|
||||
let give_agent = 0;
|
||||
for (const key of Object.keys(blueprint_data.materials)) {
|
||||
initialInventory[JSON.stringify(give_agent)][key] = blueprint_data.materials[key];
|
||||
give_agent = (give_agent + 1) % num_agents;
|
||||
}
|
||||
|
||||
const task = {
|
||||
type: "construction",
|
||||
goal: "Make a structure with the blueprint below",
|
||||
conversation: "Let's share materials and make a structure with the blueprint",
|
||||
agent_count: 2,
|
||||
blueprint: blueprint_data,
|
||||
initial_inventory: initialInventory,
|
||||
};
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// testing code
|
||||
|
|
|
@ -379,7 +379,7 @@ export class Prompter {
|
|||
let prompt = this.profile.saving_memory;
|
||||
prompt = await this.replaceStrings(prompt, null, null, to_summarize);
|
||||
let resp = await this.chat_model.sendRequest([], prompt);
|
||||
await this._saveLog(prompt, null, resp, 'memSaving');
|
||||
await this._saveLog(prompt, to_summarize, resp, 'memSaving');
|
||||
if (resp?.includes('</think>')) {
|
||||
const [_, afterThink] = resp.split('</think>')
|
||||
resp = afterThink
|
||||
|
|
BIN
tasks/.DS_Store
vendored
BIN
tasks/.DS_Store
vendored
Binary file not shown.
688
tasks/construction_tasks/custom/pyramid.json
Normal file
688
tasks/construction_tasks/custom/pyramid.json
Normal file
|
@ -0,0 +1,688 @@
|
|||
{
|
||||
"pyramid": {
|
||||
"type": "construction",
|
||||
"goal": "Make a structure with the blueprint below",
|
||||
"conversation": "Let's share materials and make a structure with the blueprint",
|
||||
"agent_count": 2,
|
||||
"blueprint": {
|
||||
"materials": {
|
||||
"polished_granite": 1,
|
||||
"gold_block": 27,
|
||||
"stone_bricks": 41,
|
||||
"polished_andesite": 34,
|
||||
"quartz_block": 16,
|
||||
"stone": 23,
|
||||
"polished_diorite": 21,
|
||||
"quartz_pillar": 2,
|
||||
"glowstone": 3
|
||||
},
|
||||
"levels": [
|
||||
{
|
||||
"level": 0,
|
||||
"coordinates": [
|
||||
-60,
|
||||
-60,
|
||||
6
|
||||
],
|
||||
"placement": [
|
||||
[
|
||||
"polished_granite",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"gold_block",
|
||||
"quartz_block",
|
||||
"polished_andesite",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"gold_block"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"gold_block"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"gold_block",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"quartz_block",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"quartz_block"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"polished_diorite",
|
||||
"stone_bricks"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"polished_diorite",
|
||||
"stone_bricks",
|
||||
"polished_andesite"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"polished_diorite",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"gold_block"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"gold_block",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"quartz_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"gold_block",
|
||||
"gold_block"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": 1,
|
||||
"coordinates": [
|
||||
-60,
|
||||
-60,
|
||||
6
|
||||
],
|
||||
"placement": [
|
||||
[
|
||||
"quartz_pillar",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"quartz_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"gold_block",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"stone_bricks",
|
||||
"stone",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"stone_bricks",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"polished_andesite",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"quartz_block",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"glowstone",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"quartz_block",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"stone_bricks",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"stone_bricks",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"polished_andesite",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"polished_andesite",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"quartz_block",
|
||||
"stone_bricks",
|
||||
"polished_andesite",
|
||||
"gold_block",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"coordinates": [
|
||||
-60,
|
||||
-60,
|
||||
6
|
||||
],
|
||||
"placement": [
|
||||
[
|
||||
"quartz_pillar",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone_bricks",
|
||||
"quartz_block",
|
||||
"gold_block",
|
||||
"gold_block",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"polished_andesite",
|
||||
"stone",
|
||||
"polished_andesite",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"quartz_block",
|
||||
"polished_andesite",
|
||||
"glowstone",
|
||||
"stone_bricks",
|
||||
"quartz_block",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"stone",
|
||||
"stone_bricks",
|
||||
"polished_diorite",
|
||||
"stone_bricks",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"polished_andesite",
|
||||
"quartz_block",
|
||||
"stone_bricks",
|
||||
"gold_block",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"coordinates": [
|
||||
-60,
|
||||
-60,
|
||||
6
|
||||
],
|
||||
"placement": [
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"quartz_block",
|
||||
"gold_block",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"quartz_block",
|
||||
"glowstone",
|
||||
"quartz_block",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"quartz_block",
|
||||
"gold_block",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"level": 4,
|
||||
"coordinates": [
|
||||
-60,
|
||||
-60,
|
||||
6
|
||||
],
|
||||
"placement": [
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"gold_block",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
],
|
||||
[
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air",
|
||||
"air"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"initial_inventory": {
|
||||
"0": {
|
||||
"polished_granite": 1,
|
||||
"stone_bricks": 41,
|
||||
"quartz_block": 16,
|
||||
"polished_diorite": 21,
|
||||
"glowstone": 3
|
||||
},
|
||||
"1": {
|
||||
"gold_block": 27,
|
||||
"polished_andesite": 34,
|
||||
"stone": 23,
|
||||
"quartz_pillar": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1034
tasks/construction_tasks/custom/tasks.json
Normal file
1034
tasks/construction_tasks/custom/tasks.json
Normal file
File diff suppressed because it is too large
Load diff
54
tasks/construction_tasks/get_blueprint.js
Normal file
54
tasks/construction_tasks/get_blueprint.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
import mineflayer from 'mineflayer';
|
||||
import { worldToBlueprint, blueprintToTask } from '../../src/agent/task_types/construction_tasks.js';
|
||||
import fs from 'fs';
|
||||
import { start } from 'repl';
|
||||
|
||||
const bot = mineflayer.createBot({
|
||||
host: 'localhost', // Replace with your server IP or hostname
|
||||
port: 55916, // Replace with your server port
|
||||
username: 'andy', // Replace with your bot's username
|
||||
// password: 'your_bot_password' // Only if the server has online-mode=true
|
||||
});
|
||||
|
||||
bot.on('spawn', async () => {
|
||||
console.log("Bot spawned. Starting blueprint check...");
|
||||
// set this to be minX, minY, minZ
|
||||
const startCoord = {
|
||||
x: -60,
|
||||
y: 1,
|
||||
z: 6,
|
||||
}
|
||||
bot.chat(`/tp andy ${startCoord.x} ${startCoord.y} ${startCoord.z}`);
|
||||
const yOffset = 5;
|
||||
const xOffset = 10;
|
||||
const zOffset = 10;
|
||||
|
||||
const taskFilePath = '/Users/isadorawhite/izzy_mindcraft/mindcraft/tasks/construction_tasks/custom/pyramid.json';
|
||||
const task_name = "pyramid";
|
||||
|
||||
|
||||
setTimeout(async () => {
|
||||
let task_blueprint = await worldToBlueprint(startCoord, yOffset, xOffset, zOffset, bot);
|
||||
|
||||
for (const level of task_blueprint.levels) {
|
||||
// Perform operations on each level
|
||||
console.log("Level coordinates:", level.coordinates);
|
||||
const new_coordinates = [level.coordinates[0], -60, level.coordinates[2]];
|
||||
level.coordinates = new_coordinates;
|
||||
console.log("New coordinates:", level.coordinates);
|
||||
}
|
||||
console.log("Blueprint generated:", task_blueprint.levels[0].coordinates);
|
||||
|
||||
const task = blueprintToTask(task_blueprint, 2);
|
||||
const task_collection = {}
|
||||
task_collection[task_name] = task;
|
||||
|
||||
fs.writeFileSync(taskFilePath, JSON.stringify(task_collection, null, 2), (err) => {
|
||||
if (err) {
|
||||
console.error('Error writing task to file:', err);
|
||||
} else {
|
||||
console.log('Task dumped to file successfully.');
|
||||
}
|
||||
});
|
||||
}, 5000); // Delay of 5 seconds (5000 milliseconds)
|
||||
});
|
BIN
tasks/construction_tasks/test.zip
Normal file
BIN
tasks/construction_tasks/test.zip
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue