McRogueFace/docs/api_reference_complete.html

1602 lines
53 KiB
HTML
Raw Normal View History

Squashed commit of 53 Commits: [alpha_streamline_2] * Field of View, Pathing courtesy of libtcod * python-tcod emulation at `mcrfpy.libtcod` - partial implementation * documentation, tutorial drafts: in middling to good shape ┌────────────┬────────────────────┬───────────┬────────────┬───────────────┬────────────────┬────────────────┬─────────────┐ │ Date │ Models │ Input │ Output │ Cache Create │ Cache Read │ Total Tokens │ Cost (USD) │ ├────────────┼────────────────────┼───────────┼────────────┼───────────────┼────────────────┼────────────────┼─────────────┤ │ 2025-07-05 │ - opus-4 │ 13,630 │ 159,500 │ 3,854,900 │ 84,185,034 │ 88,213,064 │ $210.72 │ ├────────────┼────────────────────┼───────────┼────────────┼───────────────┼────────────────┼────────────────┼─────────────┤ │ 2025-07-06 │ - opus-4 │ 5,814 │ 113,190 │ 4,242,407 │ 150,191,183 │ 154,552,594 │ $313.41 │ ├────────────┼────────────────────┼───────────┼────────────┼───────────────┼────────────────┼────────────────┼─────────────┤ │ 2025-07-07 │ - opus-4 │ 7,244 │ 104,599 │ 3,894,453 │ 81,781,179 │ 85,787,475 │ $184.46 │ │ │ - sonnet-4 │ │ │ │ │ │ │ ├────────────┼────────────────────┼───────────┼────────────┼───────────────┼────────────────┼────────────────┼─────────────┤ │ 2025-07-08 │ - opus-4 │ 50,312 │ 158,599 │ 5,021,189 │ 60,028,561 │ 65,258,661 │ $167.05 │ │ │ - sonnet-4 │ │ │ │ │ │ │ ├────────────┼────────────────────┼───────────┼────────────┼───────────────┼────────────────┼────────────────┼─────────────┤ │ 2025-07-09 │ - opus-4 │ 6,311 │ 109,653 │ 4,171,140 │ 80,092,875 │ 84,379,979 │ $193.09 │ │ │ - sonnet-4 │ │ │ │ │ │ │ └────────────┴────────────────────┴───────────┴────────────┴───────────────┴────────────────┴────────────────┴─────────────┘ 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> Author: John McCardle <mccardle.john@gmail.com> Draft tutorials Author: John McCardle <mccardle.john@gmail.com> docs: update ROADMAP with FOV, A* pathfinding, and GUI text widget completions - Mark TCOD Integration Sprint as complete - Document FOV system with perspective rendering implementation - Update UIEntity pathfinding status to complete with A* and caching - Add comprehensive achievement entry for July 10 work - Reflect current engine capabilities accurately The engine now has all core roguelike mechanics: - Field of View with per-entity visibility - Pathfinding (both Dijkstra and A*) - Text input for in-game consoles - Performance optimizations throughout Author: John McCardle <mccardle.john@gmail.com> feat(engine): implement perspective FOV, pathfinding, and GUI text widgets Major Engine Enhancements: - Complete FOV (Field of View) system with perspective rendering - UIGrid.perspective property for entity-based visibility - Three-layer overlay colors (unexplored, explored, visible) - Per-entity visibility state tracking - Perfect knowledge updates only for explored areas - Advanced Pathfinding Integration - A* pathfinding implementation in UIGrid - Entity.path_to() method for direct pathfinding - Dijkstra maps for multi-target pathfinding - Path caching for performance optimization - GUI Text Input Widgets - TextInputWidget class with cursor, selection, scrolling - Improved widget with proper text rendering and input handling - Example showcase of multiple text input fields - Foundation for in-game console and chat systems - Performance & Architecture Improvements - PyTexture copy operations optimized - GameEngine update cycle refined - UIEntity property handling enhanced - UITestScene modernized Test Suite: - Interactive visibility demos showing FOV in action - Pathfinding comparison (A* vs Dijkstra) - Debug utilities for visibility and empty path handling - Sizzle reel demo combining pathfinding and vision - Multiple text input test scenarios This commit brings McRogueFace closer to a complete roguelike engine with essential features like line-of-sight, intelligent pathfinding, and interactive text input capabilities. Author: John McCardle <mccardle.john@gmail.com> feat(demos): enhance interactive pathfinding demos with entity.path_to() - dijkstra_interactive_enhanced.py: Animation along paths with smooth movement - M key to start movement animation - P to pause/resume - R to reset positions - Visual path gradient for better clarity - pathfinding_showcase.py: Advanced multi-entity behaviors - Chase mode: enemies pursue player - Flee mode: enemies avoid player - Patrol mode: entities follow waypoints - WASD player movement - Dijkstra distance field visualization (D key) - Larger dungeon map with multiple rooms - Both demos use new entity.path_to() method - Smooth interpolated movement animations - Real-time pathfinding recalculation - Comprehensive test coverage These demos showcase the power of integrated pathfinding for game AI. Author: John McCardle <mccardle.john@gmail.com> feat(entity): implement path_to() method for entity pathfinding - Add path_to(target_x, target_y) method to UIEntity class - Uses existing Dijkstra pathfinding implementation from UIGrid - Returns list of (x, y) coordinate tuples for complete path - Supports both positional and keyword argument formats - Proper error handling for out-of-bounds and no-grid scenarios - Comprehensive test suite covering normal and edge cases Part of TCOD integration sprint - gives entities immediate pathfinding capabilities. Author: John McCardle <mccardle.john@gmail.com> docs: update roadmap with Dijkstra pathfinding progress - Mark UIGrid TCOD Integration as completed - Document critical PyArg bug fix achievement - Update UIEntity Pathfinding to 50% complete - Add detailed progress notes for July 9 sprint work Author: John McCardle <mccardle.john@gmail.com> feat(tcod): complete Dijkstra pathfinding implementation with critical PyArg fix - Add complete Dijkstra pathfinding to UIGrid class - compute_dijkstra(), get_dijkstra_distance(), get_dijkstra_path() - Full TCODMap and TCODDijkstra integration - Proper memory management in constructors/destructors - Create mcrfpy.libtcod submodule with Python bindings - dijkstra_compute(), dijkstra_get_distance(), dijkstra_get_path() - line() function for drawing corridors - Foundation for future FOV and pathfinding algorithms - Fix critical PyArg bug in UIGridPoint color setter - PyObject_to_sfColor() now handles both Color objects and tuples - Prevents "SystemError: new style getargs format but argument is not a tuple" - Proper error handling and exception propagation - Add comprehensive test suite - test_dijkstra_simple.py validates all pathfinding operations - dijkstra_test.py for headless testing with screenshots - dijkstra_interactive.py for full user interaction demos - Consolidate and clean up test files - Removed 6 duplicate/broken demo attempts - Two clean versions: headless test + interactive demo Part of TCOD integration sprint for RoguelikeDev Tutorial Event. Author: John McCardle <mccardle.john@gmail.com> Roguelike Tutorial Planning + Prep Author: John McCardle <mccardle.john@gmail.com> feat(docs): complete markdown API documentation export - Created comprehensive markdown documentation matching HTML completeness - Documented all 75 functions, 20 classes, 56 methods, and 20 automation methods - Zero ellipsis instances - complete coverage with no missing documentation - Added proper markdown formatting with code blocks and navigation - Included full parameter documentation, return values, and examples Key features: - 23KB GitHub-compatible markdown documentation - 47 argument sections with detailed parameters - 35 return value specifications - 23 code examples with syntax highlighting - 38 explanatory notes and 10 exception specifications - Full table of contents with anchor links - Professional markdown formatting Both export formats now available: - HTML: docs/api_reference_complete.html (54KB, rich styling) - Markdown: docs/API_REFERENCE_COMPLETE.md (23KB, GitHub-compatible) Author: John McCardle <mccardle.john@gmail.com> feat(docs): complete API documentation with zero missing methods - Eliminated ALL ellipsis instances (0 remaining) - Documented 40 functions with complete signatures and examples - Documented 21 classes with full method and property documentation - Added 56 method descriptions with detailed parameters and return values - Included 15 complete property specifications - Added 24 code examples and 38 explanatory notes - Comprehensive coverage of all collection methods, system classes, and functions Key highlights: - EntityCollection/UICollection: Complete method docs (append, remove, extend, count, index) - Animation: Full property and method documentation with examples - Color: All manipulation methods (from_hex, to_hex, lerp) with examples - Vector: Complete mathematical operations (magnitude, normalize, dot, distance_to, angle, copy) - Scene: All management methods including register_keyboard - Timer: Complete control methods (pause, resume, cancel, restart) - Window: All management methods (get, center, screenshot) - System functions: Complete audio, scene, UI, and system function documentation Author: John McCardle <mccardle.john@gmail.com> feat(docs): create professional HTML API documentation - Fixed all formatting issues from original HTML output - Added comprehensive constructor documentation for all classes - Enhanced visual design with modern styling and typography - Fixed literal newline display and markdown link conversion - Added proper semantic HTML structure and navigation - Includes detailed documentation for Entity, collections, and system types Author: John McCardle <mccardle.john@gmail.com> feat: complete API reference generator and finish Phase 7 documentation Implemented comprehensive API documentation generator that: - Introspects live mcrfpy module for accurate documentation - Generates organized Markdown reference (docs/API_REFERENCE.md) - Categorizes classes and functions by type - Includes full automation module documentation - Provides summary statistics Results: - 20 classes documented - 19 module functions documented - 20 automation methods documented - 100% coverage of public API - Clean, readable Markdown output Phase 7 Summary: - Completed 4/5 tasks (1 cancelled as architecturally inappropriate) - All documentation tasks successful - Type stubs, docstrings, and API reference all complete Author: John McCardle <mccardle.john@gmail.com> docs: cancel PyPI wheel task and add future vision for Python extension architecture Task #70 Analysis: - Discovered fundamental incompatibility with PyPI distribution - McRogueFace embeds CPython rather than being loaded by it - Traditional wheels expect to extend existing Python interpreter - Current architecture is application-with-embedded-Python Decisions: - Cancelled PyPI wheel preparation as out of scope for Alpha - Cleaned up attempted packaging files (pyproject.toml, setup.py, etc.) - Identified better distribution methods (installers, package managers) Added Future Vision: - Comprehensive plan for pure Python extension architecture - Would allow true "pip install mcrogueface" experience - Requires major refactoring to invert control flow - Python would drive main loop with C++ performance extensions - Unscheduled but documented as long-term possibility This clarifies the architectural boundaries and sets realistic expectations for distribution methods while preserving the vision of what McRogueFace could become with significant rework. Author: John McCardle <mccardle.john@gmail.com> feat: generate comprehensive .pyi type stubs for IDE support (#108) Created complete type stub files for the mcrfpy module to enable: - Full IntelliSense/autocomplete in IDEs - Static type checking with mypy/pyright - Better documentation tooltips - Parameter hints and return types Implementation details: - Manually crafted stubs for accuracy (15KB, 533 lines) - Complete coverage: 19 classes, 112 functions/methods - Proper type annotations using typing module - @overload decorators for multiple signatures - Type aliases for common patterns (UIElement union) - Preserved all docstrings for IDE help - Automation module fully typed - PEP 561 compliant with py.typed marker Testing: - Validated Python syntax with ast.parse() - Verified all expected classes and functions - Confirmed type annotations are well-formed - Checked docstring preservation (80 docstrings) Usage: - VS Code: Add stubs/ to python.analysis.extraPaths - PyCharm: Mark stubs/ directory as Sources Root - Other IDEs will auto-detect .pyi files This significantly improves the developer experience when using McRogueFace as a Python game engine. Author: John McCardle <mccardle.john@gmail.com> docs: add comprehensive parameter documentation to all API methods (#86) Enhanced documentation for the mcrfpy module with: - Detailed docstrings for all API methods - Type hints in documentation (name: type format) - Return type specifications - Exception documentation where applicable - Usage examples for complex methods - Module-level documentation with overview and example code Specific improvements: - Audio API: Added parameter types and return values - Scene API: Documented transition types and error conditions - Timer API: Clarified handler signature and runtime parameter - UI Search: Added wildcard pattern examples for findAll() - Metrics API: Documented all dictionary keys returned Also fixed method signatures: - Changed METH_VARARGS to METH_NOARGS for parameterless methods - Ensures proper Python calling conventions Test coverage included - all documentation is accessible via Python's __doc__ attributes and shows correctly formatted information. Author: John McCardle <mccardle.john@gmail.com> docs: mark issue #85 as completed in Phase 7 Author: John McCardle <mccardle.john@gmail.com> docs: replace all 'docstring' placeholders with comprehensive documentation (#85) Added proper Python docstrings for all UI component classes: UIFrame: - Container element that can hold child drawables - Documents position, size, colors, outline, and clip_children - Includes constructor signature with all parameters UICaption: - Text display element with font and styling - Documents text content, position, font, colors, outline - Notes that w/h are computed from text content UISprite: - Texture/sprite display element - Documents position, texture, sprite_index, scale - Notes that w/h are computed from texture and scale UIGrid: - Tile-based grid for game worlds - Documents grid dimensions, tile size, texture atlas - Includes entities collection and background_color All docstrings follow consistent format: - Constructor signature with defaults - Brief description - Args section with types and defaults - Attributes section with all properties This completes Phase 7 task #85 for documentation improvements. Author: John McCardle <mccardle.john@gmail.com> docs: update ROADMAP with PyArgHelpers infrastructure completion Author: John McCardle <mccardle.john@gmail.com> refactor: implement PyArgHelpers for standardized Python argument parsing This major refactoring standardizes how position, size, and other arguments are parsed across all UI components. PyArgHelpers provides consistent handling for various argument patterns: - Position as (x, y) tuple or separate x, y args - Size as (w, h) tuple or separate width, height args - Grid position and size with proper validation - Color parsing with PyColorObject support Changes across UI components: - UICaption: Migrated to PyArgHelpers, improved resize() for future multiline support - UIFrame: Uses standardized position parsing - UISprite: Consistent position handling - UIGrid: Grid-specific position/size helpers - UIEntity: Unified argument parsing Also includes: - Improved error messages for type mismatches (int or float accepted) - Reduced code duplication across constructors - Better handling of keyword/positional argument conflicts - Maintains backward compatibility with existing API This addresses the inconsistent argument handling patterns discovered during the inheritance hierarchy work and prepares for Phase 7 documentation. Author: John McCardle <mccardle.john@gmail.com> feat(Python): establish proper inheritance hierarchy for UI types All UIDrawable-derived Python types now properly inherit from the Drawable base class in Python, matching the C++ inheritance structure. Changes: - Add Py_TPFLAGS_BASETYPE to PyDrawableType to allow inheritance - Set tp_base = &mcrfpydef::PyDrawableType for all UI types - Add PyDrawable.h include to UI type headers - Rename _Drawable to Drawable and update error message This enables proper Python inheritance: Frame, Caption, Sprite, Grid, and Entity all inherit from Drawable, allowing shared functionality and isinstance() checks. Author: John McCardle <mccardle.john@gmail.com> refactor: move position property to UIDrawable base class (UISprite) - Update UISprite to use base class position instead of sprite position - Synchronize sprite position with base class position for rendering - Implement onPositionChanged() for position synchronization - Update all UISprite methods to use base position consistently - Add comprehensive test coverage for UISprite position handling This is part 3 of moving position to the base class. UIGrid is the final class that needs to be updated. Author: John McCardle <mccardle.john@gmail.com> refactor: move position property to UIDrawable base class (UICaption) - Update UICaption to use base class position instead of text position - Synchronize text position with base class position for rendering - Add onPositionChanged() virtual method for position synchronization - Update all UICaption methods to use base position consistently - Add comprehensive test coverage for UICaption position handling This is part 2 of moving position to the base class. UISprite and UIGrid will be updated in subsequent commits. Author: John McCardle <mccardle.john@gmail.com> refactor: move position property to UIDrawable base class (UIFrame) - Add position member to UIDrawable base class - Add common position getters/setters (x, y, pos) to base class - Update UIFrame to use base class position instead of box position - Synchronize box position with base class position for rendering - Update all UIFrame methods to use base position consistently - Add comprehensive test coverage for UIFrame position handling This is part 1 of moving position to the base class. Other derived classes (UICaption, UISprite, UIGrid) will be updated in subsequent commits. Author: John McCardle <mccardle.john@gmail.com> refactor: remove UIEntity collision_pos field - Remove redundant collision_pos field from UIEntity - Update position getters/setters to use integer-cast position when needed - Remove all collision_pos synchronization code - Simplify entity position handling to use single float position field - Add comprehensive test coverage proving functionality is preserved This removes technical debt and simplifies the codebase without changing API behavior. Author: John McCardle <mccardle.john@gmail.com> feat: add PyArgHelpers infrastructure for standardized argument parsing - Create PyArgHelpers.h with parsing functions for position, size, grid coordinates, and color - Support tuple-based vector arguments with conflict detection - Provide consistent error messages and validation - Add comprehensive test coverage for infrastructure This sets the foundation for standardizing all Python API constructors. Author: John McCardle <mccardle.john@gmail.com> docs: mark Phase 6 (Rendering Revolution) as complete Phase 6 is now complete with all core rendering features implemented: Completed Features: - Grid background colors (#50) - customizable backgrounds with animation - RenderTexture overhaul (#6) - UIFrame clipping with opt-in architecture - Viewport-based rendering (#8) - three scaling modes with coordinate transform Strategic Decisions: - UIGrid already has optimal RenderTexture implementation for its viewport needs - UICaption/UISprite clipping deemed unnecessary (no children to clip) - Effects/Shader/Particle systems deferred to post-Phase 7 for focused delivery The rendering foundation is now solid and ready for Phase 7: Documentation & Distribution. Author: John McCardle <mccardle.john@gmail.com> feat(viewport): complete viewport-based rendering system (#8) Implements a comprehensive viewport system that allows fixed game resolution with flexible window scaling, addressing the primary wishes for issues #34, #49, and #8. Key Features: - Fixed game resolution independent of window size (window.game_resolution property) - Three scaling modes accessible via window.scaling_mode: - "center": 1:1 pixels, viewport centered in window - "stretch": viewport fills window, ignores aspect ratio - "fit": maintains aspect ratio with black bars - Automatic window-to-game coordinate transformation for mouse input - Full Python API integration with PyWindow properties Technical Implementation: - GameEngine::ViewportMode enum with Center, Stretch, Fit modes - SFML View system for efficient GPU-based viewport scaling - updateViewport() recalculates on window resize or mode change - windowToGameCoords() transforms mouse coordinates correctly - PyScene mouse input automatically uses transformed coordinates Tests: - test_viewport_simple.py: Basic API functionality - test_viewport_visual.py: Visual verification with screenshots - test_viewport_scaling.py: Interactive mode switching and resizing This completes the viewport-based rendering task and provides the foundation for resolution-independent game development as requested for Crypt of Sokoban. Author: John McCardle <mccardle.john@gmail.com> docs: update ROADMAP for Phase 6 progress - Marked Phase 6 as IN PROGRESS - Updated RenderTexture overhaul (#6) as PARTIALLY COMPLETE - Marked Grid background colors (#50) as COMPLETED - Added technical notes from implementation experience - Identified viewport rendering (#8) as next priority Author: John McCardle <mccardle.john@gmail.com> feat(rendering): implement RenderTexture base infrastructure and UIFrame clipping (#6) - Added RenderTexture support to UIDrawable base class - std::unique_ptr<sf::RenderTexture> for opt-in rendering - Dirty flag system for optimization - enableRenderTexture() and markDirty() methods - Implemented clip_children property for UIFrame - Python-accessible boolean property - Automatic RenderTexture creation when enabled - Proper coordinate transformation for nested frames - Updated UIFrame::render() for clipping support - Renders to RenderTexture when clip_children=true - Handles nested clipping correctly - Only re-renders when dirty flag is set - Added comprehensive dirty flag propagation - All property setters mark frame as dirty - Size changes recreate RenderTexture - Animation system integration - Created tests for clipping functionality - Basic clipping test with visual verification - Advanced nested clipping test - Dynamic resize handling test This is Phase 1 of the RenderTexture overhaul, providing the foundation for advanced rendering effects like blur, glow, and viewport rendering. Author: John McCardle <mccardle.john@gmail.com> docs: create RenderTexture overhaul design document - Comprehensive design for Issue #6 implementation - Opt-in architecture to maintain backward compatibility - Phased implementation plan with clear milestones - Performance considerations and risk mitigation - API design for clipping and future effects Also includes Grid background color test Author: John McCardle <mccardle.john@gmail.com> feat(Grid): add customizable background_color property (#50) - Added sf::Color background_color member with default dark gray - Python property getter/setter for background_color - Animation support for individual color components (r/g/b/a) - Replaces hardcoded clear color in render method - Test demonstrates color changes and property access Closes #50 Author: John McCardle <mccardle.john@gmail.com> docs: update roadmap for Phase 6 preparation - Mark Phase 5 (Window/Scene Architecture) as complete - Update issue statuses (#34, #61, #1, #105 completed) - Add Phase 6 implementation strategy for RenderTexture overhaul - Archive Phase 5 test files to .archive/ - Identify quick wins and technical approach for rendering work Author: John McCardle <mccardle.john@gmail.com> feat(Phase 5): Complete Window/Scene Architecture - Window singleton with properties (resolution, fullscreen, vsync, title) - OOP Scene support with lifecycle methods (on_enter, on_exit, on_keypress, update) - Window resize events trigger scene.on_resize callbacks - Scene transitions (fade, slide_left/right/up/down) with smooth animations - Full integration of Python Scene objects with C++ engine All Phase 5 tasks (#34, #1, #61, #105) completed successfully. Author: John McCardle <mccardle.john@gmail.com> research: SFML 3.0 migration analysis - Analyzed SFML 3.0 breaking changes (event system, scoped enums, C++17) - Assessed migration impact on McRogueFace (40+ files affected) - Evaluated timing relative to mcrfpy.sfml module plans - Recommended deferring migration until after mcrfpy.sfml implementation - Created SFML_3_MIGRATION_RESEARCH.md with comprehensive strategy Author: John McCardle <mccardle.john@gmail.com> research: SFML exposure options analysis (#14) - Analyzed current SFML 2.6.1 usage throughout codebase - Evaluated python-sfml (abandoned, only supports SFML 2.3.2) - Recommended direct integration as mcrfpy.sfml module - Created comprehensive SFML_EXPOSURE_RESEARCH.md with implementation plan - Identified opportunity to provide modern SFML 2.6+ Python bindings Author: John McCardle <mccardle.john@gmail.com> feat: add basic profiling/metrics system (#104) - Add ProfilingMetrics struct to track performance data - Track frame time (current and 60-frame rolling average) - Calculate FPS from average frame time - Count draw calls, UI elements, and visible elements per frame - Track total runtime and current frame number - PyScene counts elements during render - Expose metrics via mcrfpy.getMetrics() returning dict This provides basic performance monitoring capabilities for identifying bottlenecks and optimizing rendering performance. Author: John McCardle <mccardle.john@gmail.com> fix: improve click handling with proper z-order and coordinate transforms - UIFrame: Fix coordinate transformation (subtract parent pos, not add) - UIFrame: Check children in reverse order (highest z-index first) - UIFrame: Skip invisible elements entirely - PyScene: Sort elements by z-index before checking clicks - PyScene: Stop at first element that handles the click - UIGrid: Implement entity click detection with grid coordinate transform - UIGrid: Check entities in reverse order, return sprite as target Click events now correctly respect z-order (top elements get priority), handle coordinate transforms for nested frames, and support clicking on grid entities. Elements without click handlers are transparent to clicks, allowing elements below to receive them. Note: Click testing requires non-headless mode due to PyScene limitation. feat: implement name system for finding UI elements (#39/40/41) - Add 'name' property to UIDrawable base class - All UI elements (Frame, Caption, Sprite, Grid, Entity) support .name - Entity delegates name to its sprite member - Add find(name, scene=None) function for exact match search - Add findAll(pattern, scene=None) with wildcard support (* matches any sequence) - Both functions search recursively through Frame children and Grid entities - Comprehensive test coverage for all functionality This provides a simple way to find UI elements by name in Python scripts, supporting both exact matches and wildcard patterns. Author: John McCardle <mccardle.john@gmail.com> fix: prevent segfault when closing window via X button - Add cleanup() method to GameEngine to clear Python references before destruction - Clear timers and McRFPy_API references in proper order - Call cleanup() at end of run loop and in destructor - Ensure cleanup is only called once per GameEngine instance Also includes: - Fix audio ::stop() calls (already in place, OpenAL warning is benign) - Add Caption support for x, y keywords (e.g. Caption("text", x=5, y=10)) - Refactor UIDrawable_methods.h into UIBase.h for better organization - Move UIEntity-specific implementations to UIEntityPyMethods.h Author: John McCardle <mccardle.john@gmail.com> feat: stabilize test suite and add UIDrawable methods - Add visible, opacity properties to all UI classes (#87, #88) - Add get_bounds(), move(), resize() methods to UIDrawable (#89, #98) - Create UIDrawable_methods.h with template implementations - Fix test termination issues - all tests now exit properly - Fix test_sprite_texture_swap.py click handler signature - Fix test_drawable_base.py segfault in headless mode - Convert audio objects to pointers for cleanup (OpenAL warning persists) - Remove debug print statements from UICaption - Special handling for UIEntity to delegate drawable methods to sprite All test files are now "airtight" - they complete successfully, terminate on their own, and handle edge cases properly. Author: John McCardle <mccardle.john@gmail.com> docs: add Phase 1-3 completion summary - Document all completed tasks across three phases - Show before/after API improvements - Highlight technical achievements - Outline next steps for Phase 4-7 Author: John McCardle <mccardle.john@gmail.com> feat: implement mcrfpy.Timer object with pause/resume/cancel capabilities closes #103 - Created PyTimer.h/cpp with object-oriented timer interface - Enhanced PyTimerCallable with pause/resume state tracking - Added timer control methods: pause(), resume(), cancel(), restart() - Added timer properties: interval, remaining, paused, active, callback - Fixed timing logic to prevent rapid catch-up after resume - Timer objects automatically register with game engine - Added comprehensive test demonstrating all functionality Author: John McCardle <mccardle.john@gmail.com> feat(Color): add helper methods from_hex, to_hex, lerp closes #94 - Add Color.from_hex(hex_string) class method for creating colors from hex - Support formats: #RRGGBB, RRGGBB, #RRGGBBAA, RRGGBBAA - Add color.to_hex() to convert Color to hex string - Add color.lerp(other, t) for smooth color interpolation - Comprehensive test coverage for all methods Author: John McCardle <mccardle.john@gmail.com> fix: properly configure UTF-8 encoding for Python stdio - Use PyConfig to set stdio_encoding="UTF-8" during initialization - Set stdio_errors="surrogateescape" for robust handling - Configure in both init_python() and init_python_with_config() - Cleaner solution than wrapping streams after initialization - Fixes UnicodeEncodeError when printing unicode characters Author: John McCardle <mccardle.john@gmail.com> feat(Vector): implement arithmetic operations closes #93 - Add PyNumberMethods with add, subtract, multiply, divide, negate, absolute - Add rich comparison for equality/inequality checks - Add boolean check (zero vector is False) - Implement vector methods: magnitude(), normalize(), dot(), distance_to(), angle(), copy() - Fix UIDrawable::get_click() segfault when click_callable is null - Comprehensive test coverage for all arithmetic operations Author: John McCardle <mccardle.john@gmail.com> feat: Complete position argument standardization for all UI classes - Frame and Sprite now support pos keyword override - Entity now accepts x,y arguments (was pos-only before) - All UI classes now consistently support: - (x, y) positional - ((x, y)) tuple - x=x, y=y keywords - pos=(x,y) keyword - pos=Vector keyword - Improves API consistency and flexibility Author: John McCardle <mccardle.john@gmail.com> feat: Standardize position arguments across all UI classes - Create PyPositionHelper for consistent position parsing - Grid.at() now accepts (x,y), ((x,y)), x=x, y=y, pos=(x,y) - Caption now accepts x,y args in addition to pos - Grid init fully supports keyword arguments - Maintain backward compatibility for all formats - Consistent error messages across classes Author: John McCardle <mccardle.john@gmail.com> feat: Add Entity.die() method for lifecycle management closes #30 - Remove entity from its grid's entity list - Clear grid reference after removal - Safe to call multiple times (no-op if not on grid) - Works with shared_ptr entity management Author: John McCardle <mccardle.john@gmail.com> perf: Skip out-of-bounds entities during Grid rendering closes #52 - Add visibility bounds check in entity render loop - Skip entities outside view with 1 cell margin - Improves performance for large grids with many entities - Bounds check considers zoom and pan settings Author: John McCardle <mccardle.john@gmail.com> verify: Sprite texture swapping functionality closes #19 - Texture property getter/setter already implemented - Position/scale preservation during swap confirmed - Type validation for texture assignment working - Tests verify functionality is complete Author: John McCardle <mccardle.john@gmail.com> feat: Grid size tuple support closes #90 - Add grid_size keyword parameter to Grid.__init__ - Accept tuple or list of two integers - Override grid_x/grid_y if grid_size provided - Maintain backward compatibility - Add comprehensive test coverage Author: John McCardle <mccardle.john@gmail.com> feat: Phase 1 - safe constructors and _Drawable foundation Closes #7 - Make all UI class constructors safe: - Added safe default constructors for UISprite, UIGrid, UIEntity, UICaption - Initialize all members to predictable values - Made Python init functions accept no arguments - Added x,y properties to UIEntity Closes #71 - Create _Drawable Python base class: - Created PyDrawable.h/cpp with base type (not yet inherited by UI types) - Registered in module initialization Closes #87 - Add visible property: - Added bool visible=true to UIDrawable base class - All render methods check visibility before drawing Closes #88 - Add opacity property: - Added float opacity=1.0 to UIDrawable base class - UICaption and UISprite apply opacity to alpha channel Closes #89 - Add get_bounds() method: - Virtual method returns sf::FloatRect(x,y,w,h) - Implemented in Frame, Caption, Sprite, Grid Closes #98 - Add move() and resize() methods: - move(dx,dy) for relative movement - resize(w,h) for absolute sizing - Caption resize is no-op (size controlled by font) Author: John McCardle <mccardle.john@gmail.com> docs: comprehensive alpha_streamline_2 plan and strategic vision - Add 7-phase development plan for alpha_streamline_2 branch - Define architectural dependencies and critical path - Identify new issues needed (Timer objects, event system, etc.) - Add strategic vision document with 3 transformative directions - Timeline: 10-12 weeks to solid Beta foundation Author: John McCardle <mccardle.john@gmail.com> feat(Grid): flexible at() method arguments - Support tuple argument: grid.at((x, y)) - Support keyword arguments: grid.at(x=5, y=3) - Support pos keyword: grid.at(pos=(2, 8)) - Maintain backward compatibility with grid.at(x, y) - Add comprehensive error handling for invalid arguments Improves API ergonomics and Python-like flexibility
2025-07-09 22:41:15 -04:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>McRogueFace API Reference - Complete Documentation</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #2c3e50;
border-bottom: 3px solid #3498db;
padding-bottom: 15px;
margin-bottom: 30px;
}
h2 {
color: #34495e;
border-bottom: 2px solid #ecf0f1;
padding-bottom: 10px;
margin-top: 40px;
}
h3 {
color: #2c3e50;
margin-top: 30px;
}
h4 {
color: #34495e;
margin-top: 20px;
font-size: 1.1em;
}
h5 {
color: #555;
margin-top: 15px;
font-size: 1em;
}
code {
background: #f4f4f4;
padding: 2px 6px;
border-radius: 3px;
font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
font-size: 0.9em;
}
pre {
background: #f8f8f8;
border: 1px solid #e1e4e8;
border-radius: 6px;
padding: 16px;
overflow-x: auto;
margin: 15px 0;
}
pre code {
background: none;
padding: 0;
font-size: 0.875em;
line-height: 1.45;
}
.class-name {
color: #8e44ad;
font-weight: bold;
}
.property {
color: #27ae60;
font-weight: 600;
}
.method {
color: #2980b9;
font-weight: 600;
}
.function-signature {
color: #d73a49;
font-weight: 600;
}
.method-section {
margin: 20px 0;
padding: 15px;
background: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #3498db;
}
.arg-list {
margin: 10px 0;
}
.arg-item {
margin: 8px 0;
padding: 8px;
background: #fff;
border-radius: 4px;
border: 1px solid #e1e4e8;
}
.arg-name {
color: #d73a49;
font-weight: 600;
}
.arg-type {
color: #6f42c1;
font-style: italic;
}
.returns {
background: #e8f5e8;
padding: 10px;
border-radius: 4px;
border-left: 4px solid #28a745;
margin: 10px 0;
}
.note {
background: #fff3cd;
padding: 10px;
border-radius: 4px;
border-left: 4px solid #ffc107;
margin: 10px 0;
}
.example {
background: #e7f3ff;
padding: 15px;
border-radius: 4px;
border-left: 4px solid #0366d6;
margin: 15px 0;
}
.toc {
background: #f8f9fa;
border: 1px solid #e1e4e8;
border-radius: 6px;
padding: 20px;
margin: 20px 0;
}
.toc ul {
list-style: none;
padding-left: 0;
}
.toc li {
margin: 8px 0;
}
.toc a {
color: #3498db;
text-decoration: none;
font-weight: 500;
}
.toc a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>McRogueFace API Reference - Complete Documentation</h1>
<p><em>Generated on 2025-07-08 11:53:54</em></p>
<div class="toc">
<h2>Table of Contents</h2>
<ul>
<li><a href="#functions">Functions</a></li>
<li><a href="#classes">Classes</a></li>
<li><a href="#automation">Automation Module</a></li>
</ul>
</div>
<h2 id="functions">Functions</h2>
<h3>Scene Management</h3>
<div class="method-section">
<h4><code class="function-signature">createScene(name: str) -> None</code></h4>
<p>Create a new empty scene with the given name.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">name</span>
<span class="arg-type">(str)</span>:
Unique name for the new scene
</div>
</div>
<div class="note">
<strong>Raises:</strong> ValueError: If a scene with this name already exists
</div>
<div class="note">
<strong>Note:</strong> The scene is created but not made active. Use setScene() to switch to it.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.createScene(&quot;game_over&quot;)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">setScene(scene: str, transition: str = None, duration: float = 0.0) -> None</code></h4>
<p>Switch to a different scene with optional transition effect.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">scene</span>
<span class="arg-type">(str)</span>:
Name of the scene to switch to
</div>
<div class="arg-item">
<span class="arg-name">transition</span>
<span class="arg-type">(str)</span>:
Transition type: &quot;fade&quot;, &quot;slide_left&quot;, &quot;slide_right&quot;, &quot;slide_up&quot;, &quot;slide_down&quot;
</div>
<div class="arg-item">
<span class="arg-name">duration</span>
<span class="arg-type">(float)</span>:
Transition duration in seconds (default: 0.0 for instant)
</div>
</div>
<div class="note">
<strong>Raises:</strong> KeyError: If the scene doesn&#x27;t exist
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.setScene(&quot;game&quot;, &quot;fade&quot;, 0.5)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">currentScene() -> str</code></h4>
<p>Get the name of the currently active scene.</p>
<div class="returns">
<strong>Returns:</strong> str: Name of the current scene
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
scene_name = mcrfpy.currentScene()
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">sceneUI(scene: str = None) -> UICollection</code></h4>
<p>Get all UI elements for a scene.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">scene</span>
<span class="arg-type">(str)</span>:
Scene name. If None, uses current scene
</div>
</div>
<div class="returns">
<strong>Returns:</strong> UICollection: All UI elements in the scene
</div>
<div class="note">
<strong>Raises:</strong> KeyError: If the specified scene doesn&#x27;t exist
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
ui_elements = mcrfpy.sceneUI(&quot;game&quot;)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">keypressScene(handler: callable) -> None</code></h4>
<p>Set the keyboard event handler for the current scene.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">handler</span>
<span class="arg-type">(callable)</span>:
Function that receives (key_name: str, is_pressed: bool)
</div>
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
def on_key(key, pressed):
if key == &quot;SPACE&quot; and pressed:
player.jump()
mcrfpy.keypressScene(on_key)
</code></pre>
</div>
</div>
<h3>Audio</h3>
<div class="method-section">
<h4><code class="function-signature">createSoundBuffer(filename: str) -> int</code></h4>
<p>Load a sound effect from a file and return its buffer ID.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">filename</span>
<span class="arg-type">(str)</span>:
Path to the sound file (WAV, OGG, FLAC)
</div>
</div>
<div class="returns">
<strong>Returns:</strong> int: Buffer ID for use with playSound()
</div>
<div class="note">
<strong>Raises:</strong> RuntimeError: If the file cannot be loaded
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
jump_sound = mcrfpy.createSoundBuffer(&quot;assets/jump.wav&quot;)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">loadMusic(filename: str, loop: bool = True) -> None</code></h4>
<p>Load and immediately play background music from a file.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">filename</span>
<span class="arg-type">(str)</span>:
Path to the music file (WAV, OGG, FLAC)
</div>
<div class="arg-item">
<span class="arg-name">loop</span>
<span class="arg-type">(bool)</span>:
Whether to loop the music (default: True)
</div>
</div>
<div class="note">
<strong>Note:</strong> Only one music track can play at a time. Loading new music stops the current track.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.loadMusic(&quot;assets/background.ogg&quot;, True)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">playSound(buffer_id: int) -> None</code></h4>
<p>Play a sound effect using a previously loaded buffer.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">buffer_id</span>
<span class="arg-type">(int)</span>:
Sound buffer ID returned by createSoundBuffer()
</div>
</div>
<div class="note">
<strong>Raises:</strong> RuntimeError: If the buffer ID is invalid
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.playSound(jump_sound)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">getMusicVolume() -> int</code></h4>
<p>Get the current music volume level.</p>
<div class="returns">
<strong>Returns:</strong> int: Current volume (0-100)
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
current_volume = mcrfpy.getMusicVolume()
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">getSoundVolume() -> int</code></h4>
<p>Get the current sound effects volume level.</p>
<div class="returns">
<strong>Returns:</strong> int: Current volume (0-100)
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
current_volume = mcrfpy.getSoundVolume()
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">setMusicVolume(volume: int) -> None</code></h4>
<p>Set the global music volume.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">volume</span>
<span class="arg-type">(int)</span>:
Volume level from 0 (silent) to 100 (full volume)
</div>
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.setMusicVolume(50) # Set to 50% volume
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">setSoundVolume(volume: int) -> None</code></h4>
<p>Set the global sound effects volume.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">volume</span>
<span class="arg-type">(int)</span>:
Volume level from 0 (silent) to 100 (full volume)
</div>
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.setSoundVolume(75) # Set to 75% volume
</code></pre>
</div>
</div>
<h3>UI Utilities</h3>
<div class="method-section">
<h4><code class="function-signature">find(name: str, scene: str = None) -> UIDrawable | None</code></h4>
<p>Find the first UI element with the specified name.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">name</span>
<span class="arg-type">(str)</span>:
Exact name to search for
</div>
<div class="arg-item">
<span class="arg-name">scene</span>
<span class="arg-type">(str)</span>:
Scene to search in (default: current scene)
</div>
</div>
<div class="returns">
<strong>Returns:</strong> UIDrawable or None: The found element, or None if not found
</div>
<div class="note">
<strong>Note:</strong> Searches scene UI elements and entities within grids.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
button = mcrfpy.find(&quot;start_button&quot;)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">findAll(pattern: str, scene: str = None) -> list</code></h4>
<p>Find all UI elements matching a name pattern.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">pattern</span>
<span class="arg-type">(str)</span>:
Name pattern with optional wildcards (* matches any characters)
</div>
<div class="arg-item">
<span class="arg-name">scene</span>
<span class="arg-type">(str)</span>:
Scene to search in (default: current scene)
</div>
</div>
<div class="returns">
<strong>Returns:</strong> list: All matching UI elements and entities
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
enemies = mcrfpy.findAll(&quot;enemy_*&quot;)
</code></pre>
</div>
</div>
<h3>System</h3>
<div class="method-section">
<h4><code class="function-signature">exit() -> None</code></h4>
<p>Cleanly shut down the game engine and exit the application.</p>
<div class="note">
<strong>Note:</strong> This immediately closes the window and terminates the program.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.exit()
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">getMetrics() -> dict</code></h4>
<p>Get current performance metrics.</p>
<div class="returns">
<strong>Returns:</strong> 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
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
metrics = mcrfpy.getMetrics()
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">setTimer(name: str, handler: callable, interval: int) -> None</code></h4>
<p>Create or update a recurring timer.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">name</span>
<span class="arg-type">(str)</span>:
Unique identifier for the timer
</div>
<div class="arg-item">
<span class="arg-name">handler</span>
<span class="arg-type">(callable)</span>:
Function called with (runtime: float) parameter
</div>
<div class="arg-item">
<span class="arg-name">interval</span>
<span class="arg-type">(int)</span>:
Time between calls in milliseconds
</div>
</div>
<div class="note">
<strong>Note:</strong> If a timer with this name exists, it will be replaced.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
def update_score(runtime):
score += 1
mcrfpy.setTimer(&quot;score_update&quot;, update_score, 1000)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">delTimer(name: str) -> None</code></h4>
<p>Stop and remove a timer.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">name</span>
<span class="arg-type">(str)</span>:
Timer identifier to remove
</div>
</div>
<div class="note">
<strong>Note:</strong> No error is raised if the timer doesn&#x27;t exist.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.delTimer(&quot;score_update&quot;)
</code></pre>
</div>
</div>
<div class="method-section">
<h4><code class="function-signature">setScale(multiplier: float) -> None</code></h4>
<p>Scale the game window size.</p>
<div class="arg-list">
<h5>Arguments:</h5>
<div class="arg-item">
<span class="arg-name">multiplier</span>
<span class="arg-type">(float)</span>:
Scale factor (e.g., 2.0 for double size)
</div>
</div>
<div class="note">
<strong>Note:</strong> The internal resolution remains 1024x768, but the window is scaled.
</div>
<div class="example">
<h5>Example:</h5>
<pre><code>
mcrfpy.setScale(2.0) # Double the window size
</code></pre>
</div>
</div>
<h2 id="classes">Classes</h2>
<div class="method-section">
<h3><span class="class-name">Animation</span></h3>
<p>Animation object for animating UI properties</p>
<h4>Properties:</h4>
<div class="arg-item">
<span class="property">property</span>: str: Name of the property being animated (e.g., &quot;x&quot;, &quot;y&quot;, &quot;scale&quot;)
</div>
<div class="arg-item">
<span class="property">duration</span>: float: Total duration of the animation in seconds
</div>
<div class="arg-item">
<span class="property">elapsed_time</span>: float: Time elapsed since animation started (read-only)
</div>
<div class="arg-item">
<span class="property">current_value</span>: float: Current interpolated value of the animation (read-only)
</div>
<div class="arg-item">
<span class="property">is_running</span>: bool: True if animation is currently running (read-only)
</div>
<div class="arg-item">
<span class="property">is_finished</span>: bool: True if animation has completed (read-only)
</div>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_current_value()</code></h5>
<p>Get the current interpolated value of the animation.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: Current animation value between start and end
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">update(delta_time)</code></h5>
<p>Update the animation by the given time delta.</p>
<div style="margin-left: 20px;">
<span class="arg-name">delta_time</span>
<span class="arg-type">(float)</span>:
Time elapsed since last update in seconds
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> bool: True if animation is still running, False if finished
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">start(target)</code></h5>
<p>Start the animation on a target UI element.</p>
<div style="margin-left: 20px;">
<span class="arg-name">target</span>
<span class="arg-type">(UIDrawable)</span>:
The UI element to animate
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The target must have the property specified in the animation constructor.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Caption</span></h3>
<p>Caption(text=&#x27;&#x27;, x=0, y=0, font=None, fill_color=None, outline_color=None, outline=0, click=None)
A text display UI element with customizable font and styling.
Args:
text (str): The text content to display. Default: &#x27;&#x27;
x (float): X position in pixels. Default: 0
y (float): Y position in pixels. Default: 0
font (Font): Font object for text rendering. Default: engine default font
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
click (callable): Click event handler. Default: None
Attributes:
text (str): The displayed text content
x, y (float): Position in pixels
font (Font): Font used for rendering
fill_color, outline_color (Color): Text appearance
outline (float): Outline thickness
click (callable): Click event handler
visible (bool): Visibility state
z_index (int): Rendering order
w, h (float): Read-only computed size based on text and font</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Color</span></h3>
<p>SFML Color Object</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">lerp(other, t)</code></h5>
<p>Linearly interpolate between this color and another.</p>
<div style="margin-left: 20px;">
<span class="arg-name">other</span>
<span class="arg-type">(Color)</span>:
The color to interpolate towards
</div>
<div style="margin-left: 20px;">
<span class="arg-name">t</span>
<span class="arg-type">(float)</span>:
Interpolation factor from 0.0 to 1.0
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> Color: New interpolated Color object
</div>
<div style="margin-left: 20px;">
<strong>Example:</strong>
<pre><code>
mixed = red.lerp(blue, 0.5) # 50% between red and blue
</code></pre>
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">to_hex()</code></h5>
<p>Convert this Color to a hexadecimal string.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> str: Hex color string in format &quot;#RRGGBB&quot;
</div>
<div style="margin-left: 20px;">
<strong>Example:</strong>
<pre><code>
hex_str = color.to_hex() # Returns &quot;#FF0000&quot;
</code></pre>
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">from_hex(hex_string)</code></h5>
<p>Create a Color from a hexadecimal color string.</p>
<div style="margin-left: 20px;">
<span class="arg-name">hex_string</span>
<span class="arg-type">(str)</span>:
Hex color string (e.g., &quot;#FF0000&quot; or &quot;FF0000&quot;)
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> Color: New Color object from hex string
</div>
<div style="margin-left: 20px;">
<strong>Example:</strong>
<pre><code>
red = Color.from_hex(&quot;#FF0000&quot;)
</code></pre>
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Drawable</span></h3>
<p>Base class for all drawable UI elements</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Entity</span></h3>
<p>UIEntity objects</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">at(x, y)</code></h5>
<p>Check if this entity is at the specified grid coordinates.</p>
<div style="margin-left: 20px;">
<span class="arg-name">x</span>
<span class="arg-type">(int)</span>:
Grid x coordinate to check
</div>
<div style="margin-left: 20px;">
<span class="arg-name">y</span>
<span class="arg-type">(int)</span>:
Grid y coordinate to check
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> bool: True if entity is at position (x, y), False otherwise
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">index()</code></h5>
<p>Get the index of this entity in its parent grid&#x27;s entity list.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> int: Index position, or -1 if not in a grid
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">die()</code></h5>
<p>Remove this entity from its parent grid.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The entity object remains valid but is no longer rendered or updated.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">EntityCollection</span></h3>
<p>Iterable, indexable collection of Entities</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">remove(entity)</code></h5>
<p>Remove the first occurrence of an entity from the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">entity</span>
<span class="arg-type">(Entity)</span>:
The entity to remove
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">extend(iterable)</code></h5>
<p>Add all entities from an iterable to the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">iterable</span>
<span class="arg-type">(Iterable[Entity])</span>:
Entities to add
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">append(entity)</code></h5>
<p>Add an entity to the end of the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">entity</span>
<span class="arg-type">(Entity)</span>:
The entity to add
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">index(entity)</code></h5>
<p>Find the index of the first occurrence of an entity.</p>
<div style="margin-left: 20px;">
<span class="arg-name">entity</span>
<span class="arg-type">(Entity)</span>:
The entity to find
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> int: Index of entity in collection
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">count(entity)</code></h5>
<p>Count the number of occurrences of an entity in the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">entity</span>
<span class="arg-type">(Entity)</span>:
The entity to count
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> int: Number of times entity appears in collection
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Font</span></h3>
<p>SFML Font Object</p>
</div>
<div class="method-section">
<h3><span class="class-name">Frame</span></h3>
<p>Frame(x=0, y=0, w=0, h=0, fill_color=None, outline_color=None, outline=0, click=None, children=None)
A rectangular frame UI element that can contain other drawable elements.
Args:
x (float): X position in pixels. Default: 0
y (float): Y position in pixels. Default: 0
w (float): Width in pixels. Default: 0
h (float): Height in pixels. Default: 0
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
Attributes:
x, y (float): Position in pixels
w, h (float): Size in pixels
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
z_index (int): Rendering order
clip_children (bool): Whether to clip children to frame bounds</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Grid</span></h3>
<p>Grid(x=0, y=0, grid_size=(20, 20), texture=None, tile_width=16, tile_height=16, scale=1.0, click=None)
A grid-based tilemap UI element for rendering tile-based levels and game worlds.
Args:
x (float): X position in pixels. Default: 0
y (float): Y position in pixels. Default: 0
grid_size (tuple): Grid dimensions as (width, height) in tiles. Default: (20, 20)
texture (Texture): Texture atlas containing tile sprites. Default: None
tile_width (int): Width of each tile in pixels. Default: 16
tile_height (int): Height of each tile in pixels. Default: 16
scale (float): Grid scaling factor. Default: 1.0
click (callable): Click event handler. Default: None
Attributes:
x, y (float): Position in pixels
grid_size (tuple): Grid dimensions (width, height) in tiles
tile_width, tile_height (int): Tile dimensions in pixels
texture (Texture): Tile texture atlas
scale (float): Scale multiplier
points (list): 2D array of GridPoint objects for tile data
entities (list): Collection of Entity objects in the grid
background_color (Color): Grid background color
click (callable): Click event handler
visible (bool): Visibility state
z_index (int): Rendering order</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">at(x, y)</code></h5>
<p>Get the GridPoint at the specified grid coordinates.</p>
<div style="margin-left: 20px;">
<span class="arg-name">x</span>
<span class="arg-type">(int)</span>:
Grid x coordinate
</div>
<div style="margin-left: 20px;">
<span class="arg-name">y</span>
<span class="arg-type">(int)</span>:
Grid y coordinate
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> GridPoint or None: The grid point at (x, y), or None if out of bounds
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">GridPoint</span></h3>
<p>UIGridPoint object</p>
<h4>Properties:</h4>
<div class="arg-item">
<span class="property">x</span>: int: Grid x coordinate of this point
</div>
<div class="arg-item">
<span class="property">y</span>: int: Grid y coordinate of this point
</div>
<div class="arg-item">
<span class="property">texture_index</span>: int: Index of the texture/sprite to display at this point
</div>
<div class="arg-item">
<span class="property">solid</span>: bool: Whether this point blocks movement
</div>
<div class="arg-item">
<span class="property">transparent</span>: bool: Whether this point allows light/vision through
</div>
<div class="arg-item">
<span class="property">color</span>: Color: Color tint applied to the texture at this point
</div>
</div>
<div class="method-section">
<h3><span class="class-name">GridPointState</span></h3>
<p>UIGridPointState object</p>
<h4>Properties:</h4>
<div class="arg-item">
<span class="property">visible</span>: bool: Whether this point is currently visible to the player
</div>
<div class="arg-item">
<span class="property">discovered</span>: bool: Whether this point has been discovered/explored
</div>
<div class="arg-item">
<span class="property">custom_flags</span>: int: Bitfield for custom game-specific flags
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Scene</span></h3>
<p>Base class for object-oriented scenes</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">keypress(handler)</code></h5>
<p>Register a keyboard handler function for this scene.</p>
<div style="margin-left: 20px;">
<span class="arg-name">handler</span>
<span class="arg-type">(callable)</span>:
Function that takes (key_name: str, is_pressed: bool)
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Alternative to overriding the on_keypress method.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_ui()</code></h5>
<p>Get the UI element collection for this scene.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> UICollection: Collection of all UI elements in this scene
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">activate()</code></h5>
<p>Make this scene the active scene.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Equivalent to calling setScene() with this scene&#x27;s name.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">register_keyboard(callable)</code></h5>
<p>Register a keyboard event handler function for the scene.</p>
<div style="margin-left: 20px;">
<span class="arg-name">callable</span>
<span class="arg-type">(callable)</span>:
Function that takes (key: str, action: str) parameters
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Alternative to overriding the on_keypress method when subclassing Scene objects.
</div>
<div style="margin-left: 20px;">
<strong>Example:</strong>
<pre><code>
def handle_keyboard(key, action):
print(f&quot;Key &#x27;{key}&#x27; was {action}&quot;)
if key == &quot;q&quot; and action == &quot;press&quot;:
# Handle quit
pass
scene.register_keyboard(handle_keyboard)
</code></pre>
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Sprite</span></h3>
<p>Sprite(x=0, y=0, texture=None, sprite_index=0, scale=1.0, click=None)
A sprite UI element that displays a texture or portion of a texture atlas.
Args:
x (float): X position in pixels. Default: 0
y (float): Y position in pixels. Default: 0
texture (Texture): Texture object to display. Default: None
sprite_index (int): Index into texture atlas (if applicable). Default: 0
scale (float): Sprite scaling factor. Default: 1.0
click (callable): Click event handler. Default: None
Attributes:
x, y (float): Position in pixels
texture (Texture): The texture being displayed
sprite_index (int): Current sprite index in texture atlas
scale (float): Scale multiplier
click (callable): Click event handler
visible (bool): Visibility state
z_index (int): Rendering order
w, h (float): Read-only computed size based on texture and scale</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get_bounds()</code></h5>
<p>Get the bounding rectangle of this drawable element.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> tuple: (x, y, width, height) representing the element&#x27;s bounds
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> The bounds are in screen coordinates and account for current position and size.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resize(width, height)</code></h5>
<p>Resize the element to new dimensions.</p>
<div style="margin-left: 20px;">
<span class="arg-name">width</span>
<span class="arg-type">(float)</span>:
New width in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">height</span>
<span class="arg-type">(float)</span>:
New height in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> For Caption and Sprite, this may not change actual size if determined by content.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">move(dx, dy)</code></h5>
<p>Move the element by a relative offset.</p>
<div style="margin-left: 20px;">
<span class="arg-name">dx</span>
<span class="arg-type">(float)</span>:
Horizontal offset in pixels
</div>
<div style="margin-left: 20px;">
<span class="arg-name">dy</span>
<span class="arg-type">(float)</span>:
Vertical offset in pixels
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This modifies the x and y position properties by the given amounts.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Texture</span></h3>
<p>SFML Texture Object</p>
</div>
<div class="method-section">
<h3><span class="class-name">Timer</span></h3>
<p>Timer object for scheduled callbacks</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">resume()</code></h5>
<p>Resume a paused timer.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Has no effect if timer is not paused.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">pause()</code></h5>
<p>Pause the timer, stopping its callback execution.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Use resume() to continue the timer from where it was paused.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">cancel()</code></h5>
<p>Cancel the timer and remove it from the system.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> After cancelling, the timer object cannot be reused.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">restart()</code></h5>
<p>Restart the timer from the beginning.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Resets the timer&#x27;s internal clock to zero.
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">UICollection</span></h3>
<p>Iterable, indexable collection of UI objects</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">remove(drawable)</code></h5>
<p>Remove the first occurrence of a drawable from the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">drawable</span>
<span class="arg-type">(UIDrawable)</span>:
The drawable to remove
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">extend(iterable)</code></h5>
<p>Add all drawables from an iterable to the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">iterable</span>
<span class="arg-type">(Iterable[UIDrawable])</span>:
Drawables to add
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">append(drawable)</code></h5>
<p>Add a drawable element to the end of the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">drawable</span>
<span class="arg-type">(UIDrawable)</span>:
The drawable element to add
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">index(drawable)</code></h5>
<p>Find the index of the first occurrence of a drawable.</p>
<div style="margin-left: 20px;">
<span class="arg-name">drawable</span>
<span class="arg-type">(UIDrawable)</span>:
The drawable to find
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> int: Index of drawable in collection
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">count(drawable)</code></h5>
<p>Count the number of occurrences of a drawable in the collection.</p>
<div style="margin-left: 20px;">
<span class="arg-name">drawable</span>
<span class="arg-type">(UIDrawable)</span>:
The drawable to count
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> int: Number of times drawable appears in collection
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">UICollectionIter</span></h3>
<p>Iterator for a collection of UI objects</p>
</div>
<div class="method-section">
<h3><span class="class-name">UIEntityCollectionIter</span></h3>
<p>Iterator for a collection of UI objects</p>
</div>
<div class="method-section">
<h3><span class="class-name">Vector</span></h3>
<p>SFML Vector Object</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">magnitude()</code></h5>
<p>Calculate the length/magnitude of this vector.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: The magnitude of the vector
</div>
<div style="margin-left: 20px;">
<strong>Example:</strong>
<pre><code>
length = vector.magnitude()
</code></pre>
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">distance_to(other)</code></h5>
<p>Calculate the distance to another vector.</p>
<div style="margin-left: 20px;">
<span class="arg-name">other</span>
<span class="arg-type">(Vector)</span>:
The other vector
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: Distance between the two vectors
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">angle()</code></h5>
<p>Get the angle of this vector in radians.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: Angle in radians from positive x-axis
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">dot(other)</code></h5>
<p>Calculate the dot product with another vector.</p>
<div style="margin-left: 20px;">
<span class="arg-name">other</span>
<span class="arg-type">(Vector)</span>:
The other vector
</div>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: Dot product of the two vectors
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">normalize()</code></h5>
<p>Return a unit vector in the same direction.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> Vector: New normalized vector with magnitude 1.0
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">magnitude_squared()</code></h5>
<p>Calculate the squared magnitude of this vector.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> float: The squared magnitude (faster than magnitude())
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Use this for comparisons to avoid expensive square root calculation.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">copy()</code></h5>
<p>Create a copy of this vector.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> Vector: New Vector object with same x and y values
</div>
</div>
</div>
<div class="method-section">
<h3><span class="class-name">Window</span></h3>
<p>Window singleton for accessing and modifying the game window properties</p>
<h4>Methods:</h4>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">screenshot(filename)</code></h5>
<p>Take a screenshot and save it to a file.</p>
<div style="margin-left: 20px;">
<span class="arg-name">filename</span>
<span class="arg-type">(str)</span>:
Path where to save the screenshot
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Supports PNG, JPG, and BMP formats based on file extension.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">center()</code></h5>
<p>Center the window on the screen.</p>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> Only works if the window is not fullscreen.
</div>
</div>
<div style="margin-left: 20px; margin-bottom: 15px;">
<h5><code class="method">get()</code></h5>
<p>Get the Window singleton instance.</p>
<div style="margin-left: 20px; color: #28a745;">
<strong>Returns:</strong> Window: The singleton window object
</div>
<div style="margin-left: 20px; color: #856404;">
<strong>Note:</strong> This is a static method that returns the same instance every time.
</div>
</div>
</div>
<h2 id="automation">Automation Module</h2>
<p>The <code>mcrfpy.automation</code> module provides testing and automation capabilities.</p>
<div class="method-section">
<h4><code class="function-signature">automation.click</code></h4>
<p>Click at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.doubleClick</code></h4>
<p>Double click at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.dragRel</code></h4>
<p>Drag mouse relative to current position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.dragTo</code></h4>
<p>Drag mouse to position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.hotkey</code></h4>
<p>Press a hotkey combination (e.g., hotkey(&#x27;ctrl&#x27;, &#x27;c&#x27;))</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.keyDown</code></h4>
<p>Press and hold a key</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.keyUp</code></h4>
<p>Release a key</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.middleClick</code></h4>
<p>Middle click at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.mouseDown</code></h4>
<p>Press mouse button</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.mouseUp</code></h4>
<p>Release mouse button</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.moveRel</code></h4>
<p>Move mouse relative to current position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.moveTo</code></h4>
<p>Move mouse to absolute position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.onScreen</code></h4>
<p>Check if coordinates are within screen bounds</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.position</code></h4>
<p>Get current mouse position as (x, y) tuple</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.rightClick</code></h4>
<p>Right click at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.screenshot</code></h4>
<p>Save a screenshot to the specified file</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.scroll</code></h4>
<p>Scroll wheel at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.size</code></h4>
<p>Get screen size as (width, height) tuple</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.tripleClick</code></h4>
<p>Triple click at position</p>
</div>
<div class="method-section">
<h4><code class="function-signature">automation.typewrite</code></h4>
<p>Type text with optional interval between keystrokes</p>
</div>
</div>
</body>
</html>