Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/EleutherAI/minetest into…
Browse files Browse the repository at this point in the history
… develop
  • Loading branch information
JJJHolscher committed Aug 23, 2023
2 parents fac3804 + b0254fd commit 856e59f
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 81 deletions.
169 changes: 107 additions & 62 deletions minetester/minetest_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
start_minetest_server, start_xserver,
unpack_pb_obs)

import pkg_resources

class Minetest(gym.Env):
metadata = {"render.modes": ["rgb_array", "human"]}
Expand All @@ -23,16 +24,16 @@ def __init__(
self,
env_port: int = 5555,
server_port: int = 30000,
minetest_executable: Optional[os.PathLike] = None,
log_dir: Optional[os.PathLike] = None,
config_path: Optional[os.PathLike] = None,
cursor_image_path: Optional[os.PathLike] = None,
minetest_root: Optional[os.PathLike] = None,
artefact_dir: Optional[os.PathLike] = None,
world_dir: Optional[os.PathLike] = None,
config_path: Optional[os.PathLike] = None,
display_size: Tuple[int, int] = default_display_size,
fov: int = 72,
seed: Optional[int] = None,
start_minetest: bool = True,
game_id: str = "minetest",
client_name: str = "minetester",
clientmods: List[str] = [],
servermods: List[str] = [],
config_dict: Dict[str, Any] = {},
Expand All @@ -43,62 +44,20 @@ def __init__(
x_display: Optional[int] = None,
):
self.unique_env_id = str(uuid.uuid4())

# Seed the environment
if seed is not None:
self.seed(seed)

# Graphics settings
self.headless = headless
self.display_size = display_size
self.fov_y = fov
self.fov_x = self.fov_y * self.display_size[0] / self.display_size[1]
self._set_graphics(headless, display_size, fov)

# 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()},
**{
"MOUSE": gym.spaces.Box(
np.array([-self.max_mouse_move_x, -self.max_mouse_move_y]),
np.array([self.max_mouse_move_x, self.max_mouse_move_y]),
shape=(2,),
dtype=int,
),
},
},
)
self.observation_space = gym.spaces.Box(
0,
255,
shape=(self.display_size[1], self.display_size[0], 3),
dtype=np.uint8,
)
self._configure_spaces()

# 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:
self.log_dir = os.path.join(self.root_dir, "log")
os.makedirs(self.log_dir, exist_ok=True)
self.world_dir = world_dir
self.config_path = config_path
self.cursor_image_path = cursor_image_path
if cursor_image_path is None:
self.cursor_image_path = os.path.join(
self.root_dir,
"cursors",
"mouse_cursor_white_16x16.png",
)

# Regenerate and clean world and config if no custom ones provided
self.reset_world = self.world_dir is None
self.clean_config = self.config_path is None
# If no custom world / config provided set folder / path based on UUID
if self.world_dir is None:
self.world_dir = os.path.join(self.root_dir, self.unique_env_id)
if self.config_path is None:
self.config_path = os.path.join(self.root_dir, f"{self.unique_env_id}.conf")
self._set_artefact_dirs(artefact_dir, world_dir, config_path, config_dict) #Stores minetest artefacts and outputs
self._set_minetest_dirs(minetest_root) #Stores actual minetest dirs and executable

