Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f90d3a4
initial tutorial info
trigaten Nov 17, 2021
2da3bb5
agent handlers
trigaten Nov 17, 2021
30aeb07
change location of random agent start handler to agent/start.py rathe…
trigaten Nov 17, 2021
2d80dbe
more progress
trigaten Nov 20, 2021
4503f74
custom env edits
trigaten Nov 24, 2021
086108f
fixed RewardForMissionEnd xml method
trigaten Nov 24, 2021
1052390
gif
trigaten Nov 24, 2021
cd2604c
corresponding methods
trigaten Nov 24, 2021
04cdbef
another template fix
trigaten Nov 27, 2021
f203251
Update minerl/herobraine/hero/handlers/server/quit.py
trigaten Nov 30, 2021
8ae4279
Update docs/source/tutorials/custom_environments.rst
trigaten Nov 30, 2021
a88f6ba
Gym environment not gym
trigaten Nov 30, 2021
d2550a1
Miffyli fixes and example code
trigaten Dec 2, 2021
4befa60
Miffyli fixes and example code
trigaten Dec 2, 2021
71f702a
fix Custom Environment Tutorial link
trigaten Dec 3, 2021
195ae5d
Merge branch 'dev' of https://github.com/minerllabs/minerl into miner…
trigaten Dec 3, 2021
ef26c9e
Merge branch 'minerllabs-dev' into dev
trigaten Dec 3, 2021
40cd10a
fix link
trigaten Dec 3, 2021
aceca29
Merge branch 'minerllabs:dev' into dev
trigaten Dec 9, 2021
12bf3de
Merge branch 'minerllabs:dev' into dev
trigaten Jan 15, 2022
941dbc6
ChatAction Handler
trigaten Jan 15, 2022
7b06e08
update str
trigaten Jan 16, 2022
a26357c
small fixes
trigaten Jan 16, 2022
a5355db
set_next_chat_message
trigaten Jan 16, 2022
9f274a1
Update keyboard.py
trigaten Jan 17, 2022
45941bd
change to other
trigaten Jan 18, 2022
cdecb2c
Merge branch 'dev' of https://github.com/trigaten/minerl into dev
trigaten Jan 18, 2022
c275551
command doc
Jan 22, 2022
f65d74f
command doc
trigaten Jan 22, 2022
ff07cc2
funny
trigaten Jan 22, 2022
45dd084
small fixes
trigaten Jan 24, 2022
e14dfee
Update doc
Miffyli Jan 24, 2022
cea834d
Update docs and add some sanity checks
Miffyli Jan 24, 2022
72b546a
Fix a dörp
Miffyli Jan 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/source/api/herobraine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ Smelt
:undoc-members:
:show-inheritance:

Chat
^^^^^^^^^^

.. automodule:: minerl.herobraine.hero.handlers.agent.actions.chat
:members:
:undoc-members:
:show-inheritance:

Observation Handlers
----------------------

Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ components:
tutorials/k-means
tutorials/minerl_tools
tutorials/custom_environments
tutorials/minecraft_commands


.. toctree::
Expand Down
112 changes: 112 additions & 0 deletions docs/source/tutorials/minecraft_commands.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.. _Custom Env Tutorial

.. admonition:: Solution
:class: toggle

====================================
Using Minecraft Commands
====================================

.. role:: python(code)
:language: python

.. role:: bash(code)
:language: bash

