WaypointPlugin¶
Manages named positions in the map used for NPC navigation, player spawning, and portal destinations.
Location¶
- Implementation: src/pedre/plugins/waypoint/plugin.py
- Base class: src/pedre/plugins/waypoint/base.py
Overview¶
The WaypointPlugin is a simple but essential plugin that stores named positions (waypoints) from Tiled maps. Waypoints are used throughout the framework for:
- Player spawning - Portal destinations when transitioning between maps
- NPC movement - Target positions for pathfinding-based movement
- Scripting - Named locations for positioning entities in cutscenes
Waypoints are defined as Point objects in Tiled's "Waypoints" object layer and automatically loaded when a map is loaded.
Configuration¶
The WaypointPlugin uses the following setting from pedre.conf.settings:
TILE_SIZE- Size of each tile in pixels, used to convert waypoint pixel coordinates to tile coordinates (default: 32)
This can be overridden in your project's settings.py:
Public API¶
Waypoint Retrieval¶
get_waypoint¶
get_waypoint(name: str) -> tuple[float, float] | None
Get waypoint position by name.
Parameters:
name- Waypoint name as defined in Tiled
Returns:
- Tuple of
(tile_x, tile_y)in tile coordinates, orNoneif not found
Example:
# Get waypoint position
waypoint = waypoint_plugin.get_waypoint("town_center")
if waypoint:
tile_x, tile_y = waypoint
print(f"Town center is at tile ({tile_x}, {tile_y})")
Notes:
- Returns tile coordinates, not pixel coordinates
- Waypoint names are case-sensitive
- Returns
Nonefor non-existent waypoints
get_waypoints¶
get_waypoints() -> dict[str, tuple[float, float]]
Get all waypoints in the current map.
Returns:
- Dictionary mapping waypoint names to
(tile_x, tile_y)tuples
Example:
# List all waypoints
for name, (x, y) in waypoint_plugin.get_waypoints().items():
print(f"{name}: tile ({x}, {y})")
Notes:
- Returns all waypoints loaded from the current map
- Dictionary is empty if no waypoints are loaded
- Waypoints are cleared when transitioning to a new map
Tiled Integration¶
load_from_tiled¶
load_from_tiled(tile_map: arcade.TileMap, arcade_scene: arcade.Scene) -> None
Load waypoints from Tiled map object layer.
Parameters:
tile_map- The loaded Tiled maparcade_scene- The arcade Scene (not used for waypoints)
Notes:
- Called automatically by PluginLoader during map loading
- Looks for "Waypoints" object layer in the Tiled map
- Converts pixel coordinates to tile coordinates using
settings.TILE_SIZE - Only processes Point objects with valid
nameandshapeproperties - Logs waypoint loading for debugging
Plugin Lifecycle¶
setup¶
setup(context: GameContext) -> None
Initialize the waypoint plugin with game context.
Parameters:
context- Game context providing access to other plugins
Notes:
- Called automatically by PluginLoader
- Stores reference to game context
reset¶
reset() -> None
Reset waypoint plugin for new game.
Notes:
- Clears all waypoints
- Called when starting a new game
Usage Examples¶
Basic Waypoint Lookup¶
# Get a specific waypoint
spawn_point = waypoint_plugin.get_waypoint("player_spawn")
if spawn_point:
tile_x, tile_y = spawn_point
# Convert to pixel coordinates if needed
pixel_x = tile_x * settings.TILE_SIZE
pixel_y = tile_y * settings.TILE_SIZE
Using Waypoints in Scripts¶
Waypoints are commonly used in scripts for NPC movement:
{
"merchant_goes_home": {
"scene": "village",
"trigger": {
"event": "time_of_day",
"hour": 18
},
"actions": [
{"type": "move_npc", "npcs": ["merchant"], "waypoint": "merchant_home"},
{"type": "wait_for_movement", "npc": "merchant"}
]
}
}
Portal Destinations¶
Waypoints define where the player spawns after portal transitions:
In Tiled (forest.tmx):
In Script:
{
"village_to_forest": {
"trigger": {"event": "portal_entered", "portal": "forest_entrance"},
"actions": [
{"type": "change_scene", "target_map": "forest.tmx", "spawn_waypoint": "from_village"}
]
}
}
Checking Waypoint Existence¶
# Verify waypoint exists before using it
waypoint_name = "secret_cave"
if waypoint_plugin.get_waypoint(waypoint_name):
print(f"Waypoint '{waypoint_name}' exists")
# Proceed with movement or spawning
else:
logger.warning(f"Waypoint '{waypoint_name}' not found in current map")
Listing All Waypoints¶
# Debug: List all available waypoints
waypoints = waypoint_plugin.get_waypoints()
if waypoints:
print(f"Found {len(waypoints)} waypoints:")
for name, (x, y) in waypoints.items():
print(f" {name}: ({x}, {y})")
else:
print("No waypoints in this map")
Tiled Map Setup¶
Creating Waypoints in Tiled¶
- Create Waypoints Layer:
- Add an Object Layer named "Waypoints"
-
This layer should be at the top of the layer stack
-
Add Point Objects:
- Select the Waypoints layer
- Click "Insert Point" tool (or press I)
- Click on the map where you want the waypoint
-
Set the
nameproperty for the point -
Naming Convention:
- Use descriptive names (e.g., "player_spawn", "merchant_home", "from_village")
- Names should be lowercase with underscores
- Names must be unique within the map
Example Waypoint Setup:
Layer: Waypoints (Object Layer)
Points:
- name: "player_spawn" at (320, 240)
- name: "merchant_home" at (640, 480)
- name: "from_village" at (100, 100)
- name: "from_forest" at (750, 50)
- name: "town_square" at (400, 300)
- name: "inn_entrance" at (200, 450)
Important Notes¶
- Point Objects Only: Waypoints must be Point objects, not rectangles or polygons
- Name Required: Each waypoint must have a
nameproperty set - No Duplicates: Waypoint names must be unique within a map
- Case Sensitive: Waypoint names are case-sensitive in lookups
- Automatic Conversion: Pixel coordinates are automatically converted to tile coordinates
Technical Details¶
Coordinate System¶
Waypoints are stored in tile coordinates internally:
# Tiled stores waypoints in pixel coordinates (e.g., x=320, y=240)
# WaypointPlugin converts to tile coordinates during loading:
tile_x = int(pixel_x // settings.TILE_SIZE) # e.g., 320 // 32 = 10
tile_y = int(pixel_y // settings.TILE_SIZE) # e.g., 240 // 32 = 7
This makes waypoints independent of tile size and easier to use with grid-based pathfinding.
Loading Process¶
When a map is loaded:
- PluginLoader calls
waypoint_plugin.load_from_tiled(tile_map, scene) - WaypointPlugin looks for "Waypoints" object layer
- For each Point object in the layer:
- Validates it has a
nameandshapeproperty - Extracts pixel coordinates from
shape[0]andshape[1] - Converts to tile coordinates using
settings.TILE_SIZE - Stores in
waypointsdictionary:{name: (tile_x, tile_y)} - Logs the number of waypoints loaded
Storage¶
Waypoints are stored in a simple dictionary:
self.waypoints: dict[str, tuple[float, float]] = {
"player_spawn": (10.0, 7.0),
"merchant_home": (20.0, 15.0),
"from_village": (3.0, 3.0),
}
Reset Behavior¶
Waypoints are automatically cleared when:
- A new map is loaded (via
reset()) - A new game is started (via
reset())
This ensures waypoints from one map don't carry over to another.
Custom Waypoint Implementation¶
If you need to replace the waypoint plugin with a custom implementation, you can extend the WaypointBasePlugin abstract base class.
WaypointBasePlugin¶
Location: src/pedre/plugins/waypoint/base.py
The WaypointBasePlugin class defines the minimum interface that any waypoint plugin must implement.
Required Methods¶
Your custom waypoint plugin must implement this abstract method:
from pedre.plugins.waypoint.base import WaypointBasePlugin
class CustomWaypointPlugin(WaypointBasePlugin):
"""Custom waypoint implementation."""
name = "waypoint"
dependencies = []
def get_waypoints(self) -> dict[str, tuple[float, float]]:
"""Get all waypoints."""
...
Registration¶
Register your custom waypoint plugin using the @PluginRegistry.register decorator:
from pedre.plugins.registry import PluginRegistry
from pedre.plugins.waypoint.base import WaypointBasePlugin
@PluginRegistry.register
class CustomWaypointPlugin(WaypointBasePlugin):
name = "waypoint"
dependencies = []
def get_waypoints(self) -> dict[str, tuple[float, float]]:
# Return waypoints from custom storage
return self.custom_waypoint_storage
Notes on Custom Implementation¶
- Your custom plugin inherits from
BasePlugin(viaWaypointBasePlugin), so you must implement the standard plugin lifecycle methods:setup(),cleanup(), andreset() - The
roleattribute is set to"waypoint_plugin"in the base class - Your implementation can use any storage system (database, JSON, CSV, etc.)
- Register your custom waypoint plugin in your project's
INSTALLED_PLUGINSsetting before the default"pedre.plugins.waypoint"to replace it
Example Custom Implementation:
# In myproject/plugins/custom_waypoint.py
from pedre.plugins.registry import PluginRegistry
from pedre.plugins.waypoint.base import WaypointBasePlugin
@PluginRegistry.register
class DatabaseWaypointPlugin(WaypointBasePlugin):
"""Waypoint plugin that stores waypoints in a database."""
name = "waypoint"
dependencies = []
def __init__(self):
self.db = Database()
# ... rest of initialization ...
def get_waypoints(self) -> dict[str, tuple[float, float]]:
# Query database for waypoints
return self.db.query("SELECT name, x, y FROM waypoints")
# ... implement other methods ...
# In myproject/settings.py
INSTALLED_PLUGINS = [
"myproject.plugins.custom_waypoint", # Load custom waypoint first
"pedre.plugins.camera",
"pedre.plugins.audio",
# ... rest of plugins (omit "pedre.plugins.waypoint") ...
]
See Also¶
- NPCPlugin - Uses waypoints for NPC movement
- PortalPlugin - Uses waypoints for player spawning
- ScriptPlugin - Uses waypoints in scripted actions
- Configuration Guide
- Tiled Integration