Follow-up to the macro conversion: an adversarial verify pass (one agent per file vs. the C++ implementation + stubs) found 62 content issues; the real ones are fixed here. Callbacks (centralized): - on_click: receives (pos, MouseButton, InputState), not str (8 files). - on_enter/on_exit/on_move (UIBase.h): hover passes only (pos) -- removed the fictional button/action args. - bounds/global_bounds (UIBase.h): mark (tuple, read-only). Signatures / types: - Grid.find_path: document heuristic + weight; get_dijkstra_map: document roots; compute_fov: FOV | int = FOV.BASIC (not the C constant FOV_BASIC) + Returns; at/is_in_fov: document (pos) and (x, y) call forms. - get_metrics: document all 16 returned dict keys (was 8); bresenham: drop the bogus '*' keyword-only separator. - Nullable defaults typed correctly: BSP seed/size, ColorLayer draw_fov/ apply_perspective Color|None, Entity.visible_entities radius int=-1 (None is rejected by the 'i' parser -> see #319). - Type-token fixes: GridView.center -> Vector; GridView.texture -> (None, read-only) (unimplemented, #318); GridPoint.grid_pos -> (tuple, read-only); EntityCollection.find -> Entity | list[Entity] | None; extend RuntimeError; UniformCollection.values -> list[float | tuple | None]. - automation: onScreen (x, y) form documented; scroll notes x is ignored (#317). Also: correct stale AStarPath/DijkstraMap signatures in docs/api-audit-2026-04.md (the bindings were right, the audit table was outdated). Rebaseline the API snapshot golden and regenerate docs/stubs. Code-level bugs surfaced by the pass are filed as #317, #318, #319. Refs #314, #317, #318, #319 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
30 KiB
McRogueFace Python API Consistency Audit
Date: 2026-04-09 Version: 0.2.6-prerelease Purpose: Catalog the full public API surface, identify inconsistencies and issues before 1.0 API freeze.
Table of Contents
- Executive Summary
- Module-Level API
- Core Value Types
- UI Drawable Types
- Grid System
- Entity System
- Collections
- Audio Types
- Procedural Generation
- Pathfinding
- Shader System
- Tiled/LDtk Import
- 3D/Experimental Types
- Enums
- Findings: Naming Inconsistencies
- Findings: Missing Functionality
- Findings: Deprecations to Resolve
- Findings: Documentation Gaps
- Recommendations
Executive Summary
The McRogueFace Python API exposes 46 exported types, 14 internal types, 10 enums, 13 module-level functions, 7 module-level properties, and 5 singleton instances through the mcrfpy module.
Overall, the API is remarkably consistent. Properties and methods use snake_case throughout the type system. The major inconsistencies are concentrated in a few areas:
- 4 module-level functions use camelCase (
setScale,findAll,getMetrics,setDevConsole) - Terse/placeholder docstrings on 5 core types (Vector, Font, Texture, GridPoint, GridPointState)
- Deprecated property aliases still exposed (
sprite_number) - Color property naming split: some types use
fill_color/outline_color, others usecolor - Redundant position aliases on Entity (
grid_posvscell_posfor the same data)
Module-Level API
Functions (mcrfpy.*)
| Function | Signature | Notes |
|---|---|---|
step |
(dt: float = None) -> float |
Advance simulation (headless mode) |
exit |
() -> None |
Shutdown engine |
find |
(name: str, scene: str = None) -> Drawable | None |
Find UI element by name |
lock |
() -> _LockContext |
Thread-safe UI update context manager |
bresenham |
(start, end, *, include_start=True, include_end=True) -> list[tuple] |
Line algorithm |
start_benchmark |
() -> None |
Begin benchmark capture |
end_benchmark |
() -> str |
End benchmark, return filename |
log_benchmark |
(message: str) -> None |
Add benchmark annotation |
_sync_storage |
() -> None |
WASM persistent storage flush |
setScale |
(multiplier: float) -> None |
CAMELCASE - deprecated |
findAll |
(pattern: str, scene: str = None) -> list |
CAMELCASE |
getMetrics |
() -> dict |
CAMELCASE |
setDevConsole |
(enabled: bool) -> None |
CAMELCASE |
Properties (mcrfpy.*)
| Property | Type | Writable | Notes |
|---|---|---|---|
current_scene |
Scene | None |
Yes | Active scene |
scenes |
dict[str, Scene] |
No | All registered scenes |
timers |
list[Timer] |
No | Active timers |
animations |
list[Animation] |
No | Active animations |
default_transition |
Transition |
Yes | Scene transition effect |
default_transition_duration |
float |
Yes | Transition duration |
save_dir |
str |
No | Platform-specific save path |
Singletons
| Name | Type | Notes |
|---|---|---|
keyboard |
Keyboard |
Modifier key state |
mouse |
Mouse |
Position and button state |
window |
Window |
Window properties |
default_font |
Font |
JetBrains Mono |
default_texture |
Texture |
Kenney Tiny Dungeon (16x16) |
Constants
| Name | Type | Value |
|---|---|---|
__version__ |
str |
Build version string |
default_fov |
FOV |
FOV.BASIC |
Submodules
| Name | Contents |
|---|---|
automation |
Screenshot, click simulation, testing utilities |
Core Value Types
Color
Color(r: int = 0, g: int = 0, b: int = 0, a: int = 255)
| Properties | Type | R/W |
|---|---|---|
r, g, b, a |
int (0-255) | R/W |
| Methods | Signature |
|---|---|
from_hex |
(cls, hex_string: str) -> Color (classmethod) |
to_hex |
() -> str |
lerp |
(other: Color, t: float) -> Color |
Protocols: __repr__, __hash__
Vector
Vector(x: float = 0, y: float = 0)
| Properties | Type | R/W |
|---|---|---|
x, y |
float | R/W |
int |
tuple[int, int] | R |
| Methods | Signature |
|---|---|
magnitude |
() -> float |
magnitude_squared |
() -> float |
normalize |
() -> Vector |
dot |
(other: Vector) -> float |
distance_to |
(other: Vector) -> float |
angle |
() -> float |
copy |
() -> Vector |
floor |
() -> Vector |
Protocols: __repr__, __hash__, __eq__/__ne__, arithmetic (+, -, *, /, -x, abs), sequence (len, [0]/[1])
Font
Font(filename: str)
| Properties | Type | R/W |
|---|---|---|
family |
str | R |
source |
str | R |
Methods: None
Protocols: __repr__
Texture
Texture(filename: str, sprite_width: int, sprite_height: int)
| Properties | Type | R/W |
|---|---|---|
sprite_width, sprite_height |
int | R |
sheet_width, sheet_height |
int | R |
sprite_count |
int | R |
source |
str | R |
| Methods | Signature |
|---|---|
from_bytes |
(cls, data, w, h, sprite_w, sprite_h, name=...) -> Texture (classmethod) |
composite |
(cls, layers, sprite_w, sprite_h, name=...) -> Texture (classmethod) |
hsl_shift |
(hue_shift, sat_shift=0, lit_shift=0) -> Texture |
Protocols: __repr__, __hash__
UI Drawable Types
Base: Drawable (abstract)
Cannot be instantiated directly.
| Properties | Type | R/W | Notes |
|---|---|---|---|
on_click |
callable | R/W | (pos, button, action) |
z_index |
int | R/W | Render order |
visible |
bool | R/W | |
opacity |
float | R/W | 0.0-1.0 |
name |
str | R/W | |
pos |
Vector | R/W | |
parent |
Drawable | R | |
align |
Alignment | R/W | |
margin, horiz_margin, vert_margin |
float | R/W | |
shader |
Shader | R/W | |
uniforms |
UniformCollection | R | |
rotation |
float | R/W | |
origin |
Vector | R/W |
| Methods | Signature |
|---|---|
move |
(dx, dy) or (delta) |
resize |
(w, h) or (size) |
animate |
(property, target, duration, easing, ...) |
Frame
Frame(pos=None, size=None, **kwargs)
Additional properties beyond Drawable:
| Properties | Type | R/W |
|---|---|---|
x, y, w, h |
float | R/W |
fill_color |
Color | R/W |
outline_color |
Color | R/W |
outline |
float | R/W |
children |
UICollection | R |
clip_children |
bool | R/W |
cache_subtree |
bool | R/W |
grid_pos, grid_size |
Vector | R/W |
Caption
Caption(pos=None, font=None, text='', **kwargs)
Additional properties beyond Drawable:
| Properties | Type | R/W |
|---|---|---|
x, y |
float | R/W |
w, h |
float | R (computed) |
size |
Vector | R (computed) |
text |
str | R/W |
font_size |
float | R/W |
fill_color |
Color | R/W |
outline_color |
Color | R/W |
outline |
float | R/W |
Sprite
Sprite(pos=None, texture=None, sprite_index=0, **kwargs)
Additional properties beyond Drawable:
| Properties | Type | R/W | Notes |
|---|---|---|---|
x, y |
float | R/W | |
w, h |
float | R (computed) | |
scale |
float | R/W | Uniform scale |
scale_x, scale_y |
float | R/W | Per-axis scale |
sprite_index |
int | R/W | |
sprite_number |
int | R/W | DEPRECATED alias |
texture |
Texture | R/W |
Line
Line(start=None, end=None, thickness=1.0, color=None, **kwargs)
| Properties | Type | R/W | Notes |
|---|---|---|---|
start |
Vector | R/W | |
end |
Vector | R/W | |
color |
Color | R/W | Not fill_color |
thickness |
float | R/W |
Circle
Circle(radius=0, center=None, fill_color=None, outline_color=None, outline=0, **kwargs)
| Properties | Type | R/W |
|---|---|---|
radius |
float | R/W |
center |
Vector | R/W |
fill_color |
Color | R/W |
outline_color |
Color | R/W |
outline |
float | R/W |
Arc
Arc(center=None, radius=0, start_angle=0, end_angle=90, color=None, thickness=1, **kwargs)
| Properties | Type | R/W | Notes |
|---|---|---|---|
center |
Vector | R/W | |
radius |
float | R/W | |
start_angle, end_angle |
float | R/W | Degrees |
color |
Color | R/W | Not fill_color |
thickness |
float | R/W |
Grid System
Grid (also available as GridView)
Grid(grid_size=None, pos=None, size=None, texture=None, **kwargs)
| Properties | Type | R/W | Notes |
|---|---|---|---|
grid_size, grid_w, grid_h |
tuple/int | R | |
x, y, w, h |
float | R/W | |
pos, position |
Vector | R/W | position is redundant alias |
center |
Vector | R/W | Camera center (pixels) |
center_x, center_y |
float | R/W | |
zoom |
float | R/W | |
camera_rotation |
float | R/W | |
fill_color |
Color | R/W | |
texture |
Texture | R | |
entities |
EntityCollection | R | |
children |
UICollection | R | |
layers |
tuple | R | |
perspective, perspective_enabled |
various | R/W | |
fov, fov_radius |
various | R/W | |
on_cell_enter, on_cell_exit, on_cell_click |
callable | R/W | |
hovered_cell |
tuple | R | |
grid_data |
_GridData | R/W | Internal grid reference |
| Methods | Signature |
|---|---|
at |
(x, y) or (pos) -> GridPoint |
compute_fov |
(pos, radius, light_walls, algorithm) |
is_in_fov |
(pos) -> bool |
find_path |
(start, end, diagonal_cost, collide) -> AStarPath |
get_dijkstra_map |
(root, diagonal_cost, collide) -> DijkstraMap |
clear_dijkstra_maps |
() |
add_layer |
(layer) |
remove_layer |
(name_or_layer) |
layer |
(name) -> ColorLayer | TileLayer |
entities_in_radius |
(pos, radius) -> list |
center_camera |
(pos) -- tile coordinates |
apply_threshold |
(source, range, walkable, transparent) |
apply_ranges |
(source, ranges) |
step |
(n, turn_order) -- turn management |
GridPoint (internal, returned by Grid.at())
| Properties | Type | R/W |
|---|---|---|
walkable |
bool | R/W |
transparent |
bool | R/W |
entities |
list | R |
grid_pos |
tuple | R |
Dynamic attributes: named layer data via __getattr__/__setattr__
GridPointState (internal, returned by entity gridstate)
| Properties | Type | R/W |
|---|---|---|
visible |
bool | R/W |
discovered |
bool | R/W |
point |
GridPoint | R |
ColorLayer
ColorLayer(z_index=-1, name=None, grid_size=None)
| Properties | Type | R/W |
|---|---|---|
z_index |
int | R/W |
visible |
bool | R/W |
grid_size |
tuple | R |
name |
str | R |
grid |
Grid | R/W |
| Methods | Signature |
|---|---|
at |
(x, y) or (pos) -> Color |
set |
(pos, color) |
fill |
(color) |
fill_rect |
(pos, size, color) |
draw_fov |
(source, radius, fov, visible, discovered, unknown) |
apply_perspective |
(entity, visible, discovered, unknown) |
update_perspective |
() |
clear_perspective |
() |
apply_threshold |
(source, range, color) |
apply_gradient |
(source, range, color_low, color_high) |
apply_ranges |
(source, ranges) |
TileLayer
TileLayer(z_index=-1, name=None, texture=None, grid_size=None)
| Properties | Type | R/W |
|---|---|---|
z_index |
int | R/W |
visible |
bool | R/W |
texture |
Texture | R/W |
grid_size |
tuple | R |
name |
str | R |
grid |
Grid | R/W |
| Methods | Signature |
|---|---|
at |
(x, y) or (pos) -> int |
set |
(pos, index) |
fill |
(index) |
fill_rect |
(pos, size, index) |
apply_threshold |
(source, range, tile) |
apply_ranges |
(source, ranges) |
Entity System
Entity
Entity(grid_pos=None, texture=None, sprite_index=0, **kwargs)
| Properties | Type | R/W | Notes |
|---|---|---|---|
pos, x, y |
Vector/float | R/W | Pixel position |
cell_pos, cell_x, cell_y |
Vector/int | R/W | Integer cell coords |
grid_pos, grid_x, grid_y |
Vector/int | R/W | Same as cell_pos |
draw_pos |
Vector | R/W | Fractional tile position |
sprite_index |
int | R/W | |
sprite_number |
int | R/W | DEPRECATED alias |
sprite_offset, sprite_offset_x, sprite_offset_y |
Vector/float | R/W | |
grid |
Grid | R/W | |
gridstate |
GridPointState | R | |
labels |
frozenset | R/W | |
step |
callable | R/W | Turn callback |
default_behavior |
Behavior | R/W | |
behavior_type |
Behavior | R | |
turn_order |
int | R/W | |
move_speed |
float | R/W | |
target_label |
str | R/W | |
sight_radius |
int | R/W | |
visible, opacity, name |
various | R/W | |
shader, uniforms |
various | R/W |
| Methods | Signature |
|---|---|
at |
(x, y) or (pos) -> GridPoint |
index |
() -> int |
die |
() |
path_to |
(x, y) or (target) -> AStarPath |
find_path |
(target, diagonal_cost, collide) -> AStarPath |
update_visibility |
() |
visible_entities |
(fov, radius) -> list |
animate |
(property, target, duration, easing, ...) |
Collections
UICollection (internal, returned by Frame.children / Scene.children)
| Methods | Signature |
|---|---|
append |
(element) |
extend |
(iterable) |
insert |
(index, element) |
remove |
(element) |
pop |
([index]) -> Drawable |
index |
(element) -> int |
count |
(element) -> int |
find |
(name, recursive=False) -> Drawable | None |
Protocols: len, [], slicing, iteration
EntityCollection (internal, returned by Grid.entities)
Same methods as UICollection. Protocols: len, [], slicing, iteration.
Audio Types
Sound
Sound(source: str | SoundBuffer)
| Properties | Type | R/W |
|---|---|---|
volume |
float (0-100) | R/W |
loop |
bool | R/W |
playing |
bool | R |
duration |
float | R |
source |
str | R |
pitch |
float | R/W |
buffer |
SoundBuffer | R |
| Methods | Signature |
|---|---|
play |
() |
pause |
() |
stop |
() |
play_varied |
(pitch_range=0.1, volume_range=3.0) |
SoundBuffer
SoundBuffer(filename: str)
| Properties | Type | R/W |
|---|---|---|
duration |
float | R |
sample_count |
int | R |
sample_rate |
int | R |
channels |
int | R |
sfxr_params |
dict | R |
| Methods | Signature | Notes |
|---|---|---|
from_samples |
(cls, data, channels, sample_rate) -> SoundBuffer |
classmethod |
tone |
(cls, frequency, duration, waveform='sine', ...) -> SoundBuffer |
classmethod |
sfxr |
(cls, preset, seed=None) -> SoundBuffer |
classmethod |
concat |
(cls, buffers) -> SoundBuffer |
classmethod |
mix |
(cls, buffers) -> SoundBuffer |
classmethod |
pitch_shift |
(semitones) -> SoundBuffer |
returns new |
low_pass |
(cutoff) -> SoundBuffer |
returns new |
high_pass |
(cutoff) -> SoundBuffer |
returns new |
echo |
(delay, decay) -> SoundBuffer |
returns new |
reverb |
(room_size) -> SoundBuffer |
returns new |
distortion |
(gain) -> SoundBuffer |
returns new |
bit_crush |
(bits) -> SoundBuffer |
returns new |
gain |
(amount) -> SoundBuffer |
returns new |
normalize |
() -> SoundBuffer |
returns new |
reverse |
() -> SoundBuffer |
returns new |
slice |
(start, end) -> SoundBuffer |
returns new |
sfxr_mutate |
(amount) -> SoundBuffer |
returns new |
Music
Music(filename: str)
| Properties | Type | R/W |
|---|---|---|
volume |
float (0-100) | R/W |
loop |
bool | R/W |
playing |
bool | R |
duration |
float | R |
position |
float | R/W |
source |
str | R |
| Methods | Signature |
|---|---|
play |
() |
pause |
() |
stop |
() |
Procedural Generation
HeightMap
HeightMap(size: tuple[int, int], fill: float = 0.0)
| Properties | Type | R/W |
|---|---|---|
size |
tuple | R |
46 methods covering: fill/clear, get/set (via []), math operations, noise, erosion, BSP integration, kernel operations, binary operations.
Protocols: [x, y] subscript (get/set)
DiscreteMap
DiscreteMap(size: tuple[int, int], fill: int = 0, enum: type[IntEnum] = None)
| Properties | Type | R/W |
|---|---|---|
size |
tuple | R |
enum_type |
type | R/W |
22 methods covering: fill/clear, get/set (via []), math, bitwise, statistics, conversion.
Protocols: [x, y] subscript (get/set)
BSP
BSP(pos: tuple[int, int], size: tuple[int, int])
| Properties | Type | R/W |
|---|---|---|
bounds, pos, size |
tuple | R |
root |
BSPNode | R |
adjacency |
BSPAdjacency | R |
| Methods | Signature |
|---|---|
split_once |
(...) |
split_recursive |
(...) |
clear |
() |
leaves |
() -> list[BSPNode] |
traverse |
(order) -> BSPIter |
find |
(pos) -> BSPNode |
get_leaf |
(index) -> BSPNode |
to_heightmap |
() -> HeightMap |
NoiseSource
NoiseSource(dimensions=2, algorithm='simplex', hurst=0.5, lacunarity=2.0, seed=None)
| Properties | Type | R/W |
|---|---|---|
dimensions, algorithm, hurst, lacunarity, seed |
various | R |
| Methods | Signature |
|---|---|
get |
(pos) -> float |
fbm |
(pos, octaves=4) -> float |
turbulence |
(pos, octaves=4) -> float |
sample |
(size, world_origin, world_size, mode, octaves) -> HeightMap |
Pathfinding
AStarPath
| Properties | Type | R/W |
|---|---|---|
origin |
tuple | R |
destination |
tuple | R |
remaining |
int | R |
| Methods | Signature |
|---|---|
walk |
() -> Vector |
peek |
() -> Vector |
Protocols: len, bool, iteration
DijkstraMap
| Properties | Type | R/W |
|---|---|---|
root |
tuple | R |
| Methods | Signature |
|---|---|
distance |
(pos) -> float | None |
path_from |
(pos) -> AStarPath |
step_from |
(pos) -> Vector | None |
to_heightmap |
(size=None, unreachable=-1.0) -> HeightMap |
Shader System
Shader
Shader(fragment_source: str, dynamic: bool = False)
| Properties | Type | R/W |
|---|---|---|
dynamic |
bool | R/W |
source |
str | R |
is_valid |
bool | R |
| Methods | Signature |
|---|---|
set_uniform |
(name: str, value: float | tuple) |
PropertyBinding
PropertyBinding(target: Drawable, property: str)
| Properties | Type | R/W |
|---|---|---|
target |
Drawable | R |
property |
str | R |
value |
float | R |
is_valid |
bool | R |
CallableBinding
CallableBinding(callable: Callable[[], float])
| Properties | Type | R/W |
|---|---|---|
callable |
callable | R |
value |
float | R |
is_valid |
bool | R |
UniformCollection (internal, returned by drawable.uniforms)
Dict-like container. Supports [], del, in, keys(), values(), items(), clear().
Tiled/LDtk Import
TileSetFile
TileSetFile(path: str)
Properties (all R): name, tile_width, tile_height, tile_count, columns, margin, spacing, image_source, properties, wang_sets
Methods: to_texture(), tile_info(id), wang_set(name)
TileMapFile
TileMapFile(path: str)
Properties (all R): width, height, tile_width, tile_height, orientation, properties, tileset_count, tile_layer_names, object_layer_names
Methods: tileset(index), tile_layer_data(name), resolve_gid(gid), object_layer(name), apply_to_tile_layer(layer, name)
WangSet (factory-created from TileSetFile)
Properties (all R): name, type, color_count, colors
Methods: terrain_enum(), resolve(discrete_map), apply(discrete_map, tile_layer)
LdtkProject
LdtkProject(path: str)
Properties (all R): version, tileset_names, ruleset_names, level_names, enums
Methods: tileset(name), ruleset(name), level(name)
AutoRuleSet (factory-created from LdtkProject)
Properties (all R): name, grid_size, value_count, values, rule_count, group_count
Methods: terrain_enum(), resolve(discrete_map), apply(discrete_map, tile_layer)
3D/Experimental Types
These are exempt from the 1.0 API freeze per ROADMAP.md.
Viewport3D, Entity3D, EntityCollection3D, Model3D, Billboard, VoxelGrid, VoxelRegion, VoxelPoint, Camera3D (via Viewport3D properties).
Enums
| Enum | Values | Notes |
|---|---|---|
Key |
42+ keyboard keys | Legacy string comparison (Key.ESCAPE == "Escape") |
InputState |
PRESSED, RELEASED |
Legacy: "start", "end" |
MouseButton |
LEFT, RIGHT, MIDDLE, X1, X2 |
Legacy: "left", "right", "middle" |
Easing |
32 easing functions | Linear, Quad, Cubic, etc. |
Transition |
Scene transition effects | |
Traversal |
BSP traversal orders | |
Alignment |
9 positions + NONE | TOP_LEFT through BOTTOM_RIGHT |
Behavior |
11 entity behaviors | For grid.step() turn system |
Trigger |
3 trigger types | Entity step callbacks |
FOV |
FOV algorithms | Maps to libtcod |
Findings: Naming Inconsistencies
F1: Module-level camelCase functions (CRITICAL)
Four module-level functions use camelCase while everything else uses snake_case:
| Current | Should Be | Status |
|---|---|---|
setScale |
set_scale |
Deprecated anyway (use Window.resolution) |
findAll |
find_all |
Active, needs alias |
getMetrics |
get_metrics |
Active, needs alias |
setDevConsole |
set_dev_console |
Active, needs alias |
Resolution: Add snake_case aliases. Keep camelCase temporarily for backward compatibility. Remove camelCase in 1.0.
F2: Color property naming split
Filled shapes (Frame, Caption, Circle) use fill_color/outline_color. Stroke-only shapes (Line, Arc) use color. This is actually semantically correct -- Line and Arc don't have a "fill" concept. No change needed, but worth documenting.
F3: Redundant Entity position aliases
Entity exposes the same cell position data under two names:
grid_pos,grid_x,grid_ycell_pos,cell_x,cell_y
Both exist because grid_pos is the constructor parameter name and cell_pos is more descriptive. Recommendation: Keep both but document grid_pos as the canonical name (matches constructor).
F4: Grid position alias
Grid.position is a redundant alias for Grid.pos. All other types use only pos. Recommendation: Deprecate position, keep pos.
F5: Iterator type naming
UICollectionIter-- has "UI" prefixUIEntityCollectionIter-- has "UI" prefixEntityCollection3DIter-- no "UI" prefix
The "UI" prefix is an internal detail leaking into type names. Since these are internal types (not exported), this is cosmetic but worth noting.
Findings: Missing Functionality
F6: No __eq__ on Color
Color has __hash__ but no __eq__/__ne__. Two colors with the same RGBA values may not compare equal. This is a bug.
F7: No Music.pitch
Sound has a pitch property but Music does not, despite SFML supporting it. Minor omission.
F8: No Font methods
Font has no methods at all -- not even a way to query available sizes or get text metrics. This limits text layout capabilities.
F9: GridPoint has no __init__
GridPoint cannot be constructed from Python (tp_new = NULL). This is intentional (it's a view into grid data) but should be clearly documented.
F10: Animation direct construction deprecated but not marked
The Animation class can still be instantiated directly even though .animate() on drawables is preferred. No deprecation warning is emitted.
Findings: Deprecations to Resolve
F11: sprite_number on Sprite and Entity
Both types expose sprite_number as a deprecated alias for sprite_index. This should be removed before 1.0.
F12: setScale module function
Deprecated in favor of Window.resolution. Should be removed before 1.0.
F13: Legacy string enum comparisons
Key, InputState, MouseButton support comparing to legacy string values (e.g., Key.ESCAPE == "Escape", InputState.PRESSED == "start"). This backward compatibility layer should be removed before 1.0.
Findings: Documentation Gaps
F14: Terse docstrings on core types
Several types have placeholder-quality tp_doc strings:
| Type | Current tp_doc | Should be |
|---|---|---|
Vector |
"SFML Vector Object" |
Full constructor docs with args |
Font |
"SFML Font Object" |
Full constructor docs |
Texture |
"SFML Texture Object" |
Full constructor docs |
GridPoint |
"UIGridPoint object" |
Description of purpose and access pattern |
GridPointState |
"UIGridPointState object" |
Description of purpose |
F15: Missing MCRF_* macro usage
Some types use raw string docstrings for methods instead of MCRF_METHOD macros. This means the documentation pipeline may miss them.
Recommendations
Before 1.0 (Breaking Changes)
- Remove camelCase functions:
setScale,findAll,getMetrics,setDevConsole - Remove
sprite_numberdeprecated alias from Sprite and Entity - Remove legacy string enum comparisons from Key, InputState, MouseButton
- Remove
Grid.positionredundant alias (keeppos) - Add
__eq__/__ne__to Color type
Immediate (Non-Breaking)
- Add snake_case aliases for the 4 camelCase module functions
- Improve docstrings on Vector, Font, Texture, GridPoint, GridPointState
- Document
grid_posvscell_pos-- state thatgrid_posis canonical
Future Considerations
- Add
pitchtoMusic - Add basic text metrics to
Font - Consider deprecation warnings for
Animation()direct construction - Unify iterator type naming (remove "UI" prefix from internal types)
Statistics
| Category | Count |
|---|---|
| Exported types | 46 |
| Internal types | 14 |
| Enums | 10 |
| Module functions | 13 |
| Module properties | 7 |
| Singletons | 5 |
| Total public API surface | ~93 named items |
| Naming inconsistencies found | 5 |
| Missing functionality items | 5 |
| Deprecations to resolve | 3 |
| Documentation gaps | 2 |
| Total findings | 15 |
#314 Freeze Decisions (2026-06, recorded before generating the API-surface snapshot)
The April audit body above is partly stale. Live introspection of the built module gives the
authoritative counts, and the snapshot test (tests/unit/api_surface_snapshot_test.py) is built
from live introspection, not from this document.
Corrected live counts (2026-06): 12 enums (audit said 10 — adds Perspective #294 and
Heuristic #315), 46 exported classes, 12 module functions, 7 singletons/constants (incl. the
automation submodule), 1 submodule. GridPointState was removed in #294 (its F14 row is moot).
Per-finding final status: F1, F4, F6, F10, F11, F13, F14 = RESOLVED (verified in source via
#304–#308). F2 = correct-by-design (docs-only). F5, F9 = cosmetic, unchanged. F7 (Music.pitch),
F8 (Font methods) = Future, explicitly NOT 1.0 blockers.
Decisions locked for the freeze (the snapshot golden enshrines these):
- F3 (cell-position canonical name):
grid_posis canonical (matches thegrid_pos=constructor argument);cell_pos/cell_x/cell_yare documented aliases. Both share the same getter/setter and remain interchangeable. Docstrings aligned atsrc/UIEntity.cppgetsetters. - F12 (
set_scale): KEPT in the 1.0 surface as a documented-deprecated function. Removing it now would itself be a new breaking change; the snapshot locks it in. mcrfpy.automation: PyAutoGUI-compatibility camelCase (moveRel/dragTo/etc.) is EXEMPT from the snake_case rule. The snapshot records it in a clearly-labeled section.entity.texture(new in #313): additive read/write property; getter returns the entity's real texture,Noneonly in the degenerate (default_texture-null) case — never re-derefs a null default_texture. Added to the frozen contract + stubs + docs when #313 lands (golden gains exactly one line). Known edges, frozen as-is (2026-06-11 adversarial review): the getter mints a NEW Texture wrapper per access and Texture has no__eq__, soe.texture == e.textureis False — compare.source/sprite dims instead (same behavior as the pre-existingSprite.texture); setting does not re-validatesprite_indexagainst the new atlas; setter rejects non-Texture (TypeError), null-data Texture wrappers (ValueError, mirrorsSprite.texture), and deletion.
1.0 freeze scope — class classification (the snapshot segregates FROZEN vs EXPERIMENTAL):
- FROZEN (stable 1.0): core value types (Color, Vector, Font, Texture), UI drawables
(Drawable [root], Frame, Caption, Sprite, Line, Circle, Arc), Grid/GridView/Entity, Scene,
Window, Timer, Keyboard, Mouse, audio (Sound, SoundBuffer, Music), procgen (BSP, HeightMap,
NoiseSource, DijkstraMap, AStarPath), all 12 enums, the snake_case module functions, and the
singletons. (Provisionally frozen, flagged for confirmation at golden review:
ColorLayer,TileLayer[core grid layers, distinct from Tiled import],DiscreteMap[#293/#294 grid data].) - EXPERIMENTAL (exempt, may change post-1.0): 3D/Voxel (Billboard, Entity3D, EntityCollection3D[Iter], Model3D, Viewport3D, VoxelGrid, VoxelRegion), Tiled import (TileSetFile, TileMapFile, WangSet), LDtk import (LdtkProject, AutoRuleSet), Shader, and binding helpers (CallableBinding, PropertyBinding).
The snapshot test FAILS on any exported class not classified (forces a deliberate decision for future additions).