McRogueFace/docs/api_reference.html

852 lines
21 KiB
HTML

<!DOCTYPE html>
<html><head>
<meta charset="UTF-8">
<title>McRogueFace API Reference</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
line-height: 1.6; color: #333; max-width: 900px; margin: 0 auto; padding: 20px; }
h1, h2, h3, h4, h5 { color: #2c3e50; margin-top: 24px; }
h1 { border-bottom: 2px solid #3498db; padding-bottom: 10px; }
h2 { border-bottom: 1px solid #ecf0f1; padding-bottom: 8px; }
code { background: #f4f4f4; padding: 2px 4px; border-radius: 3px; font-size: 90%; }
pre { background: #f4f4f4; padding: 12px; border-radius: 5px; overflow-x: auto; }
pre code { background: none; padding: 0; }
blockquote { border-left: 4px solid #3498db; margin: 0; padding-left: 16px; color: #7f8c8d; }
hr { border: none; border-top: 1px solid #ecf0f1; margin: 24px 0; }
a { color: #3498db; text-decoration: none; }
a:hover { text-decoration: underline; }
.property { color: #27ae60; }
.method { color: #2980b9; }
.class-name { color: #8e44ad; font-weight: bold; }
ul { padding-left: 24px; }
li { margin: 4px 0; }
</style>
</head><body>
<h1>McRogueFace API Reference</h1>
<em>Generated on 2025-07-08 10:11:22</em>
<h2>Overview</h2>
<p>McRogueFace Python API\n\nCore game engine interface for creating roguelike games with Python.\n\nThis module provides:\n- Scene management (createScene, setScene, currentScene)\n- UI components (Frame, Caption, Sprite, Grid)\n- Entity system for game objects\n- Audio playback (sound effects and music)\n- Timer system for scheduled events\n- Input handling\n- Performance metrics\n\nExample:\n import mcrfpy\n \n # Create a new scene\n mcrfpy.createScene('game')\n mcrfpy.setScene('game')\n \n # Add UI elements\n frame = mcrfpy.Frame(10, 10, 200, 100)\n caption = mcrfpy.Caption('Hello World', 50, 50)\n mcrfpy.sceneUI().extend([frame, caption])\n</p>
<h2>Table of Contents</h2>
<ul>
<li>[Classes](#classes)</li>
<li>[Functions](#functions)</li>
<li>[Automation Module](#automation-module)</li>
</ul>
<h2>Classes</h2>
<h3>UI Components</h3>
<h3>class `Caption`</h3>
<em>Inherits from: Drawable</em>
<pre><code class="language-python">
Caption(text='', x=0, y=0, font=None, fill_color=None, outline_color=None, outline=0, click=None)
</code></pre>
<p>A text display UI element with customizable font and styling.</p>
<p>Args:</p>
<p>text (str): The text content to display. Default: ''</p>
<p>x (float): X position in pixels. Default: 0</p>
<p>y (float): Y position in pixels. Default: 0</p>
<p>font (Font): Font object for text rendering. Default: engine default font</p>
<p>fill_color (Color): Text fill color. Default: (255, 255, 255, 255)</p>
<p>outline_color (Color): Text outline color. Default: (0, 0, 0, 255)</p>
<p>outline (float): Text outline thickness. Default: 0</p>
<p>click (callable): Click event handler. Default: None</p>
<p>Attributes:</p>
<p>text (str): The displayed text content</p>
<p>x, y (float): Position in pixels</p>
<p>font (Font): Font used for rendering</p>
<p>fill_color, outline_color (Color): Text appearance</p>
<p>outline (float): Outline thickness</p>
<p>click (callable): Click event handler</p>
<p>visible (bool): Visibility state</p>
<p>z_index (int): Rendering order</p>
<p>w, h (float): Read-only computed size based on text and font</p>
<h4>Methods</h4>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>class `Entity`</h3>
<em>Inherits from: Drawable</em>
<p>UIEntity objects</p>
<h4>Methods</h4>
<h5>`at(...)`</h5>
<h5>`die(...)`</h5>
<p>Remove this entity from its grid</p>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`index(...)`</h5>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>class `Frame`</h3>
<em>Inherits from: Drawable</em>
<pre><code class="language-python">
Frame(x=0, y=0, w=0, h=0, fill_color=None, outline_color=None, outline=0, click=None, children=None)
</code></pre>
<p>A rectangular frame UI element that can contain other drawable elements.</p>
<p>Args:</p>
<p>x (float): X position in pixels. Default: 0</p>
<p>y (float): Y position in pixels. Default: 0</p>
<p>w (float): Width in pixels. Default: 0</p>
<p>h (float): Height in pixels. Default: 0</p>
<p>fill_color (Color): Background fill color. Default: (0, 0, 0, 128)</p>
<p>outline_color (Color): Border outline color. Default: (255, 255, 255, 255)</p>
<p>outline (float): Border outline thickness. Default: 0</p>
<p>click (callable): Click event handler. Default: None</p>
<p>children (list): Initial list of child drawable elements. Default: None</p>
<p>Attributes:</p>
<p>x, y (float): Position in pixels</p>
<p>w, h (float): Size in pixels</p>
<p>fill_color, outline_color (Color): Visual appearance</p>
<p>outline (float): Border thickness</p>
<p>click (callable): Click event handler</p>
<p>children (list): Collection of child drawable elements</p>
<p>visible (bool): Visibility state</p>
<p>z_index (int): Rendering order</p>
<p>clip_children (bool): Whether to clip children to frame bounds</p>
<h4>Methods</h4>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>class `Grid`</h3>
<em>Inherits from: Drawable</em>
<pre><code class="language-python">
Grid(x=0, y=0, grid_size=(20, 20), texture=None, tile_width=16, tile_height=16, scale=1.0, click=None)
</code></pre>
<p>A grid-based tilemap UI element for rendering tile-based levels and game worlds.</p>
<p>Args:</p>
<p>x (float): X position in pixels. Default: 0</p>
<p>y (float): Y position in pixels. Default: 0</p>
<p>grid_size (tuple): Grid dimensions as (width, height) in tiles. Default: (20, 20)</p>
<p>texture (Texture): Texture atlas containing tile sprites. Default: None</p>
<p>tile_width (int): Width of each tile in pixels. Default: 16</p>
<p>tile_height (int): Height of each tile in pixels. Default: 16</p>
<p>scale (float): Grid scaling factor. Default: 1.0</p>
<p>click (callable): Click event handler. Default: None</p>
<p>Attributes:</p>
<p>x, y (float): Position in pixels</p>
<p>grid_size (tuple): Grid dimensions (width, height) in tiles</p>
<p>tile_width, tile_height (int): Tile dimensions in pixels</p>
<p>texture (Texture): Tile texture atlas</p>
<p>scale (float): Scale multiplier</p>
<p>points (list): 2D array of GridPoint objects for tile data</p>
<p>entities (list): Collection of Entity objects in the grid</p>
<p>background_color (Color): Grid background color</p>
<p>click (callable): Click event handler</p>
<p>visible (bool): Visibility state</p>
<p>z_index (int): Rendering order</p>
<h4>Methods</h4>
<h5>`at(...)`</h5>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>class `Sprite`</h3>
<em>Inherits from: Drawable</em>
<pre><code class="language-python">
Sprite(x=0, y=0, texture=None, sprite_index=0, scale=1.0, click=None)
</code></pre>
<p>A sprite UI element that displays a texture or portion of a texture atlas.</p>
<p>Args:</p>
<p>x (float): X position in pixels. Default: 0</p>
<p>y (float): Y position in pixels. Default: 0</p>
<p>texture (Texture): Texture object to display. Default: None</p>
<p>sprite_index (int): Index into texture atlas (if applicable). Default: 0</p>
<p>scale (float): Sprite scaling factor. Default: 1.0</p>
<p>click (callable): Click event handler. Default: None</p>
<p>Attributes:</p>
<p>x, y (float): Position in pixels</p>
<p>texture (Texture): The texture being displayed</p>
<p>sprite_index (int): Current sprite index in texture atlas</p>
<p>scale (float): Scale multiplier</p>
<p>click (callable): Click event handler</p>
<p>visible (bool): Visibility state</p>
<p>z_index (int): Rendering order</p>
<p>w, h (float): Read-only computed size based on texture and scale</p>
<h4>Methods</h4>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>Collections</h3>
<h3>class `EntityCollection`</h3>
<p>Iterable, indexable collection of Entities</p>
<h4>Methods</h4>
<h5>`append(...)`</h5>
<h5>`count(...)`</h5>
<h5>`extend(...)`</h5>
<h5>`index(...)`</h5>
<h5>`remove(...)`</h5>
<hr>
<h3>class `UICollection`</h3>
<p>Iterable, indexable collection of UI objects</p>
<h4>Methods</h4>
<h5>`append(...)`</h5>
<h5>`count(...)`</h5>
<h5>`extend(...)`</h5>
<h5>`index(...)`</h5>
<h5>`remove(...)`</h5>
<hr>
<h3>class `UICollectionIter`</h3>
<p>Iterator for a collection of UI objects</p>
<hr>
<h3>class `UIEntityCollectionIter`</h3>
<p>Iterator for a collection of UI objects</p>
<hr>
<h3>System Types</h3>
<h3>class `Color`</h3>
<p>SFML Color Object</p>
<h4>Methods</h4>
<h5>`Create Color from hex string (e.g., '#FF0000' or 'FF0000')`</h5>
<p>Create Color from hex string (e.g., '#FF0000' or 'FF0000')</p>
<h5>`lerp(...)`</h5>
<p>Linearly interpolate between this color and another</p>
<h5>`to_hex(...)`</h5>
<p>Convert Color to hex string</p>
<hr>
<h3>class `Font`</h3>
<p>SFML Font Object</p>
<hr>
<h3>class `Texture`</h3>
<p>SFML Texture Object</p>
<hr>
<h3>class `Vector`</h3>
<p>SFML Vector Object</p>
<h4>Methods</h4>
<h5>`angle(...)`</h5>
<h5>`copy(...)`</h5>
<h5>`distance_to(...)`</h5>
<p>Return the distance to another vector</p>
<h5>`dot(...)`</h5>
<h5>`magnitude(...)`</h5>
<p>Return the length of the vector</p>
<h5>`magnitude_squared(...)`</h5>
<p>Return the squared length of the vector</p>
<h5>`normalize(...)`</h5>
<p>Return a unit vector in the same direction</p>
<hr>
<h3>Other Classes</h3>
<h3>class `Animation`</h3>
<p>Animation object for animating UI properties</p>
<h4>Methods</h4>
<h5>`get_current_value(...)`</h5>
<p>Get the current interpolated value</p>
<h5>`start(...)`</h5>
<p>Start the animation on a target UIDrawable</p>
<h5>`Update the animation by deltaTime (returns True if still running)`</h5>
<p>Update the animation by deltaTime (returns True if still running)</p>
<hr>
<h3>class `Drawable`</h3>
<p>Base class for all drawable UI elements</p>
<h4>Methods</h4>
<h5>`Get bounding box as (x, y, width, height)`</h5>
<p>Get bounding box as (x, y, width, height)</p>
<h5>`Move by relative offset (dx, dy)`</h5>
<p>Move by relative offset (dx, dy)</p>
<h5>`Resize to new dimensions (width, height)`</h5>
<p>Resize to new dimensions (width, height)</p>
<hr>
<h3>class `GridPoint`</h3>
<p>UIGridPoint object</p>
<hr>
<h3>class `GridPointState`</h3>
<p>UIGridPointState object</p>
<hr>
<h3>class `Scene`</h3>
<p>Base class for object-oriented scenes</p>
<h4>Methods</h4>
<h5>`activate(...)`</h5>
<p>Make this the active scene</p>
<h5>`get_ui(...)`</h5>
<p>Get the UI element collection for this scene</p>
<h5>`Register a keyboard handler function (alternative to overriding on_keypress)`</h5>
<p>Register a keyboard handler function (alternative to overriding on_keypress)</p>
<hr>
<h3>class `Timer`</h3>
<p>Timer object for scheduled callbacks</p>
<h4>Methods</h4>
<h5>`cancel(...)`</h5>
<p>Cancel the timer and remove it from the system</p>
<h5>`pause(...)`</h5>
<p>Pause the timer</p>
<h5>`restart(...)`</h5>
<p>Restart the timer from the current time</p>
<h5>`resume(...)`</h5>
<p>Resume a paused timer</p>
<hr>
<h3>class `Window`</h3>
<p>Window singleton for accessing and modifying the game window properties</p>
<h4>Methods</h4>
<h5>`center(...)`</h5>
<p>Center the window on the screen</p>
<h5>`get(...)`</h5>
<p>Get the Window singleton instance</p>
<h5>`screenshot(...)`</h5>
<hr>
<h2>Functions</h2>
<h3>Scene Management</h3>
<h3>`createScene(name: str)`</h3>
<p>Create a new empty scene.</p>
<em>*Args:*</em>
<p>name: Unique name for the new scene</p>
<em>*Raises:*</em>
<p>ValueError: If a scene with this name already exists</p>
<em>*Note:*</em>
<p>The scene is created but not made active. Use setScene() to switch to it.</p>
<hr>
<h3>`currentScene()`</h3>
<p>Get the name of the currently active scene.</p>
<em>*Returns:*</em>
<p>str: Name of the current scene</p>
<hr>
<h3>`keypressScene(handler: callable)`</h3>
<p>Set the keyboard event handler for the current scene.</p>
<em>*Args:*</em>
<p>handler: Callable that receives (key_name: str, is_pressed: bool)</p>
<em>*Example:*</em>
<p>def on_key(key, pressed):</p>
<p>if key == 'A' and pressed:</p>
<p>print('A key pressed')</p>
<p>mcrfpy.keypressScene(on_key)</p>
<hr>
<h3>`sceneUI(scene: str = None)`</h3>
<p>Get all UI elements for a scene.</p>
<em>*Args:*</em>
<p>scene: Scene name. If None, uses current scene</p>
<em>*Returns:*</em>
<p>list: All UI elements (Frame, Caption, Sprite, Grid) in the scene</p>
<em>*Raises:*</em>
<p>KeyError: If the specified scene doesn't exist</p>
<hr>
<h3>`setScene(scene: str, transition: str = None, duration: float = 0.0)`</h3>
<p>Switch to a different scene with optional transition effect.</p>
<em>*Args:*</em>
<p>scene: Name of the scene to switch to</p>
<p>transition: Transition type ('fade', 'slide_left', 'slide_right', 'slide_up', 'slide_down')</p>
<p>duration: Transition duration in seconds (default: 0.0 for instant)</p>
<em>*Raises:*</em>
<p>KeyError: If the scene doesn't exist</p>
<p>ValueError: If the transition type is invalid</p>
<hr>
<h3>Audio</h3>
<h3>`createSoundBuffer(filename: str)`</h3>
<p>Load a sound effect from a file and return its buffer ID.</p>
<em>*Args:*</em>
<p>filename: Path to the sound file (WAV, OGG, FLAC)</p>
<em>*Returns:*</em>
<p>int: Buffer ID for use with playSound()</p>
<em>*Raises:*</em>
<p>RuntimeError: If the file cannot be loaded</p>
<hr>
<h3>`getMusicVolume()`</h3>
<p>Get the current music volume level.</p>
<em>*Returns:*</em>
<p>int: Current volume (0-100)</p>
<hr>
<h3>`getSoundVolume()`</h3>
<p>Get the current sound effects volume level.</p>
<em>*Returns:*</em>
<p>int: Current volume (0-100)</p>
<hr>
<h3>`loadMusic(filename: str)`</h3>
<p>Load and immediately play background music from a file.</p>
<em>*Args:*</em>
<p>filename: Path to the music file (WAV, OGG, FLAC)</p>
<em>*Note:*</em>
<p>Only one music track can play at a time. Loading new music stops the current track.</p>
<hr>
<h3>`playSound(buffer_id: int)`</h3>
<p>Play a sound effect using a previously loaded buffer.</p>
<em>*Args:*</em>
<p>buffer_id: Sound buffer ID returned by createSoundBuffer()</p>
<em>*Raises:*</em>
<p>RuntimeError: If the buffer ID is invalid</p>
<hr>
<h3>`setMusicVolume(volume: int)`</h3>
<p>Set the global music volume.</p>
<em>*Args:*</em>
<p>volume: Volume level from 0 (silent) to 100 (full volume)</p>
<hr>
<h3>`setSoundVolume(volume: int)`</h3>
<p>Set the global sound effects volume.</p>
<em>*Args:*</em>
<p>volume: Volume level from 0 (silent) to 100 (full volume)</p>
<hr>
<h3>UI Utilities</h3>
<h3>`find(name: str, scene: str = None)`</h3>
<p>Find the first UI element with the specified name.</p>
<em>*Args:*</em>
<p>name: Exact name to search for</p>
<p>scene: Scene to search in (default: current scene)</p>
<em>*Returns:*</em>
<p>Frame, Caption, Sprite, Grid, or Entity if found; None otherwise</p>
<em>*Note:*</em>
<p>Searches scene UI elements and entities within grids.</p>
<hr>
<h3>`findAll(pattern: str, scene: str = None)`</h3>
<p>Find all UI elements matching a name pattern.</p>
<em>*Args:*</em>
<p>pattern: Name pattern with optional wildcards (* matches any characters)</p>
<p>scene: Scene to search in (default: current scene)</p>
<em>*Returns:*</em>
<p>list: All matching UI elements and entities</p>
<em>*Example:*</em>
<p>findAll('enemy*') # Find all elements starting with 'enemy'</p>
<p>findAll('*_button') # Find all elements ending with '_button'</p>
<hr>
<h3>System</h3>
<h3>`delTimer(name: str)`</h3>
<p>Stop and remove a timer.</p>
<em>*Args:*</em>
<p>name: Timer identifier to remove</p>
<em>*Note:*</em>
<p>No error is raised if the timer doesn't exist.</p>
<hr>
<h3>`exit()`</h3>
<p>Cleanly shut down the game engine and exit the application.</p>
<em>*Note:*</em>
<p>This immediately closes the window and terminates the program.</p>
<hr>
<h3>`getMetrics()`</h3>
<p>Get current performance metrics.</p>
<em>*Returns:*</em>
<p>dict: Performance data with keys:</p>
<ul>
<li>frame_time: Last frame duration in seconds</li>
<li>avg_frame_time: Average frame time</li>
<li>fps: Frames per second</li>
<li>draw_calls: Number of draw calls</li>
<li>ui_elements: Total UI element count</li>
<li>visible_elements: Visible element count</li>
<li>current_frame: Frame counter</li>
<li>runtime: Total runtime in seconds</li>
</ul>
<hr>
<h3>`setScale(multiplier: float)`</h3>
<p>Scale the game window size.</p>
<em>*Args:*</em>
<p>multiplier: Scale factor (e.g., 2.0 for double size)</p>
<em>*Note:*</em>
<p>The internal resolution remains 1024x768, but the window is scaled.</p>
<p>This is deprecated - use Window.resolution instead.</p>
<hr>
<h3>`setTimer(name: str, handler: callable, interval: int)`</h3>
<p>Create or update a recurring timer.</p>
<em>*Args:*</em>
<p>name: Unique identifier for the timer</p>
<p>handler: Function called with (runtime: float) parameter</p>
<p>interval: Time between calls in milliseconds</p>
<em>*Note:*</em>
<p>If a timer with this name exists, it will be replaced.</p>
<p>The handler receives the total runtime in seconds as its argument.</p>
<hr>
<h2>Automation Module</h2>
<p>The <code>mcrfpy.automation</code> module provides testing and automation capabilities.</p>
<h3>`automation.click(x=None, y=None, clicks=1, interval=0.0, button='left') - Click at position`</h3>
<p>click(x=None, y=None, clicks=1, interval=0.0, button='left') - Click at position</p>
<hr>
<h3>`automation.doubleClick(x=None, y=None) - Double click at position`</h3>
<p>doubleClick(x=None, y=None) - Double click at position</p>
<hr>
<h3>`automation.dragRel(xOffset, yOffset, duration=0.0, button='left') - Drag mouse relative to current position`</h3>
<p>dragRel(xOffset, yOffset, duration=0.0, button='left') - Drag mouse relative to current position</p>
<hr>
<h3>`automation.dragTo(x, y, duration=0.0, button='left') - Drag mouse to position`</h3>
<p>dragTo(x, y, duration=0.0, button='left') - Drag mouse to position</p>
<hr>
<h3>`automation.hotkey(*keys) - Press a hotkey combination (e.g., hotkey('ctrl', 'c'))`</h3>
<p>hotkey(*keys) - Press a hotkey combination (e.g., hotkey('ctrl', 'c'))</p>
<hr>
<h3>`automation.keyDown(key) - Press and hold a key`</h3>
<p>keyDown(key) - Press and hold a key</p>
<hr>
<h3>`automation.keyUp(key) - Release a key`</h3>
<p>keyUp(key) - Release a key</p>
<hr>
<h3>`automation.middleClick(x=None, y=None) - Middle click at position`</h3>
<p>middleClick(x=None, y=None) - Middle click at position</p>
<hr>
<h3>`automation.mouseDown(x=None, y=None, button='left') - Press mouse button`</h3>
<p>mouseDown(x=None, y=None, button='left') - Press mouse button</p>
<hr>
<h3>`automation.mouseUp(x=None, y=None, button='left') - Release mouse button`</h3>
<p>mouseUp(x=None, y=None, button='left') - Release mouse button</p>
<hr>
<h3>`automation.moveRel(xOffset, yOffset, duration=0.0) - Move mouse relative to current position`</h3>
<p>moveRel(xOffset, yOffset, duration=0.0) - Move mouse relative to current position</p>
<hr>
<h3>`automation.moveTo(x, y, duration=0.0) - Move mouse to absolute position`</h3>
<p>moveTo(x, y, duration=0.0) - Move mouse to absolute position</p>
<hr>
<h3>`automation.onScreen(x, y) - Check if coordinates are within screen bounds`</h3>
<p>onScreen(x, y) - Check if coordinates are within screen bounds</p>
<hr>
<h3>`automation.position() - Get current mouse position as (x, y) tuple`</h3>
<p>position() - Get current mouse position as (x, y) tuple</p>
<hr>
<h3>`automation.rightClick(x=None, y=None) - Right click at position`</h3>
<p>rightClick(x=None, y=None) - Right click at position</p>
<hr>
<h3>`automation.screenshot(filename) - Save a screenshot to the specified file`</h3>
<p>screenshot(filename) - Save a screenshot to the specified file</p>
<hr>
<h3>`automation.scroll(clicks, x=None, y=None) - Scroll wheel at position`</h3>
<p>scroll(clicks, x=None, y=None) - Scroll wheel at position</p>
<hr>
<h3>`automation.size() - Get screen size as (width, height) tuple`</h3>
<p>size() - Get screen size as (width, height) tuple</p>
<hr>
<h3>`automation.tripleClick(x=None, y=None) - Triple click at position`</h3>
<p>tripleClick(x=None, y=None) - Triple click at position</p>
<hr>
<h3>`automation.typewrite(message, interval=0.0) - Type text with optional interval between keystrokes`</h3>
<p>typewrite(message, interval=0.0) - Type text with optional interval between keystrokes</p>
<hr>
</body></html>