Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- .gitattributes +2 -0
- Dockerfile +114 -0
- README.md +250 -5
- __init__.py +27 -0
- client.py +125 -0
- config.py +41 -0
- models.py +100 -0
- openenv.yaml +7 -0
- openenv_pokemonred_env.egg-info/PKG-INFO +18 -0
- openenv_pokemonred_env.egg-info/SOURCES.txt +29 -0
- openenv_pokemonred_env.egg-info/dependency_links.txt +1 -0
- openenv_pokemonred_env.egg-info/entry_points.txt +2 -0
- openenv_pokemonred_env.egg-info/requires.txt +14 -0
- openenv_pokemonred_env.egg-info/top_level.txt +1 -0
- pyproject.toml +53 -0
- rewards/__init__.py +20 -0
- rewards/badge.py +32 -0
- rewards/base.py +88 -0
- rewards/event.py +33 -0
- rewards/exploration.py +32 -0
- rewards/level.py +32 -0
- rewards/manager.py +125 -0
- server/PokemonRed.gb +3 -0
- server/__init__.py +11 -0
- server/app.py +103 -0
- server/events.json +2560 -0
- server/global_map.py +31 -0
- server/init.state +3 -0
- server/map_data.json +2716 -0
- server/pokemonred_env_environment.py +325 -0
- server/pokered.sym +0 -0
- server/requirements.txt +6 -0
- uv.lock +0 -0
- wrappers/__init__.py +8 -0
- wrappers/green_agent.py +190 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
server/PokemonRed.gb filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
server/init.state filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
# Multi-stage build for Pokemon Red OpenEnv
|
| 8 |
+
# Builds a containerized PyBoy emulator environment for RL training
|
| 9 |
+
#
|
| 10 |
+
# Build: openenv build
|
| 11 |
+
# Run: docker run -p 8000:8000 pokemonred-env:latest
|
| 12 |
+
#
|
| 13 |
+
# Environment variables:
|
| 14 |
+
# POKEMON_HEADLESS: Run without display (default: true)
|
| 15 |
+
# POKEMON_ACTION_FREQ: Emulator ticks per action (default: 24)
|
| 16 |
+
# POKEMON_ROM_PATH: Path to ROM file (default: /app/env/server/PokemonRed.gb)
|
| 17 |
+
# POKEMON_INIT_STATE: Path to save state (default: /app/env/server/init.state)
|
| 18 |
+
|
| 19 |
+
ARG BASE_IMAGE=ghcr.io/meta-pytorch/openenv-base:latest
|
| 20 |
+
FROM ${BASE_IMAGE} AS builder
|
| 21 |
+
|
| 22 |
+
WORKDIR /app
|
| 23 |
+
|
| 24 |
+
# Install build dependencies for PyBoy and SDL2
|
| 25 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 26 |
+
git \
|
| 27 |
+
build-essential \
|
| 28 |
+
libsdl2-dev \
|
| 29 |
+
libsdl2-image-dev \
|
| 30 |
+
libsdl2-mixer-dev \
|
| 31 |
+
libsdl2-ttf-dev \
|
| 32 |
+
python3-dev \
|
| 33 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 34 |
+
|
| 35 |
+
# Build arguments
|
| 36 |
+
ARG BUILD_MODE=in-repo
|
| 37 |
+
ARG ENV_NAME=pokemonred_env
|
| 38 |
+
|
| 39 |
+
# Copy environment code
|
| 40 |
+
COPY . /app/env
|
| 41 |
+
|
| 42 |
+
WORKDIR /app/env
|
| 43 |
+
|
| 44 |
+
# Ensure uv is available
|
| 45 |
+
RUN if ! command -v uv >/dev/null 2>&1; then \
|
| 46 |
+
curl -LsSf https://astral.sh/uv/install.sh | sh && \
|
| 47 |
+
mv /root/.local/bin/uv /usr/local/bin/uv && \
|
| 48 |
+
mv /root/.local/bin/uvx /usr/local/bin/uvx; \
|
| 49 |
+
fi
|
| 50 |
+
|
| 51 |
+
# Install dependencies using uv sync
|
| 52 |
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
| 53 |
+
if [ -f uv.lock ]; then \
|
| 54 |
+
uv sync --frozen --no-install-project --no-editable; \
|
| 55 |
+
else \
|
| 56 |
+
uv sync --no-install-project --no-editable; \
|
| 57 |
+
fi
|
| 58 |
+
|
| 59 |
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
| 60 |
+
if [ -f uv.lock ]; then \
|
| 61 |
+
uv sync --frozen --no-editable; \
|
| 62 |
+
else \
|
| 63 |
+
uv sync --no-editable; \
|
| 64 |
+
fi
|
| 65 |
+
|
| 66 |
+
# Final runtime stage
|
| 67 |
+
FROM ${BASE_IMAGE}
|
| 68 |
+
|
| 69 |
+
WORKDIR /app
|
| 70 |
+
|
| 71 |
+
# Install runtime dependencies for PyBoy headless operation
|
| 72 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 73 |
+
libsdl2-2.0-0 \
|
| 74 |
+
libsdl2-image-2.0-0 \
|
| 75 |
+
curl \
|
| 76 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 77 |
+
|
| 78 |
+
# Copy the virtual environment from builder
|
| 79 |
+
COPY --from=builder /app/env/.venv /app/.venv
|
| 80 |
+
|
| 81 |
+
# Copy the environment code
|
| 82 |
+
COPY --from=builder /app/env /app/env
|
| 83 |
+
|
| 84 |
+
# Set PATH to use the virtual environment
|
| 85 |
+
ENV PATH="/app/.venv/bin:$PATH"
|
| 86 |
+
|
| 87 |
+
# Set PYTHONPATH for imports
|
| 88 |
+
ENV PYTHONPATH="/app/env:$PYTHONPATH"
|
| 89 |
+
|
| 90 |
+
# Configure SDL for headless operation (no display, no audio)
|
| 91 |
+
ENV SDL_VIDEODRIVER=dummy
|
| 92 |
+
ENV SDL_AUDIODRIVER=dummy
|
| 93 |
+
|
| 94 |
+
# Default environment configuration
|
| 95 |
+
ENV POKEMON_HEADLESS=true
|
| 96 |
+
ENV POKEMON_ACTION_FREQ=24
|
| 97 |
+
ENV POKEMON_ROM_PATH=/app/env/server/PokemonRed.gb
|
| 98 |
+
ENV POKEMON_INIT_STATE=/app/env/server/init.state
|
| 99 |
+
ENV POKEMON_MAX_STEPS=163840
|
| 100 |
+
ENV POKEMON_SESSION_PATH=/tmp/pokemon_sessions
|
| 101 |
+
|
| 102 |
+
# Create session directory
|
| 103 |
+
RUN mkdir -p /tmp/pokemon_sessions
|
| 104 |
+
|
| 105 |
+
# Health check
|
| 106 |
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
| 107 |
+
CMD curl -f http://localhost:8000/health || exit 1
|
| 108 |
+
|
| 109 |
+
# Expose port
|
| 110 |
+
EXPOSE 8000
|
| 111 |
+
|
| 112 |
+
# Run the FastAPI server
|
| 113 |
+
ENV ENABLE_WEB_INTERFACE=true
|
| 114 |
+
CMD ["sh", "-c", "cd /app/env && uvicorn server.app:app --host 0.0.0.0 --port 8000"]
|
README.md
CHANGED
|
@@ -1,10 +1,255 @@
|
|
| 1 |
---
|
| 2 |
-
title: Pokemonred Env
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Pokemonred Env Environment Server
|
| 3 |
+
emoji: 🔈
|
| 4 |
+
colorFrom: red
|
| 5 |
+
colorTo: red
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
+
app_port: 8000
|
| 9 |
+
base_path: /web
|
| 10 |
+
tags:
|
| 11 |
+
- openenv
|
| 12 |
---
|
| 13 |
|
| 14 |
+
# Pokemonred Env Environment
|
| 15 |
+
|
| 16 |
+
A simple test environment that echoes back messages. Perfect for testing the env APIs as well as demonstrating environment usage patterns.
|
| 17 |
+
|
| 18 |
+
## Quick Start
|
| 19 |
+
|
| 20 |
+
The simplest way to use the Pokemonred Env environment is through the `PokemonredEnv` class:
|
| 21 |
+
|
| 22 |
+
```python
|
| 23 |
+
from pokemonred_env import PokemonredAction, PokemonredEnv
|
| 24 |
+
|
| 25 |
+
try:
|
| 26 |
+
# Create environment from Docker image
|
| 27 |
+
pokemonred_envenv = PokemonredEnv.from_docker_image("pokemonred_env-env:latest")
|
| 28 |
+
|
| 29 |
+
# Reset
|
| 30 |
+
result = pokemonred_envenv.reset()
|
| 31 |
+
print(f"Reset: {result.observation.echoed_message}")
|
| 32 |
+
|
| 33 |
+
# Send multiple messages
|
| 34 |
+
messages = ["Hello, World!", "Testing echo", "Final message"]
|
| 35 |
+
|
| 36 |
+
for msg in messages:
|
| 37 |
+
result = pokemonred_envenv.step(PokemonredAction(message=msg))
|
| 38 |
+
print(f"Sent: '{msg}'")
|
| 39 |
+
print(f" → Echoed: '{result.observation.echoed_message}'")
|
| 40 |
+
print(f" → Length: {result.observation.message_length}")
|
| 41 |
+
print(f" → Reward: {result.reward}")
|
| 42 |
+
|
| 43 |
+
finally:
|
| 44 |
+
# Always clean up
|
| 45 |
+
pokemonred_envenv.close()
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
That's it! The `PokemonredEnv.from_docker_image()` method handles:
|
| 49 |
+
- Starting the Docker container
|
| 50 |
+
- Waiting for the server to be ready
|
| 51 |
+
- Connecting to the environment
|
| 52 |
+
- Container cleanup when you call `close()`
|
| 53 |
+
|
| 54 |
+
## Building the Docker Image
|
| 55 |
+
|
| 56 |
+
Before using the environment, you need to build the Docker image:
|
| 57 |
+
|
| 58 |
+
```bash
|
| 59 |
+
# From project root
|
| 60 |
+
docker build -t pokemonred_env-env:latest -f server/Dockerfile .
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
## Deploying to Hugging Face Spaces
|
| 64 |
+
|
| 65 |
+
You can easily deploy your OpenEnv environment to Hugging Face Spaces using the `openenv push` command:
|
| 66 |
+
|
| 67 |
+
```bash
|
| 68 |
+
# From the environment directory (where openenv.yaml is located)
|
| 69 |
+
openenv push
|
| 70 |
+
|
| 71 |
+
# Or specify options
|
| 72 |
+
openenv push --namespace my-org --private
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
The `openenv push` command will:
|
| 76 |
+
1. Validate that the directory is an OpenEnv environment (checks for `openenv.yaml`)
|
| 77 |
+
2. Prepare a custom build for Hugging Face Docker space (enables web interface)
|
| 78 |
+
3. Upload to Hugging Face (ensuring you're logged in)
|
| 79 |
+
|
| 80 |
+
### Prerequisites
|
| 81 |
+
|
| 82 |
+
- Authenticate with Hugging Face: The command will prompt for login if not already authenticated
|
| 83 |
+
|
| 84 |
+
### Options
|
| 85 |
+
|
| 86 |
+
- `--directory`, `-d`: Directory containing the OpenEnv environment (defaults to current directory)
|
| 87 |
+
- `--repo-id`, `-r`: Repository ID in format 'username/repo-name' (defaults to 'username/env-name' from openenv.yaml)
|
| 88 |
+
- `--base-image`, `-b`: Base Docker image to use (overrides Dockerfile FROM)
|
| 89 |
+
- `--private`: Deploy the space as private (default: public)
|
| 90 |
+
|
| 91 |
+
### Examples
|
| 92 |
+
|
| 93 |
+
```bash
|
| 94 |
+
# Push to your personal namespace (defaults to username/env-name from openenv.yaml)
|
| 95 |
+
openenv push
|
| 96 |
+
|
| 97 |
+
# Push to a specific repository
|
| 98 |
+
openenv push --repo-id my-org/my-env
|
| 99 |
+
|
| 100 |
+
# Push with a custom base image
|
| 101 |
+
openenv push --base-image ghcr.io/meta-pytorch/openenv-base:latest
|
| 102 |
+
|
| 103 |
+
# Push as a private space
|
| 104 |
+
openenv push --private
|
| 105 |
+
|
| 106 |
+
# Combine options
|
| 107 |
+
openenv push --repo-id my-org/my-env --base-image custom-base:latest --private
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
After deployment, your space will be available at:
|
| 111 |
+
`https://huggingface.co/spaces/<repo-id>`
|
| 112 |
+
|
| 113 |
+
The deployed space includes:
|
| 114 |
+
- **Web Interface** at `/web` - Interactive UI for exploring the environment
|
| 115 |
+
- **API Documentation** at `/docs` - Full OpenAPI/Swagger interface
|
| 116 |
+
- **Health Check** at `/health` - Container health monitoring
|
| 117 |
+
- **WebSocket** at `/ws` - Persistent session endpoint for low-latency interactions
|
| 118 |
+
|
| 119 |
+
## Environment Details
|
| 120 |
+
|
| 121 |
+
### Action
|
| 122 |
+
**PokemonredAction**: Contains a single field
|
| 123 |
+
- `message` (str) - The message to echo back
|
| 124 |
+
|
| 125 |
+
### Observation
|
| 126 |
+
**PokemonredObservation**: Contains the echo response and metadata
|
| 127 |
+
- `echoed_message` (str) - The message echoed back
|
| 128 |
+
- `message_length` (int) - Length of the message
|
| 129 |
+
- `reward` (float) - Reward based on message length (length × 0.1)
|
| 130 |
+
- `done` (bool) - Always False for echo environment
|
| 131 |
+
- `metadata` (dict) - Additional info like step count
|
| 132 |
+
|
| 133 |
+
### Reward
|
| 134 |
+
The reward is calculated as: `message_length × 0.1`
|
| 135 |
+
- "Hi" → reward: 0.2
|
| 136 |
+
- "Hello, World!" → reward: 1.3
|
| 137 |
+
- Empty message → reward: 0.0
|
| 138 |
+
|
| 139 |
+
## Advanced Usage
|
| 140 |
+
|
| 141 |
+
### Connecting to an Existing Server
|
| 142 |
+
|
| 143 |
+
If you already have a Pokemonred Env environment server running, you can connect directly:
|
| 144 |
+
|
| 145 |
+
```python
|
| 146 |
+
from pokemonred_env import PokemonredEnv
|
| 147 |
+
|
| 148 |
+
# Connect to existing server
|
| 149 |
+
pokemonred_envenv = PokemonredEnv(base_url="<ENV_HTTP_URL_HERE>")
|
| 150 |
+
|
| 151 |
+
# Use as normal
|
| 152 |
+
result = pokemonred_envenv.reset()
|
| 153 |
+
result = pokemonred_envenv.step(PokemonredAction(message="Hello!"))
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
Note: When connecting to an existing server, `pokemonred_envenv.close()` will NOT stop the server.
|
| 157 |
+
|
| 158 |
+
### Using the Context Manager
|
| 159 |
+
|
| 160 |
+
The client supports context manager usage for automatic connection management:
|
| 161 |
+
|
| 162 |
+
```python
|
| 163 |
+
from pokemonred_env import PokemonredAction, PokemonredEnv
|
| 164 |
+
|
| 165 |
+
# Connect with context manager (auto-connects and closes)
|
| 166 |
+
with PokemonredEnv(base_url="http://localhost:8000") as env:
|
| 167 |
+
result = env.reset()
|
| 168 |
+
print(f"Reset: {result.observation.echoed_message}")
|
| 169 |
+
# Multiple steps with low latency
|
| 170 |
+
for msg in ["Hello", "World", "!"]:
|
| 171 |
+
result = env.step(PokemonredAction(message=msg))
|
| 172 |
+
print(f"Echoed: {result.observation.echoed_message}")
|
| 173 |
+
```
|
| 174 |
+
|
| 175 |
+
The client uses WebSocket connections for:
|
| 176 |
+
- **Lower latency**: No HTTP connection overhead per request
|
| 177 |
+
- **Persistent session**: Server maintains your environment state
|
| 178 |
+
- **Efficient for episodes**: Better for many sequential steps
|
| 179 |
+
|
| 180 |
+
### Concurrent WebSocket Sessions
|
| 181 |
+
|
| 182 |
+
The server supports multiple concurrent WebSocket connections. To enable this,
|
| 183 |
+
modify `server/app.py` to use factory mode:
|
| 184 |
+
|
| 185 |
+
```python
|
| 186 |
+
# In server/app.py - use factory mode for concurrent sessions
|
| 187 |
+
app = create_app(
|
| 188 |
+
PokemonredEnvironment, # Pass class, not instance
|
| 189 |
+
PokemonredAction,
|
| 190 |
+
PokemonredObservation,
|
| 191 |
+
max_concurrent_envs=4, # Allow 4 concurrent sessions
|
| 192 |
+
)
|
| 193 |
+
```
|
| 194 |
+
|
| 195 |
+
Then multiple clients can connect simultaneously:
|
| 196 |
+
|
| 197 |
+
```python
|
| 198 |
+
from pokemonred_env import PokemonredAction, PokemonredEnv
|
| 199 |
+
from concurrent.futures import ThreadPoolExecutor
|
| 200 |
+
|
| 201 |
+
def run_episode(client_id: int):
|
| 202 |
+
with PokemonredEnv(base_url="http://localhost:8000") as env:
|
| 203 |
+
result = env.reset()
|
| 204 |
+
for i in range(10):
|
| 205 |
+
result = env.step(PokemonredAction(message=f"Client {client_id}, step {i}"))
|
| 206 |
+
return client_id, result.observation.message_length
|
| 207 |
+
|
| 208 |
+
# Run 4 episodes concurrently
|
| 209 |
+
with ThreadPoolExecutor(max_workers=4) as executor:
|
| 210 |
+
results = list(executor.map(run_episode, range(4)))
|
| 211 |
+
```
|
| 212 |
+
|
| 213 |
+
## Development & Testing
|
| 214 |
+
|
| 215 |
+
### Direct Environment Testing
|
| 216 |
+
|
| 217 |
+
Test the environment logic directly without starting the HTTP server:
|
| 218 |
+
|
| 219 |
+
```bash
|
| 220 |
+
# From the server directory
|
| 221 |
+
python3 server/pokemonred_env_environment.py
|
| 222 |
+
```
|
| 223 |
+
|
| 224 |
+
This verifies that:
|
| 225 |
+
- Environment resets correctly
|
| 226 |
+
- Step executes actions properly
|
| 227 |
+
- State tracking works
|
| 228 |
+
- Rewards are calculated correctly
|
| 229 |
+
|
| 230 |
+
### Running Locally
|
| 231 |
+
|
| 232 |
+
Run the server locally for development:
|
| 233 |
+
|
| 234 |
+
```bash
|
| 235 |
+
uvicorn server.app:app --reload
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
## Project Structure
|
| 239 |
+
|
| 240 |
+
```
|
| 241 |
+
pokemonred_env/
|
| 242 |
+
├── .dockerignore # Docker build exclusions
|
| 243 |
+
├── __init__.py # Module exports
|
| 244 |
+
├── README.md # This file
|
| 245 |
+
├── openenv.yaml # OpenEnv manifest
|
| 246 |
+
├── pyproject.toml # Project metadata and dependencies
|
| 247 |
+
├── uv.lock # Locked dependencies (generated)
|
| 248 |
+
├── client.py # PokemonredEnv client
|
| 249 |
+
├── models.py # Action and Observation models
|
| 250 |
+
└── server/
|
| 251 |
+
├── __init__.py # Server module exports
|
| 252 |
+
├── pokemonred_env_environment.py # Core environment logic
|
| 253 |
+
├── app.py # FastAPI application (HTTP + WebSocket endpoints)
|
| 254 |
+
└── Dockerfile # Container image definition
|
| 255 |
+
```
|
__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Pokemon Red OpenEnv Environment.
|
| 9 |
+
|
| 10 |
+
A production-ready RL environment for Pokemon Red using PyBoy emulator,
|
| 11 |
+
designed for the OpenEnv Challenge hackathon.
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
from .client import PokemonRedEnv
|
| 15 |
+
from .models import PokemonRedAction, PokemonRedObservation, PokemonRedState
|
| 16 |
+
from .config import PokemonRedConfig
|
| 17 |
+
|
| 18 |
+
__all__ = [
|
| 19 |
+
# Client
|
| 20 |
+
"PokemonRedEnv",
|
| 21 |
+
# Models
|
| 22 |
+
"PokemonRedAction",
|
| 23 |
+
"PokemonRedObservation",
|
| 24 |
+
"PokemonRedState",
|
| 25 |
+
# Config
|
| 26 |
+
"PokemonRedConfig",
|
| 27 |
+
]
|
client.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Pokemon Red Environment Client.
|
| 9 |
+
|
| 10 |
+
This module provides the client for connecting to a Pokemon Red Environment server
|
| 11 |
+
via WebSocket for persistent sessions.
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
from __future__ import annotations
|
| 15 |
+
|
| 16 |
+
from typing import Any, Dict, TYPE_CHECKING
|
| 17 |
+
|
| 18 |
+
from openenv.core.client_types import StepResult
|
| 19 |
+
from openenv.core.env_client import EnvClient
|
| 20 |
+
|
| 21 |
+
from .models import PokemonRedAction, PokemonRedObservation, PokemonRedState
|
| 22 |
+
|
| 23 |
+
if TYPE_CHECKING:
|
| 24 |
+
from openenv.core.containers.runtime import ContainerProvider
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
class PokemonRedEnv(EnvClient[PokemonRedAction, PokemonRedObservation, PokemonRedState]):
|
| 28 |
+
"""
|
| 29 |
+
Client for Pokemon Red Environment.
|
| 30 |
+
|
| 31 |
+
This client maintains a persistent WebSocket connection to the environment
|
| 32 |
+
server, enabling efficient multi-step interactions with lower latency.
|
| 33 |
+
|
| 34 |
+
Example:
|
| 35 |
+
>>> # Connect to a running server
|
| 36 |
+
>>> with PokemonRedEnv(base_url="http://localhost:8000") as client:
|
| 37 |
+
... result = client.reset()
|
| 38 |
+
... print(result.observation.screen_shape)
|
| 39 |
+
...
|
| 40 |
+
... result = client.step(PokemonRedAction(action=4)) # Press A
|
| 41 |
+
... print(result.reward, result.done)
|
| 42 |
+
|
| 43 |
+
Example with Docker:
|
| 44 |
+
>>> # Automatically start container and connect
|
| 45 |
+
>>> client = PokemonRedEnv.from_docker_image("pokemonred-env:latest")
|
| 46 |
+
>>> try:
|
| 47 |
+
... result = client.reset()
|
| 48 |
+
... result = client.step(PokemonRedAction(action=0)) # Press Down
|
| 49 |
+
... finally:
|
| 50 |
+
... client.close()
|
| 51 |
+
|
| 52 |
+
Example from HuggingFace Hub:
|
| 53 |
+
>>> # Connect to hosted environment
|
| 54 |
+
>>> client = PokemonRedEnv.from_hub("openenv/pokemonred")
|
| 55 |
+
>>> with client:
|
| 56 |
+
... result = client.reset()
|
| 57 |
+
... for _ in range(100):
|
| 58 |
+
... action = PokemonRedAction(action=random.randint(0, 6))
|
| 59 |
+
... result = client.step(action)
|
| 60 |
+
"""
|
| 61 |
+
|
| 62 |
+
def _step_payload(self, action: PokemonRedAction) -> Dict[str, Any]:
|
| 63 |
+
"""
|
| 64 |
+
Convert PokemonRedAction to JSON payload for step request.
|
| 65 |
+
|
| 66 |
+
Args:
|
| 67 |
+
action: PokemonRedAction instance.
|
| 68 |
+
|
| 69 |
+
Returns:
|
| 70 |
+
Dictionary representation suitable for JSON encoding.
|
| 71 |
+
"""
|
| 72 |
+
return {"action": action.action}
|
| 73 |
+
|
| 74 |
+
def _parse_result(self, payload: Dict[str, Any]) -> StepResult[PokemonRedObservation]:
|
| 75 |
+
"""
|
| 76 |
+
Parse server response into StepResult[PokemonRedObservation].
|
| 77 |
+
|
| 78 |
+
Args:
|
| 79 |
+
payload: JSON response from server.
|
| 80 |
+
|
| 81 |
+
Returns:
|
| 82 |
+
StepResult with PokemonRedObservation.
|
| 83 |
+
"""
|
| 84 |
+
obs_data = payload.get("observation", {})
|
| 85 |
+
|
| 86 |
+
observation = PokemonRedObservation(
|
| 87 |
+
screen_b64=obs_data.get("screen_b64", ""),
|
| 88 |
+
screen_shape=obs_data.get("screen_shape", [144, 160, 3]),
|
| 89 |
+
health=obs_data.get("health", 0.0),
|
| 90 |
+
level_sum=obs_data.get("level_sum", 0),
|
| 91 |
+
badges=obs_data.get("badges", [0] * 8),
|
| 92 |
+
position=obs_data.get("position", [0, 0, 0]),
|
| 93 |
+
in_battle=obs_data.get("in_battle", False),
|
| 94 |
+
seen_coords_count=obs_data.get("seen_coords_count", 0),
|
| 95 |
+
legal_actions=obs_data.get("legal_actions", list(range(7))),
|
| 96 |
+
done=payload.get("done", False),
|
| 97 |
+
reward=payload.get("reward"),
|
| 98 |
+
metadata=obs_data.get("metadata", {}),
|
| 99 |
+
)
|
| 100 |
+
|
| 101 |
+
return StepResult(
|
| 102 |
+
observation=observation,
|
| 103 |
+
reward=payload.get("reward"),
|
| 104 |
+
done=payload.get("done", False),
|
| 105 |
+
)
|
| 106 |
+
|
| 107 |
+
def _parse_state(self, payload: Dict[str, Any]) -> PokemonRedState:
|
| 108 |
+
"""
|
| 109 |
+
Parse server response into PokemonRedState object.
|
| 110 |
+
|
| 111 |
+
Args:
|
| 112 |
+
payload: JSON response from /state endpoint.
|
| 113 |
+
|
| 114 |
+
Returns:
|
| 115 |
+
PokemonRedState object with environment state information.
|
| 116 |
+
"""
|
| 117 |
+
return PokemonRedState(
|
| 118 |
+
episode_id=payload.get("episode_id"),
|
| 119 |
+
step_count=payload.get("step_count", 0),
|
| 120 |
+
total_reward=payload.get("total_reward", 0.0),
|
| 121 |
+
reset_count=payload.get("reset_count", 0),
|
| 122 |
+
badges_obtained=payload.get("badges_obtained", 0),
|
| 123 |
+
max_level_sum=payload.get("max_level_sum", 0),
|
| 124 |
+
events_triggered=payload.get("events_triggered", 0),
|
| 125 |
+
)
|
config.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
pokemonred_env/config.py
|
| 3 |
+
--------------------------------
|
| 4 |
+
Configuration schema for Pokemon Red environment.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from pydantic import BaseModel, Field
|
| 8 |
+
from typing import Dict, Any
|
| 9 |
+
|
| 10 |
+
class PokemonRedConfig(BaseModel):
|
| 11 |
+
"""
|
| 12 |
+
Configuration for Pokemon Red Environment.
|
| 13 |
+
"""
|
| 14 |
+
# Core settings
|
| 15 |
+
session_path: str = Field("session_pokemon_vla", description="Path to save session data")
|
| 16 |
+
save_final_state: bool = Field(False, description="Save state at end of episode")
|
| 17 |
+
print_rewards: bool = Field(False, description="Print reward details to stdout")
|
| 18 |
+
headless: bool = Field(True, description="Run emulator without window")
|
| 19 |
+
init_state: str = Field("/app/src/envs/pokemon_red/server/init.state", description="Path to initial save state")
|
| 20 |
+
action_freq: int = Field(24, description="Emulator ticks per action")
|
| 21 |
+
max_steps: int = Field(163840, description="Max steps per episode")
|
| 22 |
+
save_video: bool = Field(False, description="Record video of episodes")
|
| 23 |
+
fast_video: bool = Field(True, description="Optimize video recording speed")
|
| 24 |
+
frame_stacks: int = Field(5, description="Number of recent actions to track")
|
| 25 |
+
|
| 26 |
+
# Paths (relative to possible mount points)
|
| 27 |
+
gb_path: str = Field("pokemonred_env/server/PokemonRed.gb", description="Path to ROM file")
|
| 28 |
+
|
| 29 |
+
# Reward Configuration
|
| 30 |
+
reward_scale: float = Field(1.0, description="Global reward scaling factor")
|
| 31 |
+
explore_weight: float = Field(1.0, description="Weight for exploration reward")
|
| 32 |
+
|
| 33 |
+
# Feature Flags
|
| 34 |
+
include_game_text: bool = Field(True, description="Enable text extraction")
|
| 35 |
+
text_detection_threshold: int = Field(10, description="Min chars to consider text active")
|
| 36 |
+
|
| 37 |
+
# Instance ID
|
| 38 |
+
instance_id: str = Field("default", description="Unique ID for this env instance")
|
| 39 |
+
|
| 40 |
+
# Extra options mapping
|
| 41 |
+
extra: Dict[str, Any] = Field(default_factory=dict, description="Additional backend options")
|
models.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Data models for the Pokemon Red OpenEnv Environment.
|
| 9 |
+
|
| 10 |
+
This module defines the Action, Observation, and State types for the Pokemon Red
|
| 11 |
+
Game Boy emulator environment using PyBoy.
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
from __future__ import annotations
|
| 15 |
+
|
| 16 |
+
from typing import Any, Dict, List, Optional
|
| 17 |
+
|
| 18 |
+
from pydantic import Field
|
| 19 |
+
|
| 20 |
+
from openenv.core.env_server.types import Action, Observation, State
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class PokemonRedAction(Action):
|
| 24 |
+
"""
|
| 25 |
+
Action for Pokemon Red environment.
|
| 26 |
+
|
| 27 |
+
Represents a single Game Boy button press.
|
| 28 |
+
|
| 29 |
+
Attributes:
|
| 30 |
+
action: Discrete action index (0-6) mapping to:
|
| 31 |
+
0=Down, 1=Left, 2=Right, 3=Up, 4=A, 5=B, 6=Start
|
| 32 |
+
"""
|
| 33 |
+
|
| 34 |
+
action: int = Field(
|
| 35 |
+
default=0,
|
| 36 |
+
ge=0,
|
| 37 |
+
le=6,
|
| 38 |
+
description="Button index: 0=Down, 1=Left, 2=Right, 3=Up, 4=A, 5=B, 6=Start",
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
class PokemonRedObservation(Observation):
|
| 43 |
+
"""
|
| 44 |
+
Multi-modal observation from Pokemon Red environment.
|
| 45 |
+
|
| 46 |
+
Contains the game screen, player stats, and game state information
|
| 47 |
+
suitable for both vision-based and structured RL agents.
|
| 48 |
+
|
| 49 |
+
Attributes:
|
| 50 |
+
screen_b64: Base64-encoded PNG of the current game frame.
|
| 51 |
+
screen_shape: Shape of the screen array [height, width, channels].
|
| 52 |
+
health: Party HP fraction in range [0, 1].
|
| 53 |
+
level_sum: Sum of all party Pokemon levels.
|
| 54 |
+
badges: 8-element list of badge flags (0 or 1).
|
| 55 |
+
position: Current position as [x, y, map_id].
|
| 56 |
+
in_battle: Whether player is currently in a battle.
|
| 57 |
+
seen_coords_count: Number of unique coordinates visited (exploration metric).
|
| 58 |
+
legal_actions: List of valid action indices.
|
| 59 |
+
"""
|
| 60 |
+
|
| 61 |
+
screen_b64: str = Field(default="", description="Base64-encoded PNG frame")
|
| 62 |
+
screen_shape: List[int] = Field(
|
| 63 |
+
default_factory=lambda: [144, 160, 3], description="Frame dimensions [H,W,C]"
|
| 64 |
+
)
|
| 65 |
+
health: float = Field(default=0.0, ge=0.0, le=1.0, description="Party HP fraction")
|
| 66 |
+
level_sum: int = Field(default=0, ge=0, description="Sum of party Pokemon levels")
|
| 67 |
+
badges: List[int] = Field(
|
| 68 |
+
default_factory=lambda: [0] * 8, description="8-element badge flags"
|
| 69 |
+
)
|
| 70 |
+
position: List[int] = Field(
|
| 71 |
+
default_factory=lambda: [0, 0, 0], description="Player position [x, y, map_id]"
|
| 72 |
+
)
|
| 73 |
+
in_battle: bool = Field(default=False, description="Whether in battle")
|
| 74 |
+
seen_coords_count: int = Field(
|
| 75 |
+
default=0, description="Unique coordinates visited (exploration)"
|
| 76 |
+
)
|
| 77 |
+
legal_actions: List[int] = Field(
|
| 78 |
+
default_factory=lambda: list(range(7)), description="Valid action indices"
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
class PokemonRedState(State):
|
| 83 |
+
"""
|
| 84 |
+
State for Pokemon Red environment.
|
| 85 |
+
|
| 86 |
+
Tracks episode progress and game state for the server.
|
| 87 |
+
|
| 88 |
+
Attributes:
|
| 89 |
+
total_reward: Cumulative reward for current episode.
|
| 90 |
+
reset_count: Number of times environment has been reset.
|
| 91 |
+
badges_obtained: Number of gym badges obtained (0-8).
|
| 92 |
+
max_level_sum: Maximum level sum achieved this episode.
|
| 93 |
+
events_triggered: Count of game event flags triggered.
|
| 94 |
+
"""
|
| 95 |
+
|
| 96 |
+
total_reward: float = Field(default=0.0, description="Cumulative episode reward")
|
| 97 |
+
reset_count: int = Field(default=0, description="Number of resets")
|
| 98 |
+
badges_obtained: int = Field(default=0, ge=0, le=8, description="Badges count")
|
| 99 |
+
max_level_sum: int = Field(default=0, description="Max level sum achieved")
|
| 100 |
+
events_triggered: int = Field(default=0, description="Event flags triggered")
|
openenv.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
spec_version: 1
|
| 2 |
+
name: pokemonred_env
|
| 3 |
+
type: space
|
| 4 |
+
runtime: fastapi
|
| 5 |
+
app: server.app:app
|
| 6 |
+
port: 8000
|
| 7 |
+
|
openenv_pokemonred_env.egg-info/PKG-INFO
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: openenv-pokemonred_env
|
| 3 |
+
Version: 0.1.0
|
| 4 |
+
Summary: Pokemonred Env environment for OpenEnv
|
| 5 |
+
Requires-Python: >=3.10
|
| 6 |
+
Requires-Dist: einops>=0.6.0
|
| 7 |
+
Requires-Dist: fastapi>=0.115.0
|
| 8 |
+
Requires-Dist: numpy>=1.21.0
|
| 9 |
+
Requires-Dist: openenv>=0.1.0
|
| 10 |
+
Requires-Dist: openenv-core@ git+https://github.com/meta-pytorch/OpenEnv.git
|
| 11 |
+
Requires-Dist: pillow>=9.0.0
|
| 12 |
+
Requires-Dist: psutil>=5.9.0
|
| 13 |
+
Requires-Dist: pyboy>=2.0.0
|
| 14 |
+
Requires-Dist: pydantic>=2.0.0
|
| 15 |
+
Requires-Dist: uvicorn>=0.24.0
|
| 16 |
+
Provides-Extra: dev
|
| 17 |
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
| 18 |
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
openenv_pokemonred_env.egg-info/SOURCES.txt
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
README.md
|
| 2 |
+
__init__.py
|
| 3 |
+
client.py
|
| 4 |
+
config.py
|
| 5 |
+
models.py
|
| 6 |
+
pyproject.toml
|
| 7 |
+
./__init__.py
|
| 8 |
+
./client.py
|
| 9 |
+
./config.py
|
| 10 |
+
./models.py
|
| 11 |
+
openenv_pokemonred_env.egg-info/PKG-INFO
|
| 12 |
+
openenv_pokemonred_env.egg-info/SOURCES.txt
|
| 13 |
+
openenv_pokemonred_env.egg-info/dependency_links.txt
|
| 14 |
+
openenv_pokemonred_env.egg-info/entry_points.txt
|
| 15 |
+
openenv_pokemonred_env.egg-info/requires.txt
|
| 16 |
+
openenv_pokemonred_env.egg-info/top_level.txt
|
| 17 |
+
rewards/__init__.py
|
| 18 |
+
rewards/badge.py
|
| 19 |
+
rewards/base.py
|
| 20 |
+
rewards/event.py
|
| 21 |
+
rewards/exploration.py
|
| 22 |
+
rewards/level.py
|
| 23 |
+
rewards/manager.py
|
| 24 |
+
server/__init__.py
|
| 25 |
+
server/app.py
|
| 26 |
+
server/global_map.py
|
| 27 |
+
server/pokemonred_env_environment.py
|
| 28 |
+
wrappers/__init__.py
|
| 29 |
+
wrappers/green_agent.py
|
openenv_pokemonred_env.egg-info/dependency_links.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
openenv_pokemonred_env.egg-info/entry_points.txt
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[console_scripts]
|
| 2 |
+
server = pokemonred_env.server.app:main
|
openenv_pokemonred_env.egg-info/requires.txt
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
einops>=0.6.0
|
| 2 |
+
fastapi>=0.115.0
|
| 3 |
+
numpy>=1.21.0
|
| 4 |
+
openenv>=0.1.0
|
| 5 |
+
openenv-core@ git+https://github.com/meta-pytorch/OpenEnv.git
|
| 6 |
+
pillow>=9.0.0
|
| 7 |
+
psutil>=5.9.0
|
| 8 |
+
pyboy>=2.0.0
|
| 9 |
+
pydantic>=2.0.0
|
| 10 |
+
uvicorn>=0.24.0
|
| 11 |
+
|
| 12 |
+
[dev]
|
| 13 |
+
pytest>=8.0.0
|
| 14 |
+
pytest-cov>=4.0.0
|
openenv_pokemonred_env.egg-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pokemonred_env
|
pyproject.toml
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
[build-system]
|
| 8 |
+
requires = ["setuptools>=45", "wheel"]
|
| 9 |
+
build-backend = "setuptools.build_meta"
|
| 10 |
+
|
| 11 |
+
[project]
|
| 12 |
+
name = "openenv-pokemonred_env"
|
| 13 |
+
version = "0.1.0"
|
| 14 |
+
description = "Pokemonred Env environment for OpenEnv"
|
| 15 |
+
requires-python = ">=3.10"
|
| 16 |
+
dependencies = [
|
| 17 |
+
"einops>=0.6.0",
|
| 18 |
+
"fastapi>=0.115.0",
|
| 19 |
+
"numpy>=1.21.0",
|
| 20 |
+
# OpenEnv runtime - add both for validation compatibility
|
| 21 |
+
"openenv>=0.1.0", # PyPI package (for validation check)
|
| 22 |
+
"openenv-core @ git+https://github.com/meta-pytorch/OpenEnv.git", # Latest from GitHub
|
| 23 |
+
# Environment-specific dependencies
|
| 24 |
+
# Add all dependencies needed for your environment here
|
| 25 |
+
# Examples:
|
| 26 |
+
# "numpy>=1.19.0",
|
| 27 |
+
# "torch>=2.0.0",
|
| 28 |
+
# "gymnasium>=0.29.0",
|
| 29 |
+
# "openspiel>=1.0.0",
|
| 30 |
+
# "smolagents>=1.22.0,<2",
|
| 31 |
+
"pillow>=9.0.0",
|
| 32 |
+
"psutil>=5.9.0",
|
| 33 |
+
"pyboy>=2.0.0",
|
| 34 |
+
"pydantic>=2.0.0",
|
| 35 |
+
"uvicorn>=0.24.0",
|
| 36 |
+
]
|
| 37 |
+
|
| 38 |
+
[project.optional-dependencies]
|
| 39 |
+
dev = [
|
| 40 |
+
"pytest>=8.0.0",
|
| 41 |
+
"pytest-cov>=4.0.0",
|
| 42 |
+
]
|
| 43 |
+
|
| 44 |
+
[project.scripts]
|
| 45 |
+
# Server entry point - enables running via: uv run --project . server
|
| 46 |
+
# or: python -m pokemonred_env.server.app
|
| 47 |
+
server = "pokemonred_env.server.app:main"
|
| 48 |
+
|
| 49 |
+
[tool.setuptools]
|
| 50 |
+
include-package-data = true
|
| 51 |
+
packages = ["pokemonred_env", "pokemonred_env.server", "pokemonred_env.rewards", "pokemonred_env.wrappers"]
|
| 52 |
+
package-dir = { "pokemonred_env" = ".", "pokemonred_env.server" = "server", "pokemonred_env.rewards" = "rewards", "pokemonred_env.wrappers" = "wrappers" }
|
| 53 |
+
|
rewards/__init__.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Modular reward system for Pokemon Red OpenEnv."""
|
| 5 |
+
|
| 6 |
+
from .base import BaseRewardComponent
|
| 7 |
+
from .manager import RewardManager
|
| 8 |
+
from .exploration import ExplorationReward
|
| 9 |
+
from .badge import BadgeReward
|
| 10 |
+
from .level import LevelUpReward
|
| 11 |
+
from .event import EventReward
|
| 12 |
+
|
| 13 |
+
__all__ = [
|
| 14 |
+
"BaseRewardComponent",
|
| 15 |
+
"RewardManager",
|
| 16 |
+
"ExplorationReward",
|
| 17 |
+
"BadgeReward",
|
| 18 |
+
"LevelUpReward",
|
| 19 |
+
"EventReward",
|
| 20 |
+
]
|
rewards/badge.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Badge reward component for Pokemon Red."""
|
| 5 |
+
|
| 6 |
+
from typing import Any, Dict
|
| 7 |
+
|
| 8 |
+
from .base import BaseRewardComponent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class BadgeReward(BaseRewardComponent):
|
| 12 |
+
"""
|
| 13 |
+
Rewards obtaining gym badges.
|
| 14 |
+
|
| 15 |
+
Provides significant reward for each gym badge obtained,
|
| 16 |
+
as badges represent major game progression milestones.
|
| 17 |
+
|
| 18 |
+
Attributes:
|
| 19 |
+
weight: Reward per badge (default 5.0).
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
def __init__(self, weight: float = 5.0, enabled: bool = True):
|
| 23 |
+
super().__init__(name="badge", weight=weight, enabled=enabled)
|
| 24 |
+
|
| 25 |
+
def calculate(
|
| 26 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 27 |
+
) -> float:
|
| 28 |
+
"""Calculate reward for badges obtained."""
|
| 29 |
+
current_badges = state.get("badge_count", 0)
|
| 30 |
+
previous_badges = prev_state.get("badge_count", 0)
|
| 31 |
+
new_badges = current_badges - previous_badges
|
| 32 |
+
return max(0.0, float(new_badges))
|
rewards/base.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Base class for modular reward components."""
|
| 5 |
+
|
| 6 |
+
from abc import ABC, abstractmethod
|
| 7 |
+
from typing import Any, Dict
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class BaseRewardComponent(ABC):
|
| 11 |
+
"""
|
| 12 |
+
Abstract base class for reward components.
|
| 13 |
+
|
| 14 |
+
Each reward component calculates a specific aspect of the reward signal
|
| 15 |
+
(exploration, badges, levels, etc.) and can be enabled/weighted via config.
|
| 16 |
+
|
| 17 |
+
Attributes:
|
| 18 |
+
name: Unique identifier for this reward component.
|
| 19 |
+
weight: Scaling factor applied to calculated reward.
|
| 20 |
+
enabled: Whether this component is active.
|
| 21 |
+
|
| 22 |
+
Example:
|
| 23 |
+
>>> class MyReward(BaseRewardComponent):
|
| 24 |
+
... def calculate(self, state, prev_state):
|
| 25 |
+
... return state["score"] - prev_state.get("score", 0)
|
| 26 |
+
>>>
|
| 27 |
+
>>> reward = MyReward(weight=2.0)
|
| 28 |
+
>>> reward.calculate({"score": 100}, {"score": 50})
|
| 29 |
+
100.0 # (100 - 50) * 2.0
|
| 30 |
+
"""
|
| 31 |
+
|
| 32 |
+
def __init__(self, name: str, weight: float = 1.0, enabled: bool = True):
|
| 33 |
+
"""
|
| 34 |
+
Initialize reward component.
|
| 35 |
+
|
| 36 |
+
Args:
|
| 37 |
+
name: Unique identifier for this component.
|
| 38 |
+
weight: Scaling factor for reward (default 1.0).
|
| 39 |
+
enabled: Whether component is active (default True).
|
| 40 |
+
"""
|
| 41 |
+
self.name = name
|
| 42 |
+
self.weight = weight
|
| 43 |
+
self.enabled = enabled
|
| 44 |
+
self._cumulative = 0.0
|
| 45 |
+
|
| 46 |
+
@abstractmethod
|
| 47 |
+
def calculate(
|
| 48 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 49 |
+
) -> float:
|
| 50 |
+
"""
|
| 51 |
+
Calculate reward for this component.
|
| 52 |
+
|
| 53 |
+
Args:
|
| 54 |
+
state: Current game state dictionary.
|
| 55 |
+
prev_state: Previous game state dictionary.
|
| 56 |
+
|
| 57 |
+
Returns:
|
| 58 |
+
Unweighted reward value for this component.
|
| 59 |
+
"""
|
| 60 |
+
pass
|
| 61 |
+
|
| 62 |
+
def get_reward(
|
| 63 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 64 |
+
) -> float:
|
| 65 |
+
"""
|
| 66 |
+
Get weighted reward if enabled.
|
| 67 |
+
|
| 68 |
+
Args:
|
| 69 |
+
state: Current game state.
|
| 70 |
+
prev_state: Previous game state.
|
| 71 |
+
|
| 72 |
+
Returns:
|
| 73 |
+
Weighted reward if enabled, 0.0 otherwise.
|
| 74 |
+
"""
|
| 75 |
+
if not self.enabled:
|
| 76 |
+
return 0.0
|
| 77 |
+
reward = self.calculate(state, prev_state) * self.weight
|
| 78 |
+
self._cumulative += reward
|
| 79 |
+
return reward
|
| 80 |
+
|
| 81 |
+
def reset(self) -> None:
|
| 82 |
+
"""Reset component state for new episode."""
|
| 83 |
+
self._cumulative = 0.0
|
| 84 |
+
|
| 85 |
+
@property
|
| 86 |
+
def cumulative_reward(self) -> float:
|
| 87 |
+
"""Total reward from this component in current episode."""
|
| 88 |
+
return self._cumulative
|
rewards/event.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Event reward component for Pokemon Red."""
|
| 5 |
+
|
| 6 |
+
from typing import Any, Dict
|
| 7 |
+
|
| 8 |
+
from .base import BaseRewardComponent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class EventReward(BaseRewardComponent):
|
| 12 |
+
"""
|
| 13 |
+
Rewards triggering in-game event flags.
|
| 14 |
+
|
| 15 |
+
Pokemon Red uses event flags to track story progression,
|
| 16 |
+
item collection, NPC interactions, etc. This component
|
| 17 |
+
rewards activating new event flags.
|
| 18 |
+
|
| 19 |
+
Attributes:
|
| 20 |
+
weight: Reward per event triggered (default 0.1).
|
| 21 |
+
"""
|
| 22 |
+
|
| 23 |
+
def __init__(self, weight: float = 0.1, enabled: bool = True):
|
| 24 |
+
super().__init__(name="event", weight=weight, enabled=enabled)
|
| 25 |
+
|
| 26 |
+
def calculate(
|
| 27 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 28 |
+
) -> float:
|
| 29 |
+
"""Calculate reward for new events triggered."""
|
| 30 |
+
current_events = state.get("event_count", 0)
|
| 31 |
+
previous_events = prev_state.get("event_count", 0)
|
| 32 |
+
new_events = current_events - previous_events
|
| 33 |
+
return max(0.0, float(new_events))
|
rewards/exploration.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Exploration reward component for Pokemon Red."""
|
| 5 |
+
|
| 6 |
+
from typing import Any, Dict
|
| 7 |
+
|
| 8 |
+
from .base import BaseRewardComponent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class ExplorationReward(BaseRewardComponent):
|
| 12 |
+
"""
|
| 13 |
+
Rewards visiting new map coordinates.
|
| 14 |
+
|
| 15 |
+
Encourages the agent to explore the game world by providing
|
| 16 |
+
reward for each new unique (x, y, map_id) coordinate visited.
|
| 17 |
+
|
| 18 |
+
Attributes:
|
| 19 |
+
weight: Reward per new coordinate (default 0.02).
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
def __init__(self, weight: float = 0.02, enabled: bool = True):
|
| 23 |
+
super().__init__(name="exploration", weight=weight, enabled=enabled)
|
| 24 |
+
|
| 25 |
+
def calculate(
|
| 26 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 27 |
+
) -> float:
|
| 28 |
+
"""Calculate reward for new coordinates visited."""
|
| 29 |
+
current_count = state.get("seen_coords_count", 0)
|
| 30 |
+
previous_count = prev_state.get("seen_coords_count", 0)
|
| 31 |
+
new_coords = current_count - previous_count
|
| 32 |
+
return max(0.0, float(new_coords))
|
rewards/level.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Level up reward component for Pokemon Red."""
|
| 5 |
+
|
| 6 |
+
from typing import Any, Dict
|
| 7 |
+
|
| 8 |
+
from .base import BaseRewardComponent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class LevelUpReward(BaseRewardComponent):
|
| 12 |
+
"""
|
| 13 |
+
Rewards party Pokemon level increases.
|
| 14 |
+
|
| 15 |
+
Tracks the sum of all party Pokemon levels and provides
|
| 16 |
+
reward when the total increases (from battles/training).
|
| 17 |
+
|
| 18 |
+
Attributes:
|
| 19 |
+
weight: Reward per level gained (default 1.0).
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
def __init__(self, weight: float = 1.0, enabled: bool = True):
|
| 23 |
+
super().__init__(name="level", weight=weight, enabled=enabled)
|
| 24 |
+
|
| 25 |
+
def calculate(
|
| 26 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 27 |
+
) -> float:
|
| 28 |
+
"""Calculate reward for level increases."""
|
| 29 |
+
current_levels = state.get("level_sum", 0)
|
| 30 |
+
previous_levels = prev_state.get("level_sum", 0)
|
| 31 |
+
level_gain = current_levels - previous_levels
|
| 32 |
+
return max(0.0, float(level_gain))
|
rewards/manager.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Reward manager for aggregating modular reward components."""
|
| 5 |
+
|
| 6 |
+
from typing import Any, Dict, List, Optional, Type
|
| 7 |
+
|
| 8 |
+
from .base import BaseRewardComponent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class RewardManager:
|
| 12 |
+
"""
|
| 13 |
+
Manages multiple reward components and aggregates their outputs.
|
| 14 |
+
|
| 15 |
+
Supports dynamic registration, per-component weighting, and
|
| 16 |
+
detailed reward breakdowns for debugging/analysis.
|
| 17 |
+
|
| 18 |
+
Attributes:
|
| 19 |
+
components: List of registered reward components.
|
| 20 |
+
global_scale: Global scaling factor applied to total reward.
|
| 21 |
+
|
| 22 |
+
Example:
|
| 23 |
+
>>> manager = RewardManager(global_scale=1.0)
|
| 24 |
+
>>> manager.register(ExplorationReward(weight=2.0))
|
| 25 |
+
>>> manager.register(BadgeReward(weight=5.0))
|
| 26 |
+
>>>
|
| 27 |
+
>>> reward = manager.calculate(current_state, prev_state)
|
| 28 |
+
>>> breakdown = manager.get_breakdown()
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
+
def __init__(self, global_scale: float = 1.0):
|
| 32 |
+
"""
|
| 33 |
+
Initialize reward manager.
|
| 34 |
+
|
| 35 |
+
Args:
|
| 36 |
+
global_scale: Global scaling factor for total reward.
|
| 37 |
+
"""
|
| 38 |
+
self.components: List[BaseRewardComponent] = []
|
| 39 |
+
self.global_scale = global_scale
|
| 40 |
+
self._last_breakdown: Dict[str, float] = {}
|
| 41 |
+
|
| 42 |
+
def register(self, component: BaseRewardComponent) -> "RewardManager":
|
| 43 |
+
"""
|
| 44 |
+
Register a reward component.
|
| 45 |
+
|
| 46 |
+
Args:
|
| 47 |
+
component: Reward component to register.
|
| 48 |
+
|
| 49 |
+
Returns:
|
| 50 |
+
Self for method chaining.
|
| 51 |
+
"""
|
| 52 |
+
self.components.append(component)
|
| 53 |
+
return self
|
| 54 |
+
|
| 55 |
+
def register_defaults(self, config: Optional[Dict[str, Any]] = None) -> "RewardManager":
|
| 56 |
+
"""
|
| 57 |
+
Register default reward components with optional config.
|
| 58 |
+
|
| 59 |
+
Args:
|
| 60 |
+
config: Optional config dict with component weights.
|
| 61 |
+
|
| 62 |
+
Returns:
|
| 63 |
+
Self for method chaining.
|
| 64 |
+
"""
|
| 65 |
+
from .exploration import ExplorationReward
|
| 66 |
+
from .badge import BadgeReward
|
| 67 |
+
from .level import LevelUpReward
|
| 68 |
+
from .event import EventReward
|
| 69 |
+
|
| 70 |
+
config = config or {}
|
| 71 |
+
|
| 72 |
+
self.register(ExplorationReward(
|
| 73 |
+
weight=config.get("exploration_weight", 0.02)
|
| 74 |
+
))
|
| 75 |
+
self.register(BadgeReward(
|
| 76 |
+
weight=config.get("badge_weight", 5.0)
|
| 77 |
+
))
|
| 78 |
+
self.register(LevelUpReward(
|
| 79 |
+
weight=config.get("level_weight", 1.0)
|
| 80 |
+
))
|
| 81 |
+
self.register(EventReward(
|
| 82 |
+
weight=config.get("event_weight", 0.1)
|
| 83 |
+
))
|
| 84 |
+
|
| 85 |
+
return self
|
| 86 |
+
|
| 87 |
+
def calculate(
|
| 88 |
+
self, state: Dict[str, Any], prev_state: Dict[str, Any]
|
| 89 |
+
) -> float:
|
| 90 |
+
"""
|
| 91 |
+
Calculate total reward from all components.
|
| 92 |
+
|
| 93 |
+
Args:
|
| 94 |
+
state: Current game state.
|
| 95 |
+
prev_state: Previous game state.
|
| 96 |
+
|
| 97 |
+
Returns:
|
| 98 |
+
Total weighted and scaled reward.
|
| 99 |
+
"""
|
| 100 |
+
self._last_breakdown = {}
|
| 101 |
+
total = 0.0
|
| 102 |
+
|
| 103 |
+
for component in self.components:
|
| 104 |
+
reward = component.get_reward(state, prev_state)
|
| 105 |
+
self._last_breakdown[component.name] = reward
|
| 106 |
+
total += reward
|
| 107 |
+
|
| 108 |
+
return total * self.global_scale
|
| 109 |
+
|
| 110 |
+
def reset(self) -> None:
|
| 111 |
+
"""Reset all components for new episode."""
|
| 112 |
+
self._last_breakdown = {}
|
| 113 |
+
for component in self.components:
|
| 114 |
+
component.reset()
|
| 115 |
+
|
| 116 |
+
def get_breakdown(self) -> Dict[str, float]:
|
| 117 |
+
"""Get reward breakdown by component from last calculation."""
|
| 118 |
+
return self._last_breakdown.copy()
|
| 119 |
+
|
| 120 |
+
def get_cumulative_breakdown(self) -> Dict[str, float]:
|
| 121 |
+
"""Get cumulative rewards by component for current episode."""
|
| 122 |
+
return {
|
| 123 |
+
comp.name: comp.cumulative_reward
|
| 124 |
+
for comp in self.components
|
| 125 |
+
}
|
server/PokemonRed.gb
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5ca7ba01642a3b27b0cc0b5349b52792795b62d3ed977e98a09390659af96b7b
|
| 3 |
+
size 1048576
|
server/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""Pokemon Red environment server components."""
|
| 8 |
+
|
| 9 |
+
from .pokemonred_env_environment import PokemonRedEnvironment
|
| 10 |
+
|
| 11 |
+
__all__ = ["PokemonRedEnvironment"]
|
server/app.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
FastAPI application for the Pokemon Red Environment.
|
| 9 |
+
|
| 10 |
+
This module creates an HTTP server that exposes the PokemonRedEnvironment
|
| 11 |
+
over HTTP and WebSocket endpoints, compatible with EnvClient.
|
| 12 |
+
|
| 13 |
+
Endpoints:
|
| 14 |
+
- POST /reset: Reset the environment
|
| 15 |
+
- POST /step: Execute an action
|
| 16 |
+
- GET /state: Get current environment state
|
| 17 |
+
- GET /schema: Get action/observation schemas
|
| 18 |
+
- WS /ws: WebSocket endpoint for persistent sessions
|
| 19 |
+
|
| 20 |
+
Usage:
|
| 21 |
+
# Development (with auto-reload):
|
| 22 |
+
uvicorn server.app:app --reload --host 0.0.0.0 --port 8000
|
| 23 |
+
|
| 24 |
+
# Production:
|
| 25 |
+
uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4
|
| 26 |
+
|
| 27 |
+
Environment variables:
|
| 28 |
+
POKEMON_HEADLESS: Run emulator without display (default: "true")
|
| 29 |
+
POKEMON_ACTION_FREQ: Emulator ticks per action (default: "24")
|
| 30 |
+
POKEMON_ROM_PATH: Path to Pokemon Red ROM (default: "/app/env/server/PokemonRed.gb")
|
| 31 |
+
POKEMON_INIT_STATE: Path to initial save state (default: "/app/env/server/init.state")
|
| 32 |
+
POKEMON_MAX_STEPS: Maximum steps per episode (default: "163840")
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
import os
|
| 36 |
+
|
| 37 |
+
from openenv.core.env_server import create_app
|
| 38 |
+
|
| 39 |
+
# Support both package imports (when used as package) and direct imports (Docker/standalone)
|
| 40 |
+
# Try relative imports first (package mode), fall back to absolute (Docker/standalone mode)
|
| 41 |
+
try:
|
| 42 |
+
from ..models import PokemonRedAction, PokemonRedObservation
|
| 43 |
+
from ..config import PokemonRedConfig
|
| 44 |
+
from .pokemonred_env_environment import PokemonRedEnvironment
|
| 45 |
+
except ImportError:
|
| 46 |
+
# Fallback for standalone loading (Docker, openenv validate, etc.)
|
| 47 |
+
from models import PokemonRedAction, PokemonRedObservation
|
| 48 |
+
from config import PokemonRedConfig
|
| 49 |
+
from server.pokemonred_env_environment import PokemonRedEnvironment
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def create_pokemon_environment():
|
| 53 |
+
"""
|
| 54 |
+
Factory function that creates PokemonRedEnvironment with config from env vars.
|
| 55 |
+
|
| 56 |
+
This enables WebSocket session support where each client gets their own
|
| 57 |
+
environment instance with isolated state.
|
| 58 |
+
"""
|
| 59 |
+
config = PokemonRedConfig(
|
| 60 |
+
headless=os.getenv("POKEMON_HEADLESS", "true").lower() == "true",
|
| 61 |
+
action_freq=int(os.getenv("POKEMON_ACTION_FREQ", "24")),
|
| 62 |
+
gb_path=os.getenv("POKEMON_ROM_PATH", "/app/env/server/PokemonRed.gb"),
|
| 63 |
+
init_state=os.getenv("POKEMON_INIT_STATE", "/app/env/server/init.state"),
|
| 64 |
+
max_steps=int(os.getenv("POKEMON_MAX_STEPS", "163840")),
|
| 65 |
+
session_path=os.getenv("POKEMON_SESSION_PATH", "/tmp/pokemon_sessions"),
|
| 66 |
+
)
|
| 67 |
+
return PokemonRedEnvironment(config)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
# Create the FastAPI app with web interface and README integration
|
| 71 |
+
# Pass the factory function for WebSocket session support
|
| 72 |
+
app = create_app(
|
| 73 |
+
create_pokemon_environment,
|
| 74 |
+
PokemonRedAction,
|
| 75 |
+
PokemonRedObservation,
|
| 76 |
+
env_name="pokemonred",
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def main(host: str = "0.0.0.0", port: int = 8000):
|
| 81 |
+
"""
|
| 82 |
+
Entry point for direct execution.
|
| 83 |
+
|
| 84 |
+
This function is required by openenv validate for uv_run and python_module
|
| 85 |
+
deployment modes.
|
| 86 |
+
|
| 87 |
+
Args:
|
| 88 |
+
host: Host address to bind to (default: "0.0.0.0")
|
| 89 |
+
port: Port number to listen on (default: 8000)
|
| 90 |
+
"""
|
| 91 |
+
import uvicorn
|
| 92 |
+
uvicorn.run(app, host=host, port=port)
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
if __name__ == "__main__":
|
| 96 |
+
import argparse
|
| 97 |
+
|
| 98 |
+
parser = argparse.ArgumentParser(description="Pokemon Red OpenEnv Server")
|
| 99 |
+
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind")
|
| 100 |
+
parser.add_argument("--port", type=int, default=8000, help="Port to listen on")
|
| 101 |
+
args = parser.parse_args()
|
| 102 |
+
# Call main() - openenv validate checks for literal 'main()' string
|
| 103 |
+
main()
|
server/events.json
ADDED
|
@@ -0,0 +1,2560 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"0xD747-0": "Followed Oak Into Lab",
|
| 3 |
+
"0xD747-1": "Event 001",
|
| 4 |
+
"0xD747-2": "002",
|
| 5 |
+
"0xD747-3": "Hall Of Fame Dex Rating",
|
| 6 |
+
"0xD747-4": "004",
|
| 7 |
+
"0xD747-5": "005",
|
| 8 |
+
"0xD747-6": "Pallet After Getting Pokeballs",
|
| 9 |
+
"0xD747-7": "007",
|
| 10 |
+
"0xD748-0": "008",
|
| 11 |
+
"0xD748-1": "009",
|
| 12 |
+
"0xD748-2": "00A",
|
| 13 |
+
"0xD748-3": "00B",
|
| 14 |
+
"0xD748-4": "00C",
|
| 15 |
+
"0xD748-5": "00D",
|
| 16 |
+
"0xD748-6": "00E",
|
| 17 |
+
"0xD748-7": "00F",
|
| 18 |
+
"0xD749-0": "010",
|
| 19 |
+
"0xD749-1": "011",
|
| 20 |
+
"0xD749-2": "012",
|
| 21 |
+
"0xD749-3": "013",
|
| 22 |
+
"0xD749-4": "014",
|
| 23 |
+
"0xD749-5": "015",
|
| 24 |
+
"0xD749-6": "016",
|
| 25 |
+
"0xD749-7": "017",
|
| 26 |
+
"0xD74A-0": "Got Town Map",
|
| 27 |
+
"0xD74A-1": "Entered Blues House",
|
| 28 |
+
"0xD74A-2": "Daisy Walking",
|
| 29 |
+
"0xD74A-3": "01B",
|
| 30 |
+
"0xD74A-4": "01C",
|
| 31 |
+
"0xD74A-5": "01D",
|
| 32 |
+
"0xD74A-6": "01E",
|
| 33 |
+
"0xD74A-7": "01F",
|
| 34 |
+
"0xD74B-0": "Followed Oak Into Lab 2",
|
| 35 |
+
"0xD74B-1": "Oak Asked To Choose Mon",
|
| 36 |
+
"0xD74B-2": "Got Starter",
|
| 37 |
+
"0xD74B-3": "Battled Rival In Oaks Lab",
|
| 38 |
+
"0xD74B-4": "Got Pokeballs From Oak",
|
| 39 |
+
"0xD74B-5": "Got Pokedex",
|
| 40 |
+
"0xD74B-6": "Pallet After Getting Pokeballs 2",
|
| 41 |
+
"0xD74B-7": "Oak Appeared In Pallet",
|
| 42 |
+
"0xD74C-0": "Viridian Gym Open",
|
| 43 |
+
"0xD74C-1": "Got Tm42",
|
| 44 |
+
"0xD74C-2": "02A",
|
| 45 |
+
"0xD74C-3": "02B",
|
| 46 |
+
"0xD74C-4": "02C",
|
| 47 |
+
"0xD74C-5": "02D",
|
| 48 |
+
"0xD74C-6": "02E",
|
| 49 |
+
"0xD74C-7": "02F",
|
| 50 |
+
"0xD74D-0": "030",
|
| 51 |
+
"0xD74D-1": "031",
|
| 52 |
+
"0xD74D-2": "032",
|
| 53 |
+
"0xD74D-3": "033",
|
| 54 |
+
"0xD74D-4": "034",
|
| 55 |
+
"0xD74D-5": "035",
|
| 56 |
+
"0xD74D-6": "036",
|
| 57 |
+
"0xD74D-7": "037",
|
| 58 |
+
"0xD74E-0": "Oak Got Parcel",
|
| 59 |
+
"0xD74E-1": "Got Oaks Parcel",
|
| 60 |
+
"0xD74E-2": "03A",
|
| 61 |
+
"0xD74E-3": "03B",
|
| 62 |
+
"0xD74E-4": "03C",
|
| 63 |
+
"0xD74E-5": "03D",
|
| 64 |
+
"0xD74E-6": "03E",
|
| 65 |
+
"0xD74E-7": "03F",
|
| 66 |
+
"0xD74F-0": "040",
|
| 67 |
+
"0xD74F-1": "041",
|
| 68 |
+
"0xD74F-2": "042",
|
| 69 |
+
"0xD74F-3": "043",
|
| 70 |
+
"0xD74F-4": "044",
|
| 71 |
+
"0xD74F-5": "045",
|
| 72 |
+
"0xD74F-6": "046",
|
| 73 |
+
"0xD74F-7": "047",
|
| 74 |
+
"0xD750-0": "048",
|
| 75 |
+
"0xD750-1": "049",
|
| 76 |
+
"0xD750-2": "04A",
|
| 77 |
+
"0xD750-3": "04B",
|
| 78 |
+
"0xD750-4": "04C",
|
| 79 |
+
"0xD750-5": "04D",
|
| 80 |
+
"0xD750-6": "04E",
|
| 81 |
+
"0xD750-7": "04F",
|
| 82 |
+
"0xD751-0": "Got Tm27",
|
| 83 |
+
"0xD751-1": "Beat Viridian Gym Giovanni",
|
| 84 |
+
"0xD751-2": "Beat Viridian Gym Trainer 0",
|
| 85 |
+
"0xD751-3": "Beat Viridian Gym Trainer 1",
|
| 86 |
+
"0xD751-4": "Beat Viridian Gym Trainer 2",
|
| 87 |
+
"0xD751-5": "Beat Viridian Gym Trainer 3",
|
| 88 |
+
"0xD751-6": "Beat Viridian Gym Trainer 4",
|
| 89 |
+
"0xD751-7": "Beat Viridian Gym Trainer 5",
|
| 90 |
+
"0xD752-0": "Beat Viridian Gym Trainer 6",
|
| 91 |
+
"0xD752-1": "Beat Viridian Gym Trainer 7",
|
| 92 |
+
"0xD752-2": "05A",
|
| 93 |
+
"0xD752-3": "05B",
|
| 94 |
+
"0xD752-4": "05C",
|
| 95 |
+
"0xD752-5": "05D",
|
| 96 |
+
"0xD752-6": "05E",
|
| 97 |
+
"0xD752-7": "05F",
|
| 98 |
+
"0xD753-0": "060",
|
| 99 |
+
"0xD753-1": "061",
|
| 100 |
+
"0xD753-2": "062",
|
| 101 |
+
"0xD753-3": "063",
|
| 102 |
+
"0xD753-4": "064",
|
| 103 |
+
"0xD753-5": "065",
|
| 104 |
+
"0xD753-6": "066",
|
| 105 |
+
"0xD753-7": "067",
|
| 106 |
+
"0xD754-0": "Bought Museum Ticket",
|
| 107 |
+
"0xD754-1": "Got Old Amber",
|
| 108 |
+
"0xD754-2": "06A",
|
| 109 |
+
"0xD754-3": "06B",
|
| 110 |
+
"0xD754-4": "06C",
|
| 111 |
+
"0xD754-5": "06D",
|
| 112 |
+
"0xD754-6": "06E",
|
| 113 |
+
"0xD754-7": "06F",
|
| 114 |
+
"0xD755-0": "070",
|
| 115 |
+
"0xD755-1": "071",
|
| 116 |
+
"0xD755-2": "Beat Pewter Gym Trainer 0",
|
| 117 |
+
"0xD755-3": "073",
|
| 118 |
+
"0xD755-4": "074",
|
| 119 |
+
"0xD755-5": "075",
|
| 120 |
+
"0xD755-6": "Got Tm34",
|
| 121 |
+
"0xD755-7": "Beat Brock",
|
| 122 |
+
"0xD756-0": "078",
|
| 123 |
+
"0xD756-1": "079",
|
| 124 |
+
"0xD756-2": "07A",
|
| 125 |
+
"0xD756-3": "07B",
|
| 126 |
+
"0xD756-4": "07C",
|
| 127 |
+
"0xD756-5": "07D",
|
| 128 |
+
"0xD756-6": "07E",
|
| 129 |
+
"0xD756-7": "07F",
|
| 130 |
+
"0xD757-0": "080",
|
| 131 |
+
"0xD757-1": "081",
|
| 132 |
+
"0xD757-2": "082",
|
| 133 |
+
"0xD757-3": "083",
|
| 134 |
+
"0xD757-4": "084",
|
| 135 |
+
"0xD757-5": "085",
|
| 136 |
+
"0xD757-6": "086",
|
| 137 |
+
"0xD757-7": "087",
|
| 138 |
+
"0xD758-0": "088",
|
| 139 |
+
"0xD758-1": "089",
|
| 140 |
+
"0xD758-2": "08A",
|
| 141 |
+
"0xD758-3": "08B",
|
| 142 |
+
"0xD758-4": "08C",
|
| 143 |
+
"0xD758-5": "08D",
|
| 144 |
+
"0xD758-6": "08E",
|
| 145 |
+
"0xD758-7": "08F",
|
| 146 |
+
"0xD759-0": "090",
|
| 147 |
+
"0xD759-1": "091",
|
| 148 |
+
"0xD759-2": "092",
|
| 149 |
+
"0xD759-3": "093",
|
| 150 |
+
"0xD759-4": "094",
|
| 151 |
+
"0xD759-5": "095",
|
| 152 |
+
"0xD759-6": "096",
|
| 153 |
+
"0xD759-7": "097",
|
| 154 |
+
"0xD75A-0": "Beat Cerulean Rival",
|
| 155 |
+
"0xD75A-1": "099",
|
| 156 |
+
"0xD75A-2": "09A",
|
| 157 |
+
"0xD75A-3": "09B",
|
| 158 |
+
"0xD75A-4": "09C",
|
| 159 |
+
"0xD75A-5": "09D",
|
| 160 |
+
"0xD75A-6": "09E",
|
| 161 |
+
"0xD75A-7": "09F",
|
| 162 |
+
"0xD75B-0": "0A0",
|
| 163 |
+
"0xD75B-1": "0A1",
|
| 164 |
+
"0xD75B-2": "0A2",
|
| 165 |
+
"0xD75B-3": "0A3",
|
| 166 |
+
"0xD75B-4": "0A4",
|
| 167 |
+
"0xD75B-5": "0A5",
|
| 168 |
+
"0xD75B-6": "0A6",
|
| 169 |
+
"0xD75B-7": "Beat Cerulean Rocket Thief",
|
| 170 |
+
"0xD75C-0": "0A8",
|
| 171 |
+
"0xD75C-1": "0A9",
|
| 172 |
+
"0xD75C-2": "0Aa",
|
| 173 |
+
"0xD75C-3": "0Ab",
|
| 174 |
+
"0xD75C-4": "0Ac",
|
| 175 |
+
"0xD75C-5": "0Ad",
|
| 176 |
+
"0xD75C-6": "0Ae",
|
| 177 |
+
"0xD75C-7": "0Af",
|
| 178 |
+
"0xD75D-0": "0B0",
|
| 179 |
+
"0xD75D-1": "0B1",
|
| 180 |
+
"0xD75D-2": "0B2",
|
| 181 |
+
"0xD75D-3": "0B3",
|
| 182 |
+
"0xD75D-4": "0B4",
|
| 183 |
+
"0xD75D-5": "0B5",
|
| 184 |
+
"0xD75D-6": "0B6",
|
| 185 |
+
"0xD75D-7": "0B7",
|
| 186 |
+
"0xD75E-0": "0B8",
|
| 187 |
+
"0xD75E-1": "0B9",
|
| 188 |
+
"0xD75E-2": "Beat Cerulean Gym Trainer 0",
|
| 189 |
+
"0xD75E-3": "Beat Cerulean Gym Trainer 1",
|
| 190 |
+
"0xD75E-4": "0Bc",
|
| 191 |
+
"0xD75E-5": "0Bd",
|
| 192 |
+
"0xD75E-6": "Got Tm11",
|
| 193 |
+
"0xD75E-7": "Beat Misty",
|
| 194 |
+
"0xD75F-0": "Got Bicycle",
|
| 195 |
+
"0xD75F-1": "0C1",
|
| 196 |
+
"0xD75F-2": "0C2",
|
| 197 |
+
"0xD75F-3": "0C3",
|
| 198 |
+
"0xD75F-4": "0C4",
|
| 199 |
+
"0xD75F-5": "0C5",
|
| 200 |
+
"0xD75F-6": "0C6",
|
| 201 |
+
"0xD75F-7": "0C7",
|
| 202 |
+
"0xD760-0": "0C8",
|
| 203 |
+
"0xD760-1": "0C9",
|
| 204 |
+
"0xD760-2": "0Ca",
|
| 205 |
+
"0xD760-3": "0Cb",
|
| 206 |
+
"0xD760-4": "0Cc",
|
| 207 |
+
"0xD760-5": "0Cd",
|
| 208 |
+
"0xD760-6": "0Ce",
|
| 209 |
+
"0xD760-7": "0Cf",
|
| 210 |
+
"0xD761-0": "0D0",
|
| 211 |
+
"0xD761-1": "0D1",
|
| 212 |
+
"0xD761-2": "0D2",
|
| 213 |
+
"0xD761-3": "0D3",
|
| 214 |
+
"0xD761-4": "0D4",
|
| 215 |
+
"0xD761-5": "0D5",
|
| 216 |
+
"0xD761-6": "0D6",
|
| 217 |
+
"0xD761-7": "0D7",
|
| 218 |
+
"0xD762-0": "0D8",
|
| 219 |
+
"0xD762-1": "0D9",
|
| 220 |
+
"0xD762-2": "0Da",
|
| 221 |
+
"0xD762-3": "0Db",
|
| 222 |
+
"0xD762-4": "0Dc",
|
| 223 |
+
"0xD762-5": "0Dd",
|
| 224 |
+
"0xD762-6": "0De",
|
| 225 |
+
"0xD762-7": "0Df",
|
| 226 |
+
"0xD763-0": "0E0",
|
| 227 |
+
"0xD763-1": "0E1",
|
| 228 |
+
"0xD763-2": "0E2",
|
| 229 |
+
"0xD763-3": "0E3",
|
| 230 |
+
"0xD763-4": "0E4",
|
| 231 |
+
"0xD763-5": "0E5",
|
| 232 |
+
"0xD763-6": "0E6",
|
| 233 |
+
"0xD763-7": "0E7",
|
| 234 |
+
"0xD764-0": "0E8",
|
| 235 |
+
"0xD764-1": "0E9",
|
| 236 |
+
"0xD764-2": "0Ea",
|
| 237 |
+
"0xD764-3": "0Eb",
|
| 238 |
+
"0xD764-4": "0Ec",
|
| 239 |
+
"0xD764-5": "0Ed",
|
| 240 |
+
"0xD764-6": "Pokemon Tower Rival On Left",
|
| 241 |
+
"0xD764-7": "Beat Pokemon Tower Rival",
|
| 242 |
+
"0xD765-0": "0F0",
|
| 243 |
+
"0xD765-1": "Beat Pokemontower 3 Trainer 0",
|
| 244 |
+
"0xD765-2": "Beat Pokemontower 3 Trainer 1",
|
| 245 |
+
"0xD765-3": "Beat Pokemontower 3 Trainer 2",
|
| 246 |
+
"0xD765-4": "0F4",
|
| 247 |
+
"0xD765-5": "0F5",
|
| 248 |
+
"0xD765-6": "0F6",
|
| 249 |
+
"0xD765-7": "0F7",
|
| 250 |
+
"0xD766-0": "0F8",
|
| 251 |
+
"0xD766-1": "Beat Pokemontower 4 Trainer 0",
|
| 252 |
+
"0xD766-2": "Beat Pokemontower 4 Trainer 1",
|
| 253 |
+
"0xD766-3": "Beat Pokemontower 4 Trainer 2",
|
| 254 |
+
"0xD766-4": "0Fc",
|
| 255 |
+
"0xD766-5": "0Fd",
|
| 256 |
+
"0xD766-6": "0Fe",
|
| 257 |
+
"0xD766-7": "0Ff",
|
| 258 |
+
"0xD767-0": "100",
|
| 259 |
+
"0xD767-1": "101",
|
| 260 |
+
"0xD767-2": "Beat Pokemontower 5 Trainer 0",
|
| 261 |
+
"0xD767-3": "Beat Pokemontower 5 Trainer 1",
|
| 262 |
+
"0xD767-4": "Beat Pokemontower 5 Trainer 2",
|
| 263 |
+
"0xD767-5": "Beat Pokemontower 5 Trainer 3",
|
| 264 |
+
"0xD767-6": "106",
|
| 265 |
+
"0xD767-7": "In Purified Zone",
|
| 266 |
+
"0xD768-0": "108",
|
| 267 |
+
"0xD768-1": "Beat Pokemontower 6 Trainer 0",
|
| 268 |
+
"0xD768-2": "Beat Pokemontower 6 Trainer 1",
|
| 269 |
+
"0xD768-3": "Beat Pokemontower 6 Trainer 2",
|
| 270 |
+
"0xD768-4": "10C",
|
| 271 |
+
"0xD768-5": "10D",
|
| 272 |
+
"0xD768-6": "10E",
|
| 273 |
+
"0xD768-7": "Beat Ghost Marowak",
|
| 274 |
+
"0xD769-0": "110",
|
| 275 |
+
"0xD769-1": "Beat Pokemontower 7 Trainer 0",
|
| 276 |
+
"0xD769-2": "Beat Pokemontower 7 Trainer 1",
|
| 277 |
+
"0xD769-3": "Beat Pokemontower 7 Trainer 2",
|
| 278 |
+
"0xD769-4": "114",
|
| 279 |
+
"0xD769-5": "115",
|
| 280 |
+
"0xD769-6": "116",
|
| 281 |
+
"0xD769-7": "Rescued Mr Fuji 2",
|
| 282 |
+
"0xD76A-0": "118",
|
| 283 |
+
"0xD76A-1": "119",
|
| 284 |
+
"0xD76A-2": "11A",
|
| 285 |
+
"0xD76A-3": "11B",
|
| 286 |
+
"0xD76A-4": "11C",
|
| 287 |
+
"0xD76A-5": "11D",
|
| 288 |
+
"0xD76A-6": "11E",
|
| 289 |
+
"0xD76A-7": "11F",
|
| 290 |
+
"0xD76B-0": "120",
|
| 291 |
+
"0xD76B-1": "121",
|
| 292 |
+
"0xD76B-2": "122",
|
| 293 |
+
"0xD76B-3": "123",
|
| 294 |
+
"0xD76B-4": "124",
|
| 295 |
+
"0xD76B-5": "125",
|
| 296 |
+
"0xD76B-6": "126",
|
| 297 |
+
"0xD76B-7": "127",
|
| 298 |
+
"0xD76C-0": "Got Poke Flute",
|
| 299 |
+
"0xD76C-1": "129",
|
| 300 |
+
"0xD76C-2": "12A",
|
| 301 |
+
"0xD76C-3": "12B",
|
| 302 |
+
"0xD76C-4": "12C",
|
| 303 |
+
"0xD76C-5": "12D",
|
| 304 |
+
"0xD76C-6": "12E",
|
| 305 |
+
"0xD76C-7": "12F",
|
| 306 |
+
"0xD76D-0": "130",
|
| 307 |
+
"0xD76D-1": "131",
|
| 308 |
+
"0xD76D-2": "132",
|
| 309 |
+
"0xD76D-3": "133",
|
| 310 |
+
"0xD76D-4": "134",
|
| 311 |
+
"0xD76D-5": "135",
|
| 312 |
+
"0xD76D-6": "136",
|
| 313 |
+
"0xD76D-7": "137",
|
| 314 |
+
"0xD76E-0": "138",
|
| 315 |
+
"0xD76E-1": "139",
|
| 316 |
+
"0xD76E-2": "13A",
|
| 317 |
+
"0xD76E-3": "13B",
|
| 318 |
+
"0xD76E-4": "13C",
|
| 319 |
+
"0xD76E-5": "13D",
|
| 320 |
+
"0xD76E-6": "13E",
|
| 321 |
+
"0xD76E-7": "13F",
|
| 322 |
+
"0xD76F-0": "140",
|
| 323 |
+
"0xD76F-1": "141",
|
| 324 |
+
"0xD76F-2": "142",
|
| 325 |
+
"0xD76F-3": "143",
|
| 326 |
+
"0xD76F-4": "144",
|
| 327 |
+
"0xD76F-5": "145",
|
| 328 |
+
"0xD76F-6": "146",
|
| 329 |
+
"0xD76F-7": "147",
|
| 330 |
+
"0xD770-0": "148",
|
| 331 |
+
"0xD770-1": "149",
|
| 332 |
+
"0xD770-2": "14A",
|
| 333 |
+
"0xD770-3": "14B",
|
| 334 |
+
"0xD770-4": "14C",
|
| 335 |
+
"0xD770-5": "14D",
|
| 336 |
+
"0xD770-6": "14E",
|
| 337 |
+
"0xD770-7": "14F",
|
| 338 |
+
"0xD771-0": "150",
|
| 339 |
+
"0xD771-1": "Got Bike Voucher",
|
| 340 |
+
"0xD771-2": "152",
|
| 341 |
+
"0xD771-3": "153",
|
| 342 |
+
"0xD771-4": "154",
|
| 343 |
+
"0xD771-5": "155",
|
| 344 |
+
"0xD771-6": "Seel Fan Boast",
|
| 345 |
+
"0xD771-7": "Pikachu Fan Boast",
|
| 346 |
+
"0xD772-0": "158",
|
| 347 |
+
"0xD772-1": "159",
|
| 348 |
+
"0xD772-2": "15A",
|
| 349 |
+
"0xD772-3": "15B",
|
| 350 |
+
"0xD772-4": "15C",
|
| 351 |
+
"0xD772-5": "15D",
|
| 352 |
+
"0xD772-6": "15E",
|
| 353 |
+
"0xD772-7": "15F",
|
| 354 |
+
"0xD773-0": "2Nd Lock Opened",
|
| 355 |
+
"0xD773-1": "1St Lock Opened",
|
| 356 |
+
"0xD773-2": "Beat Vermilion Gym Trainer 0",
|
| 357 |
+
"0xD773-3": "Beat Vermilion Gym Trainer 1",
|
| 358 |
+
"0xD773-4": "Beat Vermilion Gym Trainer 2",
|
| 359 |
+
"0xD773-5": "165",
|
| 360 |
+
"0xD773-6": "Got Tm24",
|
| 361 |
+
"0xD773-7": "Beat Lt Surge",
|
| 362 |
+
"0xD774-0": "168",
|
| 363 |
+
"0xD774-1": "169",
|
| 364 |
+
"0xD774-2": "16A",
|
| 365 |
+
"0xD774-3": "16B",
|
| 366 |
+
"0xD774-4": "16C",
|
| 367 |
+
"0xD774-5": "16D",
|
| 368 |
+
"0xD774-6": "16E",
|
| 369 |
+
"0xD774-7": "16F",
|
| 370 |
+
"0xD775-0": "170",
|
| 371 |
+
"0xD775-1": "171",
|
| 372 |
+
"0xD775-2": "172",
|
| 373 |
+
"0xD775-3": "173",
|
| 374 |
+
"0xD775-4": "174",
|
| 375 |
+
"0xD775-5": "175",
|
| 376 |
+
"0xD775-6": "176",
|
| 377 |
+
"0xD775-7": "177",
|
| 378 |
+
"0xD776-0": "178",
|
| 379 |
+
"0xD776-1": "179",
|
| 380 |
+
"0xD776-2": "17A",
|
| 381 |
+
"0xD776-3": "17B",
|
| 382 |
+
"0xD776-4": "17C",
|
| 383 |
+
"0xD776-5": "17D",
|
| 384 |
+
"0xD776-6": "17E",
|
| 385 |
+
"0xD776-7": "17F",
|
| 386 |
+
"0xD777-0": "Got Tm41",
|
| 387 |
+
"0xD777-1": "181",
|
| 388 |
+
"0xD777-2": "182",
|
| 389 |
+
"0xD777-3": "183",
|
| 390 |
+
"0xD777-4": "184",
|
| 391 |
+
"0xD777-5": "185",
|
| 392 |
+
"0xD777-6": "186",
|
| 393 |
+
"0xD777-7": "187",
|
| 394 |
+
"0xD778-0": "188",
|
| 395 |
+
"0xD778-1": "189",
|
| 396 |
+
"0xD778-2": "18A",
|
| 397 |
+
"0xD778-3": "18B",
|
| 398 |
+
"0xD778-4": "Got Tm13",
|
| 399 |
+
"0xD778-5": "Got Tm48",
|
| 400 |
+
"0xD778-6": "Got Tm49",
|
| 401 |
+
"0xD778-7": "Got Tm18",
|
| 402 |
+
"0xD779-0": "190",
|
| 403 |
+
"0xD779-1": "191",
|
| 404 |
+
"0xD779-2": "192",
|
| 405 |
+
"0xD779-3": "193",
|
| 406 |
+
"0xD779-4": "194",
|
| 407 |
+
"0xD779-5": "195",
|
| 408 |
+
"0xD779-6": "196",
|
| 409 |
+
"0xD779-7": "197",
|
| 410 |
+
"0xD77A-0": "198",
|
| 411 |
+
"0xD77A-1": "199",
|
| 412 |
+
"0xD77A-2": "19A",
|
| 413 |
+
"0xD77A-3": "19B",
|
| 414 |
+
"0xD77A-4": "19C",
|
| 415 |
+
"0xD77A-5": "19D",
|
| 416 |
+
"0xD77A-6": "19E",
|
| 417 |
+
"0xD77A-7": "19F",
|
| 418 |
+
"0xD77B-0": "1A0",
|
| 419 |
+
"0xD77B-1": "1A1",
|
| 420 |
+
"0xD77B-2": "1A2",
|
| 421 |
+
"0xD77B-3": "1A3",
|
| 422 |
+
"0xD77B-4": "1A4",
|
| 423 |
+
"0xD77B-5": "1A5",
|
| 424 |
+
"0xD77B-6": "1A6",
|
| 425 |
+
"0xD77B-7": "1A7",
|
| 426 |
+
"0xD77C-0": "Got Tm21",
|
| 427 |
+
"0xD77C-1": "Beat Erika",
|
| 428 |
+
"0xD77C-2": "Beat Celadon Gym Trainer 0",
|
| 429 |
+
"0xD77C-3": "Beat Celadon Gym Trainer 1",
|
| 430 |
+
"0xD77C-4": "Beat Celadon Gym Trainer 2",
|
| 431 |
+
"0xD77C-5": "Beat Celadon Gym Trainer 3",
|
| 432 |
+
"0xD77C-6": "Beat Celadon Gym Trainer 4",
|
| 433 |
+
"0xD77C-7": "Beat Celadon Gym Trainer 5",
|
| 434 |
+
"0xD77D-0": "Beat Celadon Gym Trainer 6",
|
| 435 |
+
"0xD77D-1": "1B1",
|
| 436 |
+
"0xD77D-2": "1B2",
|
| 437 |
+
"0xD77D-3": "1B3",
|
| 438 |
+
"0xD77D-4": "1B4",
|
| 439 |
+
"0xD77D-5": "1B5",
|
| 440 |
+
"0xD77D-6": "1B6",
|
| 441 |
+
"0xD77D-7": "1B7",
|
| 442 |
+
"0xD77E-0": "1B8",
|
| 443 |
+
"0xD77E-1": "Found Rocket Hideout",
|
| 444 |
+
"0xD77E-2": "Got 10 Coins",
|
| 445 |
+
"0xD77E-3": "Got 20 Coins",
|
| 446 |
+
"0xD77E-4": "Got 20 Coins 2",
|
| 447 |
+
"0xD77E-5": "1Bd",
|
| 448 |
+
"0xD77E-6": "1Be",
|
| 449 |
+
"0xD77E-7": "1Bf",
|
| 450 |
+
"0xD77F-0": "1C0",
|
| 451 |
+
"0xD77F-1": "1C1",
|
| 452 |
+
"0xD77F-2": "1C2",
|
| 453 |
+
"0xD77F-3": "1C3",
|
| 454 |
+
"0xD77F-4": "1C4",
|
| 455 |
+
"0xD77F-5": "1C5",
|
| 456 |
+
"0xD77F-6": "1C6",
|
| 457 |
+
"0xD77F-7": "1C7",
|
| 458 |
+
"0xD780-0": "1C8",
|
| 459 |
+
"0xD780-1": "1C9",
|
| 460 |
+
"0xD780-2": "1Ca",
|
| 461 |
+
"0xD780-3": "1Cb",
|
| 462 |
+
"0xD780-4": "1Cc",
|
| 463 |
+
"0xD780-5": "1Cd",
|
| 464 |
+
"0xD780-6": "1Ce",
|
| 465 |
+
"0xD780-7": "1Cf",
|
| 466 |
+
"0xD781-0": "1D0",
|
| 467 |
+
"0xD781-1": "1D1",
|
| 468 |
+
"0xD781-2": "1D2",
|
| 469 |
+
"0xD781-3": "1D3",
|
| 470 |
+
"0xD781-4": "1D4",
|
| 471 |
+
"0xD781-5": "1D5",
|
| 472 |
+
"0xD781-6": "1D6",
|
| 473 |
+
"0xD781-7": "1D7",
|
| 474 |
+
"0xD782-0": "1D8",
|
| 475 |
+
"0xD782-1": "1D9",
|
| 476 |
+
"0xD782-2": "1Da",
|
| 477 |
+
"0xD782-3": "1Db",
|
| 478 |
+
"0xD782-4": "1Dc",
|
| 479 |
+
"0xD782-5": "1Dd",
|
| 480 |
+
"0xD782-6": "1De",
|
| 481 |
+
"0xD782-7": "1Df",
|
| 482 |
+
"0xD783-0": "Got Coin Case",
|
| 483 |
+
"0xD783-1": "1E1",
|
| 484 |
+
"0xD783-2": "1E2",
|
| 485 |
+
"0xD783-3": "1E3",
|
| 486 |
+
"0xD783-4": "1E4",
|
| 487 |
+
"0xD783-5": "1E5",
|
| 488 |
+
"0xD783-6": "1E6",
|
| 489 |
+
"0xD783-7": "1E7",
|
| 490 |
+
"0xD784-0": "1E8",
|
| 491 |
+
"0xD784-1": "1E9",
|
| 492 |
+
"0xD784-2": "1Ea",
|
| 493 |
+
"0xD784-3": "1Eb",
|
| 494 |
+
"0xD784-4": "1Ec",
|
| 495 |
+
"0xD784-5": "1Ed",
|
| 496 |
+
"0xD784-6": "1Ee",
|
| 497 |
+
"0xD784-7": "1Ef",
|
| 498 |
+
"0xD785-0": "1F0",
|
| 499 |
+
"0xD785-1": "1F1",
|
| 500 |
+
"0xD785-2": "1F2",
|
| 501 |
+
"0xD785-3": "1F3",
|
| 502 |
+
"0xD785-4": "1F4",
|
| 503 |
+
"0xD785-5": "1F5",
|
| 504 |
+
"0xD785-6": "1F6",
|
| 505 |
+
"0xD785-7": "1F7",
|
| 506 |
+
"0xD786-0": "1F8",
|
| 507 |
+
"0xD786-1": "1F9",
|
| 508 |
+
"0xD786-2": "1Fa",
|
| 509 |
+
"0xD786-3": "1Fb",
|
| 510 |
+
"0xD786-4": "1Fc",
|
| 511 |
+
"0xD786-5": "1Fd",
|
| 512 |
+
"0xD786-6": "1Fe",
|
| 513 |
+
"0xD786-7": "1Ff",
|
| 514 |
+
"0xD787-0": "200",
|
| 515 |
+
"0xD787-1": "201",
|
| 516 |
+
"0xD787-2": "202",
|
| 517 |
+
"0xD787-3": "203",
|
| 518 |
+
"0xD787-4": "204",
|
| 519 |
+
"0xD787-5": "205",
|
| 520 |
+
"0xD787-6": "206",
|
| 521 |
+
"0xD787-7": "207",
|
| 522 |
+
"0xD788-0": "208",
|
| 523 |
+
"0xD788-1": "209",
|
| 524 |
+
"0xD788-2": "20A",
|
| 525 |
+
"0xD788-3": "20B",
|
| 526 |
+
"0xD788-4": "20C",
|
| 527 |
+
"0xD788-5": "20D",
|
| 528 |
+
"0xD788-6": "20E",
|
| 529 |
+
"0xD788-7": "20F",
|
| 530 |
+
"0xD789-0": "210",
|
| 531 |
+
"0xD789-1": "211",
|
| 532 |
+
"0xD789-2": "212",
|
| 533 |
+
"0xD789-3": "213",
|
| 534 |
+
"0xD789-4": "214",
|
| 535 |
+
"0xD789-5": "215",
|
| 536 |
+
"0xD789-6": "216",
|
| 537 |
+
"0xD789-7": "217",
|
| 538 |
+
"0xD78A-0": "218",
|
| 539 |
+
"0xD78A-1": "219",
|
| 540 |
+
"0xD78A-2": "21A",
|
| 541 |
+
"0xD78A-3": "21B",
|
| 542 |
+
"0xD78A-4": "21C",
|
| 543 |
+
"0xD78A-5": "21D",
|
| 544 |
+
"0xD78A-6": "21E",
|
| 545 |
+
"0xD78A-7": "21F",
|
| 546 |
+
"0xD78B-0": "220",
|
| 547 |
+
"0xD78B-1": "221",
|
| 548 |
+
"0xD78B-2": "222",
|
| 549 |
+
"0xD78B-3": "223",
|
| 550 |
+
"0xD78B-4": "224",
|
| 551 |
+
"0xD78B-5": "225",
|
| 552 |
+
"0xD78B-6": "226",
|
| 553 |
+
"0xD78B-7": "227",
|
| 554 |
+
"0xD78C-0": "228",
|
| 555 |
+
"0xD78C-1": "229",
|
| 556 |
+
"0xD78C-2": "22A",
|
| 557 |
+
"0xD78C-3": "22B",
|
| 558 |
+
"0xD78C-4": "22C",
|
| 559 |
+
"0xD78C-5": "22D",
|
| 560 |
+
"0xD78C-6": "22E",
|
| 561 |
+
"0xD78C-7": "22F",
|
| 562 |
+
"0xD78D-0": "230",
|
| 563 |
+
"0xD78D-1": "231",
|
| 564 |
+
"0xD78D-2": "232",
|
| 565 |
+
"0xD78D-3": "233",
|
| 566 |
+
"0xD78D-4": "234",
|
| 567 |
+
"0xD78D-5": "235",
|
| 568 |
+
"0xD78D-6": "236",
|
| 569 |
+
"0xD78D-7": "237",
|
| 570 |
+
"0xD78E-0": "Got Hm04",
|
| 571 |
+
"0xD78E-1": "Gave Gold Teeth",
|
| 572 |
+
"0xD78E-2": "23A",
|
| 573 |
+
"0xD78E-3": "23B",
|
| 574 |
+
"0xD78E-4": "23C",
|
| 575 |
+
"0xD78E-5": "23D",
|
| 576 |
+
"0xD78E-6": "23E",
|
| 577 |
+
"0xD78E-7": "23F",
|
| 578 |
+
"0xD78F-0": "240",
|
| 579 |
+
"0xD78F-1": "241",
|
| 580 |
+
"0xD78F-2": "242",
|
| 581 |
+
"0xD78F-3": "243",
|
| 582 |
+
"0xD78F-4": "244",
|
| 583 |
+
"0xD78F-5": "245",
|
| 584 |
+
"0xD78F-6": "246",
|
| 585 |
+
"0xD78F-7": "247",
|
| 586 |
+
"0xD790-0": "248",
|
| 587 |
+
"0xD790-1": "249",
|
| 588 |
+
"0xD790-2": "24A",
|
| 589 |
+
"0xD790-3": "24B",
|
| 590 |
+
"0xD790-4": "24C",
|
| 591 |
+
"0xD790-5": "24D",
|
| 592 |
+
"0xD790-6": "Safari Game Over",
|
| 593 |
+
"0xD790-7": "In Safari Zone",
|
| 594 |
+
"0xD791-0": "250",
|
| 595 |
+
"0xD791-1": "251",
|
| 596 |
+
"0xD791-2": "252",
|
| 597 |
+
"0xD791-3": "253",
|
| 598 |
+
"0xD791-4": "254",
|
| 599 |
+
"0xD791-5": "255",
|
| 600 |
+
"0xD791-6": "256",
|
| 601 |
+
"0xD791-7": "257",
|
| 602 |
+
"0xD792-0": "Got Tm06",
|
| 603 |
+
"0xD792-1": "Beat Koga",
|
| 604 |
+
"0xD792-2": "Beat Fuchsia Gym Trainer 0",
|
| 605 |
+
"0xD792-3": "Beat Fuchsia Gym Trainer 1",
|
| 606 |
+
"0xD792-4": "Beat Fuchsia Gym Trainer 2",
|
| 607 |
+
"0xD792-5": "Beat Fuchsia Gym Trainer 3",
|
| 608 |
+
"0xD792-6": "Beat Fuchsia Gym Trainer 4",
|
| 609 |
+
"0xD792-7": "Beat Fuchsia Gym Trainer 5",
|
| 610 |
+
"0xD793-0": "260",
|
| 611 |
+
"0xD793-1": "261",
|
| 612 |
+
"0xD793-2": "262",
|
| 613 |
+
"0xD793-3": "263",
|
| 614 |
+
"0xD793-4": "264",
|
| 615 |
+
"0xD793-5": "265",
|
| 616 |
+
"0xD793-6": "266",
|
| 617 |
+
"0xD793-7": "267",
|
| 618 |
+
"0xD794-0": "268",
|
| 619 |
+
"0xD794-1": "269",
|
| 620 |
+
"0xD794-2": "26A",
|
| 621 |
+
"0xD794-3": "26B",
|
| 622 |
+
"0xD794-4": "26C",
|
| 623 |
+
"0xD794-5": "26D",
|
| 624 |
+
"0xD794-6": "26E",
|
| 625 |
+
"0xD794-7": "26F",
|
| 626 |
+
"0xD795-0": "270",
|
| 627 |
+
"0xD795-1": "271",
|
| 628 |
+
"0xD795-2": "272",
|
| 629 |
+
"0xD795-3": "273",
|
| 630 |
+
"0xD795-4": "274",
|
| 631 |
+
"0xD795-5": "275",
|
| 632 |
+
"0xD795-6": "276",
|
| 633 |
+
"0xD795-7": "277",
|
| 634 |
+
"0xD796-0": "Mansion Switch On",
|
| 635 |
+
"0xD796-1": "279",
|
| 636 |
+
"0xD796-2": "27A",
|
| 637 |
+
"0xD796-3": "27B",
|
| 638 |
+
"0xD796-4": "27C",
|
| 639 |
+
"0xD796-5": "27D",
|
| 640 |
+
"0xD796-6": "27E",
|
| 641 |
+
"0xD796-7": "27F",
|
| 642 |
+
"0xD797-0": "280",
|
| 643 |
+
"0xD797-1": "281",
|
| 644 |
+
"0xD797-2": "282",
|
| 645 |
+
"0xD797-3": "283",
|
| 646 |
+
"0xD797-4": "284",
|
| 647 |
+
"0xD797-5": "285",
|
| 648 |
+
"0xD797-6": "286",
|
| 649 |
+
"0xD797-7": "287",
|
| 650 |
+
"0xD798-0": "288",
|
| 651 |
+
"0xD798-1": "Beat Mansion 1 Trainer 0",
|
| 652 |
+
"0xD798-2": "28A",
|
| 653 |
+
"0xD798-3": "28B",
|
| 654 |
+
"0xD798-4": "28C",
|
| 655 |
+
"0xD798-5": "28D",
|
| 656 |
+
"0xD798-6": "28E",
|
| 657 |
+
"0xD798-7": "28F",
|
| 658 |
+
"0xD799-0": "290",
|
| 659 |
+
"0xD799-1": "291",
|
| 660 |
+
"0xD799-2": "292",
|
| 661 |
+
"0xD799-3": "293",
|
| 662 |
+
"0xD799-4": "294",
|
| 663 |
+
"0xD799-5": "295",
|
| 664 |
+
"0xD799-6": "296",
|
| 665 |
+
"0xD799-7": "297",
|
| 666 |
+
"0xD79A-0": "Got Tm38",
|
| 667 |
+
"0xD79A-1": "Beat Blaine",
|
| 668 |
+
"0xD79A-2": "Beat Cinnabar Gym Trainer 0",
|
| 669 |
+
"0xD79A-3": "Beat Cinnabar Gym Trainer 1",
|
| 670 |
+
"0xD79A-4": "Beat Cinnabar Gym Trainer 2",
|
| 671 |
+
"0xD79A-5": "Beat Cinnabar Gym Trainer 3",
|
| 672 |
+
"0xD79A-6": "Beat Cinnabar Gym Trainer 4",
|
| 673 |
+
"0xD79A-7": "Beat Cinnabar Gym Trainer 5",
|
| 674 |
+
"0xD79B-0": "Beat Cinnabar Gym Trainer 6",
|
| 675 |
+
"0xD79B-1": "2A1",
|
| 676 |
+
"0xD79B-2": "2A2",
|
| 677 |
+
"0xD79B-3": "2A3",
|
| 678 |
+
"0xD79B-4": "2A4",
|
| 679 |
+
"0xD79B-5": "2A5",
|
| 680 |
+
"0xD79B-6": "2A6",
|
| 681 |
+
"0xD79B-7": "2A7",
|
| 682 |
+
"0xD79C-0": "Cinnabar Gym Gate0 Unlocked",
|
| 683 |
+
"0xD79C-1": "Cinnabar Gym Gate1 Unlocked",
|
| 684 |
+
"0xD79C-2": "Cinnabar Gym Gate2 Unlocked",
|
| 685 |
+
"0xD79C-3": "Cinnabar Gym Gate3 Unlocked",
|
| 686 |
+
"0xD79C-4": "Cinnabar Gym Gate4 Unlocked",
|
| 687 |
+
"0xD79C-5": "Cinnabar Gym Gate5 Unlocked",
|
| 688 |
+
"0xD79C-6": "Cinnabar Gym Gate6 Unlocked",
|
| 689 |
+
"0xD79C-7": "2Af",
|
| 690 |
+
"0xD79D-0": "2B0",
|
| 691 |
+
"0xD79D-1": "2B1",
|
| 692 |
+
"0xD79D-2": "2B2",
|
| 693 |
+
"0xD79D-3": "2B3",
|
| 694 |
+
"0xD79D-4": "2B4",
|
| 695 |
+
"0xD79D-5": "2B5",
|
| 696 |
+
"0xD79D-6": "2B6",
|
| 697 |
+
"0xD79D-7": "2B7",
|
| 698 |
+
"0xD79E-0": "2B8",
|
| 699 |
+
"0xD79E-1": "2B9",
|
| 700 |
+
"0xD79E-2": "2Ba",
|
| 701 |
+
"0xD79E-3": "2Bb",
|
| 702 |
+
"0xD79E-4": "2Bc",
|
| 703 |
+
"0xD79E-5": "2Bd",
|
| 704 |
+
"0xD79E-6": "2Be",
|
| 705 |
+
"0xD79E-7": "2Bf",
|
| 706 |
+
"0xD79F-0": "2C0",
|
| 707 |
+
"0xD79F-1": "2C1",
|
| 708 |
+
"0xD79F-2": "2C2",
|
| 709 |
+
"0xD79F-3": "2C3",
|
| 710 |
+
"0xD79F-4": "2C4",
|
| 711 |
+
"0xD79F-5": "2C5",
|
| 712 |
+
"0xD79F-6": "2C6",
|
| 713 |
+
"0xD79F-7": "2C7",
|
| 714 |
+
"0xD7A0-0": "2C8",
|
| 715 |
+
"0xD7A0-1": "2C9",
|
| 716 |
+
"0xD7A0-2": "2Ca",
|
| 717 |
+
"0xD7A0-3": "2Cb",
|
| 718 |
+
"0xD7A0-4": "2Cc",
|
| 719 |
+
"0xD7A0-5": "2Cd",
|
| 720 |
+
"0xD7A0-6": "2Ce",
|
| 721 |
+
"0xD7A0-7": "2Cf",
|
| 722 |
+
"0xD7A1-0": "2D0",
|
| 723 |
+
"0xD7A1-1": "2D1",
|
| 724 |
+
"0xD7A1-2": "2D2",
|
| 725 |
+
"0xD7A1-3": "2D3",
|
| 726 |
+
"0xD7A1-4": "2D4",
|
| 727 |
+
"0xD7A1-5": "2D5",
|
| 728 |
+
"0xD7A1-6": "2D6",
|
| 729 |
+
"0xD7A1-7": "Got Tm35",
|
| 730 |
+
"0xD7A2-0": "2D8",
|
| 731 |
+
"0xD7A2-1": "2D9",
|
| 732 |
+
"0xD7A2-2": "2Da",
|
| 733 |
+
"0xD7A2-3": "2Db",
|
| 734 |
+
"0xD7A2-4": "2Dc",
|
| 735 |
+
"0xD7A2-5": "2Dd",
|
| 736 |
+
"0xD7A2-6": "2De",
|
| 737 |
+
"0xD7A2-7": "2Df",
|
| 738 |
+
"0xD7A3-0": "Gave Fossil To Lab",
|
| 739 |
+
"0xD7A3-1": "Lab Still Reviving Fossil",
|
| 740 |
+
"0xD7A3-2": "Lab Handing Over Fossil Mon",
|
| 741 |
+
"0xD7A3-3": "2E3",
|
| 742 |
+
"0xD7A3-4": "2E4",
|
| 743 |
+
"0xD7A3-5": "2E5",
|
| 744 |
+
"0xD7A3-6": "2E6",
|
| 745 |
+
"0xD7A3-7": "2E7",
|
| 746 |
+
"0xD7A4-0": "2E8",
|
| 747 |
+
"0xD7A4-1": "2E9",
|
| 748 |
+
"0xD7A4-2": "2Ea",
|
| 749 |
+
"0xD7A4-3": "2Eb",
|
| 750 |
+
"0xD7A4-4": "2Ec",
|
| 751 |
+
"0xD7A4-5": "2Ed",
|
| 752 |
+
"0xD7A4-6": "2Ee",
|
| 753 |
+
"0xD7A4-7": "2Ef",
|
| 754 |
+
"0xD7A5-0": "2F0",
|
| 755 |
+
"0xD7A5-1": "2F1",
|
| 756 |
+
"0xD7A5-2": "2F2",
|
| 757 |
+
"0xD7A5-3": "2F3",
|
| 758 |
+
"0xD7A5-4": "2F4",
|
| 759 |
+
"0xD7A5-5": "2F5",
|
| 760 |
+
"0xD7A5-6": "2F6",
|
| 761 |
+
"0xD7A5-7": "2F7",
|
| 762 |
+
"0xD7A6-0": "2F8",
|
| 763 |
+
"0xD7A6-1": "2F9",
|
| 764 |
+
"0xD7A6-2": "2Fa",
|
| 765 |
+
"0xD7A6-3": "2Fb",
|
| 766 |
+
"0xD7A6-4": "2Fc",
|
| 767 |
+
"0xD7A6-5": "2Fd",
|
| 768 |
+
"0xD7A6-6": "2Fe",
|
| 769 |
+
"0xD7A6-7": "2Ff",
|
| 770 |
+
"0xD7A7-0": "300",
|
| 771 |
+
"0xD7A7-1": "301",
|
| 772 |
+
"0xD7A7-2": "302",
|
| 773 |
+
"0xD7A7-3": "303",
|
| 774 |
+
"0xD7A7-4": "304",
|
| 775 |
+
"0xD7A7-5": "305",
|
| 776 |
+
"0xD7A7-6": "306",
|
| 777 |
+
"0xD7A7-7": "307",
|
| 778 |
+
"0xD7A8-0": "308",
|
| 779 |
+
"0xD7A8-1": "309",
|
| 780 |
+
"0xD7A8-2": "30A",
|
| 781 |
+
"0xD7A8-3": "30B",
|
| 782 |
+
"0xD7A8-4": "30C",
|
| 783 |
+
"0xD7A8-5": "30D",
|
| 784 |
+
"0xD7A8-6": "30E",
|
| 785 |
+
"0xD7A8-7": "30F",
|
| 786 |
+
"0xD7A9-0": "310",
|
| 787 |
+
"0xD7A9-1": "311",
|
| 788 |
+
"0xD7A9-2": "312",
|
| 789 |
+
"0xD7A9-3": "313",
|
| 790 |
+
"0xD7A9-4": "314",
|
| 791 |
+
"0xD7A9-5": "315",
|
| 792 |
+
"0xD7A9-6": "316",
|
| 793 |
+
"0xD7A9-7": "317",
|
| 794 |
+
"0xD7AA-0": "318",
|
| 795 |
+
"0xD7AA-1": "319",
|
| 796 |
+
"0xD7AA-2": "31A",
|
| 797 |
+
"0xD7AA-3": "31B",
|
| 798 |
+
"0xD7AA-4": "31C",
|
| 799 |
+
"0xD7AA-5": "31D",
|
| 800 |
+
"0xD7AA-6": "31E",
|
| 801 |
+
"0xD7AA-7": "31F",
|
| 802 |
+
"0xD7AB-0": "320",
|
| 803 |
+
"0xD7AB-1": "321",
|
| 804 |
+
"0xD7AB-2": "322",
|
| 805 |
+
"0xD7AB-3": "323",
|
| 806 |
+
"0xD7AB-4": "324",
|
| 807 |
+
"0xD7AB-5": "325",
|
| 808 |
+
"0xD7AB-6": "326",
|
| 809 |
+
"0xD7AB-7": "327",
|
| 810 |
+
"0xD7AC-0": "328",
|
| 811 |
+
"0xD7AC-1": "329",
|
| 812 |
+
"0xD7AC-2": "32A",
|
| 813 |
+
"0xD7AC-3": "32B",
|
| 814 |
+
"0xD7AC-4": "32C",
|
| 815 |
+
"0xD7AC-5": "32D",
|
| 816 |
+
"0xD7AC-6": "32E",
|
| 817 |
+
"0xD7AC-7": "32F",
|
| 818 |
+
"0xD7AD-0": "330",
|
| 819 |
+
"0xD7AD-1": "331",
|
| 820 |
+
"0xD7AD-2": "332",
|
| 821 |
+
"0xD7AD-3": "333",
|
| 822 |
+
"0xD7AD-4": "334",
|
| 823 |
+
"0xD7AD-5": "335",
|
| 824 |
+
"0xD7AD-6": "336",
|
| 825 |
+
"0xD7AD-7": "337",
|
| 826 |
+
"0xD7AE-0": "338",
|
| 827 |
+
"0xD7AE-1": "339",
|
| 828 |
+
"0xD7AE-2": "33A",
|
| 829 |
+
"0xD7AE-3": "33B",
|
| 830 |
+
"0xD7AE-4": "33C",
|
| 831 |
+
"0xD7AE-5": "33D",
|
| 832 |
+
"0xD7AE-6": "33E",
|
| 833 |
+
"0xD7AE-7": "33F",
|
| 834 |
+
"0xD7AF-0": "Got Tm31",
|
| 835 |
+
"0xD7AF-1": "341",
|
| 836 |
+
"0xD7AF-2": "342",
|
| 837 |
+
"0xD7AF-3": "343",
|
| 838 |
+
"0xD7AF-4": "344",
|
| 839 |
+
"0xD7AF-5": "345",
|
| 840 |
+
"0xD7AF-6": "346",
|
| 841 |
+
"0xD7AF-7": "347",
|
| 842 |
+
"0xD7B0-0": "348",
|
| 843 |
+
"0xD7B0-1": "349",
|
| 844 |
+
"0xD7B0-2": "34A",
|
| 845 |
+
"0xD7B0-3": "34B",
|
| 846 |
+
"0xD7B0-4": "34C",
|
| 847 |
+
"0xD7B0-5": "34D",
|
| 848 |
+
"0xD7B0-6": "34E",
|
| 849 |
+
"0xD7B0-7": "34F",
|
| 850 |
+
"0xD7B1-0": "Defeated Fighting Dojo",
|
| 851 |
+
"0xD7B1-1": "Beat Karate Master",
|
| 852 |
+
"0xD7B1-2": "Beat Fighting Dojo Trainer 0",
|
| 853 |
+
"0xD7B1-3": "Beat Fighting Dojo Trainer 1",
|
| 854 |
+
"0xD7B1-4": "Beat Fighting Dojo Trainer 2",
|
| 855 |
+
"0xD7B1-5": "Beat Fighting Dojo Trainer 3",
|
| 856 |
+
"0xD7B1-6": "Got Hitmonlee",
|
| 857 |
+
"0xD7B1-7": "Got Hitmonchan",
|
| 858 |
+
"0xD7B2-0": "358",
|
| 859 |
+
"0xD7B2-1": "359",
|
| 860 |
+
"0xD7B2-2": "35A",
|
| 861 |
+
"0xD7B2-3": "35B",
|
| 862 |
+
"0xD7B2-4": "35C",
|
| 863 |
+
"0xD7B2-5": "35D",
|
| 864 |
+
"0xD7B2-6": "35E",
|
| 865 |
+
"0xD7B2-7": "35F",
|
| 866 |
+
"0xD7B3-0": "Got Tm46",
|
| 867 |
+
"0xD7B3-1": "Beat Sabrina",
|
| 868 |
+
"0xD7B3-2": "Beat Saffron Gym Trainer 0",
|
| 869 |
+
"0xD7B3-3": "Beat Saffron Gym Trainer 1",
|
| 870 |
+
"0xD7B3-4": "Beat Saffron Gym Trainer 2",
|
| 871 |
+
"0xD7B3-5": "Beat Saffron Gym Trainer 3",
|
| 872 |
+
"0xD7B3-6": "Beat Saffron Gym Trainer 4",
|
| 873 |
+
"0xD7B3-7": "Beat Saffron Gym Trainer 5",
|
| 874 |
+
"0xD7B4-0": "Beat Saffron Gym Trainer 6",
|
| 875 |
+
"0xD7B4-1": "369",
|
| 876 |
+
"0xD7B4-2": "36A",
|
| 877 |
+
"0xD7B4-3": "36B",
|
| 878 |
+
"0xD7B4-4": "36C",
|
| 879 |
+
"0xD7B4-5": "36D",
|
| 880 |
+
"0xD7B4-6": "36E",
|
| 881 |
+
"0xD7B4-7": "36F",
|
| 882 |
+
"0xD7B5-0": "370",
|
| 883 |
+
"0xD7B5-1": "371",
|
| 884 |
+
"0xD7B5-2": "372",
|
| 885 |
+
"0xD7B5-3": "373",
|
| 886 |
+
"0xD7B5-4": "374",
|
| 887 |
+
"0xD7B5-5": "375",
|
| 888 |
+
"0xD7B5-6": "376",
|
| 889 |
+
"0xD7B5-7": "377",
|
| 890 |
+
"0xD7B6-0": "378",
|
| 891 |
+
"0xD7B6-1": "379",
|
| 892 |
+
"0xD7B6-2": "37A",
|
| 893 |
+
"0xD7B6-3": "37B",
|
| 894 |
+
"0xD7B6-4": "37C",
|
| 895 |
+
"0xD7B6-5": "37D",
|
| 896 |
+
"0xD7B6-6": "37E",
|
| 897 |
+
"0xD7B6-7": "37F",
|
| 898 |
+
"0xD7B7-0": "380",
|
| 899 |
+
"0xD7B7-1": "381",
|
| 900 |
+
"0xD7B7-2": "382",
|
| 901 |
+
"0xD7B7-3": "383",
|
| 902 |
+
"0xD7B7-4": "384",
|
| 903 |
+
"0xD7B7-5": "385",
|
| 904 |
+
"0xD7B7-6": "386",
|
| 905 |
+
"0xD7B7-7": "387",
|
| 906 |
+
"0xD7B8-0": "388",
|
| 907 |
+
"0xD7B8-1": "389",
|
| 908 |
+
"0xD7B8-2": "38A",
|
| 909 |
+
"0xD7B8-3": "38B",
|
| 910 |
+
"0xD7B8-4": "38C",
|
| 911 |
+
"0xD7B8-5": "38D",
|
| 912 |
+
"0xD7B8-6": "38E",
|
| 913 |
+
"0xD7B8-7": "38F",
|
| 914 |
+
"0xD7B9-0": "390",
|
| 915 |
+
"0xD7B9-1": "391",
|
| 916 |
+
"0xD7B9-2": "392",
|
| 917 |
+
"0xD7B9-3": "393",
|
| 918 |
+
"0xD7B9-4": "394",
|
| 919 |
+
"0xD7B9-5": "395",
|
| 920 |
+
"0xD7B9-6": "396",
|
| 921 |
+
"0xD7B9-7": "Silph Co Receptionist At Desk",
|
| 922 |
+
"0xD7BA-0": "398",
|
| 923 |
+
"0xD7BA-1": "399",
|
| 924 |
+
"0xD7BA-2": "39A",
|
| 925 |
+
"0xD7BA-3": "39B",
|
| 926 |
+
"0xD7BA-4": "39C",
|
| 927 |
+
"0xD7BA-5": "39D",
|
| 928 |
+
"0xD7BA-6": "39E",
|
| 929 |
+
"0xD7BA-7": "39F",
|
| 930 |
+
"0xD7BB-0": "3A0",
|
| 931 |
+
"0xD7BB-1": "3A1",
|
| 932 |
+
"0xD7BB-2": "3A2",
|
| 933 |
+
"0xD7BB-3": "3A3",
|
| 934 |
+
"0xD7BB-4": "3A4",
|
| 935 |
+
"0xD7BB-5": "3A5",
|
| 936 |
+
"0xD7BB-6": "3A6",
|
| 937 |
+
"0xD7BB-7": "3A7",
|
| 938 |
+
"0xD7BC-0": "3A8",
|
| 939 |
+
"0xD7BC-1": "3A9",
|
| 940 |
+
"0xD7BC-2": "3Aa",
|
| 941 |
+
"0xD7BC-3": "3Ab",
|
| 942 |
+
"0xD7BC-4": "3Ac",
|
| 943 |
+
"0xD7BC-5": "3Ad",
|
| 944 |
+
"0xD7BC-6": "3Ae",
|
| 945 |
+
"0xD7BC-7": "3Af",
|
| 946 |
+
"0xD7BD-0": "Got Tm29",
|
| 947 |
+
"0xD7BD-1": "3B1",
|
| 948 |
+
"0xD7BD-2": "3B2",
|
| 949 |
+
"0xD7BD-3": "3B3",
|
| 950 |
+
"0xD7BD-4": "3B4",
|
| 951 |
+
"0xD7BD-5": "3B5",
|
| 952 |
+
"0xD7BD-6": "3B6",
|
| 953 |
+
"0xD7BD-7": "3B7",
|
| 954 |
+
"0xD7BE-0": "3B8",
|
| 955 |
+
"0xD7BE-1": "3B9",
|
| 956 |
+
"0xD7BE-2": "3Ba",
|
| 957 |
+
"0xD7BE-3": "3Bb",
|
| 958 |
+
"0xD7BE-4": "3Bc",
|
| 959 |
+
"0xD7BE-5": "3Bd",
|
| 960 |
+
"0xD7BE-6": "3Be",
|
| 961 |
+
"0xD7BE-7": "3Bf",
|
| 962 |
+
"0xD7BF-0": "Got Potion Sample",
|
| 963 |
+
"0xD7BF-1": "3C1",
|
| 964 |
+
"0xD7BF-2": "3C2",
|
| 965 |
+
"0xD7BF-3": "3C3",
|
| 966 |
+
"0xD7BF-4": "3C4",
|
| 967 |
+
"0xD7BF-5": "3C5",
|
| 968 |
+
"0xD7BF-6": "3C6",
|
| 969 |
+
"0xD7BF-7": "3C7",
|
| 970 |
+
"0xD7C0-0": "3C8",
|
| 971 |
+
"0xD7C0-1": "3C9",
|
| 972 |
+
"0xD7C0-2": "3Ca",
|
| 973 |
+
"0xD7C0-3": "3Cb",
|
| 974 |
+
"0xD7C0-4": "3Cc",
|
| 975 |
+
"0xD7C0-5": "3Cd",
|
| 976 |
+
"0xD7C0-6": "3Ce",
|
| 977 |
+
"0xD7C0-7": "3Cf",
|
| 978 |
+
"0xD7C1-0": "3D0",
|
| 979 |
+
"0xD7C1-1": "3D1",
|
| 980 |
+
"0xD7C1-2": "3D2",
|
| 981 |
+
"0xD7C1-3": "3D3",
|
| 982 |
+
"0xD7C1-4": "3D4",
|
| 983 |
+
"0xD7C1-5": "3D5",
|
| 984 |
+
"0xD7C1-6": "3D6",
|
| 985 |
+
"0xD7C1-7": "3D7",
|
| 986 |
+
"0xD7C2-0": "Got Hm05",
|
| 987 |
+
"0xD7C2-1": "3D9",
|
| 988 |
+
"0xD7C2-2": "3Da",
|
| 989 |
+
"0xD7C2-3": "3Db",
|
| 990 |
+
"0xD7C2-4": "3Dc",
|
| 991 |
+
"0xD7C2-5": "3Dd",
|
| 992 |
+
"0xD7C2-6": "3De",
|
| 993 |
+
"0xD7C2-7": "3Df",
|
| 994 |
+
"0xD7C3-0": "3E0",
|
| 995 |
+
"0xD7C3-1": "3E1",
|
| 996 |
+
"0xD7C3-2": "Beat Route 3 Trainer 0",
|
| 997 |
+
"0xD7C3-3": "Beat Route 3 Trainer 1",
|
| 998 |
+
"0xD7C3-4": "Beat Route 3 Trainer 2",
|
| 999 |
+
"0xD7C3-5": "Beat Route 3 Trainer 3",
|
| 1000 |
+
"0xD7C3-6": "Beat Route 3 Trainer 4",
|
| 1001 |
+
"0xD7C3-7": "Beat Route 3 Trainer 5",
|
| 1002 |
+
"0xD7C4-0": "Beat Route 3 Trainer 6",
|
| 1003 |
+
"0xD7C4-1": "Beat Route 3 Trainer 7",
|
| 1004 |
+
"0xD7C4-2": "3Ea",
|
| 1005 |
+
"0xD7C4-3": "3Eb",
|
| 1006 |
+
"0xD7C4-4": "3Ec",
|
| 1007 |
+
"0xD7C4-5": "3Ed",
|
| 1008 |
+
"0xD7C4-6": "3Ee",
|
| 1009 |
+
"0xD7C4-7": "3Ef",
|
| 1010 |
+
"0xD7C5-0": "3F0",
|
| 1011 |
+
"0xD7C5-1": "3F1",
|
| 1012 |
+
"0xD7C5-2": "Beat Route 4 Trainer 0",
|
| 1013 |
+
"0xD7C5-3": "3F3",
|
| 1014 |
+
"0xD7C5-4": "3F4",
|
| 1015 |
+
"0xD7C5-5": "3F5",
|
| 1016 |
+
"0xD7C5-6": "3F6",
|
| 1017 |
+
"0xD7C5-7": "3F7",
|
| 1018 |
+
"0xD7C6-0": "3F8",
|
| 1019 |
+
"0xD7C6-1": "3F9",
|
| 1020 |
+
"0xD7C6-2": "3Fa",
|
| 1021 |
+
"0xD7C6-3": "3Fb",
|
| 1022 |
+
"0xD7C6-4": "3Fc",
|
| 1023 |
+
"0xD7C6-5": "3Fd",
|
| 1024 |
+
"0xD7C6-6": "3Fe",
|
| 1025 |
+
"0xD7C6-7": "Bought Magikarp",
|
| 1026 |
+
"0xD7C7-0": "400",
|
| 1027 |
+
"0xD7C7-1": "401",
|
| 1028 |
+
"0xD7C7-2": "402",
|
| 1029 |
+
"0xD7C7-3": "403",
|
| 1030 |
+
"0xD7C7-4": "404",
|
| 1031 |
+
"0xD7C7-5": "405",
|
| 1032 |
+
"0xD7C7-6": "406",
|
| 1033 |
+
"0xD7C7-7": "407",
|
| 1034 |
+
"0xD7C8-0": "408",
|
| 1035 |
+
"0xD7C8-1": "409",
|
| 1036 |
+
"0xD7C8-2": "40A",
|
| 1037 |
+
"0xD7C8-3": "40B",
|
| 1038 |
+
"0xD7C8-4": "40C",
|
| 1039 |
+
"0xD7C8-5": "40D",
|
| 1040 |
+
"0xD7C8-6": "40E",
|
| 1041 |
+
"0xD7C8-7": "40F",
|
| 1042 |
+
"0xD7C9-0": "410",
|
| 1043 |
+
"0xD7C9-1": "Beat Route 6 Trainer 0",
|
| 1044 |
+
"0xD7C9-2": "Beat Route 6 Trainer 1",
|
| 1045 |
+
"0xD7C9-3": "Beat Route 6 Trainer 2",
|
| 1046 |
+
"0xD7C9-4": "Beat Route 6 Trainer 3",
|
| 1047 |
+
"0xD7C9-5": "Beat Route 6 Trainer 4",
|
| 1048 |
+
"0xD7C9-6": "Beat Route 6 Trainer 5",
|
| 1049 |
+
"0xD7C9-7": "417",
|
| 1050 |
+
"0xD7CA-0": "418",
|
| 1051 |
+
"0xD7CA-1": "419",
|
| 1052 |
+
"0xD7CA-2": "41A",
|
| 1053 |
+
"0xD7CA-3": "41B",
|
| 1054 |
+
"0xD7CA-4": "41C",
|
| 1055 |
+
"0xD7CA-5": "41D",
|
| 1056 |
+
"0xD7CA-6": "41E",
|
| 1057 |
+
"0xD7CA-7": "41F",
|
| 1058 |
+
"0xD7CB-0": "420",
|
| 1059 |
+
"0xD7CB-1": "421",
|
| 1060 |
+
"0xD7CB-2": "422",
|
| 1061 |
+
"0xD7CB-3": "423",
|
| 1062 |
+
"0xD7CB-4": "424",
|
| 1063 |
+
"0xD7CB-5": "425",
|
| 1064 |
+
"0xD7CB-6": "426",
|
| 1065 |
+
"0xD7CB-7": "427",
|
| 1066 |
+
"0xD7CC-0": "428",
|
| 1067 |
+
"0xD7CC-1": "429",
|
| 1068 |
+
"0xD7CC-2": "42A",
|
| 1069 |
+
"0xD7CC-3": "42B",
|
| 1070 |
+
"0xD7CC-4": "42C",
|
| 1071 |
+
"0xD7CC-5": "42D",
|
| 1072 |
+
"0xD7CC-6": "42E",
|
| 1073 |
+
"0xD7CC-7": "42F",
|
| 1074 |
+
"0xD7CD-0": "430",
|
| 1075 |
+
"0xD7CD-1": "Beat Route 8 Trainer 0",
|
| 1076 |
+
"0xD7CD-2": "Beat Route 8 Trainer 1",
|
| 1077 |
+
"0xD7CD-3": "Beat Route 8 Trainer 2",
|
| 1078 |
+
"0xD7CD-4": "Beat Route 8 Trainer 3",
|
| 1079 |
+
"0xD7CD-5": "Beat Route 8 Trainer 4",
|
| 1080 |
+
"0xD7CD-6": "Beat Route 8 Trainer 5",
|
| 1081 |
+
"0xD7CD-7": "Beat Route 8 Trainer 6",
|
| 1082 |
+
"0xD7CE-0": "Beat Route 8 Trainer 7",
|
| 1083 |
+
"0xD7CE-1": "Beat Route 8 Trainer 8",
|
| 1084 |
+
"0xD7CE-2": "43A",
|
| 1085 |
+
"0xD7CE-3": "43B",
|
| 1086 |
+
"0xD7CE-4": "43C",
|
| 1087 |
+
"0xD7CE-5": "43D",
|
| 1088 |
+
"0xD7CE-6": "43E",
|
| 1089 |
+
"0xD7CE-7": "43F",
|
| 1090 |
+
"0xD7CF-0": "440",
|
| 1091 |
+
"0xD7CF-1": "Beat Route 9 Trainer 0",
|
| 1092 |
+
"0xD7CF-2": "Beat Route 9 Trainer 1",
|
| 1093 |
+
"0xD7CF-3": "Beat Route 9 Trainer 2",
|
| 1094 |
+
"0xD7CF-4": "Beat Route 9 Trainer 3",
|
| 1095 |
+
"0xD7CF-5": "Beat Route 9 Trainer 4",
|
| 1096 |
+
"0xD7CF-6": "Beat Route 9 Trainer 5",
|
| 1097 |
+
"0xD7CF-7": "Beat Route 9 Trainer 6",
|
| 1098 |
+
"0xD7D0-0": "Beat Route 9 Trainer 7",
|
| 1099 |
+
"0xD7D0-1": "Beat Route 9 Trainer 8",
|
| 1100 |
+
"0xD7D0-2": "44A",
|
| 1101 |
+
"0xD7D0-3": "44B",
|
| 1102 |
+
"0xD7D0-4": "44C",
|
| 1103 |
+
"0xD7D0-5": "44D",
|
| 1104 |
+
"0xD7D0-6": "44E",
|
| 1105 |
+
"0xD7D0-7": "44F",
|
| 1106 |
+
"0xD7D1-0": "450",
|
| 1107 |
+
"0xD7D1-1": "Beat Route 10 Trainer 0",
|
| 1108 |
+
"0xD7D1-2": "Beat Route 10 Trainer 1",
|
| 1109 |
+
"0xD7D1-3": "Beat Route 10 Trainer 2",
|
| 1110 |
+
"0xD7D1-4": "Beat Route 10 Trainer 3",
|
| 1111 |
+
"0xD7D1-5": "Beat Route 10 Trainer 4",
|
| 1112 |
+
"0xD7D1-6": "Beat Route 10 Trainer 5",
|
| 1113 |
+
"0xD7D1-7": "457",
|
| 1114 |
+
"0xD7D2-0": "458",
|
| 1115 |
+
"0xD7D2-1": "Beat Rock Tunnel 1 Trainer 0",
|
| 1116 |
+
"0xD7D2-2": "Beat Rock Tunnel 1 Trainer 1",
|
| 1117 |
+
"0xD7D2-3": "Beat Rock Tunnel 1 Trainer 2",
|
| 1118 |
+
"0xD7D2-4": "Beat Rock Tunnel 1 Trainer 3",
|
| 1119 |
+
"0xD7D2-5": "Beat Rock Tunnel 1 Trainer 4",
|
| 1120 |
+
"0xD7D2-6": "Beat Rock Tunnel 1 Trainer 5",
|
| 1121 |
+
"0xD7D2-7": "Beat Rock Tunnel 1 Trainer 6",
|
| 1122 |
+
"0xD7D3-0": "460",
|
| 1123 |
+
"0xD7D3-1": "Beat Power Plant Voltorb 0",
|
| 1124 |
+
"0xD7D3-2": "Beat Power Plant Voltorb 1",
|
| 1125 |
+
"0xD7D3-3": "Beat Power Plant Voltorb 2",
|
| 1126 |
+
"0xD7D3-4": "Beat Power Plant Voltorb 3",
|
| 1127 |
+
"0xD7D3-5": "Beat Power Plant Voltorb 4",
|
| 1128 |
+
"0xD7D3-6": "Beat Power Plant Voltorb 5",
|
| 1129 |
+
"0xD7D3-7": "Beat Power Plant Voltorb 6",
|
| 1130 |
+
"0xD7D4-0": "Beat Power Plant Voltorb 7",
|
| 1131 |
+
"0xD7D4-1": "Beat Zapdos",
|
| 1132 |
+
"0xD7D4-2": "46A",
|
| 1133 |
+
"0xD7D4-3": "46B",
|
| 1134 |
+
"0xD7D4-4": "46C",
|
| 1135 |
+
"0xD7D4-5": "46D",
|
| 1136 |
+
"0xD7D4-6": "46E",
|
| 1137 |
+
"0xD7D4-7": "46F",
|
| 1138 |
+
"0xD7D5-0": "470",
|
| 1139 |
+
"0xD7D5-1": "Beat Route 11 Trainer 0",
|
| 1140 |
+
"0xD7D5-2": "Beat Route 11 Trainer 1",
|
| 1141 |
+
"0xD7D5-3": "Beat Route 11 Trainer 2",
|
| 1142 |
+
"0xD7D5-4": "Beat Route 11 Trainer 3",
|
| 1143 |
+
"0xD7D5-5": "Beat Route 11 Trainer 4",
|
| 1144 |
+
"0xD7D5-6": "Beat Route 11 Trainer 5",
|
| 1145 |
+
"0xD7D5-7": "Beat Route 11 Trainer 6",
|
| 1146 |
+
"0xD7D6-0": "Beat Route 11 Trainer 7",
|
| 1147 |
+
"0xD7D6-1": "Beat Route 11 Trainer 8",
|
| 1148 |
+
"0xD7D6-2": "Beat Route 11 Trainer 9",
|
| 1149 |
+
"0xD7D6-3": "47B",
|
| 1150 |
+
"0xD7D6-4": "47C",
|
| 1151 |
+
"0xD7D6-5": "47D",
|
| 1152 |
+
"0xD7D6-6": "47E",
|
| 1153 |
+
"0xD7D6-7": "Got Itemfinder",
|
| 1154 |
+
"0xD7D7-0": "Got Tm39",
|
| 1155 |
+
"0xD7D7-1": "481",
|
| 1156 |
+
"0xD7D7-2": "Beat Route 12 Trainer 0",
|
| 1157 |
+
"0xD7D7-3": "Beat Route 12 Trainer 1",
|
| 1158 |
+
"0xD7D7-4": "Beat Route 12 Trainer 2",
|
| 1159 |
+
"0xD7D7-5": "Beat Route 12 Trainer 3",
|
| 1160 |
+
"0xD7D7-6": "Beat Route 12 Trainer 4",
|
| 1161 |
+
"0xD7D7-7": "Beat Route 12 Trainer 5",
|
| 1162 |
+
"0xD7D8-0": "Beat Route 12 Trainer 6",
|
| 1163 |
+
"0xD7D8-1": "489",
|
| 1164 |
+
"0xD7D8-2": "48A",
|
| 1165 |
+
"0xD7D8-3": "48B",
|
| 1166 |
+
"0xD7D8-4": "48C",
|
| 1167 |
+
"0xD7D8-5": "48D",
|
| 1168 |
+
"0xD7D8-6": "Fight Route12 Snorlax",
|
| 1169 |
+
"0xD7D8-7": "Beat Route12 Snorlax",
|
| 1170 |
+
"0xD7D9-0": "490",
|
| 1171 |
+
"0xD7D9-1": "Beat Route 13 Trainer 0",
|
| 1172 |
+
"0xD7D9-2": "Beat Route 13 Trainer 1",
|
| 1173 |
+
"0xD7D9-3": "Beat Route 13 Trainer 2",
|
| 1174 |
+
"0xD7D9-4": "Beat Route 13 Trainer 3",
|
| 1175 |
+
"0xD7D9-5": "Beat Route 13 Trainer 4",
|
| 1176 |
+
"0xD7D9-6": "Beat Route 13 Trainer 5",
|
| 1177 |
+
"0xD7D9-7": "Beat Route 13 Trainer 6",
|
| 1178 |
+
"0xD7DA-0": "Beat Route 13 Trainer 7",
|
| 1179 |
+
"0xD7DA-1": "Beat Route 13 Trainer 8",
|
| 1180 |
+
"0xD7DA-2": "Beat Route 13 Trainer 9",
|
| 1181 |
+
"0xD7DA-3": "49B",
|
| 1182 |
+
"0xD7DA-4": "49C",
|
| 1183 |
+
"0xD7DA-5": "49D",
|
| 1184 |
+
"0xD7DA-6": "49E",
|
| 1185 |
+
"0xD7DA-7": "49F",
|
| 1186 |
+
"0xD7DB-0": "4A0",
|
| 1187 |
+
"0xD7DB-1": "Beat Route 14 Trainer 0",
|
| 1188 |
+
"0xD7DB-2": "Beat Route 14 Trainer 1",
|
| 1189 |
+
"0xD7DB-3": "Beat Route 14 Trainer 2",
|
| 1190 |
+
"0xD7DB-4": "Beat Route 14 Trainer 3",
|
| 1191 |
+
"0xD7DB-5": "Beat Route 14 Trainer 4",
|
| 1192 |
+
"0xD7DB-6": "Beat Route 14 Trainer 5",
|
| 1193 |
+
"0xD7DB-7": "Beat Route 14 Trainer 6",
|
| 1194 |
+
"0xD7DC-0": "Beat Route 14 Trainer 7",
|
| 1195 |
+
"0xD7DC-1": "Beat Route 14 Trainer 8",
|
| 1196 |
+
"0xD7DC-2": "Beat Route 14 Trainer 9",
|
| 1197 |
+
"0xD7DC-3": "4Ab",
|
| 1198 |
+
"0xD7DC-4": "4Ac",
|
| 1199 |
+
"0xD7DC-5": "4Ad",
|
| 1200 |
+
"0xD7DC-6": "4Ae",
|
| 1201 |
+
"0xD7DC-7": "4Af",
|
| 1202 |
+
"0xD7DD-0": "Got Exp All",
|
| 1203 |
+
"0xD7DD-1": "Beat Route 15 Trainer 0",
|
| 1204 |
+
"0xD7DD-2": "Beat Route 15 Trainer 1",
|
| 1205 |
+
"0xD7DD-3": "Beat Route 15 Trainer 2",
|
| 1206 |
+
"0xD7DD-4": "Beat Route 15 Trainer 3",
|
| 1207 |
+
"0xD7DD-5": "Beat Route 15 Trainer 4",
|
| 1208 |
+
"0xD7DD-6": "Beat Route 15 Trainer 5",
|
| 1209 |
+
"0xD7DD-7": "Beat Route 15 Trainer 6",
|
| 1210 |
+
"0xD7DE-0": "Beat Route 15 Trainer 7",
|
| 1211 |
+
"0xD7DE-1": "Beat Route 15 Trainer 8",
|
| 1212 |
+
"0xD7DE-2": "Beat Route 15 Trainer 9",
|
| 1213 |
+
"0xD7DE-3": "4Bb",
|
| 1214 |
+
"0xD7DE-4": "4Bc",
|
| 1215 |
+
"0xD7DE-5": "4Bd",
|
| 1216 |
+
"0xD7DE-6": "4Be",
|
| 1217 |
+
"0xD7DE-7": "4Bf",
|
| 1218 |
+
"0xD7DF-0": "4C0",
|
| 1219 |
+
"0xD7DF-1": "Beat Route 16 Trainer 0",
|
| 1220 |
+
"0xD7DF-2": "Beat Route 16 Trainer 1",
|
| 1221 |
+
"0xD7DF-3": "Beat Route 16 Trainer 2",
|
| 1222 |
+
"0xD7DF-4": "Beat Route 16 Trainer 3",
|
| 1223 |
+
"0xD7DF-5": "Beat Route 16 Trainer 4",
|
| 1224 |
+
"0xD7DF-6": "Beat Route 16 Trainer 5",
|
| 1225 |
+
"0xD7DF-7": "4C7",
|
| 1226 |
+
"0xD7E0-0": "Fight Route16 Snorlax",
|
| 1227 |
+
"0xD7E0-1": "Beat Route16 Snorlax",
|
| 1228 |
+
"0xD7E0-2": "4Ca",
|
| 1229 |
+
"0xD7E0-3": "4Cb",
|
| 1230 |
+
"0xD7E0-4": "4Cc",
|
| 1231 |
+
"0xD7E0-5": "4Cd",
|
| 1232 |
+
"0xD7E0-6": "Got Hm02",
|
| 1233 |
+
"0xD7E0-7": "Rescued Mr Fuji",
|
| 1234 |
+
"0xD7E1-0": "4D0",
|
| 1235 |
+
"0xD7E1-1": "Beat Route 17 Trainer 0",
|
| 1236 |
+
"0xD7E1-2": "Beat Route 17 Trainer 1",
|
| 1237 |
+
"0xD7E1-3": "Beat Route 17 Trainer 2",
|
| 1238 |
+
"0xD7E1-4": "Beat Route 17 Trainer 3",
|
| 1239 |
+
"0xD7E1-5": "Beat Route 17 Trainer 4",
|
| 1240 |
+
"0xD7E1-6": "Beat Route 17 Trainer 5",
|
| 1241 |
+
"0xD7E1-7": "Beat Route 17 Trainer 6",
|
| 1242 |
+
"0xD7E2-0": "Beat Route 17 Trainer 7",
|
| 1243 |
+
"0xD7E2-1": "Beat Route 17 Trainer 8",
|
| 1244 |
+
"0xD7E2-2": "Beat Route 17 Trainer 9",
|
| 1245 |
+
"0xD7E2-3": "4Db",
|
| 1246 |
+
"0xD7E2-4": "4Dc",
|
| 1247 |
+
"0xD7E2-5": "4Dd",
|
| 1248 |
+
"0xD7E2-6": "4De",
|
| 1249 |
+
"0xD7E2-7": "4Df",
|
| 1250 |
+
"0xD7E3-0": "4E0",
|
| 1251 |
+
"0xD7E3-1": "Beat Route 18 Trainer 0",
|
| 1252 |
+
"0xD7E3-2": "Beat Route 18 Trainer 1",
|
| 1253 |
+
"0xD7E3-3": "Beat Route 18 Trainer 2",
|
| 1254 |
+
"0xD7E3-4": "4E4",
|
| 1255 |
+
"0xD7E3-5": "4E5",
|
| 1256 |
+
"0xD7E3-6": "4E6",
|
| 1257 |
+
"0xD7E3-7": "4E7",
|
| 1258 |
+
"0xD7E4-0": "4E8",
|
| 1259 |
+
"0xD7E4-1": "4E9",
|
| 1260 |
+
"0xD7E4-2": "4Ea",
|
| 1261 |
+
"0xD7E4-3": "4Eb",
|
| 1262 |
+
"0xD7E4-4": "4Ec",
|
| 1263 |
+
"0xD7E4-5": "4Ed",
|
| 1264 |
+
"0xD7E4-6": "4Ee",
|
| 1265 |
+
"0xD7E4-7": "4Ef",
|
| 1266 |
+
"0xD7E5-0": "4F0",
|
| 1267 |
+
"0xD7E5-1": "Beat Route 19 Trainer 0",
|
| 1268 |
+
"0xD7E5-2": "Beat Route 19 Trainer 1",
|
| 1269 |
+
"0xD7E5-3": "Beat Route 19 Trainer 2",
|
| 1270 |
+
"0xD7E5-4": "Beat Route 19 Trainer 3",
|
| 1271 |
+
"0xD7E5-5": "Beat Route 19 Trainer 4",
|
| 1272 |
+
"0xD7E5-6": "Beat Route 19 Trainer 5",
|
| 1273 |
+
"0xD7E5-7": "Beat Route 19 Trainer 6",
|
| 1274 |
+
"0xD7E6-0": "Beat Route 19 Trainer 7",
|
| 1275 |
+
"0xD7E6-1": "Beat Route 19 Trainer 8",
|
| 1276 |
+
"0xD7E6-2": "Beat Route 19 Trainer 9",
|
| 1277 |
+
"0xD7E6-3": "4Fb",
|
| 1278 |
+
"0xD7E6-4": "4Fc",
|
| 1279 |
+
"0xD7E6-5": "4Fd",
|
| 1280 |
+
"0xD7E6-6": "4Fe",
|
| 1281 |
+
"0xD7E6-7": "4Ff",
|
| 1282 |
+
"0xD7E7-0": "In Seafoam Islands",
|
| 1283 |
+
"0xD7E7-1": "Beat Route 20 Trainer 0",
|
| 1284 |
+
"0xD7E7-2": "Beat Route 20 Trainer 1",
|
| 1285 |
+
"0xD7E7-3": "Beat Route 20 Trainer 2",
|
| 1286 |
+
"0xD7E7-4": "Beat Route 20 Trainer 3",
|
| 1287 |
+
"0xD7E7-5": "Beat Route 20 Trainer 4",
|
| 1288 |
+
"0xD7E7-6": "Beat Route 20 Trainer 5",
|
| 1289 |
+
"0xD7E7-7": "Beat Route 20 Trainer 6",
|
| 1290 |
+
"0xD7E8-0": "Beat Route 20 Trainer 7",
|
| 1291 |
+
"0xD7E8-1": "Beat Route 20 Trainer 8",
|
| 1292 |
+
"0xD7E8-2": "Beat Route 20 Trainer 9",
|
| 1293 |
+
"0xD7E8-3": "50B",
|
| 1294 |
+
"0xD7E8-4": "50C",
|
| 1295 |
+
"0xD7E8-5": "50D",
|
| 1296 |
+
"0xD7E8-6": "Seafoam1 Boulder1 Down Hole",
|
| 1297 |
+
"0xD7E8-7": "Seafoam1 Boulder2 Down Hole",
|
| 1298 |
+
"0xD7E9-0": "510",
|
| 1299 |
+
"0xD7E9-1": "Beat Route 21 Trainer 0",
|
| 1300 |
+
"0xD7E9-2": "Beat Route 21 Trainer 1",
|
| 1301 |
+
"0xD7E9-3": "Beat Route 21 Trainer 2",
|
| 1302 |
+
"0xD7E9-4": "Beat Route 21 Trainer 3",
|
| 1303 |
+
"0xD7E9-5": "Beat Route 21 Trainer 4",
|
| 1304 |
+
"0xD7E9-6": "Beat Route 21 Trainer 5",
|
| 1305 |
+
"0xD7E9-7": "Beat Route 21 Trainer 6",
|
| 1306 |
+
"0xD7EA-0": "Beat Route 21 Trainer 7",
|
| 1307 |
+
"0xD7EA-1": "Beat Route 21 Trainer 8",
|
| 1308 |
+
"0xD7EA-2": "51A",
|
| 1309 |
+
"0xD7EA-3": "51B",
|
| 1310 |
+
"0xD7EA-4": "51C",
|
| 1311 |
+
"0xD7EA-5": "51D",
|
| 1312 |
+
"0xD7EA-6": "51E",
|
| 1313 |
+
"0xD7EA-7": "51F",
|
| 1314 |
+
"0xD7EB-0": "1St Route22 Rival Battle",
|
| 1315 |
+
"0xD7EB-1": "2Nd Route22 Rival Battle",
|
| 1316 |
+
"0xD7EB-2": "522",
|
| 1317 |
+
"0xD7EB-3": "523",
|
| 1318 |
+
"0xD7EB-4": "524",
|
| 1319 |
+
"0xD7EB-5": "Beat Route22 Rival 1St Battle",
|
| 1320 |
+
"0xD7EB-6": "Beat Route22 Rival 2Nd Battle",
|
| 1321 |
+
"0xD7EB-7": "Route22 Rival Wants Battle",
|
| 1322 |
+
"0xD7EC-0": "528",
|
| 1323 |
+
"0xD7EC-1": "529",
|
| 1324 |
+
"0xD7EC-2": "52A",
|
| 1325 |
+
"0xD7EC-3": "52B",
|
| 1326 |
+
"0xD7EC-4": "52C",
|
| 1327 |
+
"0xD7EC-5": "52D",
|
| 1328 |
+
"0xD7EC-6": "52E",
|
| 1329 |
+
"0xD7EC-7": "52F",
|
| 1330 |
+
"0xD7ED-0": "Passed Cascadebadge Check",
|
| 1331 |
+
"0xD7ED-1": "Passed Thunderbadge Check",
|
| 1332 |
+
"0xD7ED-2": "Passed Rainbowbadge Check",
|
| 1333 |
+
"0xD7ED-3": "Passed Soulbadge Check",
|
| 1334 |
+
"0xD7ED-4": "Passed Marshbadge Check",
|
| 1335 |
+
"0xD7ED-5": "Passed Volcanobadge Check",
|
| 1336 |
+
"0xD7ED-6": "Passed Earthbadge Check",
|
| 1337 |
+
"0xD7ED-7": "537",
|
| 1338 |
+
"0xD7EE-0": "Victory Road 2 Boulder On Switch1",
|
| 1339 |
+
"0xD7EE-1": "Beat Victory Road 2 Trainer 0",
|
| 1340 |
+
"0xD7EE-2": "Beat Victory Road 2 Trainer 1",
|
| 1341 |
+
"0xD7EE-3": "Beat Victory Road 2 Trainer 2",
|
| 1342 |
+
"0xD7EE-4": "Beat Victory Road 2 Trainer 3",
|
| 1343 |
+
"0xD7EE-5": "Beat Victory Road 2 Trainer 4",
|
| 1344 |
+
"0xD7EE-6": "Beat Moltres",
|
| 1345 |
+
"0xD7EE-7": "Victory Road 2 Boulder On Switch2",
|
| 1346 |
+
"0xD7EF-0": "Got Nugget",
|
| 1347 |
+
"0xD7EF-1": "Beat Route24 Rocket",
|
| 1348 |
+
"0xD7EF-2": "Beat Route 24 Trainer 0",
|
| 1349 |
+
"0xD7EF-3": "Beat Route 24 Trainer 1",
|
| 1350 |
+
"0xD7EF-4": "Beat Route 24 Trainer 2",
|
| 1351 |
+
"0xD7EF-5": "Beat Route 24 Trainer 3",
|
| 1352 |
+
"0xD7EF-6": "Beat Route 24 Trainer 4",
|
| 1353 |
+
"0xD7EF-7": "Beat Route 24 Trainer 5",
|
| 1354 |
+
"0xD7F0-0": "548",
|
| 1355 |
+
"0xD7F0-1": "Nugget Reward Available",
|
| 1356 |
+
"0xD7F0-2": "54A",
|
| 1357 |
+
"0xD7F0-3": "54B",
|
| 1358 |
+
"0xD7F0-4": "54C",
|
| 1359 |
+
"0xD7F0-5": "54D",
|
| 1360 |
+
"0xD7F0-6": "54E",
|
| 1361 |
+
"0xD7F0-7": "54F",
|
| 1362 |
+
"0xD7F1-0": "Met Bill",
|
| 1363 |
+
"0xD7F1-1": "Beat Route 25 Trainer 0",
|
| 1364 |
+
"0xD7F1-2": "Beat Route 25 Trainer 1",
|
| 1365 |
+
"0xD7F1-3": "Beat Route 25 Trainer 2",
|
| 1366 |
+
"0xD7F1-4": "Beat Route 25 Trainer 3",
|
| 1367 |
+
"0xD7F1-5": "Beat Route 25 Trainer 4",
|
| 1368 |
+
"0xD7F1-6": "Beat Route 25 Trainer 5",
|
| 1369 |
+
"0xD7F1-7": "Beat Route 25 Trainer 6",
|
| 1370 |
+
"0xD7F2-0": "Beat Route 25 Trainer 7",
|
| 1371 |
+
"0xD7F2-1": "Beat Route 25 Trainer 8",
|
| 1372 |
+
"0xD7F2-2": "55A",
|
| 1373 |
+
"0xD7F2-3": "Used Cell Separator On Bill",
|
| 1374 |
+
"0xD7F2-4": "Got Ss Ticket",
|
| 1375 |
+
"0xD7F2-5": "Met Bill 2",
|
| 1376 |
+
"0xD7F2-6": "Bill Said Use Cell Separator",
|
| 1377 |
+
"0xD7F2-7": "Left Bills House After Helping",
|
| 1378 |
+
"0xD7F3-0": "560",
|
| 1379 |
+
"0xD7F3-1": "561",
|
| 1380 |
+
"0xD7F3-2": "Beat Viridian Forest Trainer 0",
|
| 1381 |
+
"0xD7F3-3": "Beat Viridian Forest Trainer 1",
|
| 1382 |
+
"0xD7F3-4": "Beat Viridian Forest Trainer 2",
|
| 1383 |
+
"0xD7F3-5": "565",
|
| 1384 |
+
"0xD7F3-6": "566",
|
| 1385 |
+
"0xD7F3-7": "567",
|
| 1386 |
+
"0xD7F4-0": "568",
|
| 1387 |
+
"0xD7F4-1": "569",
|
| 1388 |
+
"0xD7F4-2": "56A",
|
| 1389 |
+
"0xD7F4-3": "56B",
|
| 1390 |
+
"0xD7F4-4": "56C",
|
| 1391 |
+
"0xD7F4-5": "56D",
|
| 1392 |
+
"0xD7F4-6": "56E",
|
| 1393 |
+
"0xD7F4-7": "56F",
|
| 1394 |
+
"0xD7F5-0": "570",
|
| 1395 |
+
"0xD7F5-1": "Beat Mt Moon 1 Trainer 0",
|
| 1396 |
+
"0xD7F5-2": "Beat Mt Moon 1 Trainer 1",
|
| 1397 |
+
"0xD7F5-3": "Beat Mt Moon 1 Trainer 2",
|
| 1398 |
+
"0xD7F5-4": "Beat Mt Moon 1 Trainer 3",
|
| 1399 |
+
"0xD7F5-5": "Beat Mt Moon 1 Trainer 4",
|
| 1400 |
+
"0xD7F5-6": "Beat Mt Moon 1 Trainer 5",
|
| 1401 |
+
"0xD7F5-7": "Beat Mt Moon 1 Trainer 6",
|
| 1402 |
+
"0xD7F6-0": "578",
|
| 1403 |
+
"0xD7F6-1": "Beat Mt Moon Exit Super Nerd",
|
| 1404 |
+
"0xD7F6-2": "Beat Mt Moon 3 Trainer 0",
|
| 1405 |
+
"0xD7F6-3": "Beat Mt Moon 3 Trainer 1",
|
| 1406 |
+
"0xD7F6-4": "Beat Mt Moon 3 Trainer 2",
|
| 1407 |
+
"0xD7F6-5": "Beat Mt Moon 3 Trainer 3",
|
| 1408 |
+
"0xD7F6-6": "Got Dome Fossil",
|
| 1409 |
+
"0xD7F6-7": "Got Helix Fossil",
|
| 1410 |
+
"0xD7F7-0": "580",
|
| 1411 |
+
"0xD7F7-1": "581",
|
| 1412 |
+
"0xD7F7-2": "582",
|
| 1413 |
+
"0xD7F7-3": "583",
|
| 1414 |
+
"0xD7F7-4": "584",
|
| 1415 |
+
"0xD7F7-5": "585",
|
| 1416 |
+
"0xD7F7-6": "586",
|
| 1417 |
+
"0xD7F7-7": "587",
|
| 1418 |
+
"0xD7F8-0": "588",
|
| 1419 |
+
"0xD7F8-1": "589",
|
| 1420 |
+
"0xD7F8-2": "58A",
|
| 1421 |
+
"0xD7F8-3": "58B",
|
| 1422 |
+
"0xD7F8-4": "58C",
|
| 1423 |
+
"0xD7F8-5": "58D",
|
| 1424 |
+
"0xD7F8-6": "58E",
|
| 1425 |
+
"0xD7F8-7": "58F",
|
| 1426 |
+
"0xD7F9-0": "590",
|
| 1427 |
+
"0xD7F9-1": "591",
|
| 1428 |
+
"0xD7F9-2": "592",
|
| 1429 |
+
"0xD7F9-3": "593",
|
| 1430 |
+
"0xD7F9-4": "594",
|
| 1431 |
+
"0xD7F9-5": "595",
|
| 1432 |
+
"0xD7F9-6": "596",
|
| 1433 |
+
"0xD7F9-7": "597",
|
| 1434 |
+
"0xD7FA-0": "598",
|
| 1435 |
+
"0xD7FA-1": "599",
|
| 1436 |
+
"0xD7FA-2": "59A",
|
| 1437 |
+
"0xD7FA-3": "59B",
|
| 1438 |
+
"0xD7FA-4": "59C",
|
| 1439 |
+
"0xD7FA-5": "59D",
|
| 1440 |
+
"0xD7FA-6": "59E",
|
| 1441 |
+
"0xD7FA-7": "59F",
|
| 1442 |
+
"0xD7FB-0": "5A0",
|
| 1443 |
+
"0xD7FB-1": "5A1",
|
| 1444 |
+
"0xD7FB-2": "5A2",
|
| 1445 |
+
"0xD7FB-3": "5A3",
|
| 1446 |
+
"0xD7FB-4": "5A4",
|
| 1447 |
+
"0xD7FB-5": "5A5",
|
| 1448 |
+
"0xD7FB-6": "5A6",
|
| 1449 |
+
"0xD7FB-7": "5A7",
|
| 1450 |
+
"0xD7FC-0": "5A8",
|
| 1451 |
+
"0xD7FC-1": "5A9",
|
| 1452 |
+
"0xD7FC-2": "5Aa",
|
| 1453 |
+
"0xD7FC-3": "5Ab",
|
| 1454 |
+
"0xD7FC-4": "5Ac",
|
| 1455 |
+
"0xD7FC-5": "5Ad",
|
| 1456 |
+
"0xD7FC-6": "5Ae",
|
| 1457 |
+
"0xD7FC-7": "5Af",
|
| 1458 |
+
"0xD7FD-0": "5B0",
|
| 1459 |
+
"0xD7FD-1": "5B1",
|
| 1460 |
+
"0xD7FD-2": "5B2",
|
| 1461 |
+
"0xD7FD-3": "5B3",
|
| 1462 |
+
"0xD7FD-4": "5B4",
|
| 1463 |
+
"0xD7FD-5": "5B5",
|
| 1464 |
+
"0xD7FD-6": "5B6",
|
| 1465 |
+
"0xD7FD-7": "5B7",
|
| 1466 |
+
"0xD7FE-0": "5B8",
|
| 1467 |
+
"0xD7FE-1": "5B9",
|
| 1468 |
+
"0xD7FE-2": "5Ba",
|
| 1469 |
+
"0xD7FE-3": "5Bb",
|
| 1470 |
+
"0xD7FE-4": "5Bc",
|
| 1471 |
+
"0xD7FE-5": "5Bd",
|
| 1472 |
+
"0xD7FE-6": "5Be",
|
| 1473 |
+
"0xD7FE-7": "5Bf",
|
| 1474 |
+
"0xD7FF-0": "5C0",
|
| 1475 |
+
"0xD7FF-1": "5C1",
|
| 1476 |
+
"0xD7FF-2": "5C2",
|
| 1477 |
+
"0xD7FF-3": "5C3",
|
| 1478 |
+
"0xD7FF-4": "Beat Ss Anne 5 Trainer 0",
|
| 1479 |
+
"0xD7FF-5": "Beat Ss Anne 5 Trainer 1",
|
| 1480 |
+
"0xD7FF-6": "5C6",
|
| 1481 |
+
"0xD7FF-7": "5C7",
|
| 1482 |
+
"0xD800-0": "5C8",
|
| 1483 |
+
"0xD800-1": "5C9",
|
| 1484 |
+
"0xD800-2": "5Ca",
|
| 1485 |
+
"0xD800-3": "5Cb",
|
| 1486 |
+
"0xD800-4": "5Cc",
|
| 1487 |
+
"0xD800-5": "5Cd",
|
| 1488 |
+
"0xD800-6": "5Ce",
|
| 1489 |
+
"0xD800-7": "5Cf",
|
| 1490 |
+
"0xD801-0": "5D0",
|
| 1491 |
+
"0xD801-1": "5D1",
|
| 1492 |
+
"0xD801-2": "5D2",
|
| 1493 |
+
"0xD801-3": "5D3",
|
| 1494 |
+
"0xD801-4": "5D4",
|
| 1495 |
+
"0xD801-5": "5D5",
|
| 1496 |
+
"0xD801-6": "5D6",
|
| 1497 |
+
"0xD801-7": "5D7",
|
| 1498 |
+
"0xD802-0": "5D8",
|
| 1499 |
+
"0xD802-1": "5D9",
|
| 1500 |
+
"0xD802-2": "5Da",
|
| 1501 |
+
"0xD802-3": "5Db",
|
| 1502 |
+
"0xD802-4": "5Dc",
|
| 1503 |
+
"0xD802-5": "5Dd",
|
| 1504 |
+
"0xD802-6": "5De",
|
| 1505 |
+
"0xD802-7": "5Df",
|
| 1506 |
+
"0xD803-0": "Got Hm01",
|
| 1507 |
+
"0xD803-1": "Rubbed Captains Back",
|
| 1508 |
+
"0xD803-2": "Ss Anne Left",
|
| 1509 |
+
"0xD803-3": "Walked Past Guard After Ss Anne Left",
|
| 1510 |
+
"0xD803-4": "Started Walking Out Of Dock",
|
| 1511 |
+
"0xD803-5": "Walked Out Of Dock",
|
| 1512 |
+
"0xD803-6": "5E6",
|
| 1513 |
+
"0xD803-7": "5E7",
|
| 1514 |
+
"0xD804-0": "5E8",
|
| 1515 |
+
"0xD804-1": "5E9",
|
| 1516 |
+
"0xD804-2": "5Ea",
|
| 1517 |
+
"0xD804-3": "5Eb",
|
| 1518 |
+
"0xD804-4": "5Ec",
|
| 1519 |
+
"0xD804-5": "5Ed",
|
| 1520 |
+
"0xD804-6": "5Ee",
|
| 1521 |
+
"0xD804-7": "5Ef",
|
| 1522 |
+
"0xD805-0": "5F0",
|
| 1523 |
+
"0xD805-1": "Beat Ss Anne 8 Trainer 0",
|
| 1524 |
+
"0xD805-2": "Beat Ss Anne 8 Trainer 1",
|
| 1525 |
+
"0xD805-3": "Beat Ss Anne 8 Trainer 2",
|
| 1526 |
+
"0xD805-4": "Beat Ss Anne 8 Trainer 3",
|
| 1527 |
+
"0xD805-5": "5F5",
|
| 1528 |
+
"0xD805-6": "5F6",
|
| 1529 |
+
"0xD805-7": "5F7",
|
| 1530 |
+
"0xD806-0": "5F8",
|
| 1531 |
+
"0xD806-1": "5F9",
|
| 1532 |
+
"0xD806-2": "5Fa",
|
| 1533 |
+
"0xD806-3": "5Fb",
|
| 1534 |
+
"0xD806-4": "5Fc",
|
| 1535 |
+
"0xD806-5": "5Fd",
|
| 1536 |
+
"0xD806-6": "5Fe",
|
| 1537 |
+
"0xD806-7": "5Ff",
|
| 1538 |
+
"0xD807-0": "600",
|
| 1539 |
+
"0xD807-1": "Beat Ss Anne 9 Trainer 0",
|
| 1540 |
+
"0xD807-2": "Beat Ss Anne 9 Trainer 1",
|
| 1541 |
+
"0xD807-3": "Beat Ss Anne 9 Trainer 2",
|
| 1542 |
+
"0xD807-4": "Beat Ss Anne 9 Trainer 3",
|
| 1543 |
+
"0xD807-5": "605",
|
| 1544 |
+
"0xD807-6": "606",
|
| 1545 |
+
"0xD807-7": "607",
|
| 1546 |
+
"0xD808-0": "608",
|
| 1547 |
+
"0xD808-1": "609",
|
| 1548 |
+
"0xD808-2": "60A",
|
| 1549 |
+
"0xD808-3": "60B",
|
| 1550 |
+
"0xD808-4": "60C",
|
| 1551 |
+
"0xD808-5": "60D",
|
| 1552 |
+
"0xD808-6": "60E",
|
| 1553 |
+
"0xD808-7": "60F",
|
| 1554 |
+
"0xD809-0": "610",
|
| 1555 |
+
"0xD809-1": "Beat Ss Anne 10 Trainer 0",
|
| 1556 |
+
"0xD809-2": "Beat Ss Anne 10 Trainer 1",
|
| 1557 |
+
"0xD809-3": "Beat Ss Anne 10 Trainer 2",
|
| 1558 |
+
"0xD809-4": "Beat Ss Anne 10 Trainer 3",
|
| 1559 |
+
"0xD809-5": "Beat Ss Anne 10 Trainer 4",
|
| 1560 |
+
"0xD809-6": "Beat Ss Anne 10 Trainer 5",
|
| 1561 |
+
"0xD809-7": "617",
|
| 1562 |
+
"0xD80A-0": "618",
|
| 1563 |
+
"0xD80A-1": "619",
|
| 1564 |
+
"0xD80A-2": "61A",
|
| 1565 |
+
"0xD80A-3": "61B",
|
| 1566 |
+
"0xD80A-4": "61C",
|
| 1567 |
+
"0xD80A-5": "61D",
|
| 1568 |
+
"0xD80A-6": "61E",
|
| 1569 |
+
"0xD80A-7": "61F",
|
| 1570 |
+
"0xD80B-0": "620",
|
| 1571 |
+
"0xD80B-1": "621",
|
| 1572 |
+
"0xD80B-2": "622",
|
| 1573 |
+
"0xD80B-3": "623",
|
| 1574 |
+
"0xD80B-4": "624",
|
| 1575 |
+
"0xD80B-5": "625",
|
| 1576 |
+
"0xD80B-6": "626",
|
| 1577 |
+
"0xD80B-7": "627",
|
| 1578 |
+
"0xD80C-0": "628",
|
| 1579 |
+
"0xD80C-1": "629",
|
| 1580 |
+
"0xD80C-2": "62A",
|
| 1581 |
+
"0xD80C-3": "62B",
|
| 1582 |
+
"0xD80C-4": "62C",
|
| 1583 |
+
"0xD80C-5": "62D",
|
| 1584 |
+
"0xD80C-6": "62E",
|
| 1585 |
+
"0xD80C-7": "62F",
|
| 1586 |
+
"0xD80D-0": "630",
|
| 1587 |
+
"0xD80D-1": "631",
|
| 1588 |
+
"0xD80D-2": "632",
|
| 1589 |
+
"0xD80D-3": "633",
|
| 1590 |
+
"0xD80D-4": "634",
|
| 1591 |
+
"0xD80D-5": "635",
|
| 1592 |
+
"0xD80D-6": "636",
|
| 1593 |
+
"0xD80D-7": "637",
|
| 1594 |
+
"0xD80E-0": "638",
|
| 1595 |
+
"0xD80E-1": "639",
|
| 1596 |
+
"0xD80E-2": "63A",
|
| 1597 |
+
"0xD80E-3": "63B",
|
| 1598 |
+
"0xD80E-4": "63C",
|
| 1599 |
+
"0xD80E-5": "63D",
|
| 1600 |
+
"0xD80E-6": "63E",
|
| 1601 |
+
"0xD80E-7": "63F",
|
| 1602 |
+
"0xD80F-0": "640",
|
| 1603 |
+
"0xD80F-1": "641",
|
| 1604 |
+
"0xD80F-2": "642",
|
| 1605 |
+
"0xD80F-3": "643",
|
| 1606 |
+
"0xD80F-4": "644",
|
| 1607 |
+
"0xD80F-5": "645",
|
| 1608 |
+
"0xD80F-6": "646",
|
| 1609 |
+
"0xD80F-7": "647",
|
| 1610 |
+
"0xD810-0": "648",
|
| 1611 |
+
"0xD810-1": "649",
|
| 1612 |
+
"0xD810-2": "64A",
|
| 1613 |
+
"0xD810-3": "64B",
|
| 1614 |
+
"0xD810-4": "64C",
|
| 1615 |
+
"0xD810-5": "64D",
|
| 1616 |
+
"0xD810-6": "64E",
|
| 1617 |
+
"0xD810-7": "64F",
|
| 1618 |
+
"0xD811-0": "650",
|
| 1619 |
+
"0xD811-1": "651",
|
| 1620 |
+
"0xD811-2": "652",
|
| 1621 |
+
"0xD811-3": "653",
|
| 1622 |
+
"0xD811-4": "654",
|
| 1623 |
+
"0xD811-5": "655",
|
| 1624 |
+
"0xD811-6": "656",
|
| 1625 |
+
"0xD811-7": "657",
|
| 1626 |
+
"0xD812-0": "658",
|
| 1627 |
+
"0xD812-1": "659",
|
| 1628 |
+
"0xD812-2": "65A",
|
| 1629 |
+
"0xD812-3": "65B",
|
| 1630 |
+
"0xD812-4": "65C",
|
| 1631 |
+
"0xD812-5": "65D",
|
| 1632 |
+
"0xD812-6": "65E",
|
| 1633 |
+
"0xD812-7": "65F",
|
| 1634 |
+
"0xD813-0": "Victory Road 3 Boulder On Switch1",
|
| 1635 |
+
"0xD813-1": "Beat Victory Road 3 Trainer 0",
|
| 1636 |
+
"0xD813-2": "Beat Victory Road 3 Trainer 1",
|
| 1637 |
+
"0xD813-3": "Beat Victory Road 3 Trainer 2",
|
| 1638 |
+
"0xD813-4": "Beat Victory Road 3 Trainer 3",
|
| 1639 |
+
"0xD813-5": "665",
|
| 1640 |
+
"0xD813-6": "Victory Road 3 Boulder On Switch2",
|
| 1641 |
+
"0xD813-7": "667",
|
| 1642 |
+
"0xD814-0": "668",
|
| 1643 |
+
"0xD814-1": "669",
|
| 1644 |
+
"0xD814-2": "66A",
|
| 1645 |
+
"0xD814-3": "66B",
|
| 1646 |
+
"0xD814-4": "66C",
|
| 1647 |
+
"0xD814-5": "66D",
|
| 1648 |
+
"0xD814-6": "66E",
|
| 1649 |
+
"0xD814-7": "66F",
|
| 1650 |
+
"0xD815-0": "670",
|
| 1651 |
+
"0xD815-1": "Beat Rocket Hideout 1 Trainer 0",
|
| 1652 |
+
"0xD815-2": "Beat Rocket Hideout 1 Trainer 1",
|
| 1653 |
+
"0xD815-3": "Beat Rocket Hideout 1 Trainer 2",
|
| 1654 |
+
"0xD815-4": "Beat Rocket Hideout 1 Trainer 3",
|
| 1655 |
+
"0xD815-5": "Beat Rocket Hideout 1 Trainer 4",
|
| 1656 |
+
"0xD815-6": "676",
|
| 1657 |
+
"0xD815-7": "677",
|
| 1658 |
+
"0xD816-0": "678",
|
| 1659 |
+
"0xD816-1": "679",
|
| 1660 |
+
"0xD816-2": "67A",
|
| 1661 |
+
"0xD816-3": "67B",
|
| 1662 |
+
"0xD816-4": "67C",
|
| 1663 |
+
"0xD816-5": "67D",
|
| 1664 |
+
"0xD816-6": "67E",
|
| 1665 |
+
"0xD816-7": "67F",
|
| 1666 |
+
"0xD817-0": "680",
|
| 1667 |
+
"0xD817-1": "Beat Rocket Hideout 2 Trainer 0",
|
| 1668 |
+
"0xD817-2": "682",
|
| 1669 |
+
"0xD817-3": "683",
|
| 1670 |
+
"0xD817-4": "684",
|
| 1671 |
+
"0xD817-5": "685",
|
| 1672 |
+
"0xD817-6": "686",
|
| 1673 |
+
"0xD817-7": "687",
|
| 1674 |
+
"0xD818-0": "688",
|
| 1675 |
+
"0xD818-1": "689",
|
| 1676 |
+
"0xD818-2": "68A",
|
| 1677 |
+
"0xD818-3": "68B",
|
| 1678 |
+
"0xD818-4": "68C",
|
| 1679 |
+
"0xD818-5": "68D",
|
| 1680 |
+
"0xD818-6": "68E",
|
| 1681 |
+
"0xD818-7": "68F",
|
| 1682 |
+
"0xD819-0": "690",
|
| 1683 |
+
"0xD819-1": "Beat Rocket Hideout 3 Trainer 0",
|
| 1684 |
+
"0xD819-2": "Beat Rocket Hideout 3 Trainer 1",
|
| 1685 |
+
"0xD819-3": "693",
|
| 1686 |
+
"0xD819-4": "694",
|
| 1687 |
+
"0xD819-5": "695",
|
| 1688 |
+
"0xD819-6": "696",
|
| 1689 |
+
"0xD819-7": "697",
|
| 1690 |
+
"0xD81A-0": "698",
|
| 1691 |
+
"0xD81A-1": "699",
|
| 1692 |
+
"0xD81A-2": "69A",
|
| 1693 |
+
"0xD81A-3": "69B",
|
| 1694 |
+
"0xD81A-4": "69C",
|
| 1695 |
+
"0xD81A-5": "69D",
|
| 1696 |
+
"0xD81A-6": "69E",
|
| 1697 |
+
"0xD81A-7": "69F",
|
| 1698 |
+
"0xD81B-0": "6A0",
|
| 1699 |
+
"0xD81B-1": "6A1",
|
| 1700 |
+
"0xD81B-2": "Beat Rocket Hideout 4 Trainer 0",
|
| 1701 |
+
"0xD81B-3": "Beat Rocket Hideout 4 Trainer 1",
|
| 1702 |
+
"0xD81B-4": "Beat Rocket Hideout 4 Trainer 2",
|
| 1703 |
+
"0xD81B-5": "Rocket Hideout 4 Door Unlocked",
|
| 1704 |
+
"0xD81B-6": "Rocket Dropped Lift Key",
|
| 1705 |
+
"0xD81B-7": "Beat Rocket Hideout Giovanni",
|
| 1706 |
+
"0xD81C-0": "6A8",
|
| 1707 |
+
"0xD81C-1": "6A9",
|
| 1708 |
+
"0xD81C-2": "6Aa",
|
| 1709 |
+
"0xD81C-3": "6Ab",
|
| 1710 |
+
"0xD81C-4": "6Ac",
|
| 1711 |
+
"0xD81C-5": "6Ad",
|
| 1712 |
+
"0xD81C-6": "6Ae",
|
| 1713 |
+
"0xD81C-7": "6Af",
|
| 1714 |
+
"0xD81D-0": "6B0",
|
| 1715 |
+
"0xD81D-1": "6B1",
|
| 1716 |
+
"0xD81D-2": "6B2",
|
| 1717 |
+
"0xD81D-3": "6B3",
|
| 1718 |
+
"0xD81D-4": "6B4",
|
| 1719 |
+
"0xD81D-5": "6B5",
|
| 1720 |
+
"0xD81D-6": "6B6",
|
| 1721 |
+
"0xD81D-7": "6B7",
|
| 1722 |
+
"0xD81E-0": "6B8",
|
| 1723 |
+
"0xD81E-1": "6B9",
|
| 1724 |
+
"0xD81E-2": "6Ba",
|
| 1725 |
+
"0xD81E-3": "6Bb",
|
| 1726 |
+
"0xD81E-4": "6Bc",
|
| 1727 |
+
"0xD81E-5": "6Bd",
|
| 1728 |
+
"0xD81E-6": "6Be",
|
| 1729 |
+
"0xD81E-7": "6Bf",
|
| 1730 |
+
"0xD81F-0": "6C0",
|
| 1731 |
+
"0xD81F-1": "6C1",
|
| 1732 |
+
"0xD81F-2": "6C2",
|
| 1733 |
+
"0xD81F-3": "6C3",
|
| 1734 |
+
"0xD81F-4": "6C4",
|
| 1735 |
+
"0xD81F-5": "6C5",
|
| 1736 |
+
"0xD81F-6": "6C6",
|
| 1737 |
+
"0xD81F-7": "6C7",
|
| 1738 |
+
"0xD820-0": "6C8",
|
| 1739 |
+
"0xD820-1": "6C9",
|
| 1740 |
+
"0xD820-2": "6Ca",
|
| 1741 |
+
"0xD820-3": "6Cb",
|
| 1742 |
+
"0xD820-4": "6Cc",
|
| 1743 |
+
"0xD820-5": "6Cd",
|
| 1744 |
+
"0xD820-6": "6Ce",
|
| 1745 |
+
"0xD820-7": "6Cf",
|
| 1746 |
+
"0xD821-0": "6D0",
|
| 1747 |
+
"0xD821-1": "6D1",
|
| 1748 |
+
"0xD821-2": "6D2",
|
| 1749 |
+
"0xD821-3": "6D3",
|
| 1750 |
+
"0xD821-4": "6D4",
|
| 1751 |
+
"0xD821-5": "6D5",
|
| 1752 |
+
"0xD821-6": "6D6",
|
| 1753 |
+
"0xD821-7": "6D7",
|
| 1754 |
+
"0xD822-0": "6D8",
|
| 1755 |
+
"0xD822-1": "6D9",
|
| 1756 |
+
"0xD822-2": "6Da",
|
| 1757 |
+
"0xD822-3": "6Db",
|
| 1758 |
+
"0xD822-4": "6Dc",
|
| 1759 |
+
"0xD822-5": "6Dd",
|
| 1760 |
+
"0xD822-6": "6De",
|
| 1761 |
+
"0xD822-7": "6Df",
|
| 1762 |
+
"0xD823-0": "6E0",
|
| 1763 |
+
"0xD823-1": "6E1",
|
| 1764 |
+
"0xD823-2": "6E2",
|
| 1765 |
+
"0xD823-3": "6E3",
|
| 1766 |
+
"0xD823-4": "6E4",
|
| 1767 |
+
"0xD823-5": "6E5",
|
| 1768 |
+
"0xD823-6": "6E6",
|
| 1769 |
+
"0xD823-7": "6E7",
|
| 1770 |
+
"0xD824-0": "6E8",
|
| 1771 |
+
"0xD824-1": "6E9",
|
| 1772 |
+
"0xD824-2": "6Ea",
|
| 1773 |
+
"0xD824-3": "6Eb",
|
| 1774 |
+
"0xD824-4": "6Ec",
|
| 1775 |
+
"0xD824-5": "6Ed",
|
| 1776 |
+
"0xD824-6": "6Ee",
|
| 1777 |
+
"0xD824-7": "6Ef",
|
| 1778 |
+
"0xD825-0": "6F0",
|
| 1779 |
+
"0xD825-1": "6F1",
|
| 1780 |
+
"0xD825-2": "Beat Silph Co 2F Trainer 0",
|
| 1781 |
+
"0xD825-3": "Beat Silph Co 2F Trainer 1",
|
| 1782 |
+
"0xD825-4": "Beat Silph Co 2F Trainer 2",
|
| 1783 |
+
"0xD825-5": "Beat Silph Co 2F Trainer 3",
|
| 1784 |
+
"0xD825-6": "6F6",
|
| 1785 |
+
"0xD825-7": "6F7",
|
| 1786 |
+
"0xD826-0": "6F8",
|
| 1787 |
+
"0xD826-1": "6F9",
|
| 1788 |
+
"0xD826-2": "6Fa",
|
| 1789 |
+
"0xD826-3": "6Fb",
|
| 1790 |
+
"0xD826-4": "6Fc",
|
| 1791 |
+
"0xD826-5": "Silph Co 2 Unlocked Door1",
|
| 1792 |
+
"0xD826-6": "Silph Co 2 Unlocked Door2",
|
| 1793 |
+
"0xD826-7": "Got Tm36",
|
| 1794 |
+
"0xD827-0": "700",
|
| 1795 |
+
"0xD827-1": "701",
|
| 1796 |
+
"0xD827-2": "Beat Silph Co 3F Trainer 0",
|
| 1797 |
+
"0xD827-3": "Beat Silph Co 3F Trainer 1",
|
| 1798 |
+
"0xD827-4": "704",
|
| 1799 |
+
"0xD827-5": "705",
|
| 1800 |
+
"0xD827-6": "706",
|
| 1801 |
+
"0xD827-7": "707",
|
| 1802 |
+
"0xD828-0": "Silph Co 3 Unlocked Door1",
|
| 1803 |
+
"0xD828-1": "Silph Co 3 Unlocked Door2",
|
| 1804 |
+
"0xD828-2": "70A",
|
| 1805 |
+
"0xD828-3": "70B",
|
| 1806 |
+
"0xD828-4": "70C",
|
| 1807 |
+
"0xD828-5": "70D",
|
| 1808 |
+
"0xD828-6": "70E",
|
| 1809 |
+
"0xD828-7": "70F",
|
| 1810 |
+
"0xD829-0": "710",
|
| 1811 |
+
"0xD829-1": "711",
|
| 1812 |
+
"0xD829-2": "Beat Silph Co 4F Trainer 0",
|
| 1813 |
+
"0xD829-3": "Beat Silph Co 4F Trainer 1",
|
| 1814 |
+
"0xD829-4": "Beat Silph Co 4F Trainer 2",
|
| 1815 |
+
"0xD829-5": "715",
|
| 1816 |
+
"0xD829-6": "716",
|
| 1817 |
+
"0xD829-7": "717",
|
| 1818 |
+
"0xD82A-0": "Silph Co 4 Unlocked Door1",
|
| 1819 |
+
"0xD82A-1": "Silph Co 4 Unlocked Door2",
|
| 1820 |
+
"0xD82A-2": "71A",
|
| 1821 |
+
"0xD82A-3": "71B",
|
| 1822 |
+
"0xD82A-4": "71C",
|
| 1823 |
+
"0xD82A-5": "71D",
|
| 1824 |
+
"0xD82A-6": "71E",
|
| 1825 |
+
"0xD82A-7": "71F",
|
| 1826 |
+
"0xD82B-0": "720",
|
| 1827 |
+
"0xD82B-1": "721",
|
| 1828 |
+
"0xD82B-2": "Beat Silph Co 5F Trainer 0",
|
| 1829 |
+
"0xD82B-3": "Beat Silph Co 5F Trainer 1",
|
| 1830 |
+
"0xD82B-4": "Beat Silph Co 5F Trainer 2",
|
| 1831 |
+
"0xD82B-5": "Beat Silph Co 5F Trainer 3",
|
| 1832 |
+
"0xD82B-6": "726",
|
| 1833 |
+
"0xD82B-7": "727",
|
| 1834 |
+
"0xD82C-0": "Silph Co 5 Unlocked Door1",
|
| 1835 |
+
"0xD82C-1": "Silph Co 5 Unlocked Door2",
|
| 1836 |
+
"0xD82C-2": "Silph Co 5 Unlocked Door3",
|
| 1837 |
+
"0xD82C-3": "72B",
|
| 1838 |
+
"0xD82C-4": "72C",
|
| 1839 |
+
"0xD82C-5": "72D",
|
| 1840 |
+
"0xD82C-6": "72E",
|
| 1841 |
+
"0xD82C-7": "72F",
|
| 1842 |
+
"0xD82D-0": "730",
|
| 1843 |
+
"0xD82D-1": "731",
|
| 1844 |
+
"0xD82D-2": "732",
|
| 1845 |
+
"0xD82D-3": "733",
|
| 1846 |
+
"0xD82D-4": "734",
|
| 1847 |
+
"0xD82D-5": "735",
|
| 1848 |
+
"0xD82D-6": "Beat Silph Co 6F Trainer 0",
|
| 1849 |
+
"0xD82D-7": "Beat Silph Co 6F Trainer 1",
|
| 1850 |
+
"0xD82E-0": "Beat Silph Co 6F Trainer 2",
|
| 1851 |
+
"0xD82E-1": "739",
|
| 1852 |
+
"0xD82E-2": "73A",
|
| 1853 |
+
"0xD82E-3": "73B",
|
| 1854 |
+
"0xD82E-4": "73C",
|
| 1855 |
+
"0xD82E-5": "73D",
|
| 1856 |
+
"0xD82E-6": "73E",
|
| 1857 |
+
"0xD82E-7": "Silph Co 6 Unlocked Door",
|
| 1858 |
+
"0xD82F-0": "Beat Silph Co Rival",
|
| 1859 |
+
"0xD82F-1": "741",
|
| 1860 |
+
"0xD82F-2": "742",
|
| 1861 |
+
"0xD82F-3": "743",
|
| 1862 |
+
"0xD82F-4": "744",
|
| 1863 |
+
"0xD82F-5": "Beat Silph Co 7F Trainer 0",
|
| 1864 |
+
"0xD82F-6": "Beat Silph Co 7F Trainer 1",
|
| 1865 |
+
"0xD82F-7": "Beat Silph Co 7F Trainer 2",
|
| 1866 |
+
"0xD830-0": "Beat Silph Co 7F Trainer 3",
|
| 1867 |
+
"0xD830-1": "749",
|
| 1868 |
+
"0xD830-2": "74A",
|
| 1869 |
+
"0xD830-3": "74B",
|
| 1870 |
+
"0xD830-4": "Silph Co 7 Unlocked Door1",
|
| 1871 |
+
"0xD830-5": "Silph Co 7 Unlocked Door2",
|
| 1872 |
+
"0xD830-6": "Silph Co 7 Unlocked Door3",
|
| 1873 |
+
"0xD830-7": "74F",
|
| 1874 |
+
"0xD831-0": "750",
|
| 1875 |
+
"0xD831-1": "751",
|
| 1876 |
+
"0xD831-2": "Beat Silph Co 8F Trainer 0",
|
| 1877 |
+
"0xD831-3": "Beat Silph Co 8F Trainer 1",
|
| 1878 |
+
"0xD831-4": "Beat Silph Co 8F Trainer 2",
|
| 1879 |
+
"0xD831-5": "755",
|
| 1880 |
+
"0xD831-6": "756",
|
| 1881 |
+
"0xD831-7": "757",
|
| 1882 |
+
"0xD832-0": "Silph Co 8 Unlocked Door",
|
| 1883 |
+
"0xD832-1": "759",
|
| 1884 |
+
"0xD832-2": "75A",
|
| 1885 |
+
"0xD832-3": "75B",
|
| 1886 |
+
"0xD832-4": "75C",
|
| 1887 |
+
"0xD832-5": "75D",
|
| 1888 |
+
"0xD832-6": "75E",
|
| 1889 |
+
"0xD832-7": "75F",
|
| 1890 |
+
"0xD833-0": "760",
|
| 1891 |
+
"0xD833-1": "761",
|
| 1892 |
+
"0xD833-2": "Beat Silph Co 9F Trainer 0",
|
| 1893 |
+
"0xD833-3": "Beat Silph Co 9F Trainer 1",
|
| 1894 |
+
"0xD833-4": "Beat Silph Co 9F Trainer 2",
|
| 1895 |
+
"0xD833-5": "765",
|
| 1896 |
+
"0xD833-6": "766",
|
| 1897 |
+
"0xD833-7": "767",
|
| 1898 |
+
"0xD834-0": "Silph Co 9 Unlocked Door1",
|
| 1899 |
+
"0xD834-1": "Silph Co 9 Unlocked Door2",
|
| 1900 |
+
"0xD834-2": "Silph Co 9 Unlocked Door3",
|
| 1901 |
+
"0xD834-3": "Silph Co 9 Unlocked Door4",
|
| 1902 |
+
"0xD834-4": "76C",
|
| 1903 |
+
"0xD834-5": "76D",
|
| 1904 |
+
"0xD834-6": "76E",
|
| 1905 |
+
"0xD834-7": "76F",
|
| 1906 |
+
"0xD835-0": "770",
|
| 1907 |
+
"0xD835-1": "Beat Silph Co 10F Trainer 0",
|
| 1908 |
+
"0xD835-2": "Beat Silph Co 10F Trainer 1",
|
| 1909 |
+
"0xD835-3": "773",
|
| 1910 |
+
"0xD835-4": "774",
|
| 1911 |
+
"0xD835-5": "775",
|
| 1912 |
+
"0xD835-6": "776",
|
| 1913 |
+
"0xD835-7": "777",
|
| 1914 |
+
"0xD836-0": "Silph Co 10 Unlocked Door",
|
| 1915 |
+
"0xD836-1": "779",
|
| 1916 |
+
"0xD836-2": "77A",
|
| 1917 |
+
"0xD836-3": "77B",
|
| 1918 |
+
"0xD836-4": "77C",
|
| 1919 |
+
"0xD836-5": "77D",
|
| 1920 |
+
"0xD836-6": "77E",
|
| 1921 |
+
"0xD836-7": "77F",
|
| 1922 |
+
"0xD837-0": "780",
|
| 1923 |
+
"0xD837-1": "781",
|
| 1924 |
+
"0xD837-2": "782",
|
| 1925 |
+
"0xD837-3": "783",
|
| 1926 |
+
"0xD837-4": "Beat Silph Co 11F Trainer 0",
|
| 1927 |
+
"0xD837-5": "Beat Silph Co 11F Trainer 1",
|
| 1928 |
+
"0xD837-6": "786",
|
| 1929 |
+
"0xD837-7": "787",
|
| 1930 |
+
"0xD838-0": "Silph Co 11 Unlocked Door",
|
| 1931 |
+
"0xD838-1": "789",
|
| 1932 |
+
"0xD838-2": "78A",
|
| 1933 |
+
"0xD838-3": "78B",
|
| 1934 |
+
"0xD838-4": "78C",
|
| 1935 |
+
"0xD838-5": "Got Master Ball",
|
| 1936 |
+
"0xD838-6": "78E",
|
| 1937 |
+
"0xD838-7": "Beat Silph Co Giovanni",
|
| 1938 |
+
"0xD839-0": "790",
|
| 1939 |
+
"0xD839-1": "791",
|
| 1940 |
+
"0xD839-2": "792",
|
| 1941 |
+
"0xD839-3": "793",
|
| 1942 |
+
"0xD839-4": "794",
|
| 1943 |
+
"0xD839-5": "795",
|
| 1944 |
+
"0xD839-6": "796",
|
| 1945 |
+
"0xD839-7": "797",
|
| 1946 |
+
"0xD83A-0": "798",
|
| 1947 |
+
"0xD83A-1": "799",
|
| 1948 |
+
"0xD83A-2": "79A",
|
| 1949 |
+
"0xD83A-3": "79B",
|
| 1950 |
+
"0xD83A-4": "79C",
|
| 1951 |
+
"0xD83A-5": "79D",
|
| 1952 |
+
"0xD83A-6": "79E",
|
| 1953 |
+
"0xD83A-7": "79F",
|
| 1954 |
+
"0xD83B-0": "7A0",
|
| 1955 |
+
"0xD83B-1": "7A1",
|
| 1956 |
+
"0xD83B-2": "7A2",
|
| 1957 |
+
"0xD83B-3": "7A3",
|
| 1958 |
+
"0xD83B-4": "7A4",
|
| 1959 |
+
"0xD83B-5": "7A5",
|
| 1960 |
+
"0xD83B-6": "7A6",
|
| 1961 |
+
"0xD83B-7": "7A7",
|
| 1962 |
+
"0xD83C-0": "7A8",
|
| 1963 |
+
"0xD83C-1": "7A9",
|
| 1964 |
+
"0xD83C-2": "7Aa",
|
| 1965 |
+
"0xD83C-3": "7Ab",
|
| 1966 |
+
"0xD83C-4": "7Ac",
|
| 1967 |
+
"0xD83C-5": "7Ad",
|
| 1968 |
+
"0xD83C-6": "7Ae",
|
| 1969 |
+
"0xD83C-7": "7Af",
|
| 1970 |
+
"0xD83D-0": "7B0",
|
| 1971 |
+
"0xD83D-1": "7B1",
|
| 1972 |
+
"0xD83D-2": "7B2",
|
| 1973 |
+
"0xD83D-3": "7B3",
|
| 1974 |
+
"0xD83D-4": "7B4",
|
| 1975 |
+
"0xD83D-5": "7B5",
|
| 1976 |
+
"0xD83D-6": "7B6",
|
| 1977 |
+
"0xD83D-7": "7B7",
|
| 1978 |
+
"0xD83E-0": "7B8",
|
| 1979 |
+
"0xD83E-1": "7B9",
|
| 1980 |
+
"0xD83E-2": "7Ba",
|
| 1981 |
+
"0xD83E-3": "7Bb",
|
| 1982 |
+
"0xD83E-4": "7Bc",
|
| 1983 |
+
"0xD83E-5": "7Bd",
|
| 1984 |
+
"0xD83E-6": "7Be",
|
| 1985 |
+
"0xD83E-7": "7Bf",
|
| 1986 |
+
"0xD83F-0": "7C0",
|
| 1987 |
+
"0xD83F-1": "7C1",
|
| 1988 |
+
"0xD83F-2": "7C2",
|
| 1989 |
+
"0xD83F-3": "7C3",
|
| 1990 |
+
"0xD83F-4": "7C4",
|
| 1991 |
+
"0xD83F-5": "7C5",
|
| 1992 |
+
"0xD83F-6": "7C6",
|
| 1993 |
+
"0xD83F-7": "7C7",
|
| 1994 |
+
"0xD840-0": "7C8",
|
| 1995 |
+
"0xD840-1": "7C9",
|
| 1996 |
+
"0xD840-2": "7Ca",
|
| 1997 |
+
"0xD840-3": "7Cb",
|
| 1998 |
+
"0xD840-4": "7Cc",
|
| 1999 |
+
"0xD840-5": "7Cd",
|
| 2000 |
+
"0xD840-6": "7Ce",
|
| 2001 |
+
"0xD840-7": "7Cf",
|
| 2002 |
+
"0xD841-0": "7D0",
|
| 2003 |
+
"0xD841-1": "7D1",
|
| 2004 |
+
"0xD841-2": "7D2",
|
| 2005 |
+
"0xD841-3": "7D3",
|
| 2006 |
+
"0xD841-4": "7D4",
|
| 2007 |
+
"0xD841-5": "7D5",
|
| 2008 |
+
"0xD841-6": "7D6",
|
| 2009 |
+
"0xD841-7": "7D7",
|
| 2010 |
+
"0xD842-0": "7D8",
|
| 2011 |
+
"0xD842-1": "7D9",
|
| 2012 |
+
"0xD842-2": "7Da",
|
| 2013 |
+
"0xD842-3": "7Db",
|
| 2014 |
+
"0xD842-4": "7Dc",
|
| 2015 |
+
"0xD842-5": "7Dd",
|
| 2016 |
+
"0xD842-6": "7De",
|
| 2017 |
+
"0xD842-7": "7Df",
|
| 2018 |
+
"0xD843-0": "7E0",
|
| 2019 |
+
"0xD843-1": "7E1",
|
| 2020 |
+
"0xD843-2": "7E2",
|
| 2021 |
+
"0xD843-3": "7E3",
|
| 2022 |
+
"0xD843-4": "7E4",
|
| 2023 |
+
"0xD843-5": "7E5",
|
| 2024 |
+
"0xD843-6": "7E6",
|
| 2025 |
+
"0xD843-7": "7E7",
|
| 2026 |
+
"0xD844-0": "7E8",
|
| 2027 |
+
"0xD844-1": "7E9",
|
| 2028 |
+
"0xD844-2": "7Ea",
|
| 2029 |
+
"0xD844-3": "7Eb",
|
| 2030 |
+
"0xD844-4": "7Ec",
|
| 2031 |
+
"0xD844-5": "7Ed",
|
| 2032 |
+
"0xD844-6": "7Ee",
|
| 2033 |
+
"0xD844-7": "7Ef",
|
| 2034 |
+
"0xD845-0": "7F0",
|
| 2035 |
+
"0xD845-1": "7F1",
|
| 2036 |
+
"0xD845-2": "7F2",
|
| 2037 |
+
"0xD845-3": "7F3",
|
| 2038 |
+
"0xD845-4": "7F4",
|
| 2039 |
+
"0xD845-5": "7F5",
|
| 2040 |
+
"0xD845-6": "7F6",
|
| 2041 |
+
"0xD845-7": "7F7",
|
| 2042 |
+
"0xD846-0": "7F8",
|
| 2043 |
+
"0xD846-1": "7F9",
|
| 2044 |
+
"0xD846-2": "7Fa",
|
| 2045 |
+
"0xD846-3": "7Fb",
|
| 2046 |
+
"0xD846-4": "7Fc",
|
| 2047 |
+
"0xD846-5": "7Fd",
|
| 2048 |
+
"0xD846-6": "7Fe",
|
| 2049 |
+
"0xD846-7": "7Ff",
|
| 2050 |
+
"0xD847-0": "800",
|
| 2051 |
+
"0xD847-1": "Beat Mansion 2 Trainer 0",
|
| 2052 |
+
"0xD847-2": "802",
|
| 2053 |
+
"0xD847-3": "803",
|
| 2054 |
+
"0xD847-4": "804",
|
| 2055 |
+
"0xD847-5": "805",
|
| 2056 |
+
"0xD847-6": "806",
|
| 2057 |
+
"0xD847-7": "807",
|
| 2058 |
+
"0xD848-0": "808",
|
| 2059 |
+
"0xD848-1": "809",
|
| 2060 |
+
"0xD848-2": "80A",
|
| 2061 |
+
"0xD848-3": "80B",
|
| 2062 |
+
"0xD848-4": "80C",
|
| 2063 |
+
"0xD848-5": "80D",
|
| 2064 |
+
"0xD848-6": "80E",
|
| 2065 |
+
"0xD848-7": "80F",
|
| 2066 |
+
"0xD849-0": "810",
|
| 2067 |
+
"0xD849-1": "Beat Mansion 3 Trainer 0",
|
| 2068 |
+
"0xD849-2": "Beat Mansion 3 Trainer 1",
|
| 2069 |
+
"0xD849-3": "813",
|
| 2070 |
+
"0xD849-4": "814",
|
| 2071 |
+
"0xD849-5": "815",
|
| 2072 |
+
"0xD849-6": "816",
|
| 2073 |
+
"0xD849-7": "817",
|
| 2074 |
+
"0xD84A-0": "818",
|
| 2075 |
+
"0xD84A-1": "819",
|
| 2076 |
+
"0xD84A-2": "81A",
|
| 2077 |
+
"0xD84A-3": "81B",
|
| 2078 |
+
"0xD84A-4": "81C",
|
| 2079 |
+
"0xD84A-5": "81D",
|
| 2080 |
+
"0xD84A-6": "81E",
|
| 2081 |
+
"0xD84A-7": "81F",
|
| 2082 |
+
"0xD84B-0": "820",
|
| 2083 |
+
"0xD84B-1": "Beat Mansion 4 Trainer 0",
|
| 2084 |
+
"0xD84B-2": "Beat Mansion 4 Trainer 1",
|
| 2085 |
+
"0xD84B-3": "823",
|
| 2086 |
+
"0xD84B-4": "824",
|
| 2087 |
+
"0xD84B-5": "825",
|
| 2088 |
+
"0xD84B-6": "826",
|
| 2089 |
+
"0xD84B-7": "827",
|
| 2090 |
+
"0xD84C-0": "828",
|
| 2091 |
+
"0xD84C-1": "829",
|
| 2092 |
+
"0xD84C-2": "82A",
|
| 2093 |
+
"0xD84C-3": "82B",
|
| 2094 |
+
"0xD84C-4": "82C",
|
| 2095 |
+
"0xD84C-5": "82D",
|
| 2096 |
+
"0xD84C-6": "82E",
|
| 2097 |
+
"0xD84C-7": "82F",
|
| 2098 |
+
"0xD84D-0": "830",
|
| 2099 |
+
"0xD84D-1": "831",
|
| 2100 |
+
"0xD84D-2": "832",
|
| 2101 |
+
"0xD84D-3": "833",
|
| 2102 |
+
"0xD84D-4": "834",
|
| 2103 |
+
"0xD84D-5": "835",
|
| 2104 |
+
"0xD84D-6": "836",
|
| 2105 |
+
"0xD84D-7": "837",
|
| 2106 |
+
"0xD84E-0": "838",
|
| 2107 |
+
"0xD84E-1": "839",
|
| 2108 |
+
"0xD84E-2": "83A",
|
| 2109 |
+
"0xD84E-3": "83B",
|
| 2110 |
+
"0xD84E-4": "83C",
|
| 2111 |
+
"0xD84E-5": "83D",
|
| 2112 |
+
"0xD84E-6": "83E",
|
| 2113 |
+
"0xD84E-7": "83F",
|
| 2114 |
+
"0xD84F-0": "840",
|
| 2115 |
+
"0xD84F-1": "841",
|
| 2116 |
+
"0xD84F-2": "842",
|
| 2117 |
+
"0xD84F-3": "843",
|
| 2118 |
+
"0xD84F-4": "844",
|
| 2119 |
+
"0xD84F-5": "845",
|
| 2120 |
+
"0xD84F-6": "846",
|
| 2121 |
+
"0xD84F-7": "847",
|
| 2122 |
+
"0xD850-0": "848",
|
| 2123 |
+
"0xD850-1": "849",
|
| 2124 |
+
"0xD850-2": "84A",
|
| 2125 |
+
"0xD850-3": "84B",
|
| 2126 |
+
"0xD850-4": "84C",
|
| 2127 |
+
"0xD850-5": "84D",
|
| 2128 |
+
"0xD850-6": "84E",
|
| 2129 |
+
"0xD850-7": "84F",
|
| 2130 |
+
"0xD851-0": "850",
|
| 2131 |
+
"0xD851-1": "851",
|
| 2132 |
+
"0xD851-2": "852",
|
| 2133 |
+
"0xD851-3": "853",
|
| 2134 |
+
"0xD851-4": "854",
|
| 2135 |
+
"0xD851-5": "855",
|
| 2136 |
+
"0xD851-6": "856",
|
| 2137 |
+
"0xD851-7": "857",
|
| 2138 |
+
"0xD852-0": "858",
|
| 2139 |
+
"0xD852-1": "859",
|
| 2140 |
+
"0xD852-2": "85A",
|
| 2141 |
+
"0xD852-3": "85B",
|
| 2142 |
+
"0xD852-4": "85C",
|
| 2143 |
+
"0xD852-5": "85D",
|
| 2144 |
+
"0xD852-6": "85E",
|
| 2145 |
+
"0xD852-7": "85F",
|
| 2146 |
+
"0xD853-0": "860",
|
| 2147 |
+
"0xD853-1": "861",
|
| 2148 |
+
"0xD853-2": "862",
|
| 2149 |
+
"0xD853-3": "863",
|
| 2150 |
+
"0xD853-4": "864",
|
| 2151 |
+
"0xD853-5": "865",
|
| 2152 |
+
"0xD853-6": "866",
|
| 2153 |
+
"0xD853-7": "867",
|
| 2154 |
+
"0xD854-0": "868",
|
| 2155 |
+
"0xD854-1": "869",
|
| 2156 |
+
"0xD854-2": "86A",
|
| 2157 |
+
"0xD854-3": "86B",
|
| 2158 |
+
"0xD854-4": "86C",
|
| 2159 |
+
"0xD854-5": "86D",
|
| 2160 |
+
"0xD854-6": "86E",
|
| 2161 |
+
"0xD854-7": "86F",
|
| 2162 |
+
"0xD855-0": "870",
|
| 2163 |
+
"0xD855-1": "871",
|
| 2164 |
+
"0xD855-2": "872",
|
| 2165 |
+
"0xD855-3": "873",
|
| 2166 |
+
"0xD855-4": "874",
|
| 2167 |
+
"0xD855-5": "875",
|
| 2168 |
+
"0xD855-6": "876",
|
| 2169 |
+
"0xD855-7": "877",
|
| 2170 |
+
"0xD856-0": "878",
|
| 2171 |
+
"0xD856-1": "879",
|
| 2172 |
+
"0xD856-2": "87A",
|
| 2173 |
+
"0xD856-3": "87B",
|
| 2174 |
+
"0xD856-4": "87C",
|
| 2175 |
+
"0xD856-5": "87D",
|
| 2176 |
+
"0xD856-6": "87E",
|
| 2177 |
+
"0xD856-7": "87F",
|
| 2178 |
+
"0xD857-0": "Got Hm03",
|
| 2179 |
+
"0xD857-1": "881",
|
| 2180 |
+
"0xD857-2": "882",
|
| 2181 |
+
"0xD857-3": "883",
|
| 2182 |
+
"0xD857-4": "884",
|
| 2183 |
+
"0xD857-5": "885",
|
| 2184 |
+
"0xD857-6": "886",
|
| 2185 |
+
"0xD857-7": "887",
|
| 2186 |
+
"0xD858-0": "888",
|
| 2187 |
+
"0xD858-1": "889",
|
| 2188 |
+
"0xD858-2": "88A",
|
| 2189 |
+
"0xD858-3": "88B",
|
| 2190 |
+
"0xD858-4": "88C",
|
| 2191 |
+
"0xD858-5": "88D",
|
| 2192 |
+
"0xD858-6": "88E",
|
| 2193 |
+
"0xD858-7": "88F",
|
| 2194 |
+
"0xD859-0": "890",
|
| 2195 |
+
"0xD859-1": "891",
|
| 2196 |
+
"0xD859-2": "892",
|
| 2197 |
+
"0xD859-3": "893",
|
| 2198 |
+
"0xD859-4": "894",
|
| 2199 |
+
"0xD859-5": "895",
|
| 2200 |
+
"0xD859-6": "896",
|
| 2201 |
+
"0xD859-7": "897",
|
| 2202 |
+
"0xD85A-0": "898",
|
| 2203 |
+
"0xD85A-1": "899",
|
| 2204 |
+
"0xD85A-2": "89A",
|
| 2205 |
+
"0xD85A-3": "89B",
|
| 2206 |
+
"0xD85A-4": "89C",
|
| 2207 |
+
"0xD85A-5": "89D",
|
| 2208 |
+
"0xD85A-6": "89E",
|
| 2209 |
+
"0xD85A-7": "89F",
|
| 2210 |
+
"0xD85B-0": "8A0",
|
| 2211 |
+
"0xD85B-1": "8A1",
|
| 2212 |
+
"0xD85B-2": "8A2",
|
| 2213 |
+
"0xD85B-3": "8A3",
|
| 2214 |
+
"0xD85B-4": "8A4",
|
| 2215 |
+
"0xD85B-5": "8A5",
|
| 2216 |
+
"0xD85B-6": "8A6",
|
| 2217 |
+
"0xD85B-7": "8A7",
|
| 2218 |
+
"0xD85C-0": "8A8",
|
| 2219 |
+
"0xD85C-1": "8A9",
|
| 2220 |
+
"0xD85C-2": "8Aa",
|
| 2221 |
+
"0xD85C-3": "8Ab",
|
| 2222 |
+
"0xD85C-4": "8Ac",
|
| 2223 |
+
"0xD85C-5": "8Ad",
|
| 2224 |
+
"0xD85C-6": "8Ae",
|
| 2225 |
+
"0xD85C-7": "8Af",
|
| 2226 |
+
"0xD85D-0": "8B0",
|
| 2227 |
+
"0xD85D-1": "8B1",
|
| 2228 |
+
"0xD85D-2": "8B2",
|
| 2229 |
+
"0xD85D-3": "8B3",
|
| 2230 |
+
"0xD85D-4": "8B4",
|
| 2231 |
+
"0xD85D-5": "8B5",
|
| 2232 |
+
"0xD85D-6": "8B6",
|
| 2233 |
+
"0xD85D-7": "8B7",
|
| 2234 |
+
"0xD85E-0": "8B8",
|
| 2235 |
+
"0xD85E-1": "8B9",
|
| 2236 |
+
"0xD85E-2": "8Ba",
|
| 2237 |
+
"0xD85E-3": "8Bb",
|
| 2238 |
+
"0xD85E-4": "8Bc",
|
| 2239 |
+
"0xD85E-5": "8Bd",
|
| 2240 |
+
"0xD85E-6": "8Be",
|
| 2241 |
+
"0xD85E-7": "8Bf",
|
| 2242 |
+
"0xD85F-0": "8C0",
|
| 2243 |
+
"0xD85F-1": "Beat Mewtwo",
|
| 2244 |
+
"0xD85F-2": "8C2",
|
| 2245 |
+
"0xD85F-3": "8C3",
|
| 2246 |
+
"0xD85F-4": "8C4",
|
| 2247 |
+
"0xD85F-5": "8C5",
|
| 2248 |
+
"0xD85F-6": "8C6",
|
| 2249 |
+
"0xD85F-7": "8C7",
|
| 2250 |
+
"0xD860-0": "8C8",
|
| 2251 |
+
"0xD860-1": "8C9",
|
| 2252 |
+
"0xD860-2": "8Ca",
|
| 2253 |
+
"0xD860-3": "8Cb",
|
| 2254 |
+
"0xD860-4": "8Cc",
|
| 2255 |
+
"0xD860-5": "8Cd",
|
| 2256 |
+
"0xD860-6": "8Ce",
|
| 2257 |
+
"0xD860-7": "8Cf",
|
| 2258 |
+
"0xD861-0": "8D0",
|
| 2259 |
+
"0xD861-1": "8D1",
|
| 2260 |
+
"0xD861-2": "8D2",
|
| 2261 |
+
"0xD861-3": "8D3",
|
| 2262 |
+
"0xD861-4": "8D4",
|
| 2263 |
+
"0xD861-5": "8D5",
|
| 2264 |
+
"0xD861-6": "8D6",
|
| 2265 |
+
"0xD861-7": "8D7",
|
| 2266 |
+
"0xD862-0": "8D8",
|
| 2267 |
+
"0xD862-1": "8D9",
|
| 2268 |
+
"0xD862-2": "8Da",
|
| 2269 |
+
"0xD862-3": "8Db",
|
| 2270 |
+
"0xD862-4": "8Dc",
|
| 2271 |
+
"0xD862-5": "8Dd",
|
| 2272 |
+
"0xD862-6": "8De",
|
| 2273 |
+
"0xD862-7": "8Df",
|
| 2274 |
+
"0xD863-1": "Beat Loreleis Room Trainer 0",
|
| 2275 |
+
"0xD863-2": "8E2",
|
| 2276 |
+
"0xD863-3": "8E3",
|
| 2277 |
+
"0xD863-4": "8E4",
|
| 2278 |
+
"0xD863-5": "8E5",
|
| 2279 |
+
"0xD863-6": "Autowalked Into Loreleis Room",
|
| 2280 |
+
"0xD863-7": "8E7",
|
| 2281 |
+
"0xD864-0": "8E8",
|
| 2282 |
+
"0xD864-1": "Beat Brunos Room Trainer 0",
|
| 2283 |
+
"0xD864-2": "8Ea",
|
| 2284 |
+
"0xD864-3": "8Eb",
|
| 2285 |
+
"0xD864-4": "8Ec",
|
| 2286 |
+
"0xD864-5": "8Ed",
|
| 2287 |
+
"0xD864-6": "Autowalked Into Brunos Room",
|
| 2288 |
+
"0xD864-7": "8Ef",
|
| 2289 |
+
"0xD865-0": "8F0",
|
| 2290 |
+
"0xD865-1": "Beat Agathas Room Trainer 0",
|
| 2291 |
+
"0xD865-2": "8F2",
|
| 2292 |
+
"0xD865-3": "8F3",
|
| 2293 |
+
"0xD865-4": "8F4",
|
| 2294 |
+
"0xD865-5": "8F5",
|
| 2295 |
+
"0xD865-6": "Autowalked Into Agathas Room",
|
| 2296 |
+
"0xD865-7": "8F7",
|
| 2297 |
+
"0xD866-0": "8F8",
|
| 2298 |
+
"0xD866-1": "Beat Lances Room Trainer 0",
|
| 2299 |
+
"0xD866-2": "8Fa",
|
| 2300 |
+
"0xD866-3": "8Fb",
|
| 2301 |
+
"0xD866-4": "8Fc",
|
| 2302 |
+
"0xD866-5": "8Fd",
|
| 2303 |
+
"0xD866-6": "Beat Lance",
|
| 2304 |
+
"0xD866-7": "Lances Room Lock Door",
|
| 2305 |
+
"0xD867-0": "900",
|
| 2306 |
+
"0xD867-1": "Beat Champion Rival",
|
| 2307 |
+
"0xD867-2": "902",
|
| 2308 |
+
"0xD867-3": "903",
|
| 2309 |
+
"0xD867-4": "904",
|
| 2310 |
+
"0xD867-5": "905",
|
| 2311 |
+
"0xD867-6": "906",
|
| 2312 |
+
"0xD868-0": "908",
|
| 2313 |
+
"0xD868-1": "909",
|
| 2314 |
+
"0xD868-2": "90A",
|
| 2315 |
+
"0xD868-3": "90B",
|
| 2316 |
+
"0xD868-4": "90C",
|
| 2317 |
+
"0xD868-5": "90D",
|
| 2318 |
+
"0xD868-6": "90E",
|
| 2319 |
+
"0xD868-7": "90F",
|
| 2320 |
+
"0xD869-0": "910",
|
| 2321 |
+
"0xD869-1": "Beat Victory Road 1 Trainer 0",
|
| 2322 |
+
"0xD869-2": "Beat Victory Road 1 Trainer 1",
|
| 2323 |
+
"0xD869-3": "913",
|
| 2324 |
+
"0xD869-4": "914",
|
| 2325 |
+
"0xD869-5": "915",
|
| 2326 |
+
"0xD869-6": "916",
|
| 2327 |
+
"0xD869-7": "Victory Road 1 Boulder On Switch",
|
| 2328 |
+
"0xD86A-0": "918",
|
| 2329 |
+
"0xD86A-1": "919",
|
| 2330 |
+
"0xD86A-2": "91A",
|
| 2331 |
+
"0xD86A-3": "91B",
|
| 2332 |
+
"0xD86A-4": "91C",
|
| 2333 |
+
"0xD86A-5": "91D",
|
| 2334 |
+
"0xD86A-6": "91E",
|
| 2335 |
+
"0xD86A-7": "91F",
|
| 2336 |
+
"0xD86B-0": "920",
|
| 2337 |
+
"0xD86B-1": "921",
|
| 2338 |
+
"0xD86B-2": "922",
|
| 2339 |
+
"0xD86B-3": "923",
|
| 2340 |
+
"0xD86B-4": "924",
|
| 2341 |
+
"0xD86B-5": "925",
|
| 2342 |
+
"0xD86B-6": "926",
|
| 2343 |
+
"0xD86B-7": "927",
|
| 2344 |
+
"0xD86C-0": "928",
|
| 2345 |
+
"0xD86C-1": "929",
|
| 2346 |
+
"0xD86C-2": "92A",
|
| 2347 |
+
"0xD86C-3": "92B",
|
| 2348 |
+
"0xD86C-4": "92C",
|
| 2349 |
+
"0xD86C-5": "92D",
|
| 2350 |
+
"0xD86C-6": "92E",
|
| 2351 |
+
"0xD86C-7": "92F",
|
| 2352 |
+
"0xD86D-0": "930",
|
| 2353 |
+
"0xD86D-1": "931",
|
| 2354 |
+
"0xD86D-2": "932",
|
| 2355 |
+
"0xD86D-3": "933",
|
| 2356 |
+
"0xD86D-4": "934",
|
| 2357 |
+
"0xD86D-5": "935",
|
| 2358 |
+
"0xD86D-6": "936",
|
| 2359 |
+
"0xD86D-7": "937",
|
| 2360 |
+
"0xD86E-0": "938",
|
| 2361 |
+
"0xD86E-1": "939",
|
| 2362 |
+
"0xD86E-2": "93A",
|
| 2363 |
+
"0xD86E-3": "93B",
|
| 2364 |
+
"0xD86E-4": "93C",
|
| 2365 |
+
"0xD86E-5": "93D",
|
| 2366 |
+
"0xD86E-6": "93E",
|
| 2367 |
+
"0xD86E-7": "93F",
|
| 2368 |
+
"0xD86F-0": "940",
|
| 2369 |
+
"0xD86F-1": "941",
|
| 2370 |
+
"0xD86F-2": "942",
|
| 2371 |
+
"0xD86F-3": "943",
|
| 2372 |
+
"0xD86F-4": "944",
|
| 2373 |
+
"0xD86F-5": "945",
|
| 2374 |
+
"0xD86F-6": "946",
|
| 2375 |
+
"0xD86F-7": "947",
|
| 2376 |
+
"0xD870-0": "948",
|
| 2377 |
+
"0xD870-1": "949",
|
| 2378 |
+
"0xD870-2": "94A",
|
| 2379 |
+
"0xD870-3": "94B",
|
| 2380 |
+
"0xD870-4": "94C",
|
| 2381 |
+
"0xD870-5": "94D",
|
| 2382 |
+
"0xD870-6": "94E",
|
| 2383 |
+
"0xD870-7": "94F",
|
| 2384 |
+
"0xD871-0": "950",
|
| 2385 |
+
"0xD871-1": "951",
|
| 2386 |
+
"0xD871-2": "952",
|
| 2387 |
+
"0xD871-3": "953",
|
| 2388 |
+
"0xD871-4": "954",
|
| 2389 |
+
"0xD871-5": "955",
|
| 2390 |
+
"0xD871-6": "956",
|
| 2391 |
+
"0xD871-7": "957",
|
| 2392 |
+
"0xD872-0": "958",
|
| 2393 |
+
"0xD872-1": "959",
|
| 2394 |
+
"0xD872-2": "95A",
|
| 2395 |
+
"0xD872-3": "95B",
|
| 2396 |
+
"0xD872-4": "95C",
|
| 2397 |
+
"0xD872-5": "95D",
|
| 2398 |
+
"0xD872-6": "95E",
|
| 2399 |
+
"0xD872-7": "95F",
|
| 2400 |
+
"0xD873-0": "960",
|
| 2401 |
+
"0xD873-1": "961",
|
| 2402 |
+
"0xD873-2": "962",
|
| 2403 |
+
"0xD873-3": "963",
|
| 2404 |
+
"0xD873-4": "964",
|
| 2405 |
+
"0xD873-5": "965",
|
| 2406 |
+
"0xD873-6": "966",
|
| 2407 |
+
"0xD873-7": "967",
|
| 2408 |
+
"0xD874-0": "968",
|
| 2409 |
+
"0xD874-1": "969",
|
| 2410 |
+
"0xD874-2": "96A",
|
| 2411 |
+
"0xD874-3": "96B",
|
| 2412 |
+
"0xD874-4": "96C",
|
| 2413 |
+
"0xD874-5": "96D",
|
| 2414 |
+
"0xD874-6": "96E",
|
| 2415 |
+
"0xD874-7": "96F",
|
| 2416 |
+
"0xD875-0": "970",
|
| 2417 |
+
"0xD875-1": "971",
|
| 2418 |
+
"0xD875-2": "972",
|
| 2419 |
+
"0xD875-3": "973",
|
| 2420 |
+
"0xD875-4": "974",
|
| 2421 |
+
"0xD875-5": "975",
|
| 2422 |
+
"0xD875-6": "976",
|
| 2423 |
+
"0xD875-7": "977",
|
| 2424 |
+
"0xD876-0": "978",
|
| 2425 |
+
"0xD876-1": "979",
|
| 2426 |
+
"0xD876-2": "97A",
|
| 2427 |
+
"0xD876-3": "97B",
|
| 2428 |
+
"0xD876-4": "97C",
|
| 2429 |
+
"0xD876-5": "97D",
|
| 2430 |
+
"0xD876-6": "97E",
|
| 2431 |
+
"0xD876-7": "97F",
|
| 2432 |
+
"0xD877-0": "980",
|
| 2433 |
+
"0xD877-1": "981",
|
| 2434 |
+
"0xD877-2": "982",
|
| 2435 |
+
"0xD877-3": "983",
|
| 2436 |
+
"0xD877-4": "984",
|
| 2437 |
+
"0xD877-5": "985",
|
| 2438 |
+
"0xD877-6": "986",
|
| 2439 |
+
"0xD877-7": "987",
|
| 2440 |
+
"0xD878-0": "988",
|
| 2441 |
+
"0xD878-1": "989",
|
| 2442 |
+
"0xD878-2": "98A",
|
| 2443 |
+
"0xD878-3": "98B",
|
| 2444 |
+
"0xD878-4": "98C",
|
| 2445 |
+
"0xD878-5": "98D",
|
| 2446 |
+
"0xD878-6": "98E",
|
| 2447 |
+
"0xD878-7": "98F",
|
| 2448 |
+
"0xD879-0": "990",
|
| 2449 |
+
"0xD879-1": "991",
|
| 2450 |
+
"0xD879-2": "992",
|
| 2451 |
+
"0xD879-3": "993",
|
| 2452 |
+
"0xD879-4": "994",
|
| 2453 |
+
"0xD879-5": "995",
|
| 2454 |
+
"0xD879-6": "996",
|
| 2455 |
+
"0xD879-7": "997",
|
| 2456 |
+
"0xD87A-0": "998",
|
| 2457 |
+
"0xD87A-1": "999",
|
| 2458 |
+
"0xD87A-2": "99A",
|
| 2459 |
+
"0xD87A-3": "99B",
|
| 2460 |
+
"0xD87A-4": "99C",
|
| 2461 |
+
"0xD87A-5": "99D",
|
| 2462 |
+
"0xD87A-6": "99E",
|
| 2463 |
+
"0xD87A-7": "99F",
|
| 2464 |
+
"0xD87B-0": "9A0",
|
| 2465 |
+
"0xD87B-1": "9A1",
|
| 2466 |
+
"0xD87B-2": "9A2",
|
| 2467 |
+
"0xD87B-3": "9A3",
|
| 2468 |
+
"0xD87B-4": "9A4",
|
| 2469 |
+
"0xD87B-5": "9A5",
|
| 2470 |
+
"0xD87B-6": "9A6",
|
| 2471 |
+
"0xD87B-7": "9A7",
|
| 2472 |
+
"0xD87C-0": "9A8",
|
| 2473 |
+
"0xD87C-1": "9A9",
|
| 2474 |
+
"0xD87C-2": "9Aa",
|
| 2475 |
+
"0xD87C-3": "9Ab",
|
| 2476 |
+
"0xD87C-4": "9Ac",
|
| 2477 |
+
"0xD87C-5": "9Ad",
|
| 2478 |
+
"0xD87C-6": "9Ae",
|
| 2479 |
+
"0xD87C-7": "9Af",
|
| 2480 |
+
"0xD87D-0": "9B0",
|
| 2481 |
+
"0xD87D-1": "Beat Rock Tunnel 2 Trainer 0",
|
| 2482 |
+
"0xD87D-2": "Beat Rock Tunnel 2 Trainer 1",
|
| 2483 |
+
"0xD87D-3": "Beat Rock Tunnel 2 Trainer 2",
|
| 2484 |
+
"0xD87D-4": "Beat Rock Tunnel 2 Trainer 3",
|
| 2485 |
+
"0xD87D-5": "Beat Rock Tunnel 2 Trainer 4",
|
| 2486 |
+
"0xD87D-6": "Beat Rock Tunnel 2 Trainer 5",
|
| 2487 |
+
"0xD87D-7": "Beat Rock Tunnel 2 Trainer 6",
|
| 2488 |
+
"0xD87E-0": "Beat Rock Tunnel 2 Trainer 7",
|
| 2489 |
+
"0xD87E-1": "9B9",
|
| 2490 |
+
"0xD87E-2": "9Ba",
|
| 2491 |
+
"0xD87E-3": "9Bb",
|
| 2492 |
+
"0xD87E-4": "9Bc",
|
| 2493 |
+
"0xD87E-5": "9Bd",
|
| 2494 |
+
"0xD87E-6": "9Be",
|
| 2495 |
+
"0xD87E-7": "9Bf",
|
| 2496 |
+
"0xD87F-0": "Seafoam2 Boulder1 Down Hole",
|
| 2497 |
+
"0xD87F-1": "Seafoam2 Boulder2 Down Hole",
|
| 2498 |
+
"0xD87F-2": "9C2",
|
| 2499 |
+
"0xD87F-3": "9C3",
|
| 2500 |
+
"0xD87F-4": "9C4",
|
| 2501 |
+
"0xD87F-5": "9C5",
|
| 2502 |
+
"0xD87F-6": "9C6",
|
| 2503 |
+
"0xD87F-7": "9C7",
|
| 2504 |
+
"0xD880-0": "Seafoam3 Boulder1 Down Hole",
|
| 2505 |
+
"0xD880-1": "Seafoam3 Boulder2 Down Hole",
|
| 2506 |
+
"0xD880-2": "9Ca",
|
| 2507 |
+
"0xD880-3": "9Cb",
|
| 2508 |
+
"0xD880-4": "9Cc",
|
| 2509 |
+
"0xD880-5": "9Cd",
|
| 2510 |
+
"0xD880-6": "9Ce",
|
| 2511 |
+
"0xD880-7": "9Cf",
|
| 2512 |
+
"0xD881-0": "Seafoam4 Boulder1 Down Hole",
|
| 2513 |
+
"0xD881-1": "Seafoam4 Boulder2 Down Hole",
|
| 2514 |
+
"0xD881-2": "9D2",
|
| 2515 |
+
"0xD881-3": "9D3",
|
| 2516 |
+
"0xD881-4": "9D4",
|
| 2517 |
+
"0xD881-5": "9D5",
|
| 2518 |
+
"0xD881-6": "9D6",
|
| 2519 |
+
"0xD881-7": "9D7",
|
| 2520 |
+
"0xD882-0": "9D8",
|
| 2521 |
+
"0xD882-1": "9D9",
|
| 2522 |
+
"0xD882-2": "Beat Articuno",
|
| 2523 |
+
"0xD882-3": "9Db",
|
| 2524 |
+
"0xD882-4": "9Dc",
|
| 2525 |
+
"0xD882-5": "9Dd",
|
| 2526 |
+
"0xD882-6": "9De",
|
| 2527 |
+
"0xD882-7": "9Df",
|
| 2528 |
+
"0xD883-0": "9E0",
|
| 2529 |
+
"0xD883-1": "9E1",
|
| 2530 |
+
"0xD883-2": "9E2",
|
| 2531 |
+
"0xD883-3": "9E3",
|
| 2532 |
+
"0xD883-4": "9E4",
|
| 2533 |
+
"0xD883-5": "9E5",
|
| 2534 |
+
"0xD883-6": "9E6",
|
| 2535 |
+
"0xD883-7": "9E7",
|
| 2536 |
+
"0xD884-0": "9E8",
|
| 2537 |
+
"0xD884-1": "9E9",
|
| 2538 |
+
"0xD884-2": "9Ea",
|
| 2539 |
+
"0xD884-3": "9Eb",
|
| 2540 |
+
"0xD884-4": "9Ec",
|
| 2541 |
+
"0xD884-5": "9Ed",
|
| 2542 |
+
"0xD884-6": "9Ee",
|
| 2543 |
+
"0xD884-7": "9Ef",
|
| 2544 |
+
"0xD885-0": "9F0",
|
| 2545 |
+
"0xD885-1": "9F1",
|
| 2546 |
+
"0xD885-2": "9F2",
|
| 2547 |
+
"0xD885-3": "9F3",
|
| 2548 |
+
"0xD885-4": "9F4",
|
| 2549 |
+
"0xD885-5": "9F5",
|
| 2550 |
+
"0xD885-6": "9F6",
|
| 2551 |
+
"0xD885-7": "9F7",
|
| 2552 |
+
"0xD886-0": "9F8",
|
| 2553 |
+
"0xD886-1": "9F9",
|
| 2554 |
+
"0xD886-2": "9Fa",
|
| 2555 |
+
"0xD886-3": "9Fb",
|
| 2556 |
+
"0xD886-4": "9Fc",
|
| 2557 |
+
"0xD886-5": "9Fd",
|
| 2558 |
+
"0xD886-6": "9Fe",
|
| 2559 |
+
"0xD886-7": "9Ff"
|
| 2560 |
+
}
|
server/global_map.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# adapted from https://github.com/thatguy11325/pokemonred_puffer/blob/main/pokemonred_puffer/global_map.py
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import json
|
| 5 |
+
|
| 6 |
+
MAP_PATH = os.path.join(os.path.dirname(__file__), "map_data.json")
|
| 7 |
+
PAD = 20
|
| 8 |
+
GLOBAL_MAP_SHAPE = (444 + PAD * 2, 436 + PAD * 2)
|
| 9 |
+
MAP_ROW_OFFSET = PAD
|
| 10 |
+
MAP_COL_OFFSET = PAD
|
| 11 |
+
|
| 12 |
+
with open(MAP_PATH) as map_data:
|
| 13 |
+
MAP_DATA = json.load(map_data)["regions"]
|
| 14 |
+
MAP_DATA = {int(e["id"]): e for e in MAP_DATA}
|
| 15 |
+
|
| 16 |
+
# Handle KeyErrors
|
| 17 |
+
def local_to_global(r: int, c: int, map_n: int):
|
| 18 |
+
try:
|
| 19 |
+
(
|
| 20 |
+
map_x,
|
| 21 |
+
map_y,
|
| 22 |
+
) = MAP_DATA[map_n]["coordinates"]
|
| 23 |
+
gy = r + map_y + MAP_ROW_OFFSET
|
| 24 |
+
gx = c + map_x + MAP_COL_OFFSET
|
| 25 |
+
if 0 <= gy < GLOBAL_MAP_SHAPE[0] and 0 <= gx < GLOBAL_MAP_SHAPE[1]:
|
| 26 |
+
return gy, gx
|
| 27 |
+
print(f"coord out of bounds! global: ({gx}, {gy}) game: ({r}, {c}, {map_n})")
|
| 28 |
+
return GLOBAL_MAP_SHAPE[0] // 2, GLOBAL_MAP_SHAPE[1] // 2
|
| 29 |
+
except KeyError:
|
| 30 |
+
print(f"Map id {map_n} not found in map_data.json.")
|
| 31 |
+
return GLOBAL_MAP_SHAPE[0] // 2, GLOBAL_MAP_SHAPE[1] // 2
|
server/init.state
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ef978b1668d2fad22a7b809a45fec37f3dd3fc5ef37d996f65b4ac93041afcb8
|
| 3 |
+
size 142586
|
server/map_data.json
ADDED
|
@@ -0,0 +1,2716 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"regions": [
|
| 3 |
+
{
|
| 4 |
+
"id": "-1",
|
| 5 |
+
"name": "Kanto",
|
| 6 |
+
"coordinates": [
|
| 7 |
+
0,
|
| 8 |
+
0
|
| 9 |
+
],
|
| 10 |
+
"tileSize": [
|
| 11 |
+
436,
|
| 12 |
+
444
|
| 13 |
+
]
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"id": "0",
|
| 17 |
+
"name": "Pallet Town",
|
| 18 |
+
"coordinates": [
|
| 19 |
+
64,
|
| 20 |
+
318
|
| 21 |
+
],
|
| 22 |
+
"tileSize": [
|
| 23 |
+
20,
|
| 24 |
+
18
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"id": "1",
|
| 29 |
+
"name": "Viridian City",
|
| 30 |
+
"coordinates": [
|
| 31 |
+
54,
|
| 32 |
+
246
|
| 33 |
+
],
|
| 34 |
+
"tileSize": [
|
| 35 |
+
40,
|
| 36 |
+
36
|
| 37 |
+
]
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"id": "2",
|
| 41 |
+
"name": "Pewter City",
|
| 42 |
+
"coordinates": [
|
| 43 |
+
54,
|
| 44 |
+
138
|
| 45 |
+
],
|
| 46 |
+
"tileSize": [
|
| 47 |
+
40,
|
| 48 |
+
36
|
| 49 |
+
]
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"id": "3",
|
| 53 |
+
"name": "Cerulean City",
|
| 54 |
+
"coordinates": [
|
| 55 |
+
234,
|
| 56 |
+
120
|
| 57 |
+
],
|
| 58 |
+
"tileSize": [
|
| 59 |
+
40,
|
| 60 |
+
36
|
| 61 |
+
]
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"id": "4",
|
| 65 |
+
"name": "Lavender Town",
|
| 66 |
+
"coordinates": [
|
| 67 |
+
334,
|
| 68 |
+
200
|
| 69 |
+
],
|
| 70 |
+
"tileSize": [
|
| 71 |
+
20,
|
| 72 |
+
18
|
| 73 |
+
]
|
| 74 |
+
},
|
| 75 |
+
{
|
| 76 |
+
"id": "5",
|
| 77 |
+
"name": "Vermilion City",
|
| 78 |
+
"coordinates": [
|
| 79 |
+
234,
|
| 80 |
+
264
|
| 81 |
+
],
|
| 82 |
+
"tileSize": [
|
| 83 |
+
40,
|
| 84 |
+
36
|
| 85 |
+
]
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"id": "6",
|
| 89 |
+
"name": "Celadon City",
|
| 90 |
+
"coordinates": [
|
| 91 |
+
164,
|
| 92 |
+
192
|
| 93 |
+
],
|
| 94 |
+
"tileSize": [
|
| 95 |
+
50,
|
| 96 |
+
36
|
| 97 |
+
]
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
"id": "7",
|
| 101 |
+
"name": "Fuchsia City",
|
| 102 |
+
"coordinates": [
|
| 103 |
+
174,
|
| 104 |
+
354
|
| 105 |
+
],
|
| 106 |
+
"tileSize": [
|
| 107 |
+
40,
|
| 108 |
+
36
|
| 109 |
+
]
|
| 110 |
+
},
|
| 111 |
+
{
|
| 112 |
+
"id": "8",
|
| 113 |
+
"name": "Cinnabar island",
|
| 114 |
+
"coordinates": [
|
| 115 |
+
64,
|
| 116 |
+
426
|
| 117 |
+
],
|
| 118 |
+
"tileSize": [
|
| 119 |
+
20,
|
| 120 |
+
18
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"id": "9",
|
| 125 |
+
"name": "Indigo Plateau",
|
| 126 |
+
"coordinates": [
|
| 127 |
+
14,
|
| 128 |
+
84
|
| 129 |
+
],
|
| 130 |
+
"tileSize": [
|
| 131 |
+
20,
|
| 132 |
+
18
|
| 133 |
+
]
|
| 134 |
+
},
|
| 135 |
+
{
|
| 136 |
+
"id": "10",
|
| 137 |
+
"name": "Saffron City",
|
| 138 |
+
"coordinates": [
|
| 139 |
+
234,
|
| 140 |
+
192
|
| 141 |
+
],
|
| 142 |
+
"tileSize": [
|
| 143 |
+
40,
|
| 144 |
+
36
|
| 145 |
+
]
|
| 146 |
+
},
|
| 147 |
+
{
|
| 148 |
+
"id": "12",
|
| 149 |
+
"name": "Route 1",
|
| 150 |
+
"coordinates": [
|
| 151 |
+
64,
|
| 152 |
+
282
|
| 153 |
+
],
|
| 154 |
+
"tileSize": [
|
| 155 |
+
20,
|
| 156 |
+
36
|
| 157 |
+
]
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"id": "13",
|
| 161 |
+
"name": "Route 2",
|
| 162 |
+
"coordinates": [
|
| 163 |
+
64,
|
| 164 |
+
174
|
| 165 |
+
],
|
| 166 |
+
"tileSize": [
|
| 167 |
+
20,
|
| 168 |
+
72
|
| 169 |
+
]
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"id": "14",
|
| 173 |
+
"name": "Route 3",
|
| 174 |
+
"coordinates": [
|
| 175 |
+
94,
|
| 176 |
+
146
|
| 177 |
+
],
|
| 178 |
+
"tileSize": [
|
| 179 |
+
70,
|
| 180 |
+
18
|
| 181 |
+
]
|
| 182 |
+
},
|
| 183 |
+
{
|
| 184 |
+
"id": "15",
|
| 185 |
+
"name": "Route 4",
|
| 186 |
+
"coordinates": [
|
| 187 |
+
144,
|
| 188 |
+
128
|
| 189 |
+
],
|
| 190 |
+
"tileSize": [
|
| 191 |
+
90,
|
| 192 |
+
18
|
| 193 |
+
]
|
| 194 |
+
},
|
| 195 |
+
{
|
| 196 |
+
"id": "16",
|
| 197 |
+
"name": "Route 5",
|
| 198 |
+
"coordinates": [
|
| 199 |
+
244,
|
| 200 |
+
156
|
| 201 |
+
],
|
| 202 |
+
"tileSize": [
|
| 203 |
+
20,
|
| 204 |
+
36
|
| 205 |
+
]
|
| 206 |
+
},
|
| 207 |
+
{
|
| 208 |
+
"id": "17",
|
| 209 |
+
"name": "Route 6",
|
| 210 |
+
"coordinates": [
|
| 211 |
+
244,
|
| 212 |
+
228
|
| 213 |
+
],
|
| 214 |
+
"tileSize": [
|
| 215 |
+
20,
|
| 216 |
+
36
|
| 217 |
+
]
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"id": "18",
|
| 221 |
+
"name": "Route 7",
|
| 222 |
+
"coordinates": [
|
| 223 |
+
214,
|
| 224 |
+
200
|
| 225 |
+
],
|
| 226 |
+
"tileSize": [
|
| 227 |
+
20,
|
| 228 |
+
18
|
| 229 |
+
]
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"id": "19",
|
| 233 |
+
"name": "Route 8",
|
| 234 |
+
"coordinates": [
|
| 235 |
+
274,
|
| 236 |
+
200
|
| 237 |
+
],
|
| 238 |
+
"tileSize": [
|
| 239 |
+
60,
|
| 240 |
+
18
|
| 241 |
+
]
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"id": "20",
|
| 245 |
+
"name": "Route 9",
|
| 246 |
+
"coordinates": [
|
| 247 |
+
274,
|
| 248 |
+
128
|
| 249 |
+
],
|
| 250 |
+
"tileSize": [
|
| 251 |
+
60,
|
| 252 |
+
18
|
| 253 |
+
]
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"id": "21",
|
| 257 |
+
"name": "Route 10",
|
| 258 |
+
"coordinates": [
|
| 259 |
+
334,
|
| 260 |
+
128
|
| 261 |
+
],
|
| 262 |
+
"tileSize": [
|
| 263 |
+
20,
|
| 264 |
+
72
|
| 265 |
+
]
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
"id": "22",
|
| 269 |
+
"name": "Route 11",
|
| 270 |
+
"coordinates": [
|
| 271 |
+
274,
|
| 272 |
+
272
|
| 273 |
+
],
|
| 274 |
+
"tileSize": [
|
| 275 |
+
60,
|
| 276 |
+
18
|
| 277 |
+
]
|
| 278 |
+
},
|
| 279 |
+
{
|
| 280 |
+
"id": "23",
|
| 281 |
+
"name": "Route 12",
|
| 282 |
+
"coordinates": [
|
| 283 |
+
334,
|
| 284 |
+
218
|
| 285 |
+
],
|
| 286 |
+
"tileSize": [
|
| 287 |
+
20,
|
| 288 |
+
108
|
| 289 |
+
]
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"id": "24",
|
| 293 |
+
"name": "Route 13",
|
| 294 |
+
"coordinates": [
|
| 295 |
+
294,
|
| 296 |
+
326
|
| 297 |
+
],
|
| 298 |
+
"tileSize": [
|
| 299 |
+
60,
|
| 300 |
+
18
|
| 301 |
+
]
|
| 302 |
+
},
|
| 303 |
+
{
|
| 304 |
+
"id": "25",
|
| 305 |
+
"name": "Route 14",
|
| 306 |
+
"coordinates": [
|
| 307 |
+
274,
|
| 308 |
+
326
|
| 309 |
+
],
|
| 310 |
+
"tileSize": [
|
| 311 |
+
20,
|
| 312 |
+
54
|
| 313 |
+
]
|
| 314 |
+
},
|
| 315 |
+
{
|
| 316 |
+
"id": "26",
|
| 317 |
+
"name": "Route 15",
|
| 318 |
+
"coordinates": [
|
| 319 |
+
214,
|
| 320 |
+
362
|
| 321 |
+
],
|
| 322 |
+
"tileSize": [
|
| 323 |
+
60,
|
| 324 |
+
18
|
| 325 |
+
]
|
| 326 |
+
},
|
| 327 |
+
{
|
| 328 |
+
"id": "27",
|
| 329 |
+
"name": "Route 16",
|
| 330 |
+
"coordinates": [
|
| 331 |
+
124,
|
| 332 |
+
200
|
| 333 |
+
],
|
| 334 |
+
"tileSize": [
|
| 335 |
+
40,
|
| 336 |
+
18
|
| 337 |
+
]
|
| 338 |
+
},
|
| 339 |
+
{
|
| 340 |
+
"id": "28",
|
| 341 |
+
"name": "Route 17",
|
| 342 |
+
"coordinates": [
|
| 343 |
+
124,
|
| 344 |
+
218
|
| 345 |
+
],
|
| 346 |
+
"tileSize": [
|
| 347 |
+
20,
|
| 348 |
+
144
|
| 349 |
+
]
|
| 350 |
+
},
|
| 351 |
+
{
|
| 352 |
+
"id": "29",
|
| 353 |
+
"name": "Route 18",
|
| 354 |
+
"coordinates": [
|
| 355 |
+
124,
|
| 356 |
+
362
|
| 357 |
+
],
|
| 358 |
+
"tileSize": [
|
| 359 |
+
50,
|
| 360 |
+
18
|
| 361 |
+
]
|
| 362 |
+
},
|
| 363 |
+
{
|
| 364 |
+
"id": "30",
|
| 365 |
+
"name": "Sea Route 19",
|
| 366 |
+
"coordinates": [
|
| 367 |
+
184,
|
| 368 |
+
390
|
| 369 |
+
],
|
| 370 |
+
"tileSize": [
|
| 371 |
+
20,
|
| 372 |
+
54
|
| 373 |
+
]
|
| 374 |
+
},
|
| 375 |
+
{
|
| 376 |
+
"id": "31",
|
| 377 |
+
"name": "Sea Route 20",
|
| 378 |
+
"coordinates": [
|
| 379 |
+
84,
|
| 380 |
+
426
|
| 381 |
+
],
|
| 382 |
+
"tileSize": [
|
| 383 |
+
100,
|
| 384 |
+
18
|
| 385 |
+
]
|
| 386 |
+
},
|
| 387 |
+
{
|
| 388 |
+
"id": "32",
|
| 389 |
+
"name": "Sea Route 21",
|
| 390 |
+
"coordinates": [
|
| 391 |
+
64,
|
| 392 |
+
336
|
| 393 |
+
],
|
| 394 |
+
"tileSize": [
|
| 395 |
+
20,
|
| 396 |
+
90
|
| 397 |
+
]
|
| 398 |
+
},
|
| 399 |
+
{
|
| 400 |
+
"id": "33",
|
| 401 |
+
"name": "Route 22",
|
| 402 |
+
"coordinates": [
|
| 403 |
+
14,
|
| 404 |
+
254
|
| 405 |
+
],
|
| 406 |
+
"tileSize": [
|
| 407 |
+
40,
|
| 408 |
+
18
|
| 409 |
+
]
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"id": "34",
|
| 413 |
+
"name": "Route 23",
|
| 414 |
+
"coordinates": [
|
| 415 |
+
14,
|
| 416 |
+
102
|
| 417 |
+
],
|
| 418 |
+
"tileSize": [
|
| 419 |
+
20,
|
| 420 |
+
144
|
| 421 |
+
]
|
| 422 |
+
},
|
| 423 |
+
{
|
| 424 |
+
"id": "35",
|
| 425 |
+
"name": "Route 24",
|
| 426 |
+
"coordinates": [
|
| 427 |
+
244,
|
| 428 |
+
84
|
| 429 |
+
],
|
| 430 |
+
"tileSize": [
|
| 431 |
+
20,
|
| 432 |
+
36
|
| 433 |
+
]
|
| 434 |
+
},
|
| 435 |
+
{
|
| 436 |
+
"id": "36",
|
| 437 |
+
"name": "Route 25",
|
| 438 |
+
"coordinates": [
|
| 439 |
+
264,
|
| 440 |
+
84
|
| 441 |
+
],
|
| 442 |
+
"tileSize": [
|
| 443 |
+
60,
|
| 444 |
+
18
|
| 445 |
+
]
|
| 446 |
+
},
|
| 447 |
+
{
|
| 448 |
+
"id": "37",
|
| 449 |
+
"name": "Players House First Floor",
|
| 450 |
+
"coordinates": [
|
| 451 |
+
55,
|
| 452 |
+
328
|
| 453 |
+
],
|
| 454 |
+
"tileSize": [
|
| 455 |
+
8,
|
| 456 |
+
8
|
| 457 |
+
]
|
| 458 |
+
},
|
| 459 |
+
{
|
| 460 |
+
"id": "38",
|
| 461 |
+
"name": "Players House Second Floor",
|
| 462 |
+
"coordinates": [
|
| 463 |
+
55,
|
| 464 |
+
319
|
| 465 |
+
],
|
| 466 |
+
"tileSize": [
|
| 467 |
+
8,
|
| 468 |
+
8
|
| 469 |
+
]
|
| 470 |
+
},
|
| 471 |
+
{
|
| 472 |
+
"id": "39",
|
| 473 |
+
"name": "Rivals House",
|
| 474 |
+
"coordinates": [
|
| 475 |
+
85,
|
| 476 |
+
316
|
| 477 |
+
],
|
| 478 |
+
"tileSize": [
|
| 479 |
+
8,
|
| 480 |
+
8
|
| 481 |
+
]
|
| 482 |
+
},
|
| 483 |
+
{
|
| 484 |
+
"id": "40",
|
| 485 |
+
"name": "Oaks Lab",
|
| 486 |
+
"coordinates": [
|
| 487 |
+
85,
|
| 488 |
+
325
|
| 489 |
+
],
|
| 490 |
+
"tileSize": [
|
| 491 |
+
10,
|
| 492 |
+
12
|
| 493 |
+
]
|
| 494 |
+
},
|
| 495 |
+
{
|
| 496 |
+
"id": "41",
|
| 497 |
+
"name": "Pokemon Center Viridian",
|
| 498 |
+
"coordinates": [
|
| 499 |
+
95,
|
| 500 |
+
274
|
| 501 |
+
],
|
| 502 |
+
"tileSize": [
|
| 503 |
+
14,
|
| 504 |
+
8
|
| 505 |
+
]
|
| 506 |
+
},
|
| 507 |
+
{
|
| 508 |
+
"id": "42",
|
| 509 |
+
"name": "Pokemart Viridian",
|
| 510 |
+
"coordinates": [
|
| 511 |
+
110,
|
| 512 |
+
274
|
| 513 |
+
],
|
| 514 |
+
"tileSize": [
|
| 515 |
+
8,
|
| 516 |
+
8
|
| 517 |
+
]
|
| 518 |
+
},
|
| 519 |
+
{
|
| 520 |
+
"id": "43",
|
| 521 |
+
"name": "Pokemon Academy",
|
| 522 |
+
"coordinates": [
|
| 523 |
+
95,
|
| 524 |
+
265
|
| 525 |
+
],
|
| 526 |
+
"tileSize": [
|
| 527 |
+
8,
|
| 528 |
+
8
|
| 529 |
+
]
|
| 530 |
+
},
|
| 531 |
+
{
|
| 532 |
+
"id": "44",
|
| 533 |
+
"name": "Nickname House",
|
| 534 |
+
"coordinates": [
|
| 535 |
+
104,
|
| 536 |
+
265
|
| 537 |
+
],
|
| 538 |
+
"tileSize": [
|
| 539 |
+
8,
|
| 540 |
+
8
|
| 541 |
+
]
|
| 542 |
+
},
|
| 543 |
+
{
|
| 544 |
+
"id": "45",
|
| 545 |
+
"name": "Viridian Gym",
|
| 546 |
+
"coordinates": [
|
| 547 |
+
95,
|
| 548 |
+
246
|
| 549 |
+
],
|
| 550 |
+
"tileSize": [
|
| 551 |
+
20,
|
| 552 |
+
18
|
| 553 |
+
]
|
| 554 |
+
},
|
| 555 |
+
{
|
| 556 |
+
"id": "46",
|
| 557 |
+
"name": "Digletts Cave Entrance",
|
| 558 |
+
"coordinates": [
|
| 559 |
+
55,
|
| 560 |
+
184
|
| 561 |
+
],
|
| 562 |
+
"tileSize": [
|
| 563 |
+
8,
|
| 564 |
+
8
|
| 565 |
+
]
|
| 566 |
+
},
|
| 567 |
+
{
|
| 568 |
+
"id": "47",
|
| 569 |
+
"name": "Route 2 Gate Pewter",
|
| 570 |
+
"coordinates": [
|
| 571 |
+
85,
|
| 572 |
+
180
|
| 573 |
+
],
|
| 574 |
+
"tileSize": [
|
| 575 |
+
10,
|
| 576 |
+
8
|
| 577 |
+
]
|
| 578 |
+
},
|
| 579 |
+
{
|
| 580 |
+
"id": "48",
|
| 581 |
+
"name": "Trader House Mr Mime Trade",
|
| 582 |
+
"coordinates": [
|
| 583 |
+
55,
|
| 584 |
+
193
|
| 585 |
+
],
|
| 586 |
+
"tileSize": [
|
| 587 |
+
8,
|
| 588 |
+
8
|
| 589 |
+
]
|
| 590 |
+
},
|
| 591 |
+
{
|
| 592 |
+
"id": "49",
|
| 593 |
+
"name": "Route 2 Gate Oaks Aid",
|
| 594 |
+
"coordinates": [
|
| 595 |
+
53,
|
| 596 |
+
202
|
| 597 |
+
],
|
| 598 |
+
"tileSize": [
|
| 599 |
+
10,
|
| 600 |
+
8
|
| 601 |
+
]
|
| 602 |
+
},
|
| 603 |
+
{
|
| 604 |
+
"id": "50",
|
| 605 |
+
"name": "Route 2 Gate Viridian",
|
| 606 |
+
"coordinates": [
|
| 607 |
+
100,
|
| 608 |
+
236
|
| 609 |
+
],
|
| 610 |
+
"tileSize": [
|
| 611 |
+
10,
|
| 612 |
+
8
|
| 613 |
+
]
|
| 614 |
+
},
|
| 615 |
+
{
|
| 616 |
+
"id": "51",
|
| 617 |
+
"name": "Viridian Forest",
|
| 618 |
+
"coordinates": [
|
| 619 |
+
88,
|
| 620 |
+
188
|
| 621 |
+
],
|
| 622 |
+
"tileSize": [
|
| 623 |
+
34,
|
| 624 |
+
48
|
| 625 |
+
]
|
| 626 |
+
},
|
| 627 |
+
{
|
| 628 |
+
"id": "52",
|
| 629 |
+
"name": "Museum F1",
|
| 630 |
+
"coordinates": [
|
| 631 |
+
57,
|
| 632 |
+
130
|
| 633 |
+
],
|
| 634 |
+
"tileSize": [
|
| 635 |
+
20,
|
| 636 |
+
8
|
| 637 |
+
]
|
| 638 |
+
},
|
| 639 |
+
{
|
| 640 |
+
"id": "53",
|
| 641 |
+
"name": "Museum F2",
|
| 642 |
+
"coordinates": [
|
| 643 |
+
57,
|
| 644 |
+
122
|
| 645 |
+
],
|
| 646 |
+
"tileSize": [
|
| 647 |
+
14,
|
| 648 |
+
8
|
| 649 |
+
]
|
| 650 |
+
},
|
| 651 |
+
{
|
| 652 |
+
"id": "54",
|
| 653 |
+
"name": "Pewter Gym",
|
| 654 |
+
"coordinates": [
|
| 655 |
+
43,
|
| 656 |
+
145
|
| 657 |
+
],
|
| 658 |
+
"tileSize": [
|
| 659 |
+
10,
|
| 660 |
+
14
|
| 661 |
+
]
|
| 662 |
+
},
|
| 663 |
+
{
|
| 664 |
+
"id": "55",
|
| 665 |
+
"name": "Trainer House Trading Tips",
|
| 666 |
+
"coordinates": [
|
| 667 |
+
45,
|
| 668 |
+
161
|
| 669 |
+
],
|
| 670 |
+
"tileSize": [
|
| 671 |
+
8,
|
| 672 |
+
8
|
| 673 |
+
]
|
| 674 |
+
},
|
| 675 |
+
{
|
| 676 |
+
"id": "56",
|
| 677 |
+
"name": "Pokemart",
|
| 678 |
+
"coordinates": [
|
| 679 |
+
36,
|
| 680 |
+
161
|
| 681 |
+
],
|
| 682 |
+
"tileSize": [
|
| 683 |
+
8,
|
| 684 |
+
8
|
| 685 |
+
]
|
| 686 |
+
},
|
| 687 |
+
{
|
| 688 |
+
"id": "57",
|
| 689 |
+
"name": "Trainer House Catching Tips",
|
| 690 |
+
"coordinates": [
|
| 691 |
+
55,
|
| 692 |
+
175
|
| 693 |
+
],
|
| 694 |
+
"tileSize": [
|
| 695 |
+
8,
|
| 696 |
+
8
|
| 697 |
+
]
|
| 698 |
+
},
|
| 699 |
+
{
|
| 700 |
+
"id": "58",
|
| 701 |
+
"name": "Pokemon Center Pewter",
|
| 702 |
+
"coordinates": [
|
| 703 |
+
39,
|
| 704 |
+
170
|
| 705 |
+
],
|
| 706 |
+
"tileSize": [
|
| 707 |
+
14,
|
| 708 |
+
8
|
| 709 |
+
]
|
| 710 |
+
},
|
| 711 |
+
{
|
| 712 |
+
"id": "59",
|
| 713 |
+
"name": "Mt Moon Route 3",
|
| 714 |
+
"coordinates": [
|
| 715 |
+
147,
|
| 716 |
+
92
|
| 717 |
+
],
|
| 718 |
+
"tileSize": [
|
| 719 |
+
40,
|
| 720 |
+
36
|
| 721 |
+
]
|
| 722 |
+
},
|
| 723 |
+
{
|
| 724 |
+
"id": "60",
|
| 725 |
+
"name": "Mt Moon B1F",
|
| 726 |
+
"coordinates": [
|
| 727 |
+
147,
|
| 728 |
+
63
|
| 729 |
+
],
|
| 730 |
+
"tileSize": [
|
| 731 |
+
28,
|
| 732 |
+
28
|
| 733 |
+
]
|
| 734 |
+
},
|
| 735 |
+
{
|
| 736 |
+
"id": "61",
|
| 737 |
+
"name": "Mt Moon B2F",
|
| 738 |
+
"coordinates": [
|
| 739 |
+
147,
|
| 740 |
+
26
|
| 741 |
+
],
|
| 742 |
+
"tileSize": [
|
| 743 |
+
40,
|
| 744 |
+
36
|
| 745 |
+
]
|
| 746 |
+
},
|
| 747 |
+
{
|
| 748 |
+
"id": "62",
|
| 749 |
+
"name": "House Breakin",
|
| 750 |
+
"coordinates": [
|
| 751 |
+
280,
|
| 752 |
+
104
|
| 753 |
+
],
|
| 754 |
+
"tileSize": [
|
| 755 |
+
8,
|
| 756 |
+
8
|
| 757 |
+
]
|
| 758 |
+
},
|
| 759 |
+
{
|
| 760 |
+
"id": "63",
|
| 761 |
+
"name": "Trader House Jynx",
|
| 762 |
+
"coordinates": [
|
| 763 |
+
225,
|
| 764 |
+
119
|
| 765 |
+
],
|
| 766 |
+
"tileSize": [
|
| 767 |
+
8,
|
| 768 |
+
8
|
| 769 |
+
]
|
| 770 |
+
},
|
| 771 |
+
{
|
| 772 |
+
"id": "64",
|
| 773 |
+
"name": "Pokemon Center Cerulean",
|
| 774 |
+
"coordinates": [
|
| 775 |
+
265,
|
| 776 |
+
104
|
| 777 |
+
],
|
| 778 |
+
"tileSize": [
|
| 779 |
+
14,
|
| 780 |
+
8
|
| 781 |
+
]
|
| 782 |
+
},
|
| 783 |
+
{
|
| 784 |
+
"id": "65",
|
| 785 |
+
"name": "Cerulean Gym",
|
| 786 |
+
"coordinates": [
|
| 787 |
+
275,
|
| 788 |
+
113
|
| 789 |
+
],
|
| 790 |
+
"tileSize": [
|
| 791 |
+
10,
|
| 792 |
+
14
|
| 793 |
+
]
|
| 794 |
+
},
|
| 795 |
+
{
|
| 796 |
+
"id": "66",
|
| 797 |
+
"name": "Bike Shop",
|
| 798 |
+
"coordinates": [
|
| 799 |
+
225,
|
| 800 |
+
147
|
| 801 |
+
],
|
| 802 |
+
"tileSize": [
|
| 803 |
+
8,
|
| 804 |
+
8
|
| 805 |
+
]
|
| 806 |
+
},
|
| 807 |
+
{
|
| 808 |
+
"id": "67",
|
| 809 |
+
"name": "Pokemart Cerulean",
|
| 810 |
+
"coordinates": [
|
| 811 |
+
225,
|
| 812 |
+
156
|
| 813 |
+
],
|
| 814 |
+
"tileSize": [
|
| 815 |
+
8,
|
| 816 |
+
8
|
| 817 |
+
]
|
| 818 |
+
},
|
| 819 |
+
{
|
| 820 |
+
"id": "68",
|
| 821 |
+
"name": "Pokemon Center Route 4",
|
| 822 |
+
"coordinates": [
|
| 823 |
+
129,
|
| 824 |
+
128
|
| 825 |
+
],
|
| 826 |
+
"tileSize": [
|
| 827 |
+
14,
|
| 828 |
+
8
|
| 829 |
+
]
|
| 830 |
+
},
|
| 831 |
+
{
|
| 832 |
+
"id": "69",
|
| 833 |
+
"name": "House Breakin V2",
|
| 834 |
+
"coordinates": [
|
| 835 |
+
280,
|
| 836 |
+
104
|
| 837 |
+
],
|
| 838 |
+
"tileSize": [
|
| 839 |
+
8,
|
| 840 |
+
8
|
| 841 |
+
]
|
| 842 |
+
},
|
| 843 |
+
{
|
| 844 |
+
"id": "70",
|
| 845 |
+
"name": "Saffron City Gate North",
|
| 846 |
+
"coordinates": [
|
| 847 |
+
265,
|
| 848 |
+
165
|
| 849 |
+
],
|
| 850 |
+
"tileSize": [
|
| 851 |
+
8,
|
| 852 |
+
6
|
| 853 |
+
]
|
| 854 |
+
},
|
| 855 |
+
{
|
| 856 |
+
"id": "71",
|
| 857 |
+
"name": "Underground Entrance North",
|
| 858 |
+
"coordinates": [
|
| 859 |
+
274,
|
| 860 |
+
163
|
| 861 |
+
],
|
| 862 |
+
"tileSize": [
|
| 863 |
+
8,
|
| 864 |
+
8
|
| 865 |
+
]
|
| 866 |
+
},
|
| 867 |
+
{
|
| 868 |
+
"id": "72",
|
| 869 |
+
"name": "Daycare",
|
| 870 |
+
"coordinates": [
|
| 871 |
+
235,
|
| 872 |
+
157
|
| 873 |
+
],
|
| 874 |
+
"tileSize": [
|
| 875 |
+
8,
|
| 876 |
+
8
|
| 877 |
+
]
|
| 878 |
+
},
|
| 879 |
+
{
|
| 880 |
+
"id": "73",
|
| 881 |
+
"name": "Underground Entrance",
|
| 882 |
+
"coordinates": [
|
| 883 |
+
265,
|
| 884 |
+
248
|
| 885 |
+
],
|
| 886 |
+
"tileSize": [
|
| 887 |
+
8,
|
| 888 |
+
6
|
| 889 |
+
]
|
| 890 |
+
},
|
| 891 |
+
{
|
| 892 |
+
"id": "74",
|
| 893 |
+
"name": "Underground Entrance South",
|
| 894 |
+
"coordinates": [
|
| 895 |
+
265,
|
| 896 |
+
255
|
| 897 |
+
],
|
| 898 |
+
"tileSize": [
|
| 899 |
+
8,
|
| 900 |
+
8
|
| 901 |
+
]
|
| 902 |
+
},
|
| 903 |
+
{
|
| 904 |
+
"id": "76",
|
| 905 |
+
"name": "Saffron City Gate",
|
| 906 |
+
"coordinates": [
|
| 907 |
+
227,
|
| 908 |
+
219
|
| 909 |
+
],
|
| 910 |
+
"tileSize": [
|
| 911 |
+
6,
|
| 912 |
+
8
|
| 913 |
+
]
|
| 914 |
+
},
|
| 915 |
+
{
|
| 916 |
+
"id": "77",
|
| 917 |
+
"name": "Underground Entrance",
|
| 918 |
+
"coordinates": [
|
| 919 |
+
216,
|
| 920 |
+
219
|
| 921 |
+
],
|
| 922 |
+
"tileSize": [
|
| 923 |
+
8,
|
| 924 |
+
8
|
| 925 |
+
]
|
| 926 |
+
},
|
| 927 |
+
{
|
| 928 |
+
"id": "78",
|
| 929 |
+
"name": "Underground Entrance V2",
|
| 930 |
+
"coordinates": [
|
| 931 |
+
216,
|
| 932 |
+
219
|
| 933 |
+
],
|
| 934 |
+
"tileSize": [
|
| 935 |
+
8,
|
| 936 |
+
8
|
| 937 |
+
]
|
| 938 |
+
},
|
| 939 |
+
{
|
| 940 |
+
"id": "79",
|
| 941 |
+
"name": "Underground Entrance V2",
|
| 942 |
+
"coordinates": [
|
| 943 |
+
275,
|
| 944 |
+
219
|
| 945 |
+
],
|
| 946 |
+
"tileSize": [
|
| 947 |
+
6,
|
| 948 |
+
8
|
| 949 |
+
]
|
| 950 |
+
},
|
| 951 |
+
{
|
| 952 |
+
"id": "80",
|
| 953 |
+
"name": "Underground Entrance V2",
|
| 954 |
+
"coordinates": [
|
| 955 |
+
282,
|
| 956 |
+
219
|
| 957 |
+
],
|
| 958 |
+
"tileSize": [
|
| 959 |
+
8,
|
| 960 |
+
8
|
| 961 |
+
]
|
| 962 |
+
},
|
| 963 |
+
{
|
| 964 |
+
"id": "81",
|
| 965 |
+
"name": "Pokemon Center Route 10",
|
| 966 |
+
"coordinates": [
|
| 967 |
+
355,
|
| 968 |
+
136
|
| 969 |
+
],
|
| 970 |
+
"tileSize": [
|
| 971 |
+
14,
|
| 972 |
+
8
|
| 973 |
+
]
|
| 974 |
+
},
|
| 975 |
+
{
|
| 976 |
+
"id": "82",
|
| 977 |
+
"name": "Rock Tunnel 1F",
|
| 978 |
+
"coordinates": [
|
| 979 |
+
355,
|
| 980 |
+
145
|
| 981 |
+
],
|
| 982 |
+
"tileSize": [
|
| 983 |
+
40,
|
| 984 |
+
36
|
| 985 |
+
]
|
| 986 |
+
},
|
| 987 |
+
{
|
| 988 |
+
"id": "83",
|
| 989 |
+
"name": "Power Plant",
|
| 990 |
+
"coordinates": [
|
| 991 |
+
293,
|
| 992 |
+
147
|
| 993 |
+
],
|
| 994 |
+
"tileSize": [
|
| 995 |
+
40,
|
| 996 |
+
36
|
| 997 |
+
]
|
| 998 |
+
},
|
| 999 |
+
{
|
| 1000 |
+
"id": "84",
|
| 1001 |
+
"name": "Gate 1F",
|
| 1002 |
+
"coordinates": [
|
| 1003 |
+
325,
|
| 1004 |
+
261
|
| 1005 |
+
],
|
| 1006 |
+
"tileSize": [
|
| 1007 |
+
8,
|
| 1008 |
+
10
|
| 1009 |
+
]
|
| 1010 |
+
},
|
| 1011 |
+
{
|
| 1012 |
+
"id": "85",
|
| 1013 |
+
"name": "Digletts Cave Entrance",
|
| 1014 |
+
"coordinates": [
|
| 1015 |
+
275,
|
| 1016 |
+
264
|
| 1017 |
+
],
|
| 1018 |
+
"tileSize": [
|
| 1019 |
+
8,
|
| 1020 |
+
8
|
| 1021 |
+
]
|
| 1022 |
+
},
|
| 1023 |
+
{
|
| 1024 |
+
"id": "86",
|
| 1025 |
+
"name": "Gate 2F",
|
| 1026 |
+
"coordinates": [
|
| 1027 |
+
325,
|
| 1028 |
+
252
|
| 1029 |
+
],
|
| 1030 |
+
"tileSize": [
|
| 1031 |
+
8,
|
| 1032 |
+
8
|
| 1033 |
+
]
|
| 1034 |
+
},
|
| 1035 |
+
{
|
| 1036 |
+
"id": "87",
|
| 1037 |
+
"name": "Gate 1F",
|
| 1038 |
+
"coordinates": [
|
| 1039 |
+
355,
|
| 1040 |
+
232
|
| 1041 |
+
],
|
| 1042 |
+
"tileSize": [
|
| 1043 |
+
10,
|
| 1044 |
+
8
|
| 1045 |
+
]
|
| 1046 |
+
},
|
| 1047 |
+
{
|
| 1048 |
+
"id": "88",
|
| 1049 |
+
"name": "Bills Lab",
|
| 1050 |
+
"coordinates": [
|
| 1051 |
+
307,
|
| 1052 |
+
76
|
| 1053 |
+
],
|
| 1054 |
+
"tileSize": [
|
| 1055 |
+
8,
|
| 1056 |
+
8
|
| 1057 |
+
]
|
| 1058 |
+
},
|
| 1059 |
+
{
|
| 1060 |
+
"id": "89",
|
| 1061 |
+
"name": "Pokemon Center Vermilion",
|
| 1062 |
+
"coordinates": [
|
| 1063 |
+
219,
|
| 1064 |
+
264
|
| 1065 |
+
],
|
| 1066 |
+
"tileSize": [
|
| 1067 |
+
14,
|
| 1068 |
+
8
|
| 1069 |
+
]
|
| 1070 |
+
},
|
| 1071 |
+
{
|
| 1072 |
+
"id": "90",
|
| 1073 |
+
"name": "Pokemon Fan Club",
|
| 1074 |
+
"coordinates": [
|
| 1075 |
+
216,
|
| 1076 |
+
273
|
| 1077 |
+
],
|
| 1078 |
+
"tileSize": [
|
| 1079 |
+
8,
|
| 1080 |
+
8
|
| 1081 |
+
]
|
| 1082 |
+
},
|
| 1083 |
+
{
|
| 1084 |
+
"id": "91",
|
| 1085 |
+
"name": "Pokemart Vermilion",
|
| 1086 |
+
"coordinates": [
|
| 1087 |
+
225,
|
| 1088 |
+
282
|
| 1089 |
+
],
|
| 1090 |
+
"tileSize": [
|
| 1091 |
+
8,
|
| 1092 |
+
8
|
| 1093 |
+
]
|
| 1094 |
+
},
|
| 1095 |
+
{
|
| 1096 |
+
"id": "92",
|
| 1097 |
+
"name": "Vermilion Gym",
|
| 1098 |
+
"coordinates": [
|
| 1099 |
+
214,
|
| 1100 |
+
282
|
| 1101 |
+
],
|
| 1102 |
+
"tileSize": [
|
| 1103 |
+
10,
|
| 1104 |
+
18
|
| 1105 |
+
]
|
| 1106 |
+
},
|
| 1107 |
+
{
|
| 1108 |
+
"id": "93",
|
| 1109 |
+
"name": "Trader House Pidgy Letter",
|
| 1110 |
+
"coordinates": [
|
| 1111 |
+
225,
|
| 1112 |
+
273
|
| 1113 |
+
],
|
| 1114 |
+
"tileSize": [
|
| 1115 |
+
8,
|
| 1116 |
+
8
|
| 1117 |
+
]
|
| 1118 |
+
},
|
| 1119 |
+
{
|
| 1120 |
+
"id": "94",
|
| 1121 |
+
"name": "Vermilion Harbor",
|
| 1122 |
+
"coordinates": [
|
| 1123 |
+
239,
|
| 1124 |
+
300
|
| 1125 |
+
],
|
| 1126 |
+
"tileSize": [
|
| 1127 |
+
28,
|
| 1128 |
+
12
|
| 1129 |
+
]
|
| 1130 |
+
},
|
| 1131 |
+
{
|
| 1132 |
+
"id": "95",
|
| 1133 |
+
"name": "SS Anne F1",
|
| 1134 |
+
"coordinates": [
|
| 1135 |
+
298,
|
| 1136 |
+
345
|
| 1137 |
+
],
|
| 1138 |
+
"tileSize": [
|
| 1139 |
+
40,
|
| 1140 |
+
18
|
| 1141 |
+
]
|
| 1142 |
+
},
|
| 1143 |
+
{
|
| 1144 |
+
"id": "96",
|
| 1145 |
+
"name": "SS Anne F2",
|
| 1146 |
+
"coordinates": [
|
| 1147 |
+
298,
|
| 1148 |
+
377
|
| 1149 |
+
],
|
| 1150 |
+
"tileSize": [
|
| 1151 |
+
40,
|
| 1152 |
+
18
|
| 1153 |
+
]
|
| 1154 |
+
},
|
| 1155 |
+
{
|
| 1156 |
+
"id": "97",
|
| 1157 |
+
"name": "SS Anne F3",
|
| 1158 |
+
"coordinates": [
|
| 1159 |
+
279,
|
| 1160 |
+
387
|
| 1161 |
+
],
|
| 1162 |
+
"tileSize": [
|
| 1163 |
+
20,
|
| 1164 |
+
6
|
| 1165 |
+
]
|
| 1166 |
+
},
|
| 1167 |
+
{
|
| 1168 |
+
"id": "98",
|
| 1169 |
+
"name": "SS Anne B1F",
|
| 1170 |
+
"coordinates": [
|
| 1171 |
+
308,
|
| 1172 |
+
362
|
| 1173 |
+
],
|
| 1174 |
+
"tileSize": [
|
| 1175 |
+
30,
|
| 1176 |
+
8
|
| 1177 |
+
]
|
| 1178 |
+
},
|
| 1179 |
+
{
|
| 1180 |
+
"id": "99",
|
| 1181 |
+
"name": "SS Anne Deck",
|
| 1182 |
+
"coordinates": [
|
| 1183 |
+
265,
|
| 1184 |
+
384
|
| 1185 |
+
],
|
| 1186 |
+
"tileSize": [
|
| 1187 |
+
20,
|
| 1188 |
+
14
|
| 1189 |
+
]
|
| 1190 |
+
},
|
| 1191 |
+
{
|
| 1192 |
+
"id": "100",
|
| 1193 |
+
"name": "SS Anne Kitchen",
|
| 1194 |
+
"coordinates": [
|
| 1195 |
+
295,
|
| 1196 |
+
363
|
| 1197 |
+
],
|
| 1198 |
+
"tileSize": [
|
| 1199 |
+
14,
|
| 1200 |
+
16
|
| 1201 |
+
]
|
| 1202 |
+
},
|
| 1203 |
+
{
|
| 1204 |
+
"id": "101",
|
| 1205 |
+
"name": "SS Anne Captains Office",
|
| 1206 |
+
"coordinates": [
|
| 1207 |
+
334,
|
| 1208 |
+
371
|
| 1209 |
+
],
|
| 1210 |
+
"tileSize": [
|
| 1211 |
+
6,
|
| 1212 |
+
8
|
| 1213 |
+
]
|
| 1214 |
+
},
|
| 1215 |
+
{
|
| 1216 |
+
"id": "102",
|
| 1217 |
+
"name": "SS Anne Cabins 1F",
|
| 1218 |
+
"coordinates": [
|
| 1219 |
+
341,
|
| 1220 |
+
345
|
| 1221 |
+
],
|
| 1222 |
+
"tileSize": [
|
| 1223 |
+
24,
|
| 1224 |
+
16
|
| 1225 |
+
]
|
| 1226 |
+
},
|
| 1227 |
+
{
|
| 1228 |
+
"id": "103",
|
| 1229 |
+
"name": "SS Anne Cabins 2F",
|
| 1230 |
+
"coordinates": [
|
| 1231 |
+
341,
|
| 1232 |
+
379
|
| 1233 |
+
],
|
| 1234 |
+
"tileSize": [
|
| 1235 |
+
24,
|
| 1236 |
+
16
|
| 1237 |
+
]
|
| 1238 |
+
},
|
| 1239 |
+
{
|
| 1240 |
+
"id": "104",
|
| 1241 |
+
"name": "SS Anne Cabins B1F",
|
| 1242 |
+
"coordinates": [
|
| 1243 |
+
341,
|
| 1244 |
+
362
|
| 1245 |
+
],
|
| 1246 |
+
"tileSize": [
|
| 1247 |
+
24,
|
| 1248 |
+
16
|
| 1249 |
+
]
|
| 1250 |
+
},
|
| 1251 |
+
{
|
| 1252 |
+
"id": "108",
|
| 1253 |
+
"name": "Victory Road Entrance",
|
| 1254 |
+
"coordinates": [
|
| 1255 |
+
35,
|
| 1256 |
+
116
|
| 1257 |
+
],
|
| 1258 |
+
"tileSize": [
|
| 1259 |
+
20,
|
| 1260 |
+
18
|
| 1261 |
+
]
|
| 1262 |
+
},
|
| 1263 |
+
{
|
| 1264 |
+
"id": "113",
|
| 1265 |
+
"name": "Lances Room",
|
| 1266 |
+
"coordinates": [
|
| 1267 |
+
0,
|
| 1268 |
+
16
|
| 1269 |
+
],
|
| 1270 |
+
"tileSize": [
|
| 1271 |
+
26,
|
| 1272 |
+
26
|
| 1273 |
+
]
|
| 1274 |
+
},
|
| 1275 |
+
{
|
| 1276 |
+
"id": "118",
|
| 1277 |
+
"name": "Hall of Fame",
|
| 1278 |
+
"coordinates": [
|
| 1279 |
+
1,
|
| 1280 |
+
0
|
| 1281 |
+
],
|
| 1282 |
+
"tileSize": [
|
| 1283 |
+
10,
|
| 1284 |
+
8
|
| 1285 |
+
]
|
| 1286 |
+
},
|
| 1287 |
+
{
|
| 1288 |
+
"id": "119",
|
| 1289 |
+
"name": "Underground Path Route 5 to Route 6",
|
| 1290 |
+
"coordinates": [
|
| 1291 |
+
356,
|
| 1292 |
+
241
|
| 1293 |
+
],
|
| 1294 |
+
"tileSize": [
|
| 1295 |
+
8,
|
| 1296 |
+
48
|
| 1297 |
+
]
|
| 1298 |
+
},
|
| 1299 |
+
{
|
| 1300 |
+
"id": "120",
|
| 1301 |
+
"name": "Champions Room",
|
| 1302 |
+
"coordinates": [
|
| 1303 |
+
2,
|
| 1304 |
+
8
|
| 1305 |
+
],
|
| 1306 |
+
"tileSize": [
|
| 1307 |
+
8,
|
| 1308 |
+
8
|
| 1309 |
+
]
|
| 1310 |
+
},
|
| 1311 |
+
{
|
| 1312 |
+
"id": "121",
|
| 1313 |
+
"name": "Undeground Path",
|
| 1314 |
+
"coordinates": [
|
| 1315 |
+
355,
|
| 1316 |
+
287
|
| 1317 |
+
],
|
| 1318 |
+
"tileSize": [
|
| 1319 |
+
50,
|
| 1320 |
+
8
|
| 1321 |
+
]
|
| 1322 |
+
},
|
| 1323 |
+
{
|
| 1324 |
+
"id": "122",
|
| 1325 |
+
"name": "Department Store F1",
|
| 1326 |
+
"coordinates": [
|
| 1327 |
+
170,
|
| 1328 |
+
183
|
| 1329 |
+
],
|
| 1330 |
+
"tileSize": [
|
| 1331 |
+
20,
|
| 1332 |
+
8
|
| 1333 |
+
]
|
| 1334 |
+
},
|
| 1335 |
+
{
|
| 1336 |
+
"id": "123",
|
| 1337 |
+
"name": "Department Store F2",
|
| 1338 |
+
"coordinates": [
|
| 1339 |
+
170,
|
| 1340 |
+
174
|
| 1341 |
+
],
|
| 1342 |
+
"tileSize": [
|
| 1343 |
+
20,
|
| 1344 |
+
8
|
| 1345 |
+
]
|
| 1346 |
+
},
|
| 1347 |
+
{
|
| 1348 |
+
"id": "124",
|
| 1349 |
+
"name": "Department Store F3",
|
| 1350 |
+
"coordinates": [
|
| 1351 |
+
170,
|
| 1352 |
+
165
|
| 1353 |
+
],
|
| 1354 |
+
"tileSize": [
|
| 1355 |
+
20,
|
| 1356 |
+
8
|
| 1357 |
+
]
|
| 1358 |
+
},
|
| 1359 |
+
{
|
| 1360 |
+
"id": "125",
|
| 1361 |
+
"name": "Department Store F4",
|
| 1362 |
+
"coordinates": [
|
| 1363 |
+
170,
|
| 1364 |
+
156
|
| 1365 |
+
],
|
| 1366 |
+
"tileSize": [
|
| 1367 |
+
20,
|
| 1368 |
+
8
|
| 1369 |
+
]
|
| 1370 |
+
},
|
| 1371 |
+
{
|
| 1372 |
+
"id": "126",
|
| 1373 |
+
"name": "Department Store Roof",
|
| 1374 |
+
"coordinates": [
|
| 1375 |
+
149,
|
| 1376 |
+
174
|
| 1377 |
+
],
|
| 1378 |
+
"tileSize": [
|
| 1379 |
+
20,
|
| 1380 |
+
8
|
| 1381 |
+
]
|
| 1382 |
+
},
|
| 1383 |
+
{
|
| 1384 |
+
"id": "127",
|
| 1385 |
+
"name": "Department Store Lift",
|
| 1386 |
+
"coordinates": [
|
| 1387 |
+
159,
|
| 1388 |
+
192
|
| 1389 |
+
],
|
| 1390 |
+
"tileSize": [
|
| 1391 |
+
4,
|
| 1392 |
+
4
|
| 1393 |
+
]
|
| 1394 |
+
},
|
| 1395 |
+
{
|
| 1396 |
+
"id": "128",
|
| 1397 |
+
"name": "Office Building F1",
|
| 1398 |
+
"coordinates": [
|
| 1399 |
+
191,
|
| 1400 |
+
179
|
| 1401 |
+
],
|
| 1402 |
+
"tileSize": [
|
| 1403 |
+
8,
|
| 1404 |
+
12
|
| 1405 |
+
]
|
| 1406 |
+
},
|
| 1407 |
+
{
|
| 1408 |
+
"id": "129",
|
| 1409 |
+
"name": "Office Building F2",
|
| 1410 |
+
"coordinates": [
|
| 1411 |
+
191,
|
| 1412 |
+
166
|
| 1413 |
+
],
|
| 1414 |
+
"tileSize": [
|
| 1415 |
+
8,
|
| 1416 |
+
12
|
| 1417 |
+
]
|
| 1418 |
+
},
|
| 1419 |
+
{
|
| 1420 |
+
"id": "130",
|
| 1421 |
+
"name": "Office Building F3",
|
| 1422 |
+
"coordinates": [
|
| 1423 |
+
191,
|
| 1424 |
+
153
|
| 1425 |
+
],
|
| 1426 |
+
"tileSize": [
|
| 1427 |
+
8,
|
| 1428 |
+
12
|
| 1429 |
+
]
|
| 1430 |
+
},
|
| 1431 |
+
{
|
| 1432 |
+
"id": "131",
|
| 1433 |
+
"name": "Office Building F1",
|
| 1434 |
+
"coordinates": [
|
| 1435 |
+
200,
|
| 1436 |
+
170
|
| 1437 |
+
],
|
| 1438 |
+
"tileSize": [
|
| 1439 |
+
8,
|
| 1440 |
+
12
|
| 1441 |
+
]
|
| 1442 |
+
},
|
| 1443 |
+
{
|
| 1444 |
+
"id": "132",
|
| 1445 |
+
"name": "Office Building Roof Room",
|
| 1446 |
+
"coordinates": [
|
| 1447 |
+
200,
|
| 1448 |
+
161
|
| 1449 |
+
],
|
| 1450 |
+
"tileSize": [
|
| 1451 |
+
8,
|
| 1452 |
+
8
|
| 1453 |
+
]
|
| 1454 |
+
},
|
| 1455 |
+
{
|
| 1456 |
+
"id": "133",
|
| 1457 |
+
"name": "Pokemon Center Celedon",
|
| 1458 |
+
"coordinates": [
|
| 1459 |
+
200,
|
| 1460 |
+
183
|
| 1461 |
+
],
|
| 1462 |
+
"tileSize": [
|
| 1463 |
+
14,
|
| 1464 |
+
8
|
| 1465 |
+
]
|
| 1466 |
+
},
|
| 1467 |
+
{
|
| 1468 |
+
"id": "134",
|
| 1469 |
+
"name": "Celadon Gym",
|
| 1470 |
+
"coordinates": [
|
| 1471 |
+
153,
|
| 1472 |
+
219
|
| 1473 |
+
],
|
| 1474 |
+
"tileSize": [
|
| 1475 |
+
10,
|
| 1476 |
+
18
|
| 1477 |
+
]
|
| 1478 |
+
},
|
| 1479 |
+
{
|
| 1480 |
+
"id": "135",
|
| 1481 |
+
"name": "Rocket Game Corner",
|
| 1482 |
+
"coordinates": [
|
| 1483 |
+
164,
|
| 1484 |
+
238
|
| 1485 |
+
],
|
| 1486 |
+
"tileSize": [
|
| 1487 |
+
20,
|
| 1488 |
+
18
|
| 1489 |
+
]
|
| 1490 |
+
},
|
| 1491 |
+
{
|
| 1492 |
+
"id": "136",
|
| 1493 |
+
"name": "Department Store F5",
|
| 1494 |
+
"coordinates": [
|
| 1495 |
+
149,
|
| 1496 |
+
183
|
| 1497 |
+
],
|
| 1498 |
+
"tileSize": [
|
| 1499 |
+
20,
|
| 1500 |
+
8
|
| 1501 |
+
]
|
| 1502 |
+
},
|
| 1503 |
+
{
|
| 1504 |
+
"id": "137",
|
| 1505 |
+
"name": "Prize Corner",
|
| 1506 |
+
"coordinates": [
|
| 1507 |
+
169,
|
| 1508 |
+
229
|
| 1509 |
+
],
|
| 1510 |
+
"tileSize": [
|
| 1511 |
+
10,
|
| 1512 |
+
8
|
| 1513 |
+
]
|
| 1514 |
+
},
|
| 1515 |
+
{
|
| 1516 |
+
"id": "138",
|
| 1517 |
+
"name": "Restaurant",
|
| 1518 |
+
"coordinates": [
|
| 1519 |
+
180,
|
| 1520 |
+
229
|
| 1521 |
+
],
|
| 1522 |
+
"tileSize": [
|
| 1523 |
+
10,
|
| 1524 |
+
8
|
| 1525 |
+
]
|
| 1526 |
+
},
|
| 1527 |
+
{
|
| 1528 |
+
"id": "139",
|
| 1529 |
+
"name": "Rocket House",
|
| 1530 |
+
"coordinates": [
|
| 1531 |
+
191,
|
| 1532 |
+
229
|
| 1533 |
+
],
|
| 1534 |
+
"tileSize": [
|
| 1535 |
+
8,
|
| 1536 |
+
8
|
| 1537 |
+
]
|
| 1538 |
+
},
|
| 1539 |
+
{
|
| 1540 |
+
"id": "140",
|
| 1541 |
+
"name": "Hotel",
|
| 1542 |
+
"coordinates": [
|
| 1543 |
+
200,
|
| 1544 |
+
229
|
| 1545 |
+
],
|
| 1546 |
+
"tileSize": [
|
| 1547 |
+
14,
|
| 1548 |
+
8
|
| 1549 |
+
]
|
| 1550 |
+
},
|
| 1551 |
+
{
|
| 1552 |
+
"id": "141",
|
| 1553 |
+
"name": "Pokemon Center Lavender",
|
| 1554 |
+
"coordinates": [
|
| 1555 |
+
310,
|
| 1556 |
+
191
|
| 1557 |
+
],
|
| 1558 |
+
"tileSize": [
|
| 1559 |
+
14,
|
| 1560 |
+
8
|
| 1561 |
+
]
|
| 1562 |
+
},
|
| 1563 |
+
{
|
| 1564 |
+
"id": "142",
|
| 1565 |
+
"name": "Pokemon Tower F1",
|
| 1566 |
+
"coordinates": [
|
| 1567 |
+
387,
|
| 1568 |
+
239
|
| 1569 |
+
],
|
| 1570 |
+
"tileSize": [
|
| 1571 |
+
20,
|
| 1572 |
+
18
|
| 1573 |
+
]
|
| 1574 |
+
},
|
| 1575 |
+
{
|
| 1576 |
+
"id": "143",
|
| 1577 |
+
"name": "Pokemon Tower F2",
|
| 1578 |
+
"coordinates": [
|
| 1579 |
+
366,
|
| 1580 |
+
239
|
| 1581 |
+
],
|
| 1582 |
+
"tileSize": [
|
| 1583 |
+
20,
|
| 1584 |
+
18
|
| 1585 |
+
]
|
| 1586 |
+
},
|
| 1587 |
+
{
|
| 1588 |
+
"id": "144",
|
| 1589 |
+
"name": "Pokemon Tower F3",
|
| 1590 |
+
"coordinates": [
|
| 1591 |
+
387,
|
| 1592 |
+
220
|
| 1593 |
+
],
|
| 1594 |
+
"tileSize": [
|
| 1595 |
+
20,
|
| 1596 |
+
18
|
| 1597 |
+
]
|
| 1598 |
+
},
|
| 1599 |
+
{
|
| 1600 |
+
"id": "145",
|
| 1601 |
+
"name": "Pokemon Tower F4",
|
| 1602 |
+
"coordinates": [
|
| 1603 |
+
366,
|
| 1604 |
+
220
|
| 1605 |
+
],
|
| 1606 |
+
"tileSize": [
|
| 1607 |
+
20,
|
| 1608 |
+
18
|
| 1609 |
+
]
|
| 1610 |
+
},
|
| 1611 |
+
{
|
| 1612 |
+
"id": "146",
|
| 1613 |
+
"name": "Pokemon Tower F5",
|
| 1614 |
+
"coordinates": [
|
| 1615 |
+
387,
|
| 1616 |
+
201
|
| 1617 |
+
],
|
| 1618 |
+
"tileSize": [
|
| 1619 |
+
20,
|
| 1620 |
+
18
|
| 1621 |
+
]
|
| 1622 |
+
},
|
| 1623 |
+
{
|
| 1624 |
+
"id": "147",
|
| 1625 |
+
"name": "Pokemon Tower F6",
|
| 1626 |
+
"coordinates": [
|
| 1627 |
+
366,
|
| 1628 |
+
201
|
| 1629 |
+
],
|
| 1630 |
+
"tileSize": [
|
| 1631 |
+
20,
|
| 1632 |
+
18
|
| 1633 |
+
]
|
| 1634 |
+
},
|
| 1635 |
+
{
|
| 1636 |
+
"id": "148",
|
| 1637 |
+
"name": "Pokemon Tower F7",
|
| 1638 |
+
"coordinates": [
|
| 1639 |
+
366,
|
| 1640 |
+
182
|
| 1641 |
+
],
|
| 1642 |
+
"tileSize": [
|
| 1643 |
+
20,
|
| 1644 |
+
18
|
| 1645 |
+
]
|
| 1646 |
+
},
|
| 1647 |
+
{
|
| 1648 |
+
"id": "149",
|
| 1649 |
+
"name": "Mr Fuji House",
|
| 1650 |
+
"coordinates": [
|
| 1651 |
+
325,
|
| 1652 |
+
191
|
| 1653 |
+
],
|
| 1654 |
+
"tileSize": [
|
| 1655 |
+
8,
|
| 1656 |
+
8
|
| 1657 |
+
]
|
| 1658 |
+
},
|
| 1659 |
+
{
|
| 1660 |
+
"id": "150",
|
| 1661 |
+
"name": "Pokemart Lavender",
|
| 1662 |
+
"coordinates": [
|
| 1663 |
+
355,
|
| 1664 |
+
210
|
| 1665 |
+
],
|
| 1666 |
+
"tileSize": [
|
| 1667 |
+
8,
|
| 1668 |
+
8
|
| 1669 |
+
]
|
| 1670 |
+
},
|
| 1671 |
+
{
|
| 1672 |
+
"id": "151",
|
| 1673 |
+
"name": "Cubone House",
|
| 1674 |
+
"coordinates": [
|
| 1675 |
+
316,
|
| 1676 |
+
219
|
| 1677 |
+
],
|
| 1678 |
+
"tileSize": [
|
| 1679 |
+
8,
|
| 1680 |
+
8
|
| 1681 |
+
]
|
| 1682 |
+
},
|
| 1683 |
+
{
|
| 1684 |
+
"id": "152",
|
| 1685 |
+
"name": "Pokemart Fuchsia",
|
| 1686 |
+
"coordinates": [
|
| 1687 |
+
165,
|
| 1688 |
+
353
|
| 1689 |
+
],
|
| 1690 |
+
"tileSize": [
|
| 1691 |
+
8,
|
| 1692 |
+
8
|
| 1693 |
+
]
|
| 1694 |
+
},
|
| 1695 |
+
{
|
| 1696 |
+
"id": "153",
|
| 1697 |
+
"name": "Bills Mom",
|
| 1698 |
+
"coordinates": [
|
| 1699 |
+
165,
|
| 1700 |
+
381
|
| 1701 |
+
],
|
| 1702 |
+
"tileSize": [
|
| 1703 |
+
8,
|
| 1704 |
+
8
|
| 1705 |
+
]
|
| 1706 |
+
},
|
| 1707 |
+
{
|
| 1708 |
+
"id": "154",
|
| 1709 |
+
"name": "Pokemon Center Fuchsia",
|
| 1710 |
+
"coordinates": [
|
| 1711 |
+
165,
|
| 1712 |
+
391
|
| 1713 |
+
],
|
| 1714 |
+
"tileSize": [
|
| 1715 |
+
14,
|
| 1716 |
+
8
|
| 1717 |
+
]
|
| 1718 |
+
},
|
| 1719 |
+
{
|
| 1720 |
+
"id": "155",
|
| 1721 |
+
"name": "Wardens House",
|
| 1722 |
+
"coordinates": [
|
| 1723 |
+
205,
|
| 1724 |
+
391
|
| 1725 |
+
],
|
| 1726 |
+
"tileSize": [
|
| 1727 |
+
10,
|
| 1728 |
+
8
|
| 1729 |
+
]
|
| 1730 |
+
},
|
| 1731 |
+
{
|
| 1732 |
+
"id": "156",
|
| 1733 |
+
"name": "Safari Gate",
|
| 1734 |
+
"coordinates": [
|
| 1735 |
+
189,
|
| 1736 |
+
348
|
| 1737 |
+
],
|
| 1738 |
+
"tileSize": [
|
| 1739 |
+
8,
|
| 1740 |
+
6
|
| 1741 |
+
]
|
| 1742 |
+
},
|
| 1743 |
+
{
|
| 1744 |
+
"id": "157",
|
| 1745 |
+
"name": "Fuchsia Gym",
|
| 1746 |
+
"coordinates": [
|
| 1747 |
+
154,
|
| 1748 |
+
381
|
| 1749 |
+
],
|
| 1750 |
+
"tileSize": [
|
| 1751 |
+
10,
|
| 1752 |
+
18
|
| 1753 |
+
]
|
| 1754 |
+
},
|
| 1755 |
+
{
|
| 1756 |
+
"id": "158",
|
| 1757 |
+
"name": "Meeting Room",
|
| 1758 |
+
"coordinates": [
|
| 1759 |
+
215,
|
| 1760 |
+
353
|
| 1761 |
+
],
|
| 1762 |
+
"tileSize": [
|
| 1763 |
+
14,
|
| 1764 |
+
8
|
| 1765 |
+
]
|
| 1766 |
+
},
|
| 1767 |
+
{
|
| 1768 |
+
"id": "159",
|
| 1769 |
+
"name": "Sea Foam Islands B1F",
|
| 1770 |
+
"coordinates": [
|
| 1771 |
+
116,
|
| 1772 |
+
388
|
| 1773 |
+
],
|
| 1774 |
+
"tileSize": [
|
| 1775 |
+
30,
|
| 1776 |
+
18
|
| 1777 |
+
]
|
| 1778 |
+
},
|
| 1779 |
+
{
|
| 1780 |
+
"id": "160",
|
| 1781 |
+
"name": "Sea Foam Islands B2F",
|
| 1782 |
+
"coordinates": [
|
| 1783 |
+
85,
|
| 1784 |
+
388
|
| 1785 |
+
],
|
| 1786 |
+
"tileSize": [
|
| 1787 |
+
30,
|
| 1788 |
+
18
|
| 1789 |
+
]
|
| 1790 |
+
},
|
| 1791 |
+
{
|
| 1792 |
+
"id": "161",
|
| 1793 |
+
"name": "Sea Foam Islands B3F",
|
| 1794 |
+
"coordinates": [
|
| 1795 |
+
85,
|
| 1796 |
+
369
|
| 1797 |
+
],
|
| 1798 |
+
"tileSize": [
|
| 1799 |
+
30,
|
| 1800 |
+
18
|
| 1801 |
+
]
|
| 1802 |
+
},
|
| 1803 |
+
{
|
| 1804 |
+
"id": "162",
|
| 1805 |
+
"name": "Sea Foam Islands B4F",
|
| 1806 |
+
"coordinates": [
|
| 1807 |
+
85,
|
| 1808 |
+
350
|
| 1809 |
+
],
|
| 1810 |
+
"tileSize": [
|
| 1811 |
+
30,
|
| 1812 |
+
18
|
| 1813 |
+
]
|
| 1814 |
+
},
|
| 1815 |
+
{
|
| 1816 |
+
"id": "163",
|
| 1817 |
+
"name": "Fishing Guru Vermilion",
|
| 1818 |
+
"coordinates": [
|
| 1819 |
+
210,
|
| 1820 |
+
264
|
| 1821 |
+
],
|
| 1822 |
+
"tileSize": [
|
| 1823 |
+
8,
|
| 1824 |
+
8
|
| 1825 |
+
]
|
| 1826 |
+
},
|
| 1827 |
+
{
|
| 1828 |
+
"id": "164",
|
| 1829 |
+
"name": "Fishing Guru Fuchsia",
|
| 1830 |
+
"coordinates": [
|
| 1831 |
+
215,
|
| 1832 |
+
381
|
| 1833 |
+
],
|
| 1834 |
+
"tileSize": [
|
| 1835 |
+
8,
|
| 1836 |
+
8
|
| 1837 |
+
]
|
| 1838 |
+
},
|
| 1839 |
+
{
|
| 1840 |
+
"id": "165",
|
| 1841 |
+
"name": "Pokemon Mansion F1",
|
| 1842 |
+
"coordinates": [
|
| 1843 |
+
33,
|
| 1844 |
+
389
|
| 1845 |
+
],
|
| 1846 |
+
"tileSize": [
|
| 1847 |
+
30,
|
| 1848 |
+
28
|
| 1849 |
+
]
|
| 1850 |
+
},
|
| 1851 |
+
{
|
| 1852 |
+
"id": "166",
|
| 1853 |
+
"name": "Cinnabar Gym",
|
| 1854 |
+
"coordinates": [
|
| 1855 |
+
85,
|
| 1856 |
+
407
|
| 1857 |
+
],
|
| 1858 |
+
"tileSize": [
|
| 1859 |
+
20,
|
| 1860 |
+
18
|
| 1861 |
+
]
|
| 1862 |
+
},
|
| 1863 |
+
{
|
| 1864 |
+
"id": "167",
|
| 1865 |
+
"name": "Pokemon Lab",
|
| 1866 |
+
"coordinates": [
|
| 1867 |
+
45,
|
| 1868 |
+
427
|
| 1869 |
+
],
|
| 1870 |
+
"tileSize": [
|
| 1871 |
+
18,
|
| 1872 |
+
8
|
| 1873 |
+
]
|
| 1874 |
+
},
|
| 1875 |
+
{
|
| 1876 |
+
"id": "168",
|
| 1877 |
+
"name": "Lab Room 1",
|
| 1878 |
+
"coordinates": [
|
| 1879 |
+
37,
|
| 1880 |
+
418
|
| 1881 |
+
],
|
| 1882 |
+
"tileSize": [
|
| 1883 |
+
8,
|
| 1884 |
+
8
|
| 1885 |
+
]
|
| 1886 |
+
},
|
| 1887 |
+
{
|
| 1888 |
+
"id": "169",
|
| 1889 |
+
"name": "Lab Room 2",
|
| 1890 |
+
"coordinates": [
|
| 1891 |
+
46,
|
| 1892 |
+
418
|
| 1893 |
+
],
|
| 1894 |
+
"tileSize": [
|
| 1895 |
+
8,
|
| 1896 |
+
8
|
| 1897 |
+
]
|
| 1898 |
+
},
|
| 1899 |
+
{
|
| 1900 |
+
"id": "170",
|
| 1901 |
+
"name": "Lab Room 3",
|
| 1902 |
+
"coordinates": [
|
| 1903 |
+
55,
|
| 1904 |
+
418
|
| 1905 |
+
],
|
| 1906 |
+
"tileSize": [
|
| 1907 |
+
8,
|
| 1908 |
+
8
|
| 1909 |
+
]
|
| 1910 |
+
},
|
| 1911 |
+
{
|
| 1912 |
+
"id": "171",
|
| 1913 |
+
"name": "Pokemon Center Cinnabar",
|
| 1914 |
+
"coordinates": [
|
| 1915 |
+
40,
|
| 1916 |
+
436
|
| 1917 |
+
],
|
| 1918 |
+
"tileSize": [
|
| 1919 |
+
14,
|
| 1920 |
+
8
|
| 1921 |
+
]
|
| 1922 |
+
},
|
| 1923 |
+
{
|
| 1924 |
+
"id": "172",
|
| 1925 |
+
"name": "Pokemart Cinnabar",
|
| 1926 |
+
"coordinates": [
|
| 1927 |
+
55,
|
| 1928 |
+
436
|
| 1929 |
+
],
|
| 1930 |
+
"tileSize": [
|
| 1931 |
+
8,
|
| 1932 |
+
8
|
| 1933 |
+
]
|
| 1934 |
+
},
|
| 1935 |
+
{
|
| 1936 |
+
"id": "173",
|
| 1937 |
+
"name": "Pokemart V2",
|
| 1938 |
+
"coordinates": [
|
| 1939 |
+
55,
|
| 1940 |
+
436
|
| 1941 |
+
],
|
| 1942 |
+
"tileSize": [
|
| 1943 |
+
8,
|
| 1944 |
+
8
|
| 1945 |
+
]
|
| 1946 |
+
},
|
| 1947 |
+
{
|
| 1948 |
+
"id": "174",
|
| 1949 |
+
"name": "Indigo Plateau Lobby",
|
| 1950 |
+
"coordinates": [
|
| 1951 |
+
16,
|
| 1952 |
+
72
|
| 1953 |
+
],
|
| 1954 |
+
"tileSize": [
|
| 1955 |
+
16,
|
| 1956 |
+
12
|
| 1957 |
+
]
|
| 1958 |
+
},
|
| 1959 |
+
{
|
| 1960 |
+
"id": "175",
|
| 1961 |
+
"name": "Coppy Cat F1",
|
| 1962 |
+
"coordinates": [
|
| 1963 |
+
215,
|
| 1964 |
+
191
|
| 1965 |
+
],
|
| 1966 |
+
"tileSize": [
|
| 1967 |
+
8,
|
| 1968 |
+
8
|
| 1969 |
+
]
|
| 1970 |
+
},
|
| 1971 |
+
{
|
| 1972 |
+
"id": "176",
|
| 1973 |
+
"name": "Coppy Cat F2",
|
| 1974 |
+
"coordinates": [
|
| 1975 |
+
215,
|
| 1976 |
+
182
|
| 1977 |
+
],
|
| 1978 |
+
"tileSize": [
|
| 1979 |
+
8,
|
| 1980 |
+
8
|
| 1981 |
+
]
|
| 1982 |
+
},
|
| 1983 |
+
{
|
| 1984 |
+
"id": "177",
|
| 1985 |
+
"name": "Fighting Dojo",
|
| 1986 |
+
"coordinates": [
|
| 1987 |
+
233,
|
| 1988 |
+
179
|
| 1989 |
+
],
|
| 1990 |
+
"tileSize": [
|
| 1991 |
+
10,
|
| 1992 |
+
12
|
| 1993 |
+
]
|
| 1994 |
+
},
|
| 1995 |
+
{
|
| 1996 |
+
"id": "178",
|
| 1997 |
+
"name": "Saffron Gym",
|
| 1998 |
+
"coordinates": [
|
| 1999 |
+
265,
|
| 2000 |
+
172
|
| 2001 |
+
],
|
| 2002 |
+
"tileSize": [
|
| 2003 |
+
20,
|
| 2004 |
+
18
|
| 2005 |
+
]
|
| 2006 |
+
},
|
| 2007 |
+
{
|
| 2008 |
+
"id": "179",
|
| 2009 |
+
"name": "Trainer House",
|
| 2010 |
+
"coordinates": [
|
| 2011 |
+
224,
|
| 2012 |
+
191
|
| 2013 |
+
],
|
| 2014 |
+
"tileSize": [
|
| 2015 |
+
8,
|
| 2016 |
+
8
|
| 2017 |
+
]
|
| 2018 |
+
},
|
| 2019 |
+
{
|
| 2020 |
+
"id": "180",
|
| 2021 |
+
"name": "Pokemart Saffron",
|
| 2022 |
+
"coordinates": [
|
| 2023 |
+
275,
|
| 2024 |
+
191
|
| 2025 |
+
],
|
| 2026 |
+
"tileSize": [
|
| 2027 |
+
8,
|
| 2028 |
+
8
|
| 2029 |
+
]
|
| 2030 |
+
},
|
| 2031 |
+
{
|
| 2032 |
+
"id": "181",
|
| 2033 |
+
"name": "Silph Co 1F",
|
| 2034 |
+
"coordinates": [
|
| 2035 |
+
325,
|
| 2036 |
+
109
|
| 2037 |
+
],
|
| 2038 |
+
"tileSize": [
|
| 2039 |
+
30,
|
| 2040 |
+
18
|
| 2041 |
+
]
|
| 2042 |
+
},
|
| 2043 |
+
{
|
| 2044 |
+
"id": "182",
|
| 2045 |
+
"name": "Pokemon Center Saffron",
|
| 2046 |
+
"coordinates": [
|
| 2047 |
+
229,
|
| 2048 |
+
229
|
| 2049 |
+
],
|
| 2050 |
+
"tileSize": [
|
| 2051 |
+
14,
|
| 2052 |
+
8
|
| 2053 |
+
]
|
| 2054 |
+
},
|
| 2055 |
+
{
|
| 2056 |
+
"id": "183",
|
| 2057 |
+
"name": "Mr Psychics",
|
| 2058 |
+
"coordinates": [
|
| 2059 |
+
265,
|
| 2060 |
+
229
|
| 2061 |
+
],
|
| 2062 |
+
"tileSize": [
|
| 2063 |
+
8,
|
| 2064 |
+
8
|
| 2065 |
+
]
|
| 2066 |
+
},
|
| 2067 |
+
{
|
| 2068 |
+
"id": "184",
|
| 2069 |
+
"name": "Gate House F1",
|
| 2070 |
+
"coordinates": [
|
| 2071 |
+
230,
|
| 2072 |
+
351
|
| 2073 |
+
],
|
| 2074 |
+
"tileSize": [
|
| 2075 |
+
8,
|
| 2076 |
+
10
|
| 2077 |
+
]
|
| 2078 |
+
},
|
| 2079 |
+
{
|
| 2080 |
+
"id": "185",
|
| 2081 |
+
"name": "Gate House F2",
|
| 2082 |
+
"coordinates": [
|
| 2083 |
+
230,
|
| 2084 |
+
342
|
| 2085 |
+
],
|
| 2086 |
+
"tileSize": [
|
| 2087 |
+
8,
|
| 2088 |
+
8
|
| 2089 |
+
]
|
| 2090 |
+
},
|
| 2091 |
+
{
|
| 2092 |
+
"id": "186",
|
| 2093 |
+
"name": "Cycling Gate F1",
|
| 2094 |
+
"coordinates": [
|
| 2095 |
+
140,
|
| 2096 |
+
185
|
| 2097 |
+
],
|
| 2098 |
+
"tileSize": [
|
| 2099 |
+
8,
|
| 2100 |
+
14
|
| 2101 |
+
]
|
| 2102 |
+
},
|
| 2103 |
+
{
|
| 2104 |
+
"id": "187",
|
| 2105 |
+
"name": "Cycling Gate F2",
|
| 2106 |
+
"coordinates": [
|
| 2107 |
+
140,
|
| 2108 |
+
176
|
| 2109 |
+
],
|
| 2110 |
+
"tileSize": [
|
| 2111 |
+
8,
|
| 2112 |
+
8
|
| 2113 |
+
]
|
| 2114 |
+
},
|
| 2115 |
+
{
|
| 2116 |
+
"id": "188",
|
| 2117 |
+
"name": "Secret House",
|
| 2118 |
+
"coordinates": [
|
| 2119 |
+
128,
|
| 2120 |
+
191
|
| 2121 |
+
],
|
| 2122 |
+
"tileSize": [
|
| 2123 |
+
8,
|
| 2124 |
+
8
|
| 2125 |
+
]
|
| 2126 |
+
},
|
| 2127 |
+
{
|
| 2128 |
+
"id": "189",
|
| 2129 |
+
"name": "Fishing Guru Route 12",
|
| 2130 |
+
"coordinates": [
|
| 2131 |
+
325,
|
| 2132 |
+
291
|
| 2133 |
+
],
|
| 2134 |
+
"tileSize": [
|
| 2135 |
+
8,
|
| 2136 |
+
8
|
| 2137 |
+
]
|
| 2138 |
+
},
|
| 2139 |
+
{
|
| 2140 |
+
"id": "190",
|
| 2141 |
+
"name": "Cycling Gate F1",
|
| 2142 |
+
"coordinates": [
|
| 2143 |
+
156,
|
| 2144 |
+
351
|
| 2145 |
+
],
|
| 2146 |
+
"tileSize": [
|
| 2147 |
+
8,
|
| 2148 |
+
10
|
| 2149 |
+
]
|
| 2150 |
+
},
|
| 2151 |
+
{
|
| 2152 |
+
"id": "191",
|
| 2153 |
+
"name": "Cycling Gate F2",
|
| 2154 |
+
"coordinates": [
|
| 2155 |
+
156,
|
| 2156 |
+
342
|
| 2157 |
+
],
|
| 2158 |
+
"tileSize": [
|
| 2159 |
+
8,
|
| 2160 |
+
8
|
| 2161 |
+
]
|
| 2162 |
+
},
|
| 2163 |
+
{
|
| 2164 |
+
"id": "192",
|
| 2165 |
+
"name": "Sea Foam Islands 1F",
|
| 2166 |
+
"coordinates": [
|
| 2167 |
+
116,
|
| 2168 |
+
407
|
| 2169 |
+
],
|
| 2170 |
+
"tileSize": [
|
| 2171 |
+
30,
|
| 2172 |
+
18
|
| 2173 |
+
]
|
| 2174 |
+
},
|
| 2175 |
+
{
|
| 2176 |
+
"id": "193",
|
| 2177 |
+
"name": "Badge Gate House",
|
| 2178 |
+
"coordinates": [
|
| 2179 |
+
17,
|
| 2180 |
+
246
|
| 2181 |
+
],
|
| 2182 |
+
"tileSize": [
|
| 2183 |
+
10,
|
| 2184 |
+
8
|
| 2185 |
+
]
|
| 2186 |
+
},
|
| 2187 |
+
{
|
| 2188 |
+
"id": "194",
|
| 2189 |
+
"name": "Victory Road F2",
|
| 2190 |
+
"coordinates": [
|
| 2191 |
+
35,
|
| 2192 |
+
97
|
| 2193 |
+
],
|
| 2194 |
+
"tileSize": [
|
| 2195 |
+
30,
|
| 2196 |
+
18
|
| 2197 |
+
]
|
| 2198 |
+
},
|
| 2199 |
+
{
|
| 2200 |
+
"id": "195",
|
| 2201 |
+
"name": "Gate 2F",
|
| 2202 |
+
"coordinates": [
|
| 2203 |
+
355,
|
| 2204 |
+
223
|
| 2205 |
+
],
|
| 2206 |
+
"tileSize": [
|
| 2207 |
+
8,
|
| 2208 |
+
8
|
| 2209 |
+
]
|
| 2210 |
+
},
|
| 2211 |
+
{
|
| 2212 |
+
"id": "196",
|
| 2213 |
+
"name": "Trainer House Farfetch'd Trade",
|
| 2214 |
+
"coordinates": [
|
| 2215 |
+
225,
|
| 2216 |
+
291
|
| 2217 |
+
],
|
| 2218 |
+
"tileSize": [
|
| 2219 |
+
8,
|
| 2220 |
+
8
|
| 2221 |
+
]
|
| 2222 |
+
},
|
| 2223 |
+
{
|
| 2224 |
+
"id": "197",
|
| 2225 |
+
"name": "DIgletts Cave",
|
| 2226 |
+
"coordinates": [
|
| 2227 |
+
284,
|
| 2228 |
+
235
|
| 2229 |
+
],
|
| 2230 |
+
"tileSize": [
|
| 2231 |
+
40,
|
| 2232 |
+
36
|
| 2233 |
+
]
|
| 2234 |
+
},
|
| 2235 |
+
{
|
| 2236 |
+
"id": "198",
|
| 2237 |
+
"name": "Victory Road F3",
|
| 2238 |
+
"coordinates": [
|
| 2239 |
+
35,
|
| 2240 |
+
78
|
| 2241 |
+
],
|
| 2242 |
+
"tileSize": [
|
| 2243 |
+
30,
|
| 2244 |
+
18
|
| 2245 |
+
]
|
| 2246 |
+
},
|
| 2247 |
+
{
|
| 2248 |
+
"id": "199",
|
| 2249 |
+
"name": "Rocket Hideout B1F",
|
| 2250 |
+
"coordinates": [
|
| 2251 |
+
97,
|
| 2252 |
+
117
|
| 2253 |
+
],
|
| 2254 |
+
"tileSize": [
|
| 2255 |
+
30,
|
| 2256 |
+
28
|
| 2257 |
+
]
|
| 2258 |
+
},
|
| 2259 |
+
{
|
| 2260 |
+
"id": "200",
|
| 2261 |
+
"name": "Rocket Hideout B2F",
|
| 2262 |
+
"coordinates": [
|
| 2263 |
+
97,
|
| 2264 |
+
88
|
| 2265 |
+
],
|
| 2266 |
+
"tileSize": [
|
| 2267 |
+
30,
|
| 2268 |
+
28
|
| 2269 |
+
]
|
| 2270 |
+
},
|
| 2271 |
+
{
|
| 2272 |
+
"id": "201",
|
| 2273 |
+
"name": "Rocket Hideout B3F",
|
| 2274 |
+
"coordinates": [
|
| 2275 |
+
97,
|
| 2276 |
+
59
|
| 2277 |
+
],
|
| 2278 |
+
"tileSize": [
|
| 2279 |
+
30,
|
| 2280 |
+
28
|
| 2281 |
+
]
|
| 2282 |
+
},
|
| 2283 |
+
{
|
| 2284 |
+
"id": "202",
|
| 2285 |
+
"name": "Rocket Hideout B4F",
|
| 2286 |
+
"coordinates": [
|
| 2287 |
+
97,
|
| 2288 |
+
34
|
| 2289 |
+
],
|
| 2290 |
+
"tileSize": [
|
| 2291 |
+
30,
|
| 2292 |
+
24
|
| 2293 |
+
]
|
| 2294 |
+
},
|
| 2295 |
+
{
|
| 2296 |
+
"id": "203",
|
| 2297 |
+
"name": "Rocket Hideout Lift",
|
| 2298 |
+
"coordinates": [
|
| 2299 |
+
121,
|
| 2300 |
+
137
|
| 2301 |
+
],
|
| 2302 |
+
"tileSize": [
|
| 2303 |
+
6,
|
| 2304 |
+
8
|
| 2305 |
+
]
|
| 2306 |
+
},
|
| 2307 |
+
{
|
| 2308 |
+
"id": "207",
|
| 2309 |
+
"name": "Silph Co 2F",
|
| 2310 |
+
"coordinates": [
|
| 2311 |
+
325,
|
| 2312 |
+
90
|
| 2313 |
+
],
|
| 2314 |
+
"tileSize": [
|
| 2315 |
+
30,
|
| 2316 |
+
18
|
| 2317 |
+
]
|
| 2318 |
+
},
|
| 2319 |
+
{
|
| 2320 |
+
"id": "208",
|
| 2321 |
+
"name": "Silph Co 3F",
|
| 2322 |
+
"coordinates": [
|
| 2323 |
+
325,
|
| 2324 |
+
71
|
| 2325 |
+
],
|
| 2326 |
+
"tileSize": [
|
| 2327 |
+
30,
|
| 2328 |
+
18
|
| 2329 |
+
]
|
| 2330 |
+
},
|
| 2331 |
+
{
|
| 2332 |
+
"id": "209",
|
| 2333 |
+
"name": "Silph Co 4F",
|
| 2334 |
+
"coordinates": [
|
| 2335 |
+
325,
|
| 2336 |
+
52
|
| 2337 |
+
],
|
| 2338 |
+
"tileSize": [
|
| 2339 |
+
30,
|
| 2340 |
+
18
|
| 2341 |
+
]
|
| 2342 |
+
},
|
| 2343 |
+
{
|
| 2344 |
+
"id": "210",
|
| 2345 |
+
"name": "Silph Co 5F",
|
| 2346 |
+
"coordinates": [
|
| 2347 |
+
325,
|
| 2348 |
+
33
|
| 2349 |
+
],
|
| 2350 |
+
"tileSize": [
|
| 2351 |
+
30,
|
| 2352 |
+
18
|
| 2353 |
+
]
|
| 2354 |
+
},
|
| 2355 |
+
{
|
| 2356 |
+
"id": "211",
|
| 2357 |
+
"name": "Silph Co 6F",
|
| 2358 |
+
"coordinates": [
|
| 2359 |
+
325,
|
| 2360 |
+
14
|
| 2361 |
+
],
|
| 2362 |
+
"tileSize": [
|
| 2363 |
+
26,
|
| 2364 |
+
18
|
| 2365 |
+
]
|
| 2366 |
+
},
|
| 2367 |
+
{
|
| 2368 |
+
"id": "212",
|
| 2369 |
+
"name": "Silph Co 7F",
|
| 2370 |
+
"coordinates": [
|
| 2371 |
+
356,
|
| 2372 |
+
109
|
| 2373 |
+
],
|
| 2374 |
+
"tileSize": [
|
| 2375 |
+
26,
|
| 2376 |
+
18
|
| 2377 |
+
]
|
| 2378 |
+
},
|
| 2379 |
+
{
|
| 2380 |
+
"id": "213",
|
| 2381 |
+
"name": "Silph Co 8F",
|
| 2382 |
+
"coordinates": [
|
| 2383 |
+
356,
|
| 2384 |
+
90
|
| 2385 |
+
],
|
| 2386 |
+
"tileSize": [
|
| 2387 |
+
26,
|
| 2388 |
+
18
|
| 2389 |
+
]
|
| 2390 |
+
},
|
| 2391 |
+
{
|
| 2392 |
+
"id": "214",
|
| 2393 |
+
"name": "Pokemon Mansion F2",
|
| 2394 |
+
"coordinates": [
|
| 2395 |
+
33,
|
| 2396 |
+
360
|
| 2397 |
+
],
|
| 2398 |
+
"tileSize": [
|
| 2399 |
+
30,
|
| 2400 |
+
28
|
| 2401 |
+
]
|
| 2402 |
+
},
|
| 2403 |
+
{
|
| 2404 |
+
"id": "215",
|
| 2405 |
+
"name": "Pokemon Mansion F3",
|
| 2406 |
+
"coordinates": [
|
| 2407 |
+
33,
|
| 2408 |
+
341
|
| 2409 |
+
],
|
| 2410 |
+
"tileSize": [
|
| 2411 |
+
30,
|
| 2412 |
+
18
|
| 2413 |
+
]
|
| 2414 |
+
},
|
| 2415 |
+
{
|
| 2416 |
+
"id": "216",
|
| 2417 |
+
"name": "Pokemon Mansion B1F",
|
| 2418 |
+
"coordinates": [
|
| 2419 |
+
2,
|
| 2420 |
+
389
|
| 2421 |
+
],
|
| 2422 |
+
"tileSize": [
|
| 2423 |
+
30,
|
| 2424 |
+
28
|
| 2425 |
+
]
|
| 2426 |
+
},
|
| 2427 |
+
{
|
| 2428 |
+
"id": "217",
|
| 2429 |
+
"name": "Safari East",
|
| 2430 |
+
"coordinates": [
|
| 2431 |
+
208,
|
| 2432 |
+
310
|
| 2433 |
+
],
|
| 2434 |
+
"tileSize": [
|
| 2435 |
+
30,
|
| 2436 |
+
26
|
| 2437 |
+
]
|
| 2438 |
+
},
|
| 2439 |
+
{
|
| 2440 |
+
"id": "218",
|
| 2441 |
+
"name": "Safari North",
|
| 2442 |
+
"coordinates": [
|
| 2443 |
+
166,
|
| 2444 |
+
274
|
| 2445 |
+
],
|
| 2446 |
+
"tileSize": [
|
| 2447 |
+
40,
|
| 2448 |
+
36
|
| 2449 |
+
]
|
| 2450 |
+
},
|
| 2451 |
+
{
|
| 2452 |
+
"id": "219",
|
| 2453 |
+
"name": "Safari West",
|
| 2454 |
+
"coordinates": [
|
| 2455 |
+
148,
|
| 2456 |
+
310
|
| 2457 |
+
],
|
| 2458 |
+
"tileSize": [
|
| 2459 |
+
30,
|
| 2460 |
+
26
|
| 2461 |
+
]
|
| 2462 |
+
},
|
| 2463 |
+
{
|
| 2464 |
+
"id": "220",
|
| 2465 |
+
"name": "Safari South",
|
| 2466 |
+
"coordinates": [
|
| 2467 |
+
178,
|
| 2468 |
+
322
|
| 2469 |
+
],
|
| 2470 |
+
"tileSize": [
|
| 2471 |
+
30,
|
| 2472 |
+
26
|
| 2473 |
+
]
|
| 2474 |
+
},
|
| 2475 |
+
{
|
| 2476 |
+
"id": "221",
|
| 2477 |
+
"name": "Rest House South",
|
| 2478 |
+
"coordinates": [
|
| 2479 |
+
209,
|
| 2480 |
+
337
|
| 2481 |
+
],
|
| 2482 |
+
"tileSize": [
|
| 2483 |
+
8,
|
| 2484 |
+
8
|
| 2485 |
+
]
|
| 2486 |
+
},
|
| 2487 |
+
{
|
| 2488 |
+
"id": "222",
|
| 2489 |
+
"name": "Secret House",
|
| 2490 |
+
"coordinates": [
|
| 2491 |
+
148,
|
| 2492 |
+
301
|
| 2493 |
+
],
|
| 2494 |
+
"tileSize": [
|
| 2495 |
+
8,
|
| 2496 |
+
8
|
| 2497 |
+
]
|
| 2498 |
+
},
|
| 2499 |
+
{
|
| 2500 |
+
"id": "223",
|
| 2501 |
+
"name": "Rest House",
|
| 2502 |
+
"coordinates": [
|
| 2503 |
+
157,
|
| 2504 |
+
301
|
| 2505 |
+
],
|
| 2506 |
+
"tileSize": [
|
| 2507 |
+
8,
|
| 2508 |
+
8
|
| 2509 |
+
]
|
| 2510 |
+
},
|
| 2511 |
+
{
|
| 2512 |
+
"id": "224",
|
| 2513 |
+
"name": "Rest House East",
|
| 2514 |
+
"coordinates": [
|
| 2515 |
+
230,
|
| 2516 |
+
301
|
| 2517 |
+
],
|
| 2518 |
+
"tileSize": [
|
| 2519 |
+
8,
|
| 2520 |
+
8
|
| 2521 |
+
]
|
| 2522 |
+
},
|
| 2523 |
+
{
|
| 2524 |
+
"id": "225",
|
| 2525 |
+
"name": "Rest House North",
|
| 2526 |
+
"coordinates": [
|
| 2527 |
+
207,
|
| 2528 |
+
273
|
| 2529 |
+
],
|
| 2530 |
+
"tileSize": [
|
| 2531 |
+
8,
|
| 2532 |
+
8
|
| 2533 |
+
]
|
| 2534 |
+
},
|
| 2535 |
+
{
|
| 2536 |
+
"id": "226",
|
| 2537 |
+
"name": "Cerulean Cave 2F",
|
| 2538 |
+
"coordinates": [
|
| 2539 |
+
213,
|
| 2540 |
+
81
|
| 2541 |
+
],
|
| 2542 |
+
"tileSize": [
|
| 2543 |
+
30,
|
| 2544 |
+
18
|
| 2545 |
+
]
|
| 2546 |
+
},
|
| 2547 |
+
{
|
| 2548 |
+
"id": "227",
|
| 2549 |
+
"name": "Cerulean Cave B1F",
|
| 2550 |
+
"coordinates": [
|
| 2551 |
+
213,
|
| 2552 |
+
62
|
| 2553 |
+
],
|
| 2554 |
+
"tileSize": [
|
| 2555 |
+
30,
|
| 2556 |
+
18
|
| 2557 |
+
]
|
| 2558 |
+
},
|
| 2559 |
+
{
|
| 2560 |
+
"id": "228",
|
| 2561 |
+
"name": "Cerulean Cave Entrance",
|
| 2562 |
+
"coordinates": [
|
| 2563 |
+
213,
|
| 2564 |
+
100
|
| 2565 |
+
],
|
| 2566 |
+
"tileSize": [
|
| 2567 |
+
30,
|
| 2568 |
+
18
|
| 2569 |
+
]
|
| 2570 |
+
},
|
| 2571 |
+
{
|
| 2572 |
+
"id": "229",
|
| 2573 |
+
"name": "Name Rater House",
|
| 2574 |
+
"coordinates": [
|
| 2575 |
+
325,
|
| 2576 |
+
219
|
| 2577 |
+
],
|
| 2578 |
+
"tileSize": [
|
| 2579 |
+
8,
|
| 2580 |
+
8
|
| 2581 |
+
]
|
| 2582 |
+
},
|
| 2583 |
+
{
|
| 2584 |
+
"id": "230",
|
| 2585 |
+
"name": "Badge Man House",
|
| 2586 |
+
"coordinates": [
|
| 2587 |
+
216,
|
| 2588 |
+
119
|
| 2589 |
+
],
|
| 2590 |
+
"tileSize": [
|
| 2591 |
+
8,
|
| 2592 |
+
8
|
| 2593 |
+
]
|
| 2594 |
+
},
|
| 2595 |
+
{
|
| 2596 |
+
"id": "232",
|
| 2597 |
+
"name": "Rock Tunnel 1F",
|
| 2598 |
+
"coordinates": [
|
| 2599 |
+
396,
|
| 2600 |
+
145
|
| 2601 |
+
],
|
| 2602 |
+
"tileSize": [
|
| 2603 |
+
40,
|
| 2604 |
+
36
|
| 2605 |
+
]
|
| 2606 |
+
},
|
| 2607 |
+
{
|
| 2608 |
+
"id": "233",
|
| 2609 |
+
"name": "Silph Co 9F",
|
| 2610 |
+
"coordinates": [
|
| 2611 |
+
356,
|
| 2612 |
+
71
|
| 2613 |
+
],
|
| 2614 |
+
"tileSize": [
|
| 2615 |
+
26,
|
| 2616 |
+
18
|
| 2617 |
+
]
|
| 2618 |
+
},
|
| 2619 |
+
{
|
| 2620 |
+
"id": "234",
|
| 2621 |
+
"name": "Silph Co 10F",
|
| 2622 |
+
"coordinates": [
|
| 2623 |
+
356,
|
| 2624 |
+
52
|
| 2625 |
+
],
|
| 2626 |
+
"tileSize": [
|
| 2627 |
+
16,
|
| 2628 |
+
18
|
| 2629 |
+
]
|
| 2630 |
+
},
|
| 2631 |
+
{
|
| 2632 |
+
"id": "235",
|
| 2633 |
+
"name": "Silph Co 11F",
|
| 2634 |
+
"coordinates": [
|
| 2635 |
+
356,
|
| 2636 |
+
32
|
| 2637 |
+
],
|
| 2638 |
+
"tileSize": [
|
| 2639 |
+
18,
|
| 2640 |
+
18
|
| 2641 |
+
]
|
| 2642 |
+
},
|
| 2643 |
+
{
|
| 2644 |
+
"id": "236",
|
| 2645 |
+
"name": "Silph Co Lift",
|
| 2646 |
+
"coordinates": [
|
| 2647 |
+
355,
|
| 2648 |
+
128
|
| 2649 |
+
],
|
| 2650 |
+
"tileSize": [
|
| 2651 |
+
4,
|
| 2652 |
+
4
|
| 2653 |
+
]
|
| 2654 |
+
},
|
| 2655 |
+
{
|
| 2656 |
+
"id": "239",
|
| 2657 |
+
"name": "Trade Center",
|
| 2658 |
+
"coordinates": [
|
| 2659 |
+
85,
|
| 2660 |
+
283
|
| 2661 |
+
],
|
| 2662 |
+
"tileSize": [
|
| 2663 |
+
10,
|
| 2664 |
+
8
|
| 2665 |
+
]
|
| 2666 |
+
},
|
| 2667 |
+
{
|
| 2668 |
+
"id": "240",
|
| 2669 |
+
"name": "Colosseum Club",
|
| 2670 |
+
"coordinates": [
|
| 2671 |
+
96,
|
| 2672 |
+
283
|
| 2673 |
+
],
|
| 2674 |
+
"tileSize": [
|
| 2675 |
+
10,
|
| 2676 |
+
8
|
| 2677 |
+
]
|
| 2678 |
+
},
|
| 2679 |
+
{
|
| 2680 |
+
"id": "245",
|
| 2681 |
+
"name": "Loreleis Room",
|
| 2682 |
+
"coordinates": [
|
| 2683 |
+
20,
|
| 2684 |
+
60
|
| 2685 |
+
],
|
| 2686 |
+
"tileSize": [
|
| 2687 |
+
10,
|
| 2688 |
+
12
|
| 2689 |
+
]
|
| 2690 |
+
},
|
| 2691 |
+
{
|
| 2692 |
+
"id": "246",
|
| 2693 |
+
"name": "Brunos Room",
|
| 2694 |
+
"coordinates": [
|
| 2695 |
+
20,
|
| 2696 |
+
48
|
| 2697 |
+
],
|
| 2698 |
+
"tileSize": [
|
| 2699 |
+
10,
|
| 2700 |
+
12
|
| 2701 |
+
]
|
| 2702 |
+
},
|
| 2703 |
+
{
|
| 2704 |
+
"id": "247",
|
| 2705 |
+
"name": "Agathas Room",
|
| 2706 |
+
"coordinates": [
|
| 2707 |
+
20,
|
| 2708 |
+
36
|
| 2709 |
+
],
|
| 2710 |
+
"tileSize": [
|
| 2711 |
+
10,
|
| 2712 |
+
12
|
| 2713 |
+
]
|
| 2714 |
+
}
|
| 2715 |
+
]
|
| 2716 |
+
}
|
server/pokemonred_env_environment.py
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This source code is licensed under the BSD-style license found in the
|
| 5 |
+
# LICENSE file in the root directory of this source tree.
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
Pokemon Red Environment Server Implementation.
|
| 9 |
+
|
| 10 |
+
This module wraps the PyBoy Game Boy emulator and exposes Pokemon Red
|
| 11 |
+
as an OpenEnv Environment for RL training.
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
from __future__ import annotations
|
| 15 |
+
|
| 16 |
+
import base64
|
| 17 |
+
import io
|
| 18 |
+
import uuid
|
| 19 |
+
from pathlib import Path
|
| 20 |
+
from typing import Any, Dict, List, Tuple
|
| 21 |
+
|
| 22 |
+
import numpy as np
|
| 23 |
+
from PIL import Image
|
| 24 |
+
|
| 25 |
+
try:
|
| 26 |
+
from pyboy import PyBoy
|
| 27 |
+
from pyboy.utils import WindowEvent
|
| 28 |
+
except ImportError as e:
|
| 29 |
+
raise ImportError(
|
| 30 |
+
"PyBoy is required for the Pokemon Red environment. "
|
| 31 |
+
"Install with: pip install pyboy"
|
| 32 |
+
) from e
|
| 33 |
+
|
| 34 |
+
from openenv.core.env_server import Environment
|
| 35 |
+
from openenv.core.env_server.types import Action, Observation
|
| 36 |
+
|
| 37 |
+
from models import PokemonRedAction, PokemonRedObservation, PokemonRedState
|
| 38 |
+
from config import PokemonRedConfig
|
| 39 |
+
from .global_map import local_to_global, GLOBAL_MAP_SHAPE
|
| 40 |
+
|
| 41 |
+
# Memory addresses for Pokemon Red
|
| 42 |
+
EVENT_FLAGS_START = 0xD747
|
| 43 |
+
EVENT_FLAGS_END = 0xD87E
|
| 44 |
+
IS_IN_BATTLE_ADDR = 0xD057
|
| 45 |
+
|
| 46 |
+
# Party Pokemon HP addresses
|
| 47 |
+
HP_ADDRESSES = [0xD16C, 0xD198, 0xD1C4, 0xD1F0, 0xD21C, 0xD248]
|
| 48 |
+
MAX_HP_ADDRESSES = [0xD18D, 0xD1B9, 0xD1E5, 0xD211, 0xD23D, 0xD269]
|
| 49 |
+
LEVEL_ADDRESSES = [0xD18C, 0xD1B8, 0xD1E4, 0xD210, 0xD23C, 0xD268]
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class PokemonRedEnvironment(Environment):
|
| 53 |
+
"""
|
| 54 |
+
Pokemon Red Environment wrapper for OpenEnv.
|
| 55 |
+
|
| 56 |
+
This environment wraps Pokemon Red via PyBoy emulator and provides
|
| 57 |
+
a clean interface for RL training with rich observations and
|
| 58 |
+
configurable reward shaping.
|
| 59 |
+
|
| 60 |
+
Supported actions: 0=Down, 1=Left, 2=Right, 3=Up, 4=A, 5=B, 6=Start
|
| 61 |
+
|
| 62 |
+
Args:
|
| 63 |
+
config: PokemonRedConfig with environment settings.
|
| 64 |
+
|
| 65 |
+
Example:
|
| 66 |
+
>>> config = PokemonRedConfig(headless=True)
|
| 67 |
+
>>> env = PokemonRedEnvironment(config)
|
| 68 |
+
>>> obs = env.reset()
|
| 69 |
+
>>> obs = env.step(PokemonRedAction(action=4)) # Press A
|
| 70 |
+
"""
|
| 71 |
+
|
| 72 |
+
# Enable concurrent WebSocket sessions
|
| 73 |
+
SUPPORTS_CONCURRENT_SESSIONS: bool = True
|
| 74 |
+
|
| 75 |
+
# Action mappings
|
| 76 |
+
VALID_ACTIONS = [
|
| 77 |
+
WindowEvent.PRESS_ARROW_DOWN,
|
| 78 |
+
WindowEvent.PRESS_ARROW_LEFT,
|
| 79 |
+
WindowEvent.PRESS_ARROW_RIGHT,
|
| 80 |
+
WindowEvent.PRESS_ARROW_UP,
|
| 81 |
+
WindowEvent.PRESS_BUTTON_A,
|
| 82 |
+
WindowEvent.PRESS_BUTTON_B,
|
| 83 |
+
WindowEvent.PRESS_BUTTON_START,
|
| 84 |
+
]
|
| 85 |
+
RELEASE_ACTIONS = [
|
| 86 |
+
WindowEvent.RELEASE_ARROW_DOWN,
|
| 87 |
+
WindowEvent.RELEASE_ARROW_LEFT,
|
| 88 |
+
WindowEvent.RELEASE_ARROW_RIGHT,
|
| 89 |
+
WindowEvent.RELEASE_ARROW_UP,
|
| 90 |
+
WindowEvent.RELEASE_BUTTON_A,
|
| 91 |
+
WindowEvent.RELEASE_BUTTON_B,
|
| 92 |
+
WindowEvent.RELEASE_BUTTON_START,
|
| 93 |
+
]
|
| 94 |
+
ACTION_NAMES = ["Down", "Left", "Right", "Up", "A", "B", "Start"]
|
| 95 |
+
|
| 96 |
+
def __init__(self, config: PokemonRedConfig):
|
| 97 |
+
"""Initialize Pokemon Red environment."""
|
| 98 |
+
super().__init__()
|
| 99 |
+
self.config = config
|
| 100 |
+
|
| 101 |
+
# Initialize state
|
| 102 |
+
self._state = PokemonRedState(episode_id=str(uuid.uuid4()))
|
| 103 |
+
|
| 104 |
+
# Session path for saving states
|
| 105 |
+
self.session_path = Path(config.session_path)
|
| 106 |
+
self.session_path.mkdir(exist_ok=True, parents=True)
|
| 107 |
+
|
| 108 |
+
# Initialize PyBoy emulator
|
| 109 |
+
window_type = "null" if config.headless else "SDL2"
|
| 110 |
+
self.pyboy = PyBoy(
|
| 111 |
+
config.gb_path,
|
| 112 |
+
window=window_type,
|
| 113 |
+
sound_emulated=False, # Disable sound for headless operation
|
| 114 |
+
)
|
| 115 |
+
if not config.headless:
|
| 116 |
+
self.pyboy.set_emulation_speed(6)
|
| 117 |
+
|
| 118 |
+
# Tracking state
|
| 119 |
+
self.seen_coords: Dict[str, int] = {}
|
| 120 |
+
self.explore_map = np.zeros(GLOBAL_MAP_SHAPE, dtype=np.uint8)
|
| 121 |
+
self._prev_state_dict: Dict[str, Any] = {}
|
| 122 |
+
|
| 123 |
+
def reset(self) -> Observation:
|
| 124 |
+
"""
|
| 125 |
+
Reset the environment and return initial observation.
|
| 126 |
+
|
| 127 |
+
Returns:
|
| 128 |
+
Initial PokemonRedObservation for the agent.
|
| 129 |
+
"""
|
| 130 |
+
# Reset state tracking
|
| 131 |
+
self._state = PokemonRedState(episode_id=str(uuid.uuid4()))
|
| 132 |
+
self.seen_coords = {}
|
| 133 |
+
self.explore_map.fill(0)
|
| 134 |
+
self._prev_state_dict = {}
|
| 135 |
+
|
| 136 |
+
# Load initial save state
|
| 137 |
+
with open(self.config.init_state, "rb") as f:
|
| 138 |
+
self.pyboy.load_state(f)
|
| 139 |
+
|
| 140 |
+
# Tick once to render initial frame
|
| 141 |
+
self.pyboy.tick(1, True)
|
| 142 |
+
|
| 143 |
+
return self._make_observation(reward=0.0, done=False)
|
| 144 |
+
|
| 145 |
+
def step(self, action: Action) -> Observation:
|
| 146 |
+
"""
|
| 147 |
+
Execute agent's action and return resulting observation.
|
| 148 |
+
|
| 149 |
+
Args:
|
| 150 |
+
action: PokemonRedAction containing the button to press.
|
| 151 |
+
|
| 152 |
+
Returns:
|
| 153 |
+
Observation after action execution.
|
| 154 |
+
|
| 155 |
+
Raises:
|
| 156 |
+
ValueError: If action is not a PokemonRedAction.
|
| 157 |
+
"""
|
| 158 |
+
if not isinstance(action, PokemonRedAction):
|
| 159 |
+
raise ValueError(f"Expected PokemonRedAction, got {type(action)}")
|
| 160 |
+
|
| 161 |
+
# Validate action
|
| 162 |
+
action_idx = action.action
|
| 163 |
+
if action_idx < 0 or action_idx >= len(self.VALID_ACTIONS):
|
| 164 |
+
raise ValueError(f"Invalid action: {action_idx}. Valid range: [0, 6]")
|
| 165 |
+
|
| 166 |
+
# Execute action with press/release timing
|
| 167 |
+
press_duration = 8
|
| 168 |
+
self.pyboy.send_input(self.VALID_ACTIONS[action_idx])
|
| 169 |
+
self.pyboy.tick(press_duration, False)
|
| 170 |
+
self.pyboy.send_input(self.RELEASE_ACTIONS[action_idx])
|
| 171 |
+
self.pyboy.tick(self.config.action_freq - press_duration - 1, False)
|
| 172 |
+
self.pyboy.tick(1, True) # Render on final tick
|
| 173 |
+
|
| 174 |
+
# Update exploration tracking
|
| 175 |
+
self._update_exploration()
|
| 176 |
+
|
| 177 |
+
# Calculate reward
|
| 178 |
+
current_state = self._get_state_dict()
|
| 179 |
+
reward = self._calculate_reward(current_state, self._prev_state_dict)
|
| 180 |
+
self._prev_state_dict = current_state
|
| 181 |
+
|
| 182 |
+
# Update state
|
| 183 |
+
self._state.step_count += 1
|
| 184 |
+
self._state.total_reward += reward
|
| 185 |
+
self._state.badges_obtained = current_state["badge_count"]
|
| 186 |
+
self._state.max_level_sum = max(
|
| 187 |
+
self._state.max_level_sum, current_state["level_sum"]
|
| 188 |
+
)
|
| 189 |
+
self._state.events_triggered = current_state["event_count"]
|
| 190 |
+
|
| 191 |
+
# Check termination
|
| 192 |
+
done = self._state.step_count >= self.config.max_steps
|
| 193 |
+
|
| 194 |
+
return self._make_observation(reward=reward, done=done)
|
| 195 |
+
|
| 196 |
+
@property
|
| 197 |
+
def state(self) -> PokemonRedState:
|
| 198 |
+
"""Get current environment state."""
|
| 199 |
+
return self._state
|
| 200 |
+
|
| 201 |
+
def _make_observation(self, reward: float, done: bool) -> PokemonRedObservation:
|
| 202 |
+
"""Create observation from current game state."""
|
| 203 |
+
# Capture screen as base64 PNG
|
| 204 |
+
screen = self.pyboy.screen.ndarray[:, :, :3].astype(np.uint8)
|
| 205 |
+
img = Image.fromarray(screen)
|
| 206 |
+
buffer = io.BytesIO()
|
| 207 |
+
img.save(buffer, format="PNG")
|
| 208 |
+
screen_b64 = base64.b64encode(buffer.getvalue()).decode("utf-8")
|
| 209 |
+
|
| 210 |
+
# Read game state
|
| 211 |
+
x, y, map_id = self._get_position()
|
| 212 |
+
health = self._get_hp_fraction()
|
| 213 |
+
level_sum = self._get_level_sum()
|
| 214 |
+
badges = self._get_badges_list()
|
| 215 |
+
in_battle = self._is_in_battle()
|
| 216 |
+
|
| 217 |
+
return PokemonRedObservation(
|
| 218 |
+
screen_b64=screen_b64,
|
| 219 |
+
screen_shape=list(screen.shape),
|
| 220 |
+
health=health,
|
| 221 |
+
level_sum=level_sum,
|
| 222 |
+
badges=badges,
|
| 223 |
+
position=[x, y, map_id],
|
| 224 |
+
in_battle=in_battle,
|
| 225 |
+
seen_coords_count=len(self.seen_coords),
|
| 226 |
+
legal_actions=list(range(7)),
|
| 227 |
+
done=done,
|
| 228 |
+
reward=reward,
|
| 229 |
+
metadata={
|
| 230 |
+
"action_names": self.ACTION_NAMES,
|
| 231 |
+
"step_count": self._state.step_count,
|
| 232 |
+
"total_reward": self._state.total_reward,
|
| 233 |
+
},
|
| 234 |
+
)
|
| 235 |
+
|
| 236 |
+
def _get_position(self) -> Tuple[int, int, int]:
|
| 237 |
+
"""Get player position (x, y, map_id)."""
|
| 238 |
+
return (
|
| 239 |
+
self.pyboy.memory[0xD362],
|
| 240 |
+
self.pyboy.memory[0xD361],
|
| 241 |
+
self.pyboy.memory[0xD35E],
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
def _update_exploration(self) -> None:
|
| 245 |
+
"""Update exploration tracking with current position."""
|
| 246 |
+
x, y, map_id = self._get_position()
|
| 247 |
+
coord_key = f"{x}:{y}:{map_id}"
|
| 248 |
+
self.seen_coords[coord_key] = self.seen_coords.get(coord_key, 0) + 1
|
| 249 |
+
|
| 250 |
+
# Update global exploration map
|
| 251 |
+
gx, gy = local_to_global(y, x, map_id)
|
| 252 |
+
if 0 <= gx < GLOBAL_MAP_SHAPE[0] and 0 <= gy < GLOBAL_MAP_SHAPE[1]:
|
| 253 |
+
self.explore_map[gx, gy] = 255
|
| 254 |
+
|
| 255 |
+
def _get_hp_fraction(self) -> float:
|
| 256 |
+
"""Get party HP as fraction [0, 1]."""
|
| 257 |
+
hp_sum = sum(self._read_hp(addr) for addr in HP_ADDRESSES)
|
| 258 |
+
max_hp_sum = sum(self._read_hp(addr) for addr in MAX_HP_ADDRESSES)
|
| 259 |
+
return hp_sum / max(max_hp_sum, 1)
|
| 260 |
+
|
| 261 |
+
def _read_hp(self, addr: int) -> int:
|
| 262 |
+
"""Read 16-bit HP value from memory."""
|
| 263 |
+
return 256 * self.pyboy.memory[addr] + self.pyboy.memory[addr + 1]
|
| 264 |
+
|
| 265 |
+
def _get_level_sum(self) -> int:
|
| 266 |
+
"""Get sum of party Pokemon levels."""
|
| 267 |
+
return sum(self.pyboy.memory[addr] for addr in LEVEL_ADDRESSES)
|
| 268 |
+
|
| 269 |
+
def _get_badges_list(self) -> List[int]:
|
| 270 |
+
"""Get 8-element list of badge flags."""
|
| 271 |
+
badge_byte = self.pyboy.memory[0xD356]
|
| 272 |
+
return [int(b) for b in f"{badge_byte:08b}"][::-1]
|
| 273 |
+
|
| 274 |
+
def _is_in_battle(self) -> bool:
|
| 275 |
+
"""Check if player is in battle."""
|
| 276 |
+
return self.pyboy.memory[IS_IN_BATTLE_ADDR] != 0
|
| 277 |
+
|
| 278 |
+
def _get_event_count(self) -> int:
|
| 279 |
+
"""Count triggered event flags."""
|
| 280 |
+
count = 0
|
| 281 |
+
for addr in range(EVENT_FLAGS_START, EVENT_FLAGS_END):
|
| 282 |
+
count += self.pyboy.memory[addr].bit_count()
|
| 283 |
+
return count
|
| 284 |
+
|
| 285 |
+
def _get_state_dict(self) -> Dict[str, Any]:
|
| 286 |
+
"""Get current game state as dictionary for reward calculation."""
|
| 287 |
+
return {
|
| 288 |
+
"seen_coords_count": len(self.seen_coords),
|
| 289 |
+
"badge_count": self.pyboy.memory[0xD356].bit_count(),
|
| 290 |
+
"level_sum": self._get_level_sum(),
|
| 291 |
+
"event_count": self._get_event_count(),
|
| 292 |
+
"hp_fraction": self._get_hp_fraction(),
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
def _calculate_reward(
|
| 296 |
+
self, current: Dict[str, Any], previous: Dict[str, Any]
|
| 297 |
+
) -> float:
|
| 298 |
+
"""
|
| 299 |
+
Calculate reward based on state changes.
|
| 300 |
+
|
| 301 |
+
Simple built-in reward shaping. For more complex reward functions,
|
| 302 |
+
see the rewards/ module for modular components.
|
| 303 |
+
"""
|
| 304 |
+
if not previous:
|
| 305 |
+
return 0.0
|
| 306 |
+
|
| 307 |
+
reward = 0.0
|
| 308 |
+
|
| 309 |
+
# Exploration reward
|
| 310 |
+
new_coords = current["seen_coords_count"] - previous.get("seen_coords_count", 0)
|
| 311 |
+
reward += new_coords * 0.02
|
| 312 |
+
|
| 313 |
+
# Badge reward
|
| 314 |
+
new_badges = current["badge_count"] - previous.get("badge_count", 0)
|
| 315 |
+
reward += new_badges * 5.0
|
| 316 |
+
|
| 317 |
+
# Level up reward
|
| 318 |
+
level_diff = current["level_sum"] - previous.get("level_sum", 0)
|
| 319 |
+
reward += max(0, level_diff) * 1.0
|
| 320 |
+
|
| 321 |
+
# Event progress reward
|
| 322 |
+
event_diff = current["event_count"] - previous.get("event_count", 0)
|
| 323 |
+
reward += max(0, event_diff) * 0.1
|
| 324 |
+
|
| 325 |
+
return reward * self.config.reward_scale
|
server/pokered.sym
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
server/requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
openenv[core]>=0.2.0
|
| 2 |
+
fastapi>=0.115.0
|
| 3 |
+
uvicorn>=0.24.0
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
|
uv.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
wrappers/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""Wrappers for Pokemon Red OpenEnv environment."""
|
| 5 |
+
|
| 6 |
+
from .green_agent import GreenAgentTracker
|
| 7 |
+
|
| 8 |
+
__all__ = ["GreenAgentTracker"]
|
wrappers/green_agent.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
| 2 |
+
# All rights reserved.
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
Green Agent compute efficiency tracker for Pokemon Red OpenEnv.
|
| 6 |
+
|
| 7 |
+
This module implements compute efficiency tracking as required by
|
| 8 |
+
The OpenEnv Challenge evaluation criteria. It measures wall-clock time,
|
| 9 |
+
memory usage, and provides transparency metrics for sustainability analysis.
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
from __future__ import annotations
|
| 13 |
+
|
| 14 |
+
import os
|
| 15 |
+
import time
|
| 16 |
+
from dataclasses import dataclass, field
|
| 17 |
+
from typing import Any, Callable, Dict, Optional, TypeVar
|
| 18 |
+
|
| 19 |
+
try:
|
| 20 |
+
import psutil
|
| 21 |
+
HAS_PSUTIL = True
|
| 22 |
+
except ImportError:
|
| 23 |
+
HAS_PSUTIL = False
|
| 24 |
+
|
| 25 |
+
T = TypeVar("T")
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@dataclass
|
| 29 |
+
class GreenMetrics:
|
| 30 |
+
"""
|
| 31 |
+
Compute efficiency metrics for a single step or episode.
|
| 32 |
+
|
| 33 |
+
Attributes:
|
| 34 |
+
step_time_ms: Wall-clock time for last step in milliseconds.
|
| 35 |
+
avg_step_time_ms: Running average step time in milliseconds.
|
| 36 |
+
total_steps: Total steps executed.
|
| 37 |
+
total_time_s: Total wall-clock time in seconds.
|
| 38 |
+
peak_memory_mb: Peak memory usage in megabytes.
|
| 39 |
+
current_memory_mb: Current memory usage in megabytes.
|
| 40 |
+
cpu_percent: CPU utilization percentage (if available).
|
| 41 |
+
"""
|
| 42 |
+
step_time_ms: float = 0.0
|
| 43 |
+
avg_step_time_ms: float = 0.0
|
| 44 |
+
total_steps: int = 0
|
| 45 |
+
total_time_s: float = 0.0
|
| 46 |
+
peak_memory_mb: float = 0.0
|
| 47 |
+
current_memory_mb: float = 0.0
|
| 48 |
+
cpu_percent: float = 0.0
|
| 49 |
+
|
| 50 |
+
def to_dict(self) -> Dict[str, Any]:
|
| 51 |
+
"""Convert metrics to dictionary for JSON serialization."""
|
| 52 |
+
return {
|
| 53 |
+
"green_step_time_ms": round(self.step_time_ms, 3),
|
| 54 |
+
"green_avg_step_time_ms": round(self.avg_step_time_ms, 3),
|
| 55 |
+
"green_total_steps": self.total_steps,
|
| 56 |
+
"green_total_time_s": round(self.total_time_s, 3),
|
| 57 |
+
"green_peak_memory_mb": round(self.peak_memory_mb, 2),
|
| 58 |
+
"green_current_memory_mb": round(self.current_memory_mb, 2),
|
| 59 |
+
"green_cpu_percent": round(self.cpu_percent, 1),
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
class GreenAgentTracker:
|
| 64 |
+
"""
|
| 65 |
+
Tracks compute efficiency metrics for RL environment steps.
|
| 66 |
+
|
| 67 |
+
Designed for the OpenEnv Challenge "Green Agent" evaluation criteria,
|
| 68 |
+
measuring the computational cost of environment interactions to
|
| 69 |
+
promote sustainable AI development.
|
| 70 |
+
|
| 71 |
+
Example:
|
| 72 |
+
>>> tracker = GreenAgentTracker()
|
| 73 |
+
>>>
|
| 74 |
+
>>> # Track a step
|
| 75 |
+
>>> result, metrics = tracker.track_step(lambda: env.step(action))
|
| 76 |
+
>>> print(f"Step took {metrics['green_step_time_ms']:.2f}ms")
|
| 77 |
+
>>>
|
| 78 |
+
>>> # Get summary
|
| 79 |
+
>>> summary = tracker.get_summary()
|
| 80 |
+
>>> print(f"Avg step: {summary['green_avg_step_time_ms']:.2f}ms")
|
| 81 |
+
|
| 82 |
+
Attributes:
|
| 83 |
+
enabled: Whether tracking is active.
|
| 84 |
+
metrics: Current aggregated metrics.
|
| 85 |
+
"""
|
| 86 |
+
|
| 87 |
+
def __init__(self, enabled: bool = True):
|
| 88 |
+
"""
|
| 89 |
+
Initialize Green Agent tracker.
|
| 90 |
+
|
| 91 |
+
Args:
|
| 92 |
+
enabled: Whether to enable tracking (default True).
|
| 93 |
+
Disable for benchmarking without overhead.
|
| 94 |
+
"""
|
| 95 |
+
self.enabled = enabled
|
| 96 |
+
self._process: Optional[Any] = None
|
| 97 |
+
if HAS_PSUTIL:
|
| 98 |
+
self._process = psutil.Process(os.getpid())
|
| 99 |
+
|
| 100 |
+
self.reset()
|
| 101 |
+
|
| 102 |
+
def reset(self) -> None:
|
| 103 |
+
"""Reset tracking metrics for new episode."""
|
| 104 |
+
self._total_steps = 0
|
| 105 |
+
self._total_time = 0.0
|
| 106 |
+
self._peak_memory = 0.0
|
| 107 |
+
self._last_step_time = 0.0
|
| 108 |
+
|
| 109 |
+
def track_step(self, step_fn: Callable[[], T]) -> tuple[T, Dict[str, Any]]:
|
| 110 |
+
"""
|
| 111 |
+
Execute and track a step function.
|
| 112 |
+
|
| 113 |
+
Args:
|
| 114 |
+
step_fn: Callable that executes the environment step.
|
| 115 |
+
|
| 116 |
+
Returns:
|
| 117 |
+
Tuple of (step result, metrics dictionary).
|
| 118 |
+
"""
|
| 119 |
+
if not self.enabled:
|
| 120 |
+
return step_fn(), {}
|
| 121 |
+
|
| 122 |
+
# Measure memory before
|
| 123 |
+
start_memory = self._get_memory_mb()
|
| 124 |
+
|
| 125 |
+
# Time the step
|
| 126 |
+
start_time = time.perf_counter()
|
| 127 |
+
result = step_fn()
|
| 128 |
+
elapsed = time.perf_counter() - start_time
|
| 129 |
+
|
| 130 |
+
# Update tracking
|
| 131 |
+
self._last_step_time = elapsed
|
| 132 |
+
self._total_time += elapsed
|
| 133 |
+
self._total_steps += 1
|
| 134 |
+
|
| 135 |
+
# Update peak memory
|
| 136 |
+
current_memory = self._get_memory_mb()
|
| 137 |
+
self._peak_memory = max(self._peak_memory, current_memory)
|
| 138 |
+
|
| 139 |
+
# Build metrics
|
| 140 |
+
metrics = self.get_metrics()
|
| 141 |
+
return result, metrics.to_dict()
|
| 142 |
+
|
| 143 |
+
def track_reset(self, reset_fn: Callable[[], T]) -> tuple[T, Dict[str, Any]]:
|
| 144 |
+
"""
|
| 145 |
+
Execute and track a reset function.
|
| 146 |
+
|
| 147 |
+
Args:
|
| 148 |
+
reset_fn: Callable that executes the environment reset.
|
| 149 |
+
|
| 150 |
+
Returns:
|
| 151 |
+
Tuple of (reset result, metrics dictionary).
|
| 152 |
+
"""
|
| 153 |
+
self.reset()
|
| 154 |
+
return self.track_step(reset_fn)
|
| 155 |
+
|
| 156 |
+
def get_metrics(self) -> GreenMetrics:
|
| 157 |
+
"""Get current aggregated metrics."""
|
| 158 |
+
avg_step = self._total_time / max(self._total_steps, 1)
|
| 159 |
+
|
| 160 |
+
return GreenMetrics(
|
| 161 |
+
step_time_ms=self._last_step_time * 1000,
|
| 162 |
+
avg_step_time_ms=avg_step * 1000,
|
| 163 |
+
total_steps=self._total_steps,
|
| 164 |
+
total_time_s=self._total_time,
|
| 165 |
+
peak_memory_mb=self._peak_memory,
|
| 166 |
+
current_memory_mb=self._get_memory_mb(),
|
| 167 |
+
cpu_percent=self._get_cpu_percent(),
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
def get_summary(self) -> Dict[str, Any]:
|
| 171 |
+
"""Get metrics summary as dictionary."""
|
| 172 |
+
return self.get_metrics().to_dict()
|
| 173 |
+
|
| 174 |
+
def _get_memory_mb(self) -> float:
|
| 175 |
+
"""Get current process memory in MB."""
|
| 176 |
+
if self._process is not None:
|
| 177 |
+
try:
|
| 178 |
+
return self._process.memory_info().rss / (1024 * 1024)
|
| 179 |
+
except Exception:
|
| 180 |
+
pass
|
| 181 |
+
return 0.0
|
| 182 |
+
|
| 183 |
+
def _get_cpu_percent(self) -> float:
|
| 184 |
+
"""Get current CPU utilization percentage."""
|
| 185 |
+
if self._process is not None:
|
| 186 |
+
try:
|
| 187 |
+
return self._process.cpu_percent()
|
| 188 |
+
except Exception:
|
| 189 |
+
pass
|
| 190 |
+
return 0.0
|