Skip to content

Commit a96161a

Browse files
committed
Merge branch 'main' of github.com:Lux-AI-Challenge/Lux-Design-S2 into main
2 parents 513d8d0 + 555af09 commit a96161a

File tree

16 files changed

+55
-45
lines changed

16 files changed

+55
-45
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# ChangeLog
22

3+
### v2.2.0
4+
5+
Upgraded to gymnasium format
6+
37
### v2.1.9
48

59
Fix bug where setuptools was causing runtime errors

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,20 @@ If you use the Lux AI Season 2 environment in your work, please cite this reposi
3535

3636
## Getting Started
3737

38-
You will need Python >=3.7, <3.11 installed on your system. Once installed, you can install the Lux AI season 2 environment and optionally the GPU version with
38+
You will need Python >=3.8, <3.11 installed on your system. Once installed, you can install the Lux AI season 2 environment and optionally the GPU version with
3939

4040
```
4141
pip install --upgrade luxai_s2
4242
pip install juxai-s2 # installs the GPU version, requires a compatible GPU
4343
```
4444

45-
If you have `gym` installation issues, we recommend running `pip install setuptools==59.8.0`. If you have issues installing `vec-noise`, make sure to read the error output, it's usually because you are missing some C/C++ build tools. If you use conda, we highly recommend creating an environment based on the [environment.yml file in this repo](https://github.com/Lux-AI-Challenge/Lux-Design-S2/blob/main/environment.yml). If you don't know how conda works, I highly recommend setting it up, see the [install instructions](https://conda.io/projects/conda/en/latest/user-guide/install/index.html#regular-installation).
4645

47-
To create a conda environment and use it run
46+
If you don't know how conda works, I highly recommend setting it up, see the [install instructions](https://conda.io/projects/conda/en/latest/user-guide/install/index.html#regular-installation). You can then setup the environment as follows
47+
4848
```
49-
conda env create -f environment.yml
49+
conda create -n "luxai_s2" "python==3.9"
5050
conda activate luxai_s2
51+
pip install --upgrade luxai-s2
5152
```
5253

5354

docs/advanced_specs.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ There are two ways to create the LuxAI environment, of which the recommended way
1212
from luxai_s2 import LuxAI_S2
1313
custom_env_cfg = dict()
1414
env = LuxAI_S2(collect_stats=False, **custom_env_cfg)
15-
env.reset()
15+
obs, _ = env.reset()
1616
```
1717

1818
where `collect_stats=True` will collect aggregate stats for an episode stored in `env.state.stats` and `custom_env_cfg` can be a custom env configuration to override the default. The custom env configuration may only replace existing keys as defined in [config.py](https://github.com/Lux-AI-Challenge/Lux-Design-S2/blob/main/luxai_s2/luxai_s2/config.py).
@@ -23,7 +23,7 @@ The other way to create an environment is to do
2323
import luxai_s2
2424
custom_env_cfg = dict()
2525
env = gym.make("LuxAI_S2-v0", collect_stats=False, **custom_env_cfg)
26-
env.reset()
26+
obs, _ = env.reset()
2727
```
2828

2929
Upon creation, an empty `State` object is created and the default agent names given are `"player_0", "player_1"`.

kits/js/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def agent(observation, configuration):
121121
env.env_steps = env.state.env_steps
122122
obs_inputs = [obs_inputs]
123123
for _ in range(FORWARD_SIM):
124-
obs, _, _, _ = env.step(dict(player_0=dict(), player_1=dict()))
124+
obs, _, _, _, _ = env.step(dict(player_0=dict(), player_1=dict()))
125125
obs_inputs.append(to_json(obs[observation.player]))
126126
# except:
127127
# pass

kits/python/lux/forward_sim.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ def forward_sim(full_obs, env_cfg, n=2):
2222
if len(env.agents) == 0:
2323
# can't step any further
2424
return [full_obs]
25-
obs, _, _, _ = env.step(empty_actions)
25+
obs, _, _, _, _ = env.step(empty_actions)
2626
forward_obs.append(obs[agent])
2727
return forward_obs

kits/rl/sb3/train.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
import copy
77
import os.path as osp
88

9-
import gym
9+
import gymnasium as gym
1010
import numpy as np
1111
import torch as th
1212
import torch.nn as nn
13-
from gym import spaces
14-
from gym.wrappers import TimeLimit
13+
from gymnasium import spaces
14+
from gymnasium.wrappers import TimeLimit
1515
from luxai_s2.state import ObservationStateDict, StatsStateDict
1616
from luxai_s2.utils.heuristics.factory_placement import place_near_random_ice
1717
from luxai_s2.wrappers import SB3Wrapper
@@ -54,9 +54,11 @@ def step(self, action):
5454
# submit actions for just one agent to make it single-agent
5555
# and save single-agent versions of the data below
5656
action = {agent: action}
57-
obs, _, done, info = self.env.step(action)
57+
obs, _, termination, truncation, info = self.env.step(action)
58+
done = dict()
59+
for k in termination:
60+
done[k] = termination[k] | truncation[k]
5861
obs = obs[agent]
59-
done = done[agent]
6062

6163
# we collect stats on teams here. These are useful stats that can be used to help generate reward functions
6264
stats: StatsStateDict = self.env.state.stats[agent]
@@ -87,12 +89,12 @@ def step(self, action):
8789
reward = ice_dug_this_step / 100 + water_produced_this_step
8890

8991
self.prev_step_metrics = copy.deepcopy(metrics)
90-
return obs, reward, done, info
92+
return obs, reward, termination[agent], truncation[agent], info
9193

9294
def reset(self, **kwargs):
93-
obs = self.env.reset(**kwargs)["player_0"]
95+
obs, reset_info = self.env.reset(**kwargs)["player_0"]
9496
self.prev_step_metrics = None
95-
return obs
97+
return obs, reset_info
9698

9799

98100
def parse_args():

kits/rl/sb3/wrappers/controllers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import numpy as np
55
import numpy.typing as npt
6-
from gym import spaces
6+
from gymnasium import spaces
77

88

99
# Controller class copied here since you won't have access to the luxai_s2 package directly on the competition server

kits/rl/sb3/wrappers/obs_wrappers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from typing import Any, Dict
22

3-
import gym
3+
import gymnasium as gym
44
import numpy as np
55
import numpy.typing as npt
6-
from gym import spaces
6+
from gymnasium import spaces
77

88

99
class SimpleUnitObservationWrapper(gym.ObservationWrapper):

luxai_s2/luxai_runner/bot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def __init__(
4444
direct_import_python_bots=direct_import_python_bots,
4545
)
4646
# timing
47-
self.remainingOverageTime = 60
48-
self.time_per_step = 3
47+
self.remainingOverageTime = 600
48+
self.time_per_step = 9
4949

5050
self.log = Logger(
5151
identifier=f"{self.agent}, {self.main_file_path}", verbosity=verbose

luxai_s2/luxai_runner/episode.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from dataclasses import dataclass
77
from typing import Any, Callable, Dict, List, Optional
88

9-
import gym
9+
import gymnasium as gym
1010
import numpy as np
1111
from luxai_runner.bot import Bot
1212
from luxai_runner.logger import Logger
@@ -105,7 +105,7 @@ async def run(self):
105105

106106
metadata = dict()
107107

108-
obs = self.env.reset(seed=self.seed)
108+
obs, _ = self.env.reset(seed=self.seed)
109109
env_cfg = self.env.state.env_cfg
110110
state_obs = self.env.state.get_compressed_obs()
111111
obs = to_json(state_obs)
@@ -165,7 +165,10 @@ async def run(self):
165165
else:
166166
print(f"{agent_id} sent a invalid action {action}")
167167
actions[agent_id] = None
168-
new_state_obs, rewards, dones, infos = self.env.step(actions)
168+
new_state_obs, rewards, terminations, truncations, infos = self.env.step(actions)
169+
dones = dict()
170+
for k in terminations:
171+
dones[k] = terminations[k] | truncations[k]
169172
change_obs = self.env.state.get_change_obs(state_obs)
170173
state_obs = new_state_obs["player_0"]
171174
obs = to_json(change_obs)

luxai_s2/luxai_s2/env.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def reset(self, seed=None):
207207
self.state.stats[agent] = create_empty_stats()
208208
obs = self.state.get_obs()
209209
observations = {agent: obs for agent in self.agents}
210-
return observations
210+
return observations, {}
211211

212212
def log_error(self, *m):
213213
if self.env_cfg.verbose > 0:
@@ -762,7 +762,8 @@ def step(
762762
Dict[str, ObservationStateDict],
763763
Dict[str, float],
764764
Dict[str, bool],
765-
Dict[str, Any],
765+
Dict[str, bool],
766+
Dict[str, dict],
766767
]:
767768
"""
768769
step(action) takes in an action for each agent and should return the
@@ -996,8 +997,8 @@ def step(
996997
env_done = (
997998
env_done or failed_agents["player_0"] or failed_agents["player_1"]
998999
) # env is done if any agent fails.
999-
dones = {agent: env_done or failed_agents[agent] for agent in self.agents}
1000-
1000+
terminations = {agent: env_done or failed_agents[agent] for agent in self.agents}
1001+
truncations = {agent: False or failed_agents[agent] for agent in self.agents}
10011002
# generate observations
10021003
obs = self.state.get_obs()
10031004
observations = {}
@@ -1010,7 +1011,7 @@ def step(
10101011
if env_done:
10111012
self.agents = []
10121013

1013-
return observations, rewards, dones, infos
1014+
return observations, rewards, terminations, truncations, infos
10141015

10151016
### Game Logic ###
10161017
def add_unit(self, team: Team, unit_type, pos: np.ndarray):
@@ -1110,7 +1111,7 @@ def raw_env() -> LuxAI_S2:
11101111
return env
11111112

11121113

1113-
import gym
1114+
import gymnasium as gym
11141115

11151116
gym.register(
11161117
id="LuxAI_S2-v0",

luxai_s2/luxai_s2/spaces/act_space.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import random
22
from typing import Any, Dict, List
33

4-
import gym
4+
import gymnasium as gym
55
import numpy as np
6-
from gym import spaces
6+
from gymnasium import spaces
77

88
from luxai_s2.config import EnvConfig
99
from luxai_s2.factory import Factory

luxai_s2/luxai_s2/spaces/obs_space.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Any, List
33

44
import numpy as np
5-
from gym import spaces
5+
from gymnasium import spaces
66

77
from luxai_s2.config import EnvConfig
88
from luxai_s2.spaces.act_space import ActionsQueue, FactionString

luxai_s2/luxai_s2/wrappers/controllers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Dict, Any
22

33
import numpy.typing as npt
4-
from gym import spaces
4+
from gymnasium import spaces
55

66
class Controller:
77
def __init__(self, action_space: spaces.Space) -> None:

luxai_s2/luxai_s2/wrappers/sb3.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from typing import Callable, Dict
22

3-
import gym
3+
import gymnasium as gym
44
import numpy as np
55
import numpy.typing as npt
6-
from gym import spaces
6+
from gymnasium import spaces
77

88
import luxai_s2.env
99
from luxai_s2.env import LuxAI_S2
@@ -92,21 +92,21 @@ def step(self, action: Dict[str, npt.NDArray]):
9292
lux_action[agent] = dict()
9393

9494
# lux_action is now a dict mapping agent name to an action
95-
obs, reward, done, info = self.env.step(lux_action)
95+
obs, reward, terminated, truncated, info = self.env.step(lux_action)
9696
self.prev_obs = obs
97-
return obs, reward, done, info
97+
return obs, reward, terminated, truncated, info
9898

9999
def reset(self, **kwargs):
100100
# we upgrade the reset function here
101101

102102
# we call the original reset function first
103-
obs = self.env.reset(**kwargs)
103+
obs, _ = self.env.reset(**kwargs)
104104

105105
# then use the bid policy to go through the bidding phase
106106
action = dict()
107107
for agent in self.env.agents:
108108
action[agent] = self.bid_policy(agent, obs[agent])
109-
obs, _, _, _ = self.env.step(action)
109+
obs, _, _, _, _ = self.env.step(action)
110110

111111
# while real_env_steps < 0, we are in the factory placement phase
112112
# so we use the factory placement policy to step through this
@@ -120,7 +120,7 @@ def reset(self, **kwargs):
120120
action[agent] = self.factory_placement_policy(agent, obs[agent])
121121
else:
122122
action[agent] = dict()
123-
obs, _, _, _ = self.env.step(action)
123+
obs, _, _, _, _ = self.env.step(action)
124124
self.prev_obs = obs
125125

126-
return obs
126+
return obs, {}

luxai_s2/setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,15 @@ def get_version(rel_path):
2424
packages=find_packages(exclude="kits"),
2525
entry_points={"console_scripts": ["luxai-s2 = luxai_runner.cli:main"]},
2626
version=get_version("luxai_s2/version.py"),
27-
python_requires=">=3.7",
27+
python_requires=">=3.8",
2828
install_requires=[
2929
"numpy",
3030
"pygame",
3131
"termcolor",
3232
"matplotlib",
3333
"pettingzoo",
3434
"vec_noise",
35-
"gym==0.21.0",
35+
"gymnasium",
3636
"scipy",
37-
"importlib-metadata<5.0" # fixes bug where they deprecated an endpoint that openai gym uses
3837
],
3938
)

0 commit comments

Comments
 (0)