The complexity of XLand-MiniGrid comes from dynamic Rules and Goals.
- Rules: Functions that change the environment state deterministically based on conditions.
- Goals: Functions that test conditions without changing the state.
Encoding for JAX Compatibility
To remain JIT-compatible and efficient, rules and goals are represented as vectors (encodings). The first element is always an ID, followed by arguments. This allows:
- Dynamic rulesets (changing arguments between resets).
- Compact storage for millions of tasks.
- Efficient decoding using
jax.lax.switch inside JIT loops.
Working with Encodings
Instead of calling class methods directly, use check_goal and check_rule with encodings.
from xminigrid.core.goals import AgentNearGoal, check_goal
from xminigrid.core.rules import AgentNearRule, check_rule
# Create and encode a goal
gol = AgentNearGoal(tile=TILES_REGISTRY[Tiles.BALL, Colors.YELLOW])
goal_encoding = gol.encode()
# Check goal using encoding (efficient for JIT)
is_goal_met = check_goal(goal_encoding, grid, agent, action, position)
# Create and encode a rule
rule = AgentNearRule(tile=..., prod_tile=...)
rule_encoding = rule.encode()
# Check rule using encoding
new_grid, new_agent = check_rule(rule_encoding[None, ...], grid, agent, action, position)
from xminigrid.core.goals import AgentNearGoal, check_goal
from xminigrid.core.rules import AgentNearRule, check_rule
# Goal usage
gol = AgentNearGoal(tile=TILES_REGISTRY[Tiles.BALL, Colors.YELLOW])
goal_encoding = gol.encode()
is_goal_met = check_goal(goal_encoding, grid, agent, action, position)
# Rule usage
rule = AgentNearRule(tile=..., prod_tile=...)
rule_encoding = rule.encode()
new_grid, new_agent = check_rule(rule_encoding[None, ...], grid, agent, action, position)