Skip to content

Commit

Permalink
Merge pull request #21 from rk1a/clientmod-config
Browse files Browse the repository at this point in the history
Clientmod config
  • Loading branch information
neverix committed Jan 12, 2023
2 parents 4049a48 + 07bbe71 commit 8eb84c0
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 45 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ newworld/
/worlds
/world/
/clientmods/*
!/clientmods/preview/
!/clientmods/rewards/
!/clientmods/random/
!/clientmods/treechop/
!/clientmods/mods.conf
/client/mod_storage/
Expand Down
6 changes: 3 additions & 3 deletions clientmods/mods.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load_mod_rewards = false
load_mod_rewards = true
load_mod_random = false
load_mod_treechop = false
load_mod_preview = false
load_mod_rewards_client = false
load_mod_treechop = true
4 changes: 4 additions & 0 deletions clientmods/random/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- set random reward at every step
minetest.register_globalstep(function(dtime)
reward = math.random()
end)
1 change: 1 addition & 0 deletions clientmods/random/mod.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = random
26 changes: 5 additions & 21 deletions clientmods/rewards/init.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
-- https://github.com/minetest/minetest/issues/10682
local function register_globalstep_on_mods_loaded(func)
local function wrapper_func(dtime)
if not minetest.localplayer then return end
func(dtime)
for i, globalstep in pairs(minetest.registered_globalsteps) do
if globalstep == wrapper_func then
minetest.registered_globalsteps[i] = func
end
end
end
minetest.register_globalstep(wrapper_func)
end
-- define global reward variable
reward = 0.0
-- local loaded = false
register_globalstep_on_mods_loaded(function()
-- if(loaded) then return end
-- loaded = true
-- local channel_name = "rewards_"..minetest.localplayer:get_name()
-- minetest.mod_channel_join(channel_name)
-- minetest.register_on_modchannel_message(function(channel_name, sender, message) end)
reward = math.random()

-- reset reward every step
minetest.register_globalstep(function(dtime)
reward = 0.0
end)
8 changes: 0 additions & 8 deletions clientmods/treechop/init.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@

reward = 0.0

-- reset reward every step
minetest.register_globalstep(function(dtime)
reward = 0.0
end)

-- reward chopping tree nodes
minetest.register_on_dignode(function(pos, node)
if string.find(node["name"], "tree") then
Expand Down
45 changes: 33 additions & 12 deletions hacking_testing/minetest_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import shutil
import subprocess
import uuid
from typing import Any, Dict, Optional, Tuple
from typing import Any, Dict, List, Optional, Tuple

import gym
import matplotlib.pyplot as plt
Expand Down Expand Up @@ -167,15 +167,15 @@ def __init__(
fov: int = 72,
seed: Optional[int] = None,
start_minetest: Optional[bool] = True,
clientmods: List[str] = [],
):
# Graphics settings
self.display_size = display_size
self.fov_y = fov
self.fov_x = self.fov_y * self.display_size[0] / self.display_size[1]
self.max_mouse_move_x = 180 / self.fov_x * self.display_size[0]
self.max_mouse_move_y = 180 / self.fov_y * self.display_size[1]

# Define action and observation space
self.max_mouse_move_x = self.display_size[0]
self.max_mouse_move_y = self.display_size[1]
self.action_space = gym.spaces.Dict(
{
**{key: gym.spaces.Discrete(2) for key in KEY_MAP.keys()},
Expand All @@ -198,6 +198,7 @@ def __init__(

# Define Minetest paths
self.root_dir = os.path.dirname(os.path.dirname(__file__))
self.minetest_executable = minetest_executable
if minetest_executable is None:
self.minetest_executable = os.path.join(self.root_dir, "bin", "minetest")
if log_dir is None:
Expand Down Expand Up @@ -241,18 +242,37 @@ def __init__(

# Seed the environment
self.unique_env_id = str(uuid.uuid4()) # fallback UUID when no seed is provided
if seed:
if seed is not None:
self.seed(seed)

# Configure logging
logging.basicConfig(
filename=os.path.join(self.log_dir, f"env_{self.unique_env_id}.log"),
filemode="a",
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%H:%M:%S',
format="%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s",
datefmt="%H:%M:%S",
level=logging.DEBUG,
)

# Configure mods
self.clientmods = clientmods + ["rewards"] # require the base rewards mod
clientmods_folder = os.path.realpath(
os.path.join(os.path.dirname(self.minetest_executable), "../clientmods"),
)
if not os.path.exists(clientmods_folder):
raise ValueError(f"Clientmods must be located at {clientmods_folder}!")
# Write mods.conf
with open(os.path.join(clientmods_folder, "mods.conf"), "w") as mods_config:
for clientmod in self.clientmods:
clientmod_folder = os.path.join(clientmods_folder, clientmod)
if not os.path.exists(clientmod_folder):
logging.warning(
f"Clientmod {clientmod} was not found!"
" It must be located at {clientmod_folder}.",
)
else:
mods_config.write(f"load_mod_{clientmod} = true\n")

def _reset_zmq(self):
if self.socket:
self.socket.close()
Expand All @@ -264,7 +284,8 @@ def _reset_minetest(self):
# Determine log paths
reset_timestamp = datetime.datetime.now().strftime("%m-%d-%Y,%H:%M:%S")
log_path = os.path.join(
self.log_dir, f"{{}}_{reset_timestamp}_{self.unique_env_id}.log",
self.log_dir,
f"{{}}_{reset_timestamp}_{self.unique_env_id}.log",
)

# (Re)start Minetest server
Expand Down Expand Up @@ -296,7 +317,7 @@ def _delete_world(self):
shutil.rmtree(self.world_dir)
else:
raise RuntimeError(
"World directory was not set. Please, provide a world directory"
"World directory was not set. Please, provide a world directory "
"in the constructor or seed the environment!",
)

Expand All @@ -306,7 +327,7 @@ def _delete_config(self):
os.remove(self.config_path)
else:
raise RuntimeError(
"Minetest config path was not set. Please, provide a config path"
"Minetest config path was not set. Please, provide a config path "
"in the constructor or seed the environment!",
)

Expand Down Expand Up @@ -342,7 +363,6 @@ def seed(self, seed: int):
if self.config_path is None:
self.config_path = os.path.join(self.root_dir, f"{self.unique_env_id}.conf")
self._write_config()
# TODO seed used libraries, like numpy, pytorch etc.

def reset(self):
if self.start_minetest:
Expand All @@ -361,7 +381,8 @@ def reset(self):

def step(self, action: Dict[str, Any]):
# Send action
action["MOUSE"] = action["MOUSE"].tolist()
if isinstance(action["MOUSE"], np.ndarray):
action["MOUSE"] = action["MOUSE"].tolist()
logging.debug("Sending action: {}".format(action))
pb_action = pack_pb_action(action)
self.socket.send(pb_action.SerializeToString())
Expand Down

0 comments on commit 8eb84c0

Please sign in to comment.