Skip to content

Commit 40f5a6f

Browse files
committed
set legacy crafter rendering as default
1 parent f6f191b commit 40f5a6f

File tree

3 files changed

+92
-12
lines changed

3 files changed

+92
-12
lines changed

balrog/config/config.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ envs:
6666
size: [256, 256] # Image size in Crafter
6767
reward: True
6868
seed: null
69-
max_episode_steps: 2000
69+
max_episode_steps: 2000
70+
unique_items: True
71+
precise_location: False
72+
skip_items: []
73+
edge_only_items: []
7074
textworld_kwargs:
7175
objective: True
7276
description: True
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
from typing import Optional
22

33
import crafter
4-
54
from balrog.environments.crafter import CrafterLanguageWrapper
65
from balrog.environments.wrappers import GymV21CompatibilityV0
76

87

98
def make_crafter_env(env_name, task, config, render_mode: Optional[str] = None):
109
crafter_kwargs = dict(config.envs.crafter_kwargs)
1110
max_episode_steps = crafter_kwargs.pop("max_episode_steps", 2)
11+
unique_items = crafter_kwargs.pop("unique_items", True)
12+
precise_location = crafter_kwargs.pop("precise_location", False)
13+
skip_items = crafter_kwargs.pop("skip_items", [])
14+
edge_only_items = crafter_kwargs.pop("edge_only_items", [])
1215

1316
for param in ["area", "view", "size"]:
1417
if param in crafter_kwargs:
1518
crafter_kwargs[param] = tuple(crafter_kwargs[param])
1619

1720
env = crafter.Env(**crafter_kwargs)
18-
env = CrafterLanguageWrapper(env, task, max_episode_steps=max_episode_steps)
21+
env = CrafterLanguageWrapper(
22+
env,
23+
task,
24+
max_episode_steps=max_episode_steps,
25+
unique_items=unique_items,
26+
precise_location=precise_location,
27+
skip_items=skip_items,
28+
edge_only_items=edge_only_items,
29+
)
1930
env = GymV21CompatibilityV0(env=env, render_mode=render_mode)
2031

2132
return env

balrog/environments/crafter/env.py

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import itertools
2+
from collections import defaultdict
23

34
import crafter
45
import gym
@@ -78,7 +79,7 @@ def rotation_matrix(v1, v2):
7879
return rotation_matrix
7980

8081

