Generated on 2026-04-18 07:28:57
This documentation was dynamically generated from the compiled module.
bresenham(start, end, *, include_start=True, include_end=True) -> list[tuple[int, int]]Compute grid cells along a line using Bresenham's algorithm. Note:
Returns: list[tuple[int, int]]: List of (x, y) grid coordinates along the line Useful for line-of-sight checks, projectile paths, and drawing lines on grids. The algorithm ensures minimal grid traversal between two points.
end_benchmark() -> strStop benchmark capture and write data to JSON file. Note:
Returns: str: The filename of the written benchmark data
Raises: RuntimeError: If no benchmark is currently running Returns the auto-generated filename (e.g., 'benchmark_12345_20250528_143022.json')
exit() -> NoneCleanly shut down the game engine and exit the application. Note:
Returns: None This immediately closes the window and terminates the program.
find(name: str, scene: str = None) -> UIDrawable | NoneFind the first UI element with the specified name. Note:
Returns: Frame, Caption, Sprite, Grid, or Entity if found; None otherwise Searches scene UI elements and entities within grids.
find_all(pattern: str, scene: str = None) -> listFind all UI elements matching a name pattern. Note:
Returns: list: All matching UI elements and entities
get_metrics() -> dictGet current performance metrics.
Returns: dict: Performance data with keys: frame_time (last frame duration in seconds), avg_frame_time (average frame time), fps (frames per second), draw_calls (number of draw calls), ui_elements (total UI element count), visible_elements (visible element count), current_frame (frame counter), runtime (total runtime in seconds)
lock() -> _LockContextGet a context manager for thread-safe UI updates from background threads. Note:
Returns: _LockContext: A context manager that blocks until safe to modify UI Use with `with mcrfpy.lock():` to safely modify UI objects from a background thread. The context manager blocks until the render loop reaches a safe point between frames. Without this, modifying UI from threads may cause visual glitches or crashes.
log_benchmark(message: str) -> NoneAdd a log message to the current benchmark frame. Note:
Returns: None
Raises: RuntimeError: If no benchmark is currently running Messages appear in the 'logs' array of each frame in the output JSON.
set_dev_console(enabled: bool) -> NoneEnable or disable the developer console overlay. Note:
Returns: None When disabled, the grave/tilde key will not open the console. Use this to ship games without debug features.
set_scale(multiplier: float) -> NoneDeprecated: use Window.resolution instead. Scale the game window size. Note:
Returns: None The internal resolution remains 1024x768, but the window is scaled. This is deprecated - use Window.resolution instead.
start_benchmark() -> NoneStart capturing benchmark data to a file. Note:
Returns: None
Raises: RuntimeError: If a benchmark is already running Benchmark filename is auto-generated from PID and timestamp. Use end_benchmark() to stop and get filename.
step(dt: float = None) -> floatAdvance simulation time (headless mode only). Note:
Returns: float: Actual time advanced in seconds. Returns 0.0 in windowed mode. In windowed mode, this is a no-op and returns 0.0. Use this for deterministic simulation control in headless/testing scenarios.
A computed A* path result, consumed step by step. Created by Grid.find_path(). Cannot be instantiated directly. Use walk() to get and consume each step, or iterate directly. Use peek() to see the next step without consuming it. Use bool(path) or len(path) to check if steps remain. Properties: origin (Vector): Starting position (read-only) destination (Vector): Ending position (read-only) remaining (int): Steps remaining (read-only) Example: path = grid.find_path(start, end) if path: while path: next_pos = path.walk() entity.pos = next_pos
peek() -> VectorSee next step without consuming it.
Returns: Next position as Vector.
Raises: IndexError: If path is exhausted.
walk() -> VectorGet and consume next step in the path.
Returns: Next position as Vector.
Raises: IndexError: If path is exhausted.
Inherits from: IntEnum
Alignment enum for positioning UI elements relative to parent bounds. Values: TOP_LEFT, TOP_CENTER, TOP_RIGHT CENTER_LEFT, CENTER, CENTER_RIGHT BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT Margin Validation Rules: Margins define distance from parent edge when aligned. - CENTER: No margins allowed (raises ValueError if margin != 0) - TOP_CENTER, BOTTOM_CENTER: Only vert_margin applies (horiz_margin raises ValueError) - CENTER_LEFT, CENTER_RIGHT: Only horiz_margin applies (vert_margin raises ValueError) - Corner alignments (TOP_LEFT, etc.): All margins valid Properties: align: Alignment value or None to disable margin: General margin for all applicable edges horiz_margin: Override for horizontal edge (0 = use general margin) vert_margin: Override for vertical edge (0 = use general margin) Example: # Center a panel in the scene panel = Frame(size=(200, 100), align=Alignment.CENTER) scene.children.append(panel) # Place button in bottom-right with 10px margin button = Frame(size=(80, 30), align=Alignment.BOTTOM_RIGHT, margin=10) panel.children.append(button)
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Animation(property: str, target: Any, duration: float, easing: str = 'linear', delta: bool = False, loop: bool = False, callback: Callable = None) Create an animation that interpolates a property value over time. Args: property: Property name to animate. Valid properties depend on target type: - Position/Size: 'x', 'y', 'w', 'h', 'pos', 'size' - Appearance: 'fill_color', 'outline_color', 'outline', 'opacity' - Sprite: 'sprite_index', 'scale' - Grid: 'center', 'zoom' - Caption: 'text' - Sub-properties: 'fill_color.r', 'fill_color.g', 'fill_color.b', 'fill_color.a' target: Target value for the animation. Type depends on property: - float: For numeric properties (x, y, w, h, scale, opacity, zoom) - int: For integer properties (sprite_index) - tuple (r, g, b[, a]): For color properties - tuple (x, y): For vector properties (pos, size, center) - list[int]: For sprite animation sequences - str: For text animation duration: Animation duration in seconds. easing: Easing function name. Options: - 'linear' (default) - 'easeIn', 'easeOut', 'easeInOut' - 'easeInQuad', 'easeOutQuad', 'easeInOutQuad' - 'easeInCubic', 'easeOutCubic', 'easeInOutCubic' - 'easeInQuart', 'easeOutQuart', 'easeInOutQuart' - 'easeInSine', 'easeOutSine', 'easeInOutSine' - 'easeInExpo', 'easeOutExpo', 'easeInOutExpo' - 'easeInCirc', 'easeOutCirc', 'easeInOutCirc' - 'easeInElastic', 'easeOutElastic', 'easeInOutElastic' - 'easeInBack', 'easeOutBack', 'easeInOutBack' - 'easeInBounce', 'easeOutBounce', 'easeInOutBounce' delta: If True, target is relative to start value (additive). Default False. loop: If True, animation repeats from start when it reaches the end. Default False. callback: Function(target, property, value) called when animation completes. Not called for looping animations (since they never complete). Example: # Move a frame from current position to x=500 over 2 seconds anim = mcrfpy.Animation('x', 500.0, 2.0, 'easeInOut') anim.start(my_frame) # Looping sprite animation walk = mcrfpy.Animation('sprite_index', [0,1,2,3,2,1], 0.6, loop=True) walk.start(my_sprite)
complete() -> NoneComplete the animation immediately by jumping to the final value. Note:
Returns: None Sets elapsed = duration and applies target value immediately. Completion callback will be called if set.
get_current_value() -> AnyGet the current interpolated value of the animation. Note:
Returns: Any: Current value (type depends on property: float, int, Color tuple, Vector tuple, or str) Return type matches the target property type. For sprite_index returns int, for pos returns (x, y), for fill_color returns (r, g, b, a).
hasValidTarget() -> boolCheck if the animation still has a valid target. Note:
Returns: bool: True if the target still exists, False if it was destroyed Animations automatically clean up when targets are destroyed. Use this to check if manual cleanup is needed.
start(target: UIDrawable, conflict_mode: str = 'replace') -> NoneStart the animation on a target UI element. Note:
Returns: None
Raises: RuntimeError: When conflict_mode='error' and property is already animating The animation will automatically stop if the target is destroyed.
stop() -> NoneStop the animation without completing it. Note:
Returns: None Unlike complete(), this does NOT apply the final value and does NOT trigger the callback. The animation is simply cancelled and will be removed from the AnimationManager.
update(delta_time: float) -> boolUpdate the animation by the given time delta. Note:
Returns: bool: True if animation is still running, False if complete Typically called by AnimationManager automatically. Manual calls only needed for custom animation control.
Inherits from: Drawable
Arc(center=None, radius=0, start_angle=0, end_angle=90, color=None, thickness=1, **kwargs) An arc UI element for drawing curved line segments. Args: center (tuple, optional): Center position as (x, y). Default: (0, 0) radius (float, optional): Arc radius in pixels. Default: 0 start_angle (float, optional): Starting angle in degrees. Default: 0 end_angle (float, optional): Ending angle in degrees. Default: 90 color (Color, optional): Arc color. Default: White thickness (float, optional): Line thickness. Default: 1.0 Keyword Args: on_click (callable): Click handler. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None align (Alignment): Alignment relative to parent. Default: None margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: center (Vector): Center position radius (float): Arc radius start_angle (float): Starting angle in degrees end_angle (float): Ending angle in degrees color (Color): Arc color thickness (float): Line thickness visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
AutoRuleSet - LDtk auto-tile rule set for pattern-based terrain rendering. AutoRuleSets are obtained from LdtkProject.ruleset(). They map IntGrid terrain values to sprite tiles using LDtk's pattern-matching auto-rule system. Properties: name (str, read-only): Rule set name (layer identifier). grid_size (int, read-only): Cell size in pixels. value_count (int, read-only): Number of IntGrid values. values (list, read-only): List of value dicts. rule_count (int, read-only): Total rules across all groups. group_count (int, read-only): Number of rule groups. Example: rs = project.ruleset('Walls') Terrain = rs.terrain_enum() rs.apply(discrete_map, tile_layer, seed=42)
apply(discrete_map: DiscreteMap, tile_layer: TileLayer, seed: int = 0) -> NoneResolve auto-rules and write tile indices directly into a TileLayer.
resolve(discrete_map: DiscreteMap, seed: int = 0) -> list[int]Resolve IntGrid data to tile indices using LDtk auto-rules.
Returns: List of tile IDs (one per cell). -1 means no matching rule.
terrain_enum() -> IntEnumGenerate a Python IntEnum from this rule set's IntGrid values.
Returns: IntEnum class with NONE=0 and one member per IntGrid value (UPPER_SNAKE_CASE).
BSP(pos: tuple[int, int], size: tuple[int, int]) Binary Space Partitioning tree for procedural dungeon generation. BSP recursively divides a rectangular region into smaller sub-regions, creating a tree structure perfect for generating dungeon rooms and corridors. Args: pos: (x, y) - Top-left position of the root region. size: (w, h) - Width and height of the root region. Properties: pos (tuple[int, int]): Read-only. Top-left position (x, y). size (tuple[int, int]): Read-only. Dimensions (width, height). bounds ((pos), (size)): Read-only. Combined position and size. root (BSPNode): Read-only. Reference to the root node. Iteration: for leaf in bsp: # Iterates over leaf nodes (rooms) len(bsp) # Returns number of leaf nodes Example: bsp = mcrfpy.BSP(pos=(0, 0), size=(80, 50)) bsp.split_recursive(depth=4, min_size=(8, 8)) for leaf in bsp: print(f'Room at {leaf.pos}, size {leaf.size}')
clear() -> BSPRemove all children, keeping only the root node with original bounds. WARNING: Invalidates all existing BSPNode references from this tree.
Returns: BSP: self, for method chaining
find(pos: tuple[int, int]) -> BSPNode | NoneFind the smallest (deepest) node containing the position.
Returns: BSPNode if found, None if position is outside bounds
get_leaf(index: int) -> BSPNodeGet a leaf node by its index (0 to len(bsp)-1). This is useful when working with adjacency data, which returns leaf indices.
Returns: BSPNode at the specified index
Raises: IndexError: If index is out of range
leaves() -> Iterator[BSPNode]Iterate all leaf nodes (the actual rooms). Same as iterating the BSP directly.
Returns: Iterator yielding BSPNode objects
split_once(horizontal: bool, position: int) -> BSPSplit the root node once at the specified position. horizontal=True creates a horizontal divider, producing top/bottom rooms. horizontal=False creates a vertical divider, producing left/right rooms.
Returns: BSP: self, for method chaining
split_recursive(depth: int, min_size: tuple[int, int], max_ratio: float = 1.5, seed: int = None) -> BSPRecursively split to the specified depth. WARNING: Invalidates all existing BSPNode references from this tree.
Returns: BSP: self, for method chaining
to_heightmap(size: tuple[int, int] = None, select: str = 'leaves', shrink: int = 0, value: float = 1.0) -> HeightMapConvert BSP node selection to a HeightMap.
Returns: HeightMap with selected regions filled
traverse(order: Traversal = Traversal.LEVEL_ORDER) -> Iterator[BSPNode]Iterate all nodes in the specified order. Note:
Returns: Iterator yielding BSPNode objects Orders: PRE_ORDER, IN_ORDER, POST_ORDER, LEVEL_ORDER, INVERTED_LEVEL_ORDER
Inherits from: IntEnum
Enum representing entity behavior types for grid.step() turn management. Values: IDLE: No action each turn CUSTOM: Calls step callback only, no built-in movement NOISE4: Random movement in 4 cardinal directions NOISE8: Random movement in 8 directions (incl. diagonals) PATH: Follow a precomputed path to completion WAYPOINT: Path through a sequence of waypoints in order PATROL: Patrol waypoints back and forth (reversing at ends) LOOP: Loop through waypoints cyclically SLEEP: Wait for N turns, then trigger DONE SEEK: Move toward target using Dijkstra map FLEE: Move away from target using Dijkstra map
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Billboard(texture=None, sprite_index=0, pos=(0,0,0), scale=1.0, facing='camera_y') A camera-facing 3D sprite for trees, items, particles, etc. Args: texture (Texture, optional): Sprite sheet texture. Default: None sprite_index (int): Index into sprite sheet. Default: 0 pos (tuple): World position (x, y, z). Default: (0, 0, 0) scale (float): Uniform scale factor. Default: 1.0 facing (str): Facing mode - 'camera', 'camera_y', or 'fixed'. Default: 'camera_y' Properties: texture (Texture): Sprite sheet texture sprite_index (int): Index into sprite sheet pos (tuple): World position (x, y, z) scale (float): Uniform scale factor facing (str): Facing mode - 'camera', 'camera_y', or 'fixed' theta (float): Horizontal rotation for 'fixed' mode (radians) phi (float): Vertical tilt for 'fixed' mode (radians) opacity (float): Opacity 0.0 (transparent) to 1.0 (opaque) visible (bool): Visibility state
CallableBinding(callable: Callable[[], float]) A binding that calls a Python function to get its value. Args: callable: A function that takes no arguments and returns a float The callable is invoked every frame when the shader is rendered. Keep the callable lightweight to avoid performance issues. Example: player_health = 100 frame.uniforms['health_pct'] = mcrfpy.CallableBinding( lambda: player_health / 100.0 )
Inherits from: Drawable
Caption(pos=None, font=None, text='', **kwargs) A text display UI element with customizable font and styling. Args: pos (tuple, optional): Position as (x, y) tuple. Default: (0, 0) font (Font, optional): Font object for text rendering. Default: engine default font text (str, optional): The text content to display. Default: '' Keyword Args: fill_color (Color): Text fill color. Default: (255, 255, 255, 255) outline_color (Color): Text outline color. Default: (0, 0, 0, 255) outline (float): Text outline thickness. Default: 0 font_size (float): Font size in points. Default: 16 click (callable): Click event handler. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None x (float): X position override. Default: 0 y (float): Y position override. Default: 0 align (Alignment): Alignment relative to parent. Default: None margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: text (str): The displayed text content x, y (float): Position in pixels pos (Vector): Position as a Vector object font (Font): Font used for rendering font_size (float): Font size in points fill_color, outline_color (Color): Text appearance outline (float): Outline thickness click (callable): Click event handler visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name w, h (float): Read-only computed size based on text and font align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Inherits from: Drawable
Circle(radius=0, center=None, fill_color=None, outline_color=None, outline=0, **kwargs) A circle UI element for drawing filled or outlined circles. Args: radius (float, optional): Circle radius in pixels. Default: 0 center (tuple, optional): Center position as (x, y). Default: (0, 0) fill_color (Color, optional): Fill color. Default: White outline_color (Color, optional): Outline color. Default: Transparent outline (float, optional): Outline thickness. Default: 0 (no outline) Keyword Args: on_click (callable): Click handler. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None align (Alignment): Alignment relative to parent. Default: None margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: radius (float): Circle radius center (Vector): Center position fill_color (Color): Fill color outline_color (Color): Outline color outline (float): Outline thickness visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Color(r: int = 0, g: int = 0, b: int = 0, a: int = 255) RGBA color representation. Args: r: Red component (0-255) g: Green component (0-255) b: Blue component (0-255) a: Alpha component (0-255, default 255 = opaque) Note: When accessing colors from UI elements (e.g., frame.fill_color), you receive a COPY of the color. Modifying it doesn't affect the original. To change a component: # This does NOT work: frame.fill_color.r = 255 # Modifies a temporary copy # Do this instead: c = frame.fill_color c.r = 255 frame.fill_color = c # Or use Animation for sub-properties: anim = mcrfpy.Animation('fill_color.r', 255, 0.5, 'linear') anim.start(frame)
from_hex(hex_string: str) -> ColorCreate a Color from a hexadecimal string. Note:
Returns: Color: New Color object with values from hex string
Raises: ValueError: If hex string is not 6 or 8 characters (RGB or RGBA) This is a class method. Call as Color.from_hex('#FF0000')
lerp(other: Color, t: float) -> ColorLinearly interpolate between this color and another. Note:
Returns: Color: New Color representing the interpolated value All components (r, g, b, a) are interpolated independently
to_hex() -> strConvert this Color to a hexadecimal string. Note:
Returns: str: Hex string in format '#RRGGBB' or '#RRGGBBAA' (if alpha < 255) Alpha component is only included if not fully opaque (< 255)
ColorLayer(z_index=-1, name=None, grid_size=None) A grid layer that stores RGBA colors per cell for background/overlay effects. ColorLayers can be created standalone and attached to a Grid via add_layer() or passed to the Grid constructor's layers parameter. Layers with size (0, 0) automatically resize to match the Grid when attached. Args: z_index (int): Render order relative to entities. Negative values render below entities (as backgrounds), positive values render above entities (as overlays). Default: -1 (background) name (str): Layer name for Grid.layer(name) lookup. Default: None grid_size (tuple): Dimensions as (width, height). If None or (0, 0), the layer will auto-resize when attached to a Grid. Default: None Attributes: z_index (int): Layer z-order relative to entities (read/write) name (str): Layer name for lookup (read-only) visible (bool): Whether layer is rendered (read/write) grid_size (tuple): Layer dimensions as (width, height) (read-only) grid (Grid): Parent Grid or None. Setting manages layer association. Methods: at(x, y) -> Color: Get the color at cell position (x, y) set(x, y, color): Set the color at cell position (x, y) fill(color): Fill the entire layer with a single color fill_rect(x, y, w, h, color): Fill a rectangular region with a color draw_fov(...): Draw FOV-based visibility colors apply_perspective(entity, ...): Bind layer to entity for automatic FOV updates Example: fog = mcrfpy.ColorLayer(z_index=-1, name='fog') grid = mcrfpy.Grid(grid_size=(20, 15), layers=[fog]) fog.fill(mcrfpy.Color(40, 40, 40)) # Dark gray background grid.layer('fog').set(5, 5, mcrfpy.Color(255, 0, 0, 128))
apply_gradient(source, range, color_low, color_high) -> ColorLayerInterpolate between colors based on HeightMap value within range. Note:
Returns: self for method chaining Uses the original HeightMap value for interpolation, not binary. This allows smooth color transitions within a value range.
apply_perspective(entity, visible=None, discovered=None, unknown=None)Bind this layer to an entity for automatic FOV updates.
apply_ranges(source, ranges) -> ColorLayerApply multiple color assignments in a single pass. Note:
Returns: self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged.
apply_threshold(source, range, color) -> ColorLayerSet fixed color for cells where HeightMap value is within range.
Returns: self for method chaining
at(pos) -> Colorat(x, y) -> Color Get the color at cell position.
clear_perspective()Remove the perspective binding from this layer.
draw_fov(source, radius=None, fov=None, visible=None, discovered=None, unknown=None)Paint cells based on field-of-view visibility from source position. Note: Layer must be attached to a grid for FOV calculation.
fill(color)Fill the entire layer with the specified color.
fill_rect(pos, size, color)Fill a rectangular region with a color.
set(pos, color)Set the color at cell position.
update_perspective()Redraw FOV based on the bound entity's current position. Call this after the entity moves to update the visibility layer.
A Dijkstra distance map from a fixed root position. Created by Grid.get_dijkstra_map(). Cannot be instantiated directly. Grid caches these maps - multiple requests for the same root return the same map. Call Grid.clear_dijkstra_maps() after changing grid walkability to invalidate the cache. Properties: root (Vector): Root position (read-only) Methods: distance(pos) -> float | None: Get distance to root path_from(pos) -> AStarPath: Get full path to root step_from(pos) -> Vector | None: Get single step toward root Example: dijkstra = grid.get_dijkstra_map(player.pos) for enemy in enemies: dist = dijkstra.distance(enemy.pos) if dist and dist < 10: step = dijkstra.step_from(enemy.pos) if step: enemy.pos = step
distance(pos) -> float | NoneGet distance from position to root.
Returns: Float distance, or None if position is unreachable.
path_from(pos) -> AStarPathGet full path from position to root.
Returns: AStarPath from pos toward root.
step_from(pos) -> Vector | NoneGet single step from position toward root.
Returns: Next position as Vector, or None if at root or unreachable.
to_heightmap(size=None, unreachable=-1.0) -> HeightMapConvert distance field to a HeightMap. Each cell's height equals its pathfinding distance from the root. Useful for visualization, procedural terrain, or influence mapping.
Returns: HeightMap with distance values as heights.
DiscreteMap(size: tuple[int, int], fill: int = 0, enum: type[IntEnum] = None) A 2D grid of uint8 values (0-255) for discrete/categorical data. DiscreteMap provides memory-efficient storage for terrain types, region IDs, walkability masks, and other categorical data. Uses 4x less memory than HeightMap for the same dimensions. Args: size: (width, height) dimensions. Immutable after creation. fill: Initial value for all cells (0-255). Default 0. enum: Optional IntEnum class for value interpretation. Example: from enum import IntEnum class Terrain(IntEnum): WATER = 0 GRASS = 1 MOUNTAIN = 2 dmap = mcrfpy.DiscreteMap((100, 100), fill=0, enum=Terrain) dmap.fill(Terrain.GRASS, pos=(10, 10), size=(20, 20)) print(dmap[15, 15]) # Terrain.GRASS
add(other: DiscreteMap | int, *, pos=None, source_pos=None, size=None) -> DiscreteMapAdd values from another map or a scalar, with saturation to 0-255.
Returns: DiscreteMap: self, for method chaining
bitwise_and(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapBitwise AND with another DiscreteMap.
Returns: DiscreteMap: self, for method chaining
bitwise_or(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapBitwise OR with another DiscreteMap.
Returns: DiscreteMap: self, for method chaining
bitwise_xor(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapBitwise XOR with another DiscreteMap.
Returns: DiscreteMap: self, for method chaining
bool(condition: int | set | callable) -> DiscreteMapCreate binary mask from condition. Returns NEW DiscreteMap.
Returns: DiscreteMap: new map with 1 where condition true, 0 elsewhere
clear() -> DiscreteMapSet all cells to 0. Equivalent to fill(0).
Returns: DiscreteMap: self, for method chaining
copy_from(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapCopy values from another DiscreteMap into the specified region.
Returns: DiscreteMap: self, for method chaining
count(value: int) -> intCount cells with the specified value.
Returns: int: Number of cells with that value
count_range(min_val: int, max_val: int) -> intCount cells with values in the specified range (inclusive).
Returns: int: Number of cells in range
fill(value: int, *, pos=None, size=None) -> DiscreteMapSet cells in region to the specified value.
Returns: DiscreteMap: self, for method chaining
from_bytes(data: bytes, size: tuple[int, int], *, enum: type = None) -> DiscreteMapCreate a DiscreteMap from raw byte data.
Returns: DiscreteMap: new map initialized from data
Raises: ValueError: Data length does not match width * height
from_heightmap(hmap: HeightMap, mapping: list[tuple[tuple[float,float], int]], *, enum=None) -> DiscreteMapCreate DiscreteMap from HeightMap using range-to-value mapping.
Returns: DiscreteMap: new map with mapped values
get(x, y) or (pos) -> int | EnumGet the value at integer coordinates.
Returns: int or enum member if enum_type is set
Raises: IndexError: Position is out of bounds
histogram() -> dict[int, int]Get a histogram of value counts.
Returns: dict: {value: count} for all values present in the map
invert() -> DiscreteMapReturn NEW DiscreteMap with (255 - value) for each cell.
Returns: DiscreteMap: new inverted map (original unchanged)
mask() -> memoryviewGet raw uint8_t data as memoryview for libtcod compatibility.
Returns: memoryview: Direct access to internal buffer (read/write)
max(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapSet each cell to the maximum of this and another DiscreteMap.
Returns: DiscreteMap: self, for method chaining
min(other: DiscreteMap, *, pos=None, source_pos=None, size=None) -> DiscreteMapSet each cell to the minimum of this and another DiscreteMap.
Returns: DiscreteMap: self, for method chaining
min_max() -> tuple[int, int]Get the minimum and maximum values in the map.
Returns: tuple[int, int]: (min_value, max_value)
multiply(factor: float, *, pos=None, size=None) -> DiscreteMapMultiply values by a scalar factor, with saturation to 0-255.
Returns: DiscreteMap: self, for method chaining
set(x: int, y: int, value: int) -> NoneSet the value at integer coordinates.
Raises: IndexError: Position is out of bounds ValueError: Value out of range 0-255
subtract(other: DiscreteMap | int, *, pos=None, source_pos=None, size=None) -> DiscreteMapSubtract values from another map or a scalar, with saturation to 0-255.
Returns: DiscreteMap: self, for method chaining
to_bytes() -> bytesSerialize map data to bytes (row-major, one byte per cell).
Returns: bytes: Raw cell data, length = width * height
to_heightmap(mapping: dict[int, float] = None) -> HeightMapConvert to HeightMap, optionally mapping values to floats.
Returns: HeightMap: new heightmap with converted values
Base class for all drawable UI elements
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Inherits from: IntEnum
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Entity(grid_pos=None, texture=None, sprite_index=0, **kwargs) A game entity that exists on a grid with sprite rendering. Args: grid_pos (tuple, optional): Grid position as (x, y) tuple. Default: (0, 0) texture (Texture, optional): Texture object for sprite. Default: default texture sprite_index (int, optional): Index into texture atlas. Default: 0 Keyword Args: grid (Grid): Grid to attach entity to. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 name (str): Element name for finding. Default: None x (float): X grid position override (tile coords). Default: 0 y (float): Y grid position override (tile coords). Default: 0 sprite_offset (tuple): Pixel offset for oversized sprites. Default: (0, 0) sprite_grid (list): Per-tile sprite indices for composite entities. Default: None Attributes: pos (Vector): Pixel position relative to grid (requires grid attachment) x, y (float): Pixel position components (requires grid attachment) grid_pos (Vector): Integer tile coordinates (logical game position) grid_x, grid_y (int): Integer tile coordinate components draw_pos (Vector): Fractional tile position for smooth animation perspective_map (DiscreteMap | None): 3-state per-entity FOV memory sprite_index (int): Current sprite index visible (bool): Visibility state opacity (float): Opacity value name (str): Element name sprite_offset (Vector): Pixel offset for oversized sprites sprite_offset_x (float): X component of sprite offset sprite_offset_y (float): Y component of sprite offset
add_label(label: str) -> NoneAdd a label to this entity. Idempotent (adding same label twice is safe).
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this entity's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for Entity (draw_x, draw_y, sprite_scale, sprite_index) Use 'draw_x'/'draw_y' to animate tile coordinates for smooth movement between grid cells. Use list target with loop=True for repeating sprite frame animations.
at(x, y) or at(pos) -> GridPoint | NoneReturn the GridPoint at (x, y) if currently VISIBLE to this entity's perspective_map, otherwise None. Equivalent to: grid.at(x, y) if perspective_map[x, y] == Perspective.VISIBLE else None To inspect discovered-but-not-visible cells, read entity.perspective_map[x, y] directly and use grid.at(x, y) for cell data.
die(...)Remove this entity from its grid. Warning: Do not call during iteration over grid.entities. Modifying the collection during iteration raises RuntimeError.
find_path(target, diagonal_cost=1.41, collide=None) -> AStarPath | NoneFind a path from this entity to the target position.
Returns: AStarPath object, or None if no path exists.
has_label(label: str) -> boolCheck if this entity has the given label.
index(...)Return the index of this entity in its grid's entity collection
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
path_to(x, y) or path_to(target) -> listFind a path to the target position using Dijkstra pathfinding.
Returns: List of (x, y) tuples representing the path.
remove_label(label: str) -> NoneRemove a label from this entity. No-op if label not present.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
set_behavior(type, waypoints=None, turns=0, path=None) -> NoneConfigure this entity's behavior for grid.step() turn management.
update_visibility() -> NoneUpdate entity's visibility state based on current FOV. Recomputes which cells are visible from the entity's position and updates the entity's perspective_map (see entity.perspective_map and mcrfpy.Perspective). This is called automatically when the entity moves if it has a grid with perspective set.
visible_entities(fov=None, radius=None) -> list[Entity]Get list of other entities visible from this entity's position.
Returns: List of Entity objects that are within field of view. Computes FOV from this entity's position and returns all other entities whose positions fall within the visible area.
Entity3D(pos=None, **kwargs) A 3D game entity that exists on a Viewport3D's navigation grid. Args: pos (tuple, optional): Grid position as (x, z). Default: (0, 0) Keyword Args: viewport (Viewport3D): Viewport to attach entity to. Default: None rotation (float): Y-axis rotation in degrees. Default: 0 scale (float or tuple): Scale factor. Default: 1.0 visible (bool): Visibility state. Default: True color (Color): Entity color. Default: orange Attributes: pos (tuple): Grid position (x, z) - setting triggers movement grid_pos (tuple): Same as pos (read-only) world_pos (tuple): Current world coordinates (x, y, z) (read-only) rotation (float): Y-axis rotation in degrees scale (float): Uniform scale factor visible (bool): Visibility state color (Color): Entity render color viewport (Viewport3D): Owning viewport (read-only)
animate(property, target, duration, easing=None, delta=False, callback=None, conflict_mode=None)Animate a property over time.
at(x, z) -> dictGet visibility state for a cell from this entity's perspective. Returns dict with 'visible' and 'discovered' boolean keys.
clear_path()Clear the movement queue and stop at current position.
follow_path(path)Queue path positions for smooth movement.
path_to(x, z) or path_to(pos=(x, z)) -> listCompute A* path to target position. Returns list of (x, z) tuples, or empty list if no path exists.
teleport(x, z) or teleport(pos=(x, z))Instantly move to target position without animation.
update_visibility()Recompute field of view from current position.
Collection of Entity3D objects belonging to a Viewport3D. Supports list-like operations: indexing, iteration, append, remove. Example: viewport.entities.append(entity) for entity in viewport.entities: print(entity.pos)
append(entity)Add an Entity3D to the collection.
clear()Remove all entities from the collection.
extend(iterable)Add all Entity3D objects from iterable to the collection.
find(name) -> Entity3D or NoneFind an Entity3D by name. Returns None if not found.
pop(index=-1) -> Entity3DRemove and return Entity3D at index (default: last).
remove(entity)Remove an Entity3D from the collection.
Iterator for EntityCollection3D
Inherits from: IntEnum
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Font(filename: str) A font resource for rendering text in Caption elements. Args: filename: Path to a TrueType (.ttf) or OpenType (.otf) font file. Properties: family (str, read-only): Font family name from metadata. source (str, read-only): File path used to load this font.
Inherits from: Drawable
Frame(pos=None, size=None, **kwargs) A rectangular frame UI element that can contain other drawable elements. Args: pos (tuple, optional): Position as (x, y) tuple. Default: (0, 0) size (tuple, optional): Size as (width, height) tuple. Default: (0, 0) Keyword Args: fill_color (Color): Background fill color. Default: (0, 0, 0, 128) outline_color (Color): Border outline color. Default: (255, 255, 255, 255) outline (float): Border outline thickness. Default: 0 click (callable): Click event handler. Default: None children (list): Initial list of child drawable elements. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None x (float): X position override. Default: 0 y (float): Y position override. Default: 0 w (float): Width override. Default: 0 h (float): Height override. Default: 0 clip_children (bool): Whether to clip children to frame bounds. Default: False cache_subtree (bool): Cache rendering to texture for performance. Default: False align (Alignment): Alignment relative to parent. Default: None (manual positioning) margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: x, y (float): Position in pixels w, h (float): Size in pixels pos (Vector): Position as a Vector object fill_color, outline_color (Color): Visual appearance outline (float): Border thickness click (callable): Click event handler children (list): Collection of child drawable elements visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name clip_children (bool): Whether to clip children to frame bounds cache_subtree (bool): Cache subtree rendering to texture align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Inherits from: Drawable
Grid(grid_size=None, pos=None, size=None, texture=None, **kwargs) A grid-based UI element for tile-based rendering and entity management. Creates and owns grid data (cells, entities, layers) with an integrated rendering view (camera, zoom, perspective). Can also be constructed as a view of existing grid data: Grid(grid=existing_grid, pos=..., size=...) Args: grid_size (tuple): Grid dimensions as (grid_w, grid_h). Default: (2, 2) pos (tuple): Position as (x, y). Default: (0, 0) size (tuple): Size as (w, h). Default: auto-calculated texture (Texture): Tile texture atlas. Default: default texture Keyword Args: grid (Grid): Existing Grid to view (creates view of shared data). fill_color (Color): Background fill color. on_click (callable): Click event handler. center_x, center_y (float): Camera center coordinates. zoom (float): Zoom level. Default: 1.0 visible (bool): Visibility. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name. layers (list): List of ColorLayer/TileLayer objects.
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Inherits from: Drawable
Grid(grid_size=None, pos=None, size=None, texture=None, **kwargs) A grid-based UI element for tile-based rendering and entity management. Creates and owns grid data (cells, entities, layers) with an integrated rendering view (camera, zoom, perspective). Can also be constructed as a view of existing grid data: Grid(grid=existing_grid, pos=..., size=...) Args: grid_size (tuple): Grid dimensions as (grid_w, grid_h). Default: (2, 2) pos (tuple): Position as (x, y). Default: (0, 0) size (tuple): Size as (w, h). Default: auto-calculated texture (Texture): Tile texture atlas. Default: default texture Keyword Args: grid (Grid): Existing Grid to view (creates view of shared data). fill_color (Color): Background fill color. on_click (callable): Click event handler. center_x, center_y (float): Camera center coordinates. zoom (float): Zoom level. Default: 1.0 visible (bool): Visibility. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name. layers (list): List of ColorLayer/TileLayer objects.
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
HeightMap(size: tuple[int, int], fill: float = 0.0) A 2D grid of float values for procedural generation. HeightMap is the universal canvas for procedural generation. It stores float values that can be manipulated, combined, and applied to Grid and Layer objects. Args: size: (width, height) dimensions of the heightmap. Immutable after creation. fill: Initial value for all cells. Default 0.0. Example: hmap = mcrfpy.HeightMap((100, 100)) hmap.fill(0.5).scale(2.0).clamp(0.0, 1.0) value = hmap[5, 5] # Subscript shorthand for get()
add(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapAdd another heightmap's values to this one in the specified region.
Returns: HeightMap: self, for method chaining
add_bsp(bsp: BSP, *, pos=None, select: str = 'leaves', nodes: list = None, shrink: int = 0, value: float = 1.0) -> HeightMapAdd BSP node regions to heightmap. More efficient than creating intermediate HeightMap.
Returns: HeightMap: self, for method chaining
add_constant(value: float, *, pos=None, size=None) -> HeightMapAdd a constant value to cells in region.
Returns: HeightMap: self, for method chaining
add_hill(center, radius: float, height: float) -> HeightMapAdd a smooth hill at the specified position.
Returns: HeightMap: self, for method chaining
add_noise(source: NoiseSource, world_origin: tuple = (0.0, 0.0), world_size: tuple = None, mode: str = 'fbm', octaves: int = 4, scale: float = 1.0) -> HeightMapSample noise and add to current values. More efficient than creating intermediate HeightMap.
Returns: HeightMap: self, for method chaining
add_voronoi(num_points: int, coefficients: tuple = (1.0, -0.5), seed: int = None) -> HeightMapAdd Voronoi-based terrain features.
Returns: HeightMap: self, for method chaining
clamp(min: float = 0.0, max: float = 1.0, *, pos=None, size=None) -> HeightMapClamp values in region to the specified range.
Returns: HeightMap: self, for method chaining
clear() -> HeightMapSet all cells to 0.0. Equivalent to fill(0.0).
Returns: HeightMap: self, for method chaining
copy_from(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapCopy values from another heightmap into the specified region.
Returns: HeightMap: self, for method chaining
count_in_range(range: tuple[float, float]) -> intCount cells with values in the specified range (inclusive).
Returns: int: Number of cells with values in range
Raises: ValueError: min > max
dig_bezier(points: tuple, start_radius: float, end_radius: float, start_height: float, end_height: float) -> HeightMapConstruct a canal along a cubic Bezier curve with specified heights. Note:
Returns: HeightMap: self, for method chaining Only lowers cells; cells below target height are unchanged
dig_hill(center, radius: float, target_height: float) -> HeightMapConstruct a pit or crater with the specified center height. Note:
Returns: HeightMap: self, for method chaining Only lowers cells; cells below target_height are unchanged
fill(value: float, *, pos=None, size=None) -> HeightMapSet cells in region to the specified value.
Returns: HeightMap: self, for method chaining
get(x, y) or (pos) -> floatGet the height value at integer coordinates.
Returns: float: Height value at that position
Raises: IndexError: Position is out of bounds
get_interpolated(x, y) or (pos) -> floatGet interpolated height value at non-integer coordinates.
Returns: float: Bilinearly interpolated height value
get_normal(x, y, water_level=0.0) or (pos, water_level=0.0) -> tuple[float, float, float]Get the normal vector at given coordinates for lighting calculations.
Returns: tuple[float, float, float]: Normal vector (nx, ny, nz)
get_slope(x, y) or (pos) -> floatGet the slope at integer coordinates, from 0 (flat) to pi/2 (vertical).
Returns: float: Slope angle in radians (0 to pi/2)
Raises: IndexError: Position is out of bounds
inverse() -> HeightMapReturn NEW HeightMap with (1.0 - value) for each cell.
Returns: HeightMap: New inverted HeightMap (original is unchanged)
lerp(other: HeightMap, t: float, *, pos=None, source_pos=None, size=None) -> HeightMapLinear interpolation between this and another heightmap in the specified region.
Returns: HeightMap: self, for method chaining
max(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapSet each cell in region to the maximum of this and another heightmap.
Returns: HeightMap: self, for method chaining
mid_point_displacement(roughness: float = 0.5, seed: int = None) -> HeightMapGenerate terrain using midpoint displacement algorithm (diamond-square). Note:
Returns: HeightMap: self, for method chaining Works best with power-of-2+1 dimensions (e.g., 65x65, 129x129)
min(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapSet each cell in region to the minimum of this and another heightmap.
Returns: HeightMap: self, for method chaining
min_max() -> tuple[float, float]Get the minimum and maximum height values in the map.
Returns: tuple[float, float]: (min_value, max_value)
multiply(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapMultiply this heightmap by another in the specified region (useful for masking).
Returns: HeightMap: self, for method chaining
multiply_bsp(bsp: BSP, *, pos=None, select: str = 'leaves', nodes: list = None, shrink: int = 0, value: float = 1.0) -> HeightMapMultiply by BSP regions. Effectively masks the heightmap to node interiors.
Returns: HeightMap: self, for method chaining
multiply_noise(source: NoiseSource, world_origin: tuple = (0.0, 0.0), world_size: tuple = None, mode: str = 'fbm', octaves: int = 4, scale: float = 1.0) -> HeightMapSample noise and multiply with current values. Useful for applying noise-based masks.
Returns: HeightMap: self, for method chaining
normalize(min: float = 0.0, max: float = 1.0, *, pos=None, size=None) -> HeightMapLinearly rescale values in region. Current min becomes new min, current max becomes new max.
Returns: HeightMap: self, for method chaining
rain_erosion(drops: int, erosion: float = 0.1, sedimentation: float = 0.05, seed: int = None) -> HeightMapSimulate rain erosion on the terrain.
Returns: HeightMap: self, for method chaining
scale(factor: float, *, pos=None, size=None) -> HeightMapMultiply cells in region by a factor.
Returns: HeightMap: self, for method chaining
smooth(iterations: int = 1) -> HeightMapSmooth the heightmap by averaging neighboring cells.
Returns: HeightMap: self, for method chaining
sparse_kernel(weights: dict[tuple[int, int], float]) -> HeightMapApply sparse convolution kernel, returning a NEW HeightMap with results.
Returns: HeightMap: new heightmap with convolution result
sparse_kernel_from(source: HeightMap, weights: dict[tuple[int, int], float]) -> NoneApply sparse convolution from source heightmap into self (for reusing destination buffers).
Returns: None
subtract(other: HeightMap, *, pos=None, source_pos=None, size=None) -> HeightMapSubtract another heightmap's values from this one in the specified region.
Returns: HeightMap: self, for method chaining
threshold(range: tuple[float, float]) -> HeightMapReturn NEW HeightMap with original values where in range, 0.0 elsewhere.
Returns: HeightMap: New HeightMap (original is unchanged)
Raises: ValueError: min > max
threshold_binary(range: tuple[float, float], value: float = 1.0) -> HeightMapReturn NEW HeightMap with uniform value where in range, 0.0 elsewhere.
Returns: HeightMap: New HeightMap (original is unchanged)
Raises: ValueError: min > max
Inherits from: IntEnum
Enum representing input event states (pressed/released). Values: PRESSED: Key or button was pressed RELEASED: Key or button was released
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Inherits from: IntEnum
Enum representing keyboard keys. Values map to SFML's sf::Keyboard::Key enum. Categories: Letters: A-Z Numbers: NUM_0 through NUM_9 (top row) Numpad: NUMPAD_0 through NUMPAD_9 Function: F1 through F15 Modifiers: LEFT_SHIFT, RIGHT_SHIFT, LEFT_CONTROL, etc. Navigation: LEFT, RIGHT, UP, DOWN, HOME, END, PAGE_UP, PAGE_DOWN Editing: ENTER, BACKSPACE, DELETE, INSERT, TAB, SPACE Symbols: COMMA, PERIOD, SLASH, SEMICOLON, etc.
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Keyboard state singleton for checking modifier keys
LdtkProject(path: str) Load an LDtk project file (.ldtk). Parses the project and provides access to tilesets, auto-rule sets, levels, and enum definitions. Args: path: Path to the .ldtk project file. Properties: version (str, read-only): LDtk JSON format version. tileset_names (list[str], read-only): Names of all tilesets. ruleset_names (list[str], read-only): Names of all rule sets. level_names (list[str], read-only): Names of all levels. enums (dict, read-only): Enum definitions from the project. Example: proj = mcrfpy.LdtkProject('dungeon.ldtk') ts = proj.tileset('Dungeon_Tiles') rs = proj.ruleset('Walls') level = proj.level('Level_0')
level(name: str) -> dictGet level data by name.
Returns: Dict with name, dimensions, world position, and layer data.
Raises: KeyError: If no level with the given name exists
ruleset(name: str) -> AutoRuleSetGet an auto-rule set by layer name.
Returns: An AutoRuleSet for resolving IntGrid data to sprite tiles.
Raises: KeyError: If no ruleset with the given name exists
tileset(name: str) -> TileSetFileGet a tileset by name.
Returns: A TileSetFile object for texture creation and tile metadata.
Raises: KeyError: If no tileset with the given name exists
Inherits from: Drawable
Line(start=None, end=None, thickness=1.0, color=None, **kwargs) A line UI element for drawing straight lines between two points. Args: start (tuple, optional): Starting point as (x, y). Default: (0, 0) end (tuple, optional): Ending point as (x, y). Default: (0, 0) thickness (float, optional): Line thickness in pixels. Default: 1.0 color (Color, optional): Line color. Default: White Keyword Args: on_click (callable): Click handler. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None align (Alignment): Alignment relative to parent. Default: None margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: start (Vector): Starting point end (Vector): Ending point thickness (float): Line thickness color (Color): Line color visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Model3D(path=None) A 3D model resource that can be rendered by Entity3D. Args: path (str, optional): Path to .glb file to load. If None, creates empty model. Class Methods: cube(size=1.0) -> Model3D: Create a unit cube plane(width=1.0, depth=1.0, segments=1) -> Model3D: Create a flat plane sphere(radius=0.5, segments=16, rings=12) -> Model3D: Create a UV sphere Properties: name (str, read-only): Model name vertex_count (int, read-only): Total vertices across all meshes triangle_count (int, read-only): Total triangles across all meshes has_skeleton (bool, read-only): Whether model has skeletal animation data bounds (tuple, read-only): AABB as ((min_x, min_y, min_z), (max_x, max_y, max_z)) mesh_count (int, read-only): Number of submeshes bone_count (int, read-only): Number of bones in skeleton animation_clips (list, read-only): List of animation clip names
cube(size=1.0) -> Model3DCreate a unit cube centered at origin.
plane(width=1.0, depth=1.0, segments=1) -> Model3DCreate a flat plane.
sphere(radius=0.5, segments=16, rings=12) -> Model3DCreate a UV sphere.
Mouse state singleton for reading button/position state and controlling cursor visibility
Inherits from: IntEnum
Enum representing mouse buttons and scroll wheel. Values: LEFT: Left mouse button RIGHT: Right mouse button MIDDLE: Middle mouse button / scroll wheel click X1: Extra mouse button 1 X2: Extra mouse button 2 SCROLL_UP: Scroll wheel up SCROLL_DOWN: Scroll wheel down
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Streaming music object for longer audio tracks
pause() -> NonePause the music. Use play() to resume from the paused position.
play() -> NoneStart or resume playing the music.
stop() -> NoneStop playing and reset to the beginning.
NoiseSource(dimensions: int = 2, algorithm: str = 'simplex', hurst: float = 0.5, lacunarity: float = 2.0, seed: int = None) A configured noise generator for procedural generation. NoiseSource wraps libtcod's noise generator, providing coherent noise values that can be used for terrain generation, textures, and other procedural content. The same coordinates always produce the same value (deterministic). Args: dimensions: Number of input dimensions (1-4). Default: 2. algorithm: Noise algorithm - 'simplex', 'perlin', or 'wavelet'. Default: 'simplex'. hurst: Fractal Hurst exponent for fbm/turbulence (0.0-1.0). Default: 0.5. lacunarity: Frequency multiplier between octaves. Default: 2.0. seed: Random seed for reproducibility. None for random seed. Properties: dimensions (int): Read-only. Number of input dimensions. algorithm (str): Read-only. Noise algorithm name. hurst (float): Read-only. Hurst exponent. lacunarity (float): Read-only. Lacunarity value. seed (int): Read-only. Seed used (even if originally None). Example: noise = mcrfpy.NoiseSource(dimensions=2, algorithm='simplex', seed=42) value = noise.get((10.5, 20.3)) # Returns -1.0 to 1.0 fbm_val = noise.fbm((10.5, 20.3), octaves=6)
fbm(pos: tuple[float, ...], octaves: int = 4) -> floatGet fractal brownian motion value at coordinates.
Returns: float: FBM noise value in range [-1.0, 1.0]
Raises: ValueError: Position tuple length doesn't match dimensions
get(pos: tuple[float, ...]) -> floatGet flat noise value at coordinates.
Returns: float: Noise value in range [-1.0, 1.0]
Raises: ValueError: Position tuple length doesn't match dimensions
sample(size: tuple[int, int], world_origin: tuple[float, float] = (0.0, 0.0), world_size: tuple[float, float] = None, mode: str = 'fbm', octaves: int = 4) -> HeightMapSample noise into a HeightMap for batch processing. Note:
Returns: HeightMap: New HeightMap filled with sampled noise values Requires dimensions=2. Values are in range [-1.0, 1.0].
turbulence(pos: tuple[float, ...], octaves: int = 4) -> floatGet turbulence (absolute fbm) value at coordinates.
Returns: float: Turbulence noise value in range [-1.0, 1.0]
Raises: ValueError: Position tuple length doesn't match dimensions
Inherits from: IntEnum
Enum representing an entity's knowledge of a cell. Values: UNKNOWN: Never seen (perspective_map value 0) DISCOVERED: Seen before but not currently visible (value 1) VISIBLE: In current FOV (value 2)
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
PropertyBinding(target: UIDrawable, property: str) A binding that reads a property value from a UI drawable. Args: target: The drawable to read the property from property: Name of the property to read (e.g., 'x', 'opacity') Use this to create dynamic shader uniforms that follow a drawable's properties. The binding automatically handles cases where the target is destroyed. Example: other_frame = mcrfpy.Frame(pos=(100, 100)) frame.uniforms['offset_x'] = mcrfpy.PropertyBinding(other_frame, 'x')
Scene(name: str) Object-oriented scene management with lifecycle callbacks. This is the recommended approach for scene management, replacing module-level functions like createScene(), setScene(), and sceneUI(). Key advantage: you can set on_key handlers on ANY scene, not just the currently active one. Args: name: Unique identifier for this scene. Used for scene transitions. Properties: name (str, read-only): Scene's unique identifier. active (bool, read-only): Whether this scene is currently displayed. children (UICollection, read-only): UI elements in this scene. Modify to add/remove elements. on_key (callable): Keyboard handler. Set on ANY scene, regardless of which is active! pos (Vector): Position offset for all UI elements. visible (bool): Whether the scene renders. opacity (float): Scene transparency (0.0-1.0). Lifecycle Callbacks (override in subclass): on_enter(): Called when scene becomes active via activate(). on_exit(): Called when scene is deactivated (another scene activates). on_key(key: str, action: str): Called for keyboard events (subclass method). update(dt: float): Called every frame with delta time in seconds. on_resize(new_size: Vector): Called when window is resized. Example: # Basic usage (replacing module functions): scene = mcrfpy.Scene('main_menu') scene.children.append(mcrfpy.Caption(text='Welcome', pos=(100, 100))) scene.on_key = lambda key, action: print(f'Key: {key}') scene.activate() # Switch to this scene # Subclassing for lifecycle: class GameScene(mcrfpy.Scene): def on_enter(self): print('Game started!') def update(self, dt): self.player.move(dt)
activate(transition: Transition = None, duration: float = None) -> NoneMake this the active scene with optional transition effect. Note:
Returns: None Deactivates the current scene and activates this one. Lifecycle callbacks (on_exit, on_enter) are triggered.
realign() -> NoneRecalculate alignment for all children with alignment set. Note: Call this after window resize or when game_resolution changes. For responsive layouts, connect this to on_resize callback.
register() -> NoneRegister this scene with the game engine. Note: Makes the scene available for activation and receives lifecycle callbacks. If another scene with the same name exists, it will be unregistered first. Called automatically by activate() if needed.
unregister() -> NoneUnregister this scene from the game engine. Note: Removes the scene from the engine's registry but keeps the Python object alive. The scene's UI elements and state are preserved. Call register() to re-add it. Useful for temporary scenes or scene pooling.
Shader(fragment_source: str, dynamic: bool = False) A GPU shader program for visual effects. Args: fragment_source: GLSL fragment shader source code dynamic: If True, shader uses time-varying effects and will invalidate parent caches each frame Shaders enable GPU-accelerated visual effects like glow, distortion, color manipulation, and more. Assign to drawable.shader to apply. Engine-provided uniforms (automatically available): - float time: Seconds since engine start - float delta_time: Seconds since last frame - vec2 resolution: Texture size in pixels - vec2 mouse: Mouse position in window coordinates Example: shader = mcrfpy.Shader(''' uniform sampler2D texture; uniform float time; void main() { vec2 uv = gl_TexCoord[0].xy; vec4 color = texture2D(texture, uv); color.rgb *= 0.5 + 0.5 * sin(time); gl_FragColor = color; } ''', dynamic=True) frame.shader = shader
set_uniform(name: str, value: float|tuple) -> NoneSet a custom uniform value on this shader. Note:
Raises: ValueError: If uniform type cannot be determined Engine uniforms (time, resolution, etc.) are set automatically
Sound(source) Sound effect object for short audio clips. Args: source: Filename string or SoundBuffer object. Properties: volume (float): Volume 0-100. loop (bool): Whether to loop. playing (bool, read-only): True if playing. duration (float, read-only): Duration in seconds. source (str, read-only): Source filename. pitch (float): Playback pitch (1.0 = normal). buffer (SoundBuffer, read-only): The SoundBuffer, if created from one.
pause() -> NonePause the sound. Use play() to resume from the paused position.
play() -> NoneStart or resume playing the sound.
play_varied(pitch_range: float = 0.1, volume_range: float = 3.0) -> NonePlay with randomized pitch and volume for natural variation.
stop() -> NoneStop playing and reset to the beginning.
SoundBuffer(filename: str) SoundBuffer.from_samples(data: bytes, channels: int, sample_rate: int) SoundBuffer.tone(frequency: float, duration: float, waveform: str = 'sine', ...) SoundBuffer.sfxr(preset: str, seed: int = None) Audio sample buffer for procedural audio generation and effects. Holds PCM sample data that can be created from files, raw samples, tone synthesis, or sfxr presets. Effect methods return new SoundBuffer instances (copy-modify pattern). Properties: duration (float, read-only): Duration in seconds. sample_count (int, read-only): Total number of samples. sample_rate (int, read-only): Samples per second (e.g. 44100). channels (int, read-only): Number of audio channels. sfxr_params (dict or None, read-only): sfxr parameters if sfxr-generated.
bit_crush(bits: int, rate_divisor: int) -> SoundBufferReduce bit depth and sample rate for lo-fi effect.
concat(buffers: list[SoundBuffer], overlap: float = 0.0) -> SoundBufferConcatenate multiple SoundBuffers with optional crossfade overlap.
distortion(drive: float) -> SoundBufferApply tanh soft clipping distortion.
echo(delay_ms: float, feedback: float, wet: float) -> SoundBufferApply echo effect with delay, feedback, and wet/dry mix.
from_samples(data: bytes, channels: int, sample_rate: int) -> SoundBufferCreate a SoundBuffer from raw int16 PCM sample data.
gain(factor: float) -> SoundBufferMultiply all samples by a scalar factor. Use for volume/amplitude control before mixing.
high_pass(cutoff_hz: float) -> SoundBufferApply single-pole IIR high-pass filter.
low_pass(cutoff_hz: float) -> SoundBufferApply single-pole IIR low-pass filter.
mix(buffers: list[SoundBuffer]) -> SoundBufferMix multiple SoundBuffers together (additive, clamped).
normalize() -> SoundBufferScale samples to 95%% of int16 max.
pitch_shift(factor: float) -> SoundBufferResample to shift pitch. factor>1 = higher+shorter.
reverb(room_size: float, damping: float, wet: float) -> SoundBufferApply simplified Freeverb-style reverb.
reverse() -> SoundBufferReverse the sample order.
sfxr(preset: str = None, seed: int = None, **params) -> SoundBufferGenerate retro sound effects using sfxr synthesis.
Returns: SoundBuffer with sfxr_params set for later mutation
sfxr_mutate(amount: float = 0.05, seed: int = None) -> SoundBufferJitter sfxr params and re-synthesize. Only works on sfxr-generated buffers.
slice(start: float, end: float) -> SoundBufferExtract a time range in seconds.
tone(frequency: float, duration: float, waveform: str = 'sine', ...) -> SoundBufferGenerate a tone with optional ADSR envelope.
Inherits from: Drawable
Sprite(pos=None, texture=None, sprite_index=0, **kwargs) A sprite UI element that displays a texture or portion of a texture atlas. Args: pos (tuple, optional): Position as (x, y) tuple. Default: (0, 0) texture (Texture, optional): Texture object to display. Default: default texture sprite_index (int, optional): Index into texture atlas. Default: 0 Keyword Args: scale (float): Uniform scale factor. Default: 1.0 scale_x (float): Horizontal scale factor. Default: 1.0 scale_y (float): Vertical scale factor. Default: 1.0 click (callable): Click event handler. Default: None visible (bool): Visibility state. Default: True opacity (float): Opacity (0.0-1.0). Default: 1.0 z_index (int): Rendering order. Default: 0 name (str): Element name for finding. Default: None x (float): X position override. Default: 0 y (float): Y position override. Default: 0 align (Alignment): Alignment relative to parent. Default: None margin (float): Margin from parent edge when aligned. Default: 0 horiz_margin (float): Horizontal margin override. Default: 0 (use margin) vert_margin (float): Vertical margin override. Default: 0 (use margin) Attributes: x, y (float): Position in pixels pos (Vector): Position as a Vector object texture (Texture): The texture being displayed sprite_index (int): Current sprite index in texture atlas scale (float): Uniform scale factor scale_x, scale_y (float): Individual scale factors click (callable): Click event handler visible (bool): Visibility state opacity (float): Opacity value z_index (int): Rendering order name (str): Element name w, h (float): Read-only computed size based on texture and scale align (Alignment): Alignment relative to parent (or None) margin (float): General margin for alignment horiz_margin (float): Horizontal margin override vert_margin (float): Vertical margin override
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
Texture(filename: str, sprite_width: int = 0, sprite_height: int = 0, display_size: tuple = None, display_origin: tuple = None) A texture atlas for sprites and tiles. Args: filename: Path to an image file (PNG, BMP, etc.). sprite_width: Width of each sprite cell in pixels (0 = full image). sprite_height: Height of each sprite cell in pixels (0 = full image). display_size: Optional (w, h) actual content size within each cell. display_origin: Optional (x, y) content offset within each cell. Properties: sprite_width, sprite_height (int, read-only): Cell dimensions. sheet_width, sheet_height (int, read-only): Grid dimensions in cells. sprite_count (int, read-only): Total number of sprite cells. source (str, read-only): File path used to load this texture. display_width, display_height (int, read-only): Content size within cells. display_offset_x, display_offset_y (int, read-only): Content offset within cells.
composite(layers: list[Texture], sprite_width: int, sprite_height: int, name: str = '') -> Texture Alpha-composite multiple texture layers into a single texture. Note:
Returns: Texture: New texture with all layers composited
Raises: ValueError: If layers have different dimensions or list is empty This is a class method. Uses Porter-Duff 'over' alpha compositing.
from_bytes(data: bytes, width: int, height: int, sprite_width: int, sprite_height: int, name: str = '') -> Texture Create a Texture from raw RGBA pixel data. Note:
Returns: Texture: New texture containing the pixel data
Raises: ValueError: If data length does not match width * height * 4 This is a class method. Useful for procedurally generated textures.
hsl_shift(hue_shift: float, sat_shift: float = 0.0, lit_shift: float = 0.0) -> TextureCreate a new texture with HSL color adjustments applied. Note:
Returns: Texture: New texture with color-shifted pixels Preserves alpha channel. Skips fully transparent pixels.
TileLayer(z_index=-1, name=None, texture=None, grid_size=None) A grid layer that stores sprite indices per cell for tile-based rendering. TileLayers can be created standalone and attached to a Grid via add_layer() or passed to the Grid constructor's layers parameter. Layers with size (0, 0) automatically resize to match the Grid when attached. Args: z_index (int): Render order relative to entities. Negative values render below entities (as backgrounds), positive values render above entities (as overlays). Default: -1 (background) name (str): Layer name for Grid.layer(name) lookup. Default: None texture (Texture): Sprite atlas containing tile images. The texture's sprite_size determines individual tile dimensions. Required for rendering; can be set after creation. Default: None grid_size (tuple): Dimensions as (width, height). If None or (0, 0), the layer will auto-resize when attached to a Grid. Default: None Attributes: z_index (int): Layer z-order relative to entities (read/write) name (str): Layer name for lookup (read-only) visible (bool): Whether layer is rendered (read/write) texture (Texture): Sprite atlas for tile images (read/write) grid_size (tuple): Layer dimensions as (width, height) (read-only) grid (Grid): Parent Grid or None. Setting manages layer association. Methods: at(x, y) -> int: Get the tile index at cell position (x, y) set(x, y, index): Set the tile index at cell position (x, y) fill(index): Fill the entire layer with a single tile index fill_rect(x, y, w, h, index): Fill a rectangular region with a tile index Tile Index Values: -1: No tile (transparent/empty cell) 0+: Index into the texture's sprite atlas (row-major order) Example: terrain = mcrfpy.TileLayer(z_index=-2, name='terrain', texture=tileset) grid = mcrfpy.Grid(grid_size=(20, 15), layers=[terrain]) terrain.fill(0) # Fill with tile index 0 grid.layer('terrain').set(5, 5, 42) # Place tile 42 at (5, 5)
apply_ranges(source, ranges) -> TileLayerApply multiple tile assignments in a single pass. Note:
Returns: self for method chaining Later ranges override earlier ones if overlapping. Cells not matching any range are left unchanged.
apply_threshold(source, range, tile) -> TileLayerSet tile index for cells where HeightMap value is within range.
Returns: self for method chaining
at(pos) -> intat(x, y) -> int Get the tile index at cell position. Returns -1 if no tile.
fill(index)Fill the entire layer with the specified tile index.
fill_rect(pos, size, index)Fill a rectangular region with a tile index.
set(pos, index)Set the tile index at cell position. Use -1 for no tile.
TileMapFile(path: str) Load a Tiled map file (.tmx or .tmj). Parses the map and its referenced tilesets, providing access to tile layers, object layers, and GID resolution. Args: path: Path to the .tmx or .tmj map file. Properties: width (int, read-only): Map width in tiles. height (int, read-only): Map height in tiles. tile_width (int, read-only): Tile width in pixels. tile_height (int, read-only): Tile height in pixels. orientation (str, read-only): Map orientation (e.g. 'orthogonal'). properties (dict, read-only): Custom map properties. tileset_count (int, read-only): Number of referenced tilesets. tile_layer_names (list, read-only): Names of tile layers. object_layer_names (list, read-only): Names of object layers. Example: tm = mcrfpy.TileMapFile('map.tmx') data = tm.tile_layer_data('Ground') tm.apply_to_tile_layer(my_tile_layer, 'Ground')
apply_to_tile_layer(tile_layer: TileLayer, layer_name: str, tileset_index: int = 0) -> NoneResolve GIDs and write sprite indices into a TileLayer.
object_layer(name: str) -> list[dict]Get objects from an object layer as Python dicts.
Returns: List of dicts with object properties (id, name, x, y, width, height, etc.).
Raises: KeyError: If no object layer with that name exists
resolve_gid(gid: int) -> tuple[int, int]Resolve a global tile ID to tileset index and local tile ID.
Returns: Tuple of (tileset_index, local_tile_id). (-1, -1) for empty/invalid.
tile_layer_data(name: str) -> list[int]Get raw global GID data for a tile layer.
Returns: Flat list of global GIDs (0 = empty tile).
Raises: KeyError: If no tile layer with that name exists
tileset(index: int) -> tuple[int, TileSetFile]Get a referenced tileset by index.
Returns: Tuple of (firstgid, TileSetFile).
TileSetFile(path: str) Load a Tiled tileset file (.tsx or .tsj). Parses the tileset and provides access to tile metadata, properties, Wang sets, and texture creation. Args: path: Path to the .tsx or .tsj tileset file. Properties: name (str, read-only): Tileset name. tile_width (int, read-only): Width of each tile in pixels. tile_height (int, read-only): Height of each tile in pixels. tile_count (int, read-only): Total number of tiles. columns (int, read-only): Number of columns in the tileset image. image_source (str, read-only): Resolved path to the tileset image. properties (dict, read-only): Custom properties from the tileset. wang_sets (list, read-only): List of WangSet objects. Example: ts = mcrfpy.TileSetFile('tileset.tsx') texture = ts.to_texture() print(f'{ts.name}: {ts.tile_count} tiles')
tile_info(tile_id: int) -> dict | NoneGet metadata for a specific tile.
Returns: Dict with 'properties' and 'animation' keys, or None if no metadata.
to_texture() -> TextureCreate a Texture from the tileset image.
Returns: A Texture object for use with TileLayer.
wang_set(name: str) -> WangSetLook up a WangSet by name.
Returns: The WangSet object.
Raises: KeyError: If no WangSet with that name exists
Timer(name, callback, interval, once=False, start=True) Create a timer that calls a function at regular intervals. Args: name (str): Unique identifier for the timer callback (callable): Function to call - receives (timer, runtime) args interval (int): Time between calls in milliseconds once (bool): If True, timer stops after first call. Default: False start (bool): If True, timer starts immediately. Default: True Attributes: interval (int): Time between calls in milliseconds remaining (int): Time until next call in milliseconds (read-only) paused (bool): Whether timer is paused (read-only) stopped (bool): Whether timer is stopped (read-only) active (bool): Running state (read-write). Set True to start, False to pause callback (callable): The callback function (preserved when stopped) once (bool): Whether timer stops after firing once Methods: start(): Start the timer, adding to engine tick loop stop(): Stop the timer (removes from engine, preserves callback) pause(): Pause the timer, preserving time remaining resume(): Resume a paused timer restart(): Reset timer and ensure it's running Example: def on_timer(timer, runtime): print(f'Timer {timer} fired at {runtime}ms') if runtime > 5000: timer.stop() # Stop but can restart later timer = mcrfpy.Timer('my_timer', on_timer, 1000) timer.pause() # Pause timer timer.resume() # Resume timer timer.stop() # Stop completely timer.start() # Restart from beginning
pause() -> NonePause the timer, preserving the time remaining until next trigger. Note:
Returns: None The timer can be resumed later with resume(). Time spent paused does not count toward the interval.
restart() -> NoneRestart the timer from the beginning and ensure it's running. Note:
Returns: None Resets progress and adds timer to engine if stopped. Equivalent to stop() followed by start().
resume() -> NoneResume a paused timer from where it left off. Note:
Returns: None Has no effect if the timer is not paused. Timer will fire after the remaining time elapses.
start() -> NoneStart the timer, adding it to the engine tick loop. Note:
Returns: None Resets progress and begins counting toward the next fire. If another timer has this name, it will be stopped.
stop() -> NoneStop the timer and remove it from the engine tick loop. Note:
Returns: None The callback is preserved, so the timer can be restarted with start() or restart().
Inherits from: IntEnum
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Inherits from: IntEnum
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Inherits from: IntEnum
Enum representing trigger types passed to entity step() callbacks. Values: DONE: Behavior completed (path exhausted, sleep finished, etc.) BLOCKED: Movement blocked by wall or collision TARGET: Target entity spotted in FOV
as_integer_ratio(...)Return a pair of integers, whose ratio is equal to the original int. The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) >>> (-10).as_integer_ratio() (-10, 1) >>> (0).as_integer_ratio() (0, 1)
bit_count(...)Number of ones in the binary representation of the absolute value of self. Also known as the population count. >>> bin(13) '0b1101' >>> (13).bit_count() 3
bit_length(...)Number of bits necessary to represent self in binary. >>> bin(37) '0b100101' >>> (37).bit_length() 6
conjugate(...)Returns self, the complex conjugate of any int.
from_bytes(...)Return the integer represented by the given array of bytes. bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Indicates whether two's complement is used to represent the integer.
is_integer(...)Returns True. Exists for duck type compatibility with float.is_integer.
to_bytes(...)Return an array of bytes representing an integer. length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use 'big'. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Vector(x: float = 0, y: float = 0) 2D vector for positions, sizes, and directions. Args: x: X component. y: Y component. Supports arithmetic (+, -, *, /), abs(), len() == 2, indexing ([0] for x, [1] for y), hashing, and equality. Properties: x (float): X component. y (float): Y component. int (tuple[int, int], read-only): Integer floor of (x, y).
angle() -> floatGet the angle of this vector in radians.
Returns: float: Angle in radians from positive x-axis
copy() -> VectorCreate a copy of this vector.
Returns: Vector: New Vector object with same x and y values
distance_to(other: Vector) -> floatCalculate the distance to another vector.
Returns: float: Distance between the two vectors
dot(other: Vector) -> floatCalculate the dot product with another vector.
Returns: float: Dot product of the two vectors
floor() -> VectorReturn a new vector with floored (integer) coordinates. Note:
Returns: Vector: New Vector with floor(x) and floor(y) Useful for grid-based positioning. For a hashable tuple, use the .int property instead.
magnitude() -> floatCalculate the length/magnitude of this vector.
Returns: float: The magnitude of the vector
magnitude_squared() -> floatCalculate the squared magnitude of this vector. Note:
Returns: float: The squared magnitude (faster than magnitude()) Use this for comparisons to avoid expensive square root calculation.
normalize() -> VectorReturn a unit vector in the same direction. Note:
Returns: Vector: New normalized vector with magnitude 1.0 For zero vectors (magnitude 0.0), returns a zero vector rather than raising an exception
Inherits from: Drawable
Viewport3D(pos=None, size=None, **kwargs) A 3D rendering viewport that displays a 3D scene as a UI element. Args: pos (tuple, optional): Position as (x, y) tuple. Default: (0, 0) size (tuple, optional): Display size as (width, height). Default: (320, 240) Keyword Args: render_resolution (tuple): Internal render resolution (width, height). Default: (320, 240) fov (float): Camera field of view in degrees. Default: 60 camera_pos (tuple): Camera position (x, y, z). Default: (0, 0, 5) camera_target (tuple): Camera look-at point (x, y, z). Default: (0, 0, 0) bg_color (Color): Background clear color. Default: (25, 25, 50) enable_vertex_snap (bool): PS1-style vertex snapping. Default: True enable_affine (bool): PS1-style affine texture mapping. Default: True enable_dither (bool): PS1-style color dithering. Default: True enable_fog (bool): Distance fog. Default: True fog_color (Color): Fog color. Default: (128, 128, 153) fog_near (float): Fog start distance. Default: 10 fog_far (float): Fog end distance. Default: 100
add_billboard(billboard)Add a Billboard to the viewport.
add_layer(name, z_index=0) -> dictAdd a new mesh layer to the viewport.
add_mesh(layer_name, model, pos, rotation=0, scale=1.0) -> intAdd a Model3D instance to a layer at the specified position.
Returns: Index of the mesh instance
add_voxel_layer(voxel_grid, z_index=0)Add a VoxelGrid as a renderable layer.
animate(property: str, target: Any, duration: float, easing=None, delta=False, loop=False, callback=None, conflict_mode='replace') -> AnimationCreate and start an animation on this drawable's property. Note:
Returns: Animation object for monitoring progress
Raises: ValueError: If property name is not valid for this drawable type This is a convenience method that creates an Animation, starts it, and adds it to the AnimationManager.
apply_heightmap(heightmap, y_scale=1.0)Set cell heights from HeightMap.
apply_terrain_colors(layer_name, r_map, g_map, b_map)Apply per-vertex colors to terrain from RGB HeightMaps.
apply_threshold(heightmap, min_height, max_height, walkable=True)Set cell walkability based on height thresholds.
at(x, z) -> VoxelPointGet VoxelPoint at grid coordinates.
Returns: VoxelPoint object for the cell
billboard_count() -> intGet the number of billboards.
Returns: Number of billboards in the viewport
build_terrain(layer_name, heightmap, y_scale=1.0, cell_size=1.0) -> intBuild terrain mesh from HeightMap on specified layer.
Returns: Number of vertices in the generated mesh
clear_billboards()Remove all billboards from the viewport.
clear_meshes(layer_name)Clear all mesh instances from a layer.
clear_voxel_nav_region(voxel_grid)Clear navigation cells in a voxel grid's footprint. Resets walkability, transparency, height, and cost to defaults for all nav cells corresponding to the voxel grid's XZ extent.
compute_fov(origin, radius=10) -> listCompute field of view from a position.
Returns: List of visible (x, z) positions
find_path(start, end) -> listFind A* path between two points.
Returns: List of (x, z) tuples forming the path, or empty list if no path
follow(entity, distance=10, height=5, smoothing=1.0)Position camera to follow an entity.
get_billboard(index) -> BillboardGet a Billboard by index.
Returns: Billboard object
get_layer(name) -> dict or NoneGet a layer by name.
is_in_fov(x, z) -> boolCheck if a cell is in the current FOV (after compute_fov).
Returns: True if the cell is visible
layer_count() -> intGet the number of mesh layers.
move(dx, dy) or (delta) -> NoneMove the element by a relative offset. Note:
orbit_camera(angle=0, distance=10, height=5)Position camera to orbit around origin.
place_blocking(grid_pos, footprint, walkable=False, transparent=False)Mark grid cells as blocking for pathfinding and FOV.
project_all_voxels_to_nav(headroom=2)Project all voxel layers to the navigation grid. Resets navigation grid and projects each voxel layer in z_index order. Later layers (higher z_index) overwrite earlier ones.
project_voxel_to_nav(voxel_grid, headroom=2)Project a VoxelGrid to the navigation grid. Scans each column of the voxel grid and updates corresponding navigation cells with walkability, transparency, height, and cost.
realign() -> NoneReapply alignment relative to parent, useful for responsive layouts. Note: Call this to recalculate position after parent changes size. For elements with align=None, this has no effect.
remove_billboard(billboard)Remove a Billboard from the viewport.
remove_layer(name) -> boolRemove a layer by name. Returns True if found and removed.
remove_voxel_layer(voxel_grid) -> boolRemove a VoxelGrid layer from the viewport.
Returns: True if the layer was found and removed
resize(width, height) or (size) -> NoneResize the element to new dimensions. Note:
screen_to_world(x, y, y_plane=0.0) -> tuple or NoneConvert screen coordinates to world position via ray casting.
Returns: (x, y, z) world position tuple, or None if no intersection with the plane
set_grid_size(width, depth)Initialize navigation grid with specified dimensions.
set_slope_cost(max_slope=0.5, cost_multiplier=1.0)Calculate slope costs and mark steep cells unwalkable.
voxel_layer_count() -> intGet the number of voxel layers.
Returns: Number of voxel layers in the viewport
VoxelGrid(size: tuple[int, int, int], cell_size: float = 1.0) A dense 3D grid of voxel material IDs with a material palette. VoxelGrids provide volumetric storage for 3D structures like buildings, caves, and dungeon walls. Each cell stores a uint8 material ID (0-255), where 0 is always air. Args: size: (width, height, depth) dimensions. Immutable after creation. cell_size: World units per voxel. Default 1.0. Properties: size (tuple, read-only): Grid dimensions as (width, height, depth) width, height, depth (int, read-only): Individual dimensions cell_size (float, read-only): World units per voxel offset (tuple): World-space position (x, y, z) rotation (float): Y-axis rotation in degrees material_count (int, read-only): Number of defined materials Example: voxels = mcrfpy.VoxelGrid(size=(16, 8, 16), cell_size=1.0) stone = voxels.add_material('stone', color=mcrfpy.Color(128, 128, 128)) voxels.set(5, 0, 5, stone) assert voxels.get(5, 0, 5) == stone print(f'Non-air voxels: {voxels.count_non_air()}')
add_material(name, color=Color(255,255,255), sprite_index=-1, transparent=False, path_cost=1.0) -> intAdd a new material to the palette. Returns the material ID (1-indexed). Material 0 is always air (implicit, never stored in palette). Maximum 255 materials can be added.
clear() -> NoneClear the grid (fill with air, material 0).
copy_region(min_coord, max_coord) -> VoxelRegionCopy a rectangular region to a VoxelRegion prefab.
Returns: VoxelRegion object that can be pasted elsewhere.
count_material(material) -> intCount the number of voxels with the specified material ID.
count_non_air() -> intCount the number of non-air voxels in the grid.
fill(material) -> NoneFill the entire grid with the specified material ID.
fill_box(min_coord, max_coord, material) -> NoneFill a rectangular region with the specified material.
fill_box_hollow(min_coord, max_coord, material, thickness=1) -> NoneCreate a hollow rectangular room (walls only, hollow inside).
fill_cylinder(base_pos, radius, height, material) -> NoneFill a vertical cylinder (Y-axis aligned).
fill_noise(min_coord, max_coord, material, threshold=0.5, scale=0.1, seed=0) -> NoneFill region with 3D noise-based pattern (caves, clouds).
fill_sphere(center, radius, material) -> NoneFill a spherical region.
from_bytes(data) -> boolLoad voxel data from a bytes object. Note: This replaces the current grid data entirely.
Returns: True on success, False on failure.
get(x, y, z) -> intGet the material ID at integer coordinates. Returns 0 (air) for out-of-bounds coordinates.
get_material(id) -> dictGet material properties by ID. Returns dict with keys: name, color, sprite_index, transparent, path_cost. ID 0 returns the implicit air material.
load(path) -> boolLoad voxel data from a binary file. Note: This replaces the current grid data entirely, including
Returns: True on success, False on failure. dimensions and material palette.
paste_region(region, position, skip_air=True) -> NonePaste a VoxelRegion prefab at the specified position.
project_column(x, z, headroom=2) -> dictProject a single column to navigation info. Scans the column from top to bottom, finding the topmost floor (solid voxel with air above) and checking for adequate headroom.
Returns: dict with keys: height (float): World Y of floor surface walkable (bool): True if floor found with adequate headroom transparent (bool): True if no opaque voxels in column path_cost (float): Floor material's path cost
rebuild_mesh() -> NoneForce immediate mesh rebuild for rendering.
save(path) -> boolSave the voxel grid to a binary file.
Returns: True on success, False on failure. The file format includes grid dimensions, cell size, material palette, and RLE-compressed voxel data.
set(x, y, z, material) -> NoneSet the material ID at integer coordinates. Out-of-bounds coordinates are silently ignored.
to_bytes() -> bytesSerialize the voxel grid to a bytes object.
Returns: bytes object containing the serialized grid data. Useful for network transmission or custom storage.
VoxelRegion - Portable voxel data for copy/paste operations. Created by VoxelGrid.copy_region(), used with paste_region(). Cannot be instantiated directly. Properties: size (tuple, read-only): Dimensions as (width, height, depth) width, height, depth (int, read-only): Individual dimensions
WangSet - Wang terrain auto-tile set from a Tiled tileset. WangSets are obtained from TileSetFile.wang_sets or TileSetFile.wang_set(). They map abstract terrain types to concrete sprite indices using Tiled's Wang tile algorithm. Properties: name (str, read-only): Wang set name. type (str, read-only): 'corner', 'edge', or 'mixed'. color_count (int, read-only): Number of terrain colors. colors (list, read-only): List of color dicts. Example: ws = tileset.wang_set('overworld') Terrain = ws.terrain_enum() tiles = ws.resolve(discrete_map)
apply(discrete_map: DiscreteMap, tile_layer: TileLayer) -> NoneResolve terrain and write tile indices directly into a TileLayer.
resolve(discrete_map: DiscreteMap) -> list[int]Resolve terrain data to tile indices using Wang tile rules.
Returns: List of tile IDs (one per cell). -1 means no matching Wang tile.
terrain_enum() -> IntEnumGenerate a Python IntEnum from this WangSet's terrain colors.
Returns: IntEnum class with NONE=0 and one member per color (UPPER_SNAKE_CASE).
Window singleton for accessing and modifying the game window properties
center() -> NoneCenter the window on the screen. Note:
Returns: None Only works in windowed mode. Has no effect when fullscreen or in headless mode.
get() -> WindowGet the Window singleton instance. Note:
Returns: Window: The global window object This is a class method. Call as Window.get(). There is only one window instance per application.
screenshot(filename: str = None) -> bytes | NoneTake a screenshot of the current window contents. Note:
Returns: bytes | None: Raw RGBA pixel data if no filename given, otherwise None after saving Screenshot is taken at the actual window resolution. Use after render loop update for current frame.