# Whether to start minetest server and client
self.start_minetest = start_minetest
Expand All @@ -110,6 +69,9 @@ def __init__(

self.sync_dtime = sync_dtime

#Client Name
self.client_name = client_name

# ZMQ objects
self.socket = None
self.context = None
Expand All @@ -123,10 +85,6 @@ def __init__(
self.render_fig = None
self.render_img = None

# Seed the environment
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"),
Expand All @@ -150,10 +108,6 @@ def __init__(
self._enable_clientmods()
self._enable_servermods()

# Write minetest.conf
self.config_dict = config_dict
self._write_config()

# Start X server virtual frame buffer
self.default_display = x_display or 0
if "DISPLAY" in os.environ:
Expand All @@ -164,6 +118,95 @@ def __init__(
if self.start_xvfb:
self.x_display = x_display or self.default_display + 4
self.xserver_process = start_xserver(self.x_display, self.display_size)

def _configure_spaces(self):
# 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()},
**{
"MOUSE": gym.spaces.Box(
np.array([-self.max_mouse_move_x, -self.max_mouse_move_y]),
np.array([self.max_mouse_move_x, self.max_mouse_move_y]),
shape=(2,),
dtype=int,
),
},
},
)
self.observation_space = gym.spaces.Box(
0,
255,
shape=(self.display_size[1], self.display_size[0], 3),
dtype=np.uint8,
)

def _set_graphics(self, headless, display_size, fov):
self.headless = headless
self.display_size = display_size
self.fov_y = fov
self.fov_x = self.fov_y * self.display_size[0] / self.display_size[1]

def _set_minetest_dirs(self, minetest_root):
self.minetest_root = minetest_root
if self.minetest_root is None:
#check for local install
candiate_minetest_root = os.path.dirname(os.path.dirname(__file__))
candiate_minetest_executable = os.path.join(os.path.dirname(os.path.dirname(__file__)),"bin","minetest")
if os.path.isfile(candiate_minetest_executable):
self.minetest_root = candiate_minetest_root

if self.minetest_root is None:
#check for package install
try:
candiate_minetest_executable = pkg_resources.resource_filename(__name__,os.path.join("minetest","bin","minetest"))
if os.path.isfile(candiate_minetest_executable):
self.minetest_root = os.path.dirname(os.path.dirname(candiate_minetest_executable))
except Exception as e:
logging.warning(f"Error loading resource file 'bin.minetest': {e}")

if self.minetest_root is None:
raise Exception("Unable to locate minetest executable")

self.minetest_executable = os.path.join(self.minetest_root,"bin","minetest")

self.cursor_image_path = os.path.join(
self.minetest_root,
"cursors",
"mouse_cursor_white_16x16.png",
)

def _set_artefact_dirs(self, artefact_dir, world_dir, config_path, config_dict):
if artefact_dir is None:
self.artefact_dir = os.path.join(os.getcwd(), "artefacts")
else:
self.artefact_dir = artefact_dir

if config_path is None:
self.clean_config = True
self.config_path = os.path.join(self.artefact_dir, f"{self.unique_env_id}.conf")
else:
self.clean_config = True
self.config_path = config_path

if world_dir is None:
self.reset_world = True
self.world_dir = os.path.join(self.artefact_dir, self.unique_env_id)
else:
self.reset_world = False
self.world_dir = world_dir

self.log_dir = os.path.join(self.artefact_dir, "log")
self.media_cache_dir = os.path.join(self.artefact_dir, "media_cache")

os.makedirs(self.log_dir, exist_ok=True)
os.makedirs(self.media_cache_dir, exist_ok=True)

# Write minetest.conf
self.config_dict = config_dict
self._write_config()

def _enable_clientmods(self):
clientmods_folder = os.path.realpath(
Expand Down Expand Up @@ -246,6 +289,8 @@ def _reset_minetest(self):
self.env_port,
self.server_port,
self.cursor_image_path,
self.client_name,
self.media_cache_dir,
sync_port=self.sync_port,
headless=self.headless,
display=self.x_display,
Expand Down
33 changes: 18 additions & 15 deletions minetester/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ def pack_pb_action(action: Dict[str, Any]):


def start_minetest_server(
minetest_path: str = "bin/minetest",
config_path: str = "minetest.conf",
log_path: str = "log/{}.log",
server_port: int = 30000,
world_dir: str = "newworld",
sync_port: int = None,
sync_dtime: float = 0.001,
game_id: str = "minetest",
minetest_path: str,
config_path: str,
log_path: str,
server_port: int,
world_dir: str,
sync_port: int,
sync_dtime: float,
game_id: str,
):
cmd = [
minetest_path,
Expand All @@ -111,13 +111,14 @@ def start_minetest_server(


def start_minetest_client(
minetest_path: str = "bin/minetest",
config_path: str = "minetest.conf",
log_path: str = "log/{}.log",
client_port: int = 5555,
server_port: int = 30000,
cursor_img: str = "cursors/mouse_cursor_white_16x16.png",
client_name: str = "MinetestAgent",
minetest_path: str,
config_path: str,
log_path: str,
client_port: int,
server_port: int,
cursor_img: str,
client_name: str,
media_cache_dir: str,
sync_port: int = None,
headless: bool = False,
display: int = None,
Expand All @@ -140,6 +141,8 @@ def start_minetest_client(
"--noresizing",
"--config",
config_path,
"--cache",
media_cache_dir,
]
if headless:
# don't render to screen
Expand Down
9 changes: 8 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,12 @@ int main(int argc, char *argv[])
porting::initAndroid();
porting::initializePathsAndroid();
#else
porting::initializePaths();
std::string media_cache_dir;
if (cmd_args.getFlag("cache")){
media_cache_dir = cmd_args.get("cache");
}

porting::initializePaths(media_cache_dir);
#endif

if (!create_userdata_path()) {
Expand Down Expand Up @@ -314,6 +319,8 @@ static void set_allowed_options(OptionList *allowed_options)
_("Show allowed options"))));
allowed_options->insert(std::make_pair("version", ValueSpec(VALUETYPE_FLAG,
_("Show version information"))));
allowed_options->insert(std::make_pair("cache", ValueSpec(VALUETYPE_STRING,
_("Set media cache directory"))));
allowed_options->insert(std::make_pair("config", ValueSpec(VALUETYPE_STRING,
_("Load configuration from specified file"))));
allowed_options->insert(std::make_pair("port", ValueSpec(VALUETYPE_STRING,
Expand Down
8 changes: 6 additions & 2 deletions src/porting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ void migrateCachePath()
}
}

void initializePaths()
void initializePaths(std::string media_cache_dir)
{
#if RUN_IN_PLACE
char buf[BUFSIZ];
Expand Down Expand Up @@ -615,7 +615,11 @@ void initializePaths()
path_share = execpath;
path_user = execpath;
}
path_cache = path_user + DIR_DELIM + "cache";
if (!media_cache_dir.empty()) {
path_cache = media_cache_dir;
} else {
path_cache = path_user + DIR_DELIM + "cache";
}
#else
infostream << "Using system-wide paths (NOT RUN_IN_PLACE)" << std::endl;

Expand Down
2 changes: 1 addition & 1 deletion src/porting.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void migrateCachePath();
/*
Initialize path_*.
*/
void initializePaths();
void initializePaths(std::string media_cache_dir);

/*
Return system information
Expand Down

0 comments on commit 856e59f

Please sign in to comment.