Regenerate HTML/Markdown API reference, man page, and type stubs against
current committed HEAD (post API-freeze pass #304-#308, #252 overhaul, and
Phase 3/4/5.1/5.2 changes).
The previous tools/generate_stubs_v2.py hand-maintained hardcoded strings,
which drifted badly: stubs still contained removed module functions
(setScale, findAll, getMetrics, setDevConsole), lacked new types (GridView,
Behavior, Trigger, DiscreteMap, Viewport3D, Entity3D, Model3D, Billboard,
NoiseSource, WangSet, LdtkProject, HeightMap, DijkstraMap, AStarPath,
ColorLayer, TileLayer, etc.), and missed post-overhaul properties
(tile_width/tile_height, sprite_grid, perspective_map, cell_pos, labels,
turn_order, move_speed, etc.).
Rewrite the generator as a runtime-introspection script mirroring
generate_dynamic_docs.py's approach:
- classify mcrfpy members (classes, enums, functions, constants, submodules)
- parse signatures from docstring first line with proper paren-depth tracking
- translate multi-form signatures (foo(x,y) or foo(pos)) to *args/**kwargs
- sanitize docstring '...' placeholder params into '**kwargs'
- emit IntEnum blocks for int-subclass types with uppercase members
- discover delegated methods via instance probing (Grid/GridView -> _GridData)
- conservative property type inference (only accept recognized primitives
and CapitalCase class names in parenthesized hints)
Resulting stubs/mcrfpy.pyi (2069 lines) parses as valid Python.
Markdown/HTML/man-page regeneration is otherwise timestamp-only since the
introspection path was already current -- the stubs were the stale artifact.
Per-entity FOV memory moves from std::vector<UIGridPointState> (two-bool
visible/discovered pairs) to a 3-state DiscreteMap (0=UNKNOWN, 1=DISCOVERED,
2=VISIBLE), exposed as entity.perspective_map. The invariant
visible-subset-of-discovered becomes structural (single value per cell), and
the map is a live, serializable, first-class object rather than an implicit
internal array.
Changes:
- New DiscreteMap C++ class with shared ownership; PyDiscreteMapObject now
holds shared_ptr<DiscreteMap>. UIEntity holds the same shared_ptr.
- New mcrfpy.Perspective IntEnum (UNKNOWN/DISCOVERED/VISIBLE), modelled on
PyInputState.
- entity.perspective_map: lazy-allocated on first access with a grid;
setter validates size against grid and raises ValueError on mismatch;
None clears (next access lazy-reallocates fresh).
- updateVisibility() now demotes 2->1 then promotes visible cells to 2.
- entity.at(x, y) returns grid.at(x, y) when VISIBLE, else None.
- Fog-of-war rendering in UIGridView and UIGrid reads the 3-state map.
- Removed: UIEntity::gridstate, ensureGridstate(), entity.gridstate getter,
UIGridPointState struct + PyUIGridPointStateType.
- Obsolete tests deleted (test_gridpointstate_point,
issue_265_gridpointstate_dangle); 4 new tests cover lazy allocation,
identity, serialization round-trip, size validation, and the
visible-subset-of-discovered invariant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Breaking API change: removes 4 camelCase function aliases from the mcrfpy
module. The snake_case equivalents (set_scale, find_all, get_metrics,
set_dev_console) remain and are the canonical API going forward.
- Removed setScale, findAll, getMetrics, setDevConsole from mcrfpyMethods[]
- Updated game scripts to use snake_case names
- Updated test scripts to use snake_case names
- Removed camelCase entries from type stubs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sprite_number was a legacy alias for sprite_index. All code should use
sprite_index directly. Removed from getsetters, setProperty/getProperty/
hasProperty in UISprite and UIEntity, animation property handling, and
type stubs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
closes#251
Two related bugs where Python garbage collection destroyed callbacks
that were still needed by live C++ objects:
1. **Drawable callbacks (all 8 types)**: tp_dealloc unconditionally called
click_unregister() etc., destroying callbacks even when the C++ object
was still alive in a parent's children vector. Fixed by guarding with
shared_ptr::use_count() <= 1 — only unregister when the Python wrapper
is the last owner.
2. **Timer GC prevention**: Active timers now hold a Py_INCREF'd reference
to their Python wrapper (Timer::py_wrapper), preventing GC while the
timer is registered in the engine. Released on stop(), one-shot fire,
or destruction. mcrfpy.Timer("name", cb, 100) now works without storing
the return value.
Also includes audio synth demo UI fixes: button click handling (don't set
on_click on Caption children), single-column slider layout, improved
Animalese contrast.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace module-level audio functions with proper OOP API:
- mcrfpy.Sound: Wraps sf::SoundBuffer + sf::Sound for short effects
- mcrfpy.Music: Wraps sf::Music for streaming long tracks
- Both support: volume, loop, playing, duration, play/pause/stop
- Music adds position property for seeking
Add mcrfpy.keyboard singleton for real-time modifier state:
- shift, ctrl, alt, system properties (bool, read-only)
- Queries sf::Keyboard::isKeyPressed() directly
Add mcrfpy.__version__ = "1.0.0" for version identity
Remove old audio API entirely (no deprecation - unused in codebase):
- createSoundBuffer, loadMusic, playSound
- setMusicVolume, getMusicVolume, setSoundVolume, getSoundVolume
closes#66, closes#160, closes#164🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add to Drawable base class:
- on_click, on_enter, on_exit, on_move callbacks (#140, #141)
- hovered read-only property (#140)
Add to Scene class:
- children property (#151)
- on_key handler property
Discovered while defining implementation details for #143.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Line, Circle, Arc class definitions to type stubs
- Update UIElement type alias to include new drawable types
- Rename click kwarg to on_click throughout stubs (matches #126 change)
- Update UICollection docstring to list all drawable types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BREAKING CHANGE: Constructor keyword argument renamed from `click` to
`on_click` for all UIDrawable types (Frame, Caption, Sprite, Grid, Line,
Circle, Arc).
Before: Frame(pos=(0,0), size=(100,100), click=handler)
After: Frame(pos=(0,0), size=(100,100), on_click=handler)
The property name was already `on_click` - this makes the constructor
kwarg match, completing the callback naming standardization from #139.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add AnimationConflictMode enum with three modes:
- REPLACE (default): Complete existing animation and start new one
- QUEUE: Wait for existing animation to complete before starting
- ERROR: Raise RuntimeError if property is already being animated
Changes:
- AnimationManager now tracks property locks per (target, property) pair
- Animation.start() accepts optional conflict_mode parameter
- Queued animations start automatically when property becomes free
- Updated type stubs with ConflictMode type alias
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- grid_demo.py: Updated for new layer-based rendering
- Screenshots: Refreshed demo screenshots
- API docs: Regenerated with latest method signatures
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>