..
sphinx should really support minecraft language markdown :(

.. role:: minecraft(code)
:language: minecraft

Introduction
============

MineRL provides support for sending `Minecraft commands <https://minecraft.fandom.com/wiki/Commands>`_.
In addition to opening up numerous custom environment possibilities
(Minecraft commands can be used to move players,
summon or destroy mobs and blocks, reset player
health/food, apply potions effects, and much more),
this feature can be *very* useful for speeding up training.


.. warning::

This feature is in BETA; it comes with a number of restrictions.

Only messages from the first agent are supported in the multiagent setting.

You must add the :code:`ChatAction` handler to your envspec.

You can only execute one chat action per time step,


How Can MC Commands speed up training?
-----------------------------------------------

Consider an agent attempting the Navigate task.
After each attempt to get to the objective the Minecraft world is reset.
Resetting the world is very computationally costly and it would be better to just
reset the position, health, and food of the agent.

This could be accomplished with the following Minecraft commands:

.. code-block:: minecraft

# teleport all agents to (x=0, z=0)
/tp @a 0 ~ 0

# reset health of all agents
/effect @a minecraft:instant_health 1 100 true

# reset food of all agents
/effect @a minecraft:saturation 1 255 true

Adding the :code:`ChatAction` to your envspec
--------------------------------------------

In order to send Minecraft commands, you need to add the :code:`ChatAction`
handler to your environment's envspec. See `this tutorial <https://minerl.readthedocs.io/en/latest/tutorials/custom_environments.html>`_ on how to make custom environments and envspecs.

The :code:`ChatAction` allows the sending of regular Minecraft chat messages as well as Minecraft commands.
This can be accomplished by adding the ``ChatAction`` handler to your envspec:

.. code-block:: python

def create_actionables(self) -> List[Handler]:
return super().create_actionables() + [
# enable chat
handlers.ChatAction()
]

Abstracted Command Sending
------------------------------
All environments which use the :code:`ChatAction` handler will support
the ``set_next_chat_message`` function. This function takes a string
and sends it as a chat message the next time the environment
is stepped:

.. code-block:: python

# no actions
actions = {}
env.set_next_chat_message("/gamemode @a adventure")
# sets the gamemode of all players to adventure
env.step(actions)
# the chat message is not executed again;
# it gets cleared each time step() is called
env.step(actions)
env.set_next_chat_message("/tp @r 320 54 66")
# teleports a random agent to the given coordinates
env.step(actions)


Advanced use
---------------
If for some reason you need to execute multiple commands in
the *same* time step, you can either spawn in a chain of
Minecraft Command Blocks or load a world from the file
with a chain of command blocks. This level of complexity
shouldn’t be needed but could be useful if you need to
execute many distinct commands and don't want to spread them
over multiple time steps.
25 changes: 25 additions & 0 deletions minerl/env/_multiagent.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from minerl.env.exceptions import MissionInitException
import os
from minerl.herobraine.wrapper import EnvWrapper
import minerl.herobraine.hero.handlers as handlers
import struct
from minerl.env.malmo import InstanceManager, MinecraftInstance, launch_queue_logger_thread, malmo_version
import uuid
Expand Down Expand Up @@ -96,6 +97,11 @@ def __init__(self,
self._init_fault_tolerance(is_fault_tolerant)
self._init_logging(verbose)

# first agent can send Minecraft messages/commands each step
self.next_chat_message = None
# This will be checked first time chat is tried to be used
self.has_chat_handler = None

############ INIT METHODS ##########
# These methods are used to first initialize different systems in the environment
# These systems are not generally mutated episodically (via reset) and therefore
Expand Down Expand Up @@ -270,6 +276,15 @@ def step(self, actions) -> Tuple[dict, dict, bool, dict]:
if not self.done:
assert STEP_OPTIONS == 0 or STEP_OPTIONS == 2

# add chat action if there is one
if self.next_chat_message:
actions[self.task.agent_names[0]]["chat"] = self.next_chat_message
self.next_chat_message = None
if self.has_chat_handler is None:
self.has_chat_handler = any([isinstance(actionable, handlers.ChatAction) for actionable in self.task.actionables])
if not self.has_chat_handler:
raise RuntimeError("Tried to use chat action but no ChatAction handler is present (see docs on how to send Minecraft commands).")

multi_obs = {}
multi_reward = {}
everyone_is_done = True
Expand Down Expand Up @@ -677,6 +692,14 @@ def close(self):
def is_closed(self):
return self._already_closed

def set_next_chat_message(self, chat):
"""
Sets the next chat message to be sent to Minecraft by agent_0
This can be used to send Minecraft commands
Make sure you have the ChatAction handler enabled in your environment
"""
self.next_chat_message = chat

############# AUX HELPER METHODS ###########

# TODO - make a custom Logger with this integrated (See LogHelper.java)
Expand Down Expand Up @@ -815,3 +838,5 @@ def _get_token(self, role, ep_uid: str):

def _clean_connection(self):
pass


1 change: 1 addition & 0 deletions minerl/herobraine/hero/handlers/agent/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
from .keyboard import *
from .place import *
from .smelt import *
from .chat import *
43 changes: 43 additions & 0 deletions minerl/herobraine/hero/handlers/agent/actions/chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
__author__ = "Sander Schulhoff"
__email__ = "sanderschulhoff@gmail.com"

from minerl.herobraine.hero.handlers.agent.action import Action
import minerl.herobraine.hero.spaces as spaces

# TODO add more command support (things like what commands are allowed) from Malmo
# TODO ensure other agents can send chats, not just first agent (again, check Malmo)
class ChatAction(Action):
"""
Handler which lets agents send Minecraft chat messages

Note: this may currently be limited to the
first agent sending messages (check Malmo for this)

This can be used to execute MINECRAFT COMMANDS !!!

Example usage:

.. code-block:: python

ChatAction()

To summon a creeper, use this action dictionary:

.. code-block:: json

{"chat": "/summon creeper"}

"""

def to_string(self):
return 'chat'

def xml_template(self) -> str:
return str("<ChatCommands> </ChatCommands>")

def __init__(self):
self._command = 'chat'
super().__init__(self.command, spaces.Text([1]))

def from_universal(self, x):
return []
2 changes: 1 addition & 1 deletion minerl/herobraine/hero/handlers/agent/actions/keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class KeybasedCommandAction(Action):
A command action which is generated from human keypresses in anvil.
Examples of such actions are movement actions, etc.

This is not to be confused with keyboard acitons, wehreby both anvil and malmo
This is not to be confused with keyboard actions, whereby both anvil and malmo
simulate and act on direct key codes.

Combinations of KeybasedCommandActions yield actions like:
Expand Down
1 change: 1 addition & 0 deletions minerl/herobraine/hero/handlers/agent/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""
from minerl.herobraine.hero.handler import Handler
from typing import Dict, List, Union
import random

# <AgentStart>
# <Inventory>
Expand Down
3 changes: 2 additions & 1 deletion minerl/herobraine/hero/spaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class Text(MineRLSpace):
# TODO:
[['a text string', ..., 'last_text_string']]
Example usage:
self.observation_space = spaces.Text(1)
self.observation_space = spaces.Text([1])
"""

def no_op(self):
Expand All @@ -482,6 +482,7 @@ def unmap(self, x):

def __init__(self, shape):
super().__init__(shape, np.unicode_)
warnings.warn("The Text MineRLSpace class is not fully implemented. This may cause problems when sampling an action of this type (even when getting a noop).")

def sample(self):
total_strings = np.prod(self.shape)
Expand Down