81-
def describe_loc(ref, P):
82+
def describe_loc_precise(ref, P):
8283
"""
8384
Describe the location of P relative to ref.
8485
Example: `1 step south and 4 steps west`
@@ -100,21 +101,45 @@ def distange_to_string(distance, direction):
100101
return " and ".join(desc) if desc else "at your location"
101102

102103

104+
def describe_loc_old(ref, P):
105+
desc = []
106+
if ref[1] > P[1]:
107+
desc.append("north")
108+
elif ref[1] < P[1]:
109+
desc.append("south")
110+
if ref[0] > P[0]:
111+
desc.append("west")
112+
elif ref[0] < P[0]:
113+
desc.append("east")
114+
115+
distance = abs(ref[1] - P[1]) + abs(ref[0] - P[0])
116+
distance_str = f"{distance} step{'s' if distance > 1 else ''} to your {'-'.join(desc)}"
117+
118+
return distance_str
119+
120+
103121
def get_edge_items(semantic, item_idx):
104122
item_mask = semantic == item_idx
105123
not_item_mask = semantic != item_idx
106124
item_edge = ndimage.binary_dilation(not_item_mask) & item_mask
107125
return item_edge
108126

109127

110-
def describe_env(info):
128+
def describe_env(
129+
info,
130+
unique_items=True,
131+
precise_location=True,
132+
skip_items=["grass", "sand", "path"],
133+
edge_only_items=["water"],
134+
):
111135
assert info["semantic"][info["player_pos"][0], info["player_pos"][1]] == player_idx
112136
semantic = info["semantic"][
113137
info["player_pos"][0] - info["view"][0] // 2 : info["player_pos"][0] + info["view"][0] // 2 + 1,
114138
info["player_pos"][1] - info["view"][1] // 2 + 1 : info["player_pos"][1] + info["view"][1] // 2,
115139
]
116140
center = np.array([info["view"][0] // 2, info["view"][1] // 2 - 1])
117141
result = ""
142+
describe_loc = describe_loc_precise if precise_location else describe_loc_old
118143
obj_info_list = []
119144

120145
facing = info["player_facing"]
@@ -127,17 +152,15 @@ def describe_env(info):
127152
target_item = id_to_item[target_id]
128153

129154
# skip grass, sand or path so obs here, since we are not displaying them
130-
if target_id in [id_to_item.index(o) for o in ["grass", "sand", "path"]]:
155+
if target_id in [id_to_item.index(o) for o in skip_items]:
131156
target_item = "nothing"
132157

133158
obs = "You face {} at your front.".format(target_item)
134159
else:
135160
obs = "You face nothing at your front."
136161

137162
# Edge detection
138-
edge_only_items = ["water"]
139163
edge_masks = {}
140-
141164
for item_name in edge_only_items:
142165
item_idx = id_to_item.index(item_name)
143166
edge_masks[item_idx] = get_edge_items(semantic, item_idx)
@@ -153,11 +176,26 @@ def describe_env(info):
153176
continue
154177

155178
# skip grass, sand or path so obs is not too long
156-
if idx in [id_to_item.index(o) for o in ["grass", "sand", "path"]]:
179+
if idx in [id_to_item.index(o) for o in skip_items]:
157180
continue
158181

159182
obj_info_list.append((id_to_item[idx], describe_loc(np.array([0, 0]), np.array([i, j]) - center)))
160183

184+
# filter out items, so we only display closest item of each type
185+
if unique_items:
186+
closest_obj_info_list = defaultdict(str)
187+
for item_name, loc in obj_info_list:
188+
loc_dist = int(loc.split(" ")[0])
189+
current_dist = (
190+
int(closest_obj_info_list[item_name].split(" ")[0])
191+
if closest_obj_info_list[item_name]
192+
else float("inf")
193+
)
194+
195+
if current_dist > loc_dist:
196+
closest_obj_info_list[item_name] = loc
197+
obj_info_list = [(name, loc) for name, loc in closest_obj_info_list.items()]
198+
161199
if len(obj_info_list) > 0:
162200
status_str = "You see:\n{}".format("\n".join(["- {} {}".format(name, loc) for name, loc in obj_info_list]))
163201
else:
@@ -192,13 +230,25 @@ def describe_status(info):
192230
return ""
193231

194232

195-
def describe_frame(info):
233+
def describe_frame(
234+
info,
235+
unique_items=True,
236+
precise_location=True,
237+
skip_items=["grass", "sand", "path"],
238+
edge_only_items=["water"],
239+
):
196240
try:
197241
result = ""
198242

199243
result += describe_status(info)
200244
result += "\n\n"
201-
result += describe_env(info)
245+
result += describe_env(
246+
info,
247+
unique_items=unique_items,
248+
precise_location=precise_location,
249+
skip_items=skip_items,
250+
edge_only_items=edge_only_items,
251+
)
202252
result += "\n\n"
203253

204254
return result.strip(), describe_inventory(info)
@@ -216,6 +266,10 @@ def __init__(
216266
env,
217267
task="",
218268
max_episode_steps=2,
269+
unique_items=True,
270+
precise_location=True,
271+
skip_items=["grass", "sand", "path"],
272+
edge_only_items=["water"],
219273
):
220274
super().__init__(env)
221275
self.score_tracker = 0
@@ -224,6 +278,11 @@ def __init__(
224278
self.max_steps = max_episode_steps
225279
self.achievements = None
226280

281+
self.unique_items = unique_items
282+
self.precise_location = precise_location
283+
self.skip_items = skip_items
284+
self.edge_only_items = edge_only_items
285+
227286
def get_text_action(self, action):
228287
return self.language_action_space._values[action]
229288

@@ -257,7 +316,13 @@ def step(self, action):
257316

258317
def process_obs(self, obs, info):
259318
img = Image.fromarray(self.env.render()).convert("RGB")
260-
long_term_context, short_term_context = describe_frame(info)
319+
long_term_context, short_term_context = describe_frame(
320+
info,
321+
unique_items=self.unique_items,
322+
precise_location=self.precise_location,
323+
skip_items=self.skip_items,
324+
edge_only_items=self.edge_only_items,
325+
)
261326

262327
return {
263328
"text": {

0 commit comments

Comments
 (0)