`.parent` allocated a brand-new Python wrapper on every read, so object
identity never held: `kid.parent is parent` was False, and so was
`kid.parent is kid.parent`. A Frame/Grid subclass reached through .parent
came back as the base type with its Python attributes gone, and `.parent`
could not be used as a dict key or set member.
The cache-aware converter already existed -- convertDrawableToPython in
UICollection.cpp -- but was file-local, so three other paths hand-rolled
their own tp_alloc switch and skipped the cache:
- UIDrawable::get_parent (the filed bug)
- find_in_collection (mcrfpy.find / find_all)
- UIEntityCollection concat and slice __getitem__
The entity sites were the worst of them: a duplicate wrapper's tp_dealloc
unconditionally clears UIEntity::pyobject, destroying the #266 subclass
identity ref held by the *original* wrapper.
Promote the converter to UIDrawable::pyobject_for and route all sites
through it; add the matching convertEntityToPython for entities. This also
gives .parent the Line/Circle/Arc/Viewport3D arms it never had (they
previously fell through to None).
Residual gap, deliberately not closed here: the cache holds weakrefs, so a
subclass wrapper GC'd while only C++ holds the object still resurrects as
the base type. Closing that needs an owner-held strong ref (the #348
pattern) and is a lifetime design decision; filed separately.
Verified A/B: 17 of the new test's 22 checks fail pre-fix, all pass after.
Suite 330/330. Also corrects CLAUDE.md, which documented the long-deleted
RET_PY_INSTANCE macro and recommended bare tp_alloc as the "most common"
pattern -- i.e. taught this exact bug.
closes#369
The default Release build (-O3 -DNDEBUG) omits frame pointers and ships no
DWARF, so it can't be line-annotated or unwound; build-debug (-O0) profiles
unoptimized code. Add a dedicated profiling variant for C++ hot-path work
(validating #331/#342/#343/#344).
- CMakeLists.txt: MCRF_PROFILE option adds -fno-omit-frame-pointer on top of
RelWithDebInfo (-O2 -g). Binary not stripped. Post-build lib/assets/scripts
copy already keys on the mcrogueface target, so build-profile/ self-populates.
- Makefile: `make profile` (-> build-profile/), `make callgrind SCRIPT=...`
(one-shot Callgrind on a headless benchmark), `make clean-profile` (wired
into clean-all).
- docs/profiling.md: full Callgrind + perf workflow, incl. the one-time
`sudo sysctl kernel.perf_event_paranoid=1` perf needs on this box.
- Pointers from the Makefile header and CLAUDE.md build section.
Verified: DWARF sections present, frame-pointer prologues emitted, headless
smoke test passes, Callgrind yields source line + call-count attribution, and
perf --call-graph fp resolves engine symbols.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The issue tracker moved from gamedev.ffwf.net/gitea to
dev.ffwf.net/forgejo. Update all URLs in CLAUDE.md, README.md,
web/index.html, and tools/gitea_issues.py. CLAUDE.md also documents
the new resource-oriented forgejo MCP server (list/get/create/edit/
delete/link/unlink_gitea) and retires the stale v0.07 label-bug
workaround -- label operations re-validated working 2026-07-02.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CLAUDE.md had Audio as Stubbed for the SDL2/WASM build, but
SDL2_mixer is fully wired up via -sUSE_SDL_MIXER=2. Update table
to reflect current state (discovered during blog draft review).
Also commits previously-staged triage completion notes in
docs/ISSUE_TRIAGE_2026-04.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds MCRF_WASM_DEBUG CMake option that enables -g4, -gsource-map, and
--emit-symbol-map for WASM builds. New Makefile targets: wasm-debug,
playground-debug, serve-wasm-debug, serve-playground-debug.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous label IDs were incorrect (possibly from an older state).
Updated to match the live Gitea API as of 2026-04-09. Key differences:
- ID 2 is Minor Feature (was Alpha Release)
- ID 3 is Tiny Feature (was Bugfix)
- ID 8 is Bugfix (was tier2-foundation)
- System labels start at 9 (were at 11)
- Priority labels start at 17 (were at 7)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Doc generator fixes (tools/generate_dynamic_docs.py):
- Add types.GetSetDescriptorType detection for C++ extension properties
- All 22 classes with properties now have documented Properties sections
- Read-only detection via "read-only" docstring convention
Scene class documentation (src/PySceneObject.h):
- Expanded tp_doc with constructor, properties, lifecycle callbacks
- Documents key advantage: on_key works on ANY scene
- Includes usage examples for basic and subclass patterns
CLAUDE.md additions:
- New section "Adding Documentation for New Python Types"
- Step-by-step guide for tp_doc, PyMethodDef, PyGetSetDef
- Documentation extraction details and troubleshooting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Link to Development Workflow wiki page
- Clarify documentation update procedures
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major changes:
- Reorganized tests/ into unit/, integration/, regression/, benchmarks/, demo/
- Deleted 73 failing/outdated tests, kept 126 passing tests (100% pass rate)
- Created demo system with 6 feature screens (Caption, Frame, Primitives, Grid, Animation, Color)
- Updated .gitignore to track tests/ directory
- Updated CLAUDE.md with comprehensive testing guidelines and API quick reference
Demo system features:
- Interactive menu navigation (press 1-6 for demos, ESC to return)
- Headless screenshot generation for CI
- Per-feature demonstration screens with code examples
Testing infrastructure:
- tests/run_tests.py - unified test runner with timeout support
- tests/demo/demo_main.py - interactive/headless demo runner
- All tests are headless-compliant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added complete label category breakdown (System, Priority, Type/Scope, Workflow)
- Documented all 22 labels with descriptions and usage guidelines
- Added example label combinations for common scenarios
- Documented MCP tool label application issues (see #131)
- Provided label ID reference for documentation purposes
- Strong recommendation to apply labels manually via web interface
Related to #131🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Closes#127
Previously, `./mcrogueface --headless --exec <script>` would hang
indefinitely after the script completed because the game loop ran
continuously. This required external timeouts and explicit mcrfpy.exit()
calls in every automation script.
This commit adds automatic exit detection for headless+exec mode:
- Added `auto_exit_after_exec` flag to McRogueFaceConfig
- Set flag automatically when both --headless and --exec are present
- Game loop exits when no timers remain (timers.empty())
Benefits:
- Documentation generation scripts work without explicit exit calls
- Testing scripts don't need timeout wrappers
- Clean process termination for automation
- Backward compatible (scripts with mcrfpy.exit() continue working)
Changes:
- src/McRogueFaceConfig.h: Add auto_exit_after_exec flag
- src/main.cpp: Set flag and recreate engine with modified config
- src/GameEngine.cpp: Check timers.empty() in game loop
- ROADMAP.md: Mark Phase 7 as complete (2025-10-30)
- CLAUDE.md: Add instruction about closing issues with commit messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated documentation guidelines to reflect the new macro-based system:
- Documented MCRF_METHOD and MCRF_PROPERTY usage
- Listed all available macros (MCRF_SIG, MCRF_DESC, MCRF_ARG, etc.)
- Added prose guidelines (concise C++, verbose external docs)
- Updated regeneration workflow (removed references to deleted scripts)
- Emphasized single source of truth and zero-drift architecture
Removed references to obsolete hardcoded documentation scripts that were
deleted in previous commits.
Related: #92 (Inline C++ documentation system)
Establish Gitea as the single source of truth for issue tracking,
documentation, and project management to improve development efficiency.
CLAUDE.md changes:
- Add comprehensive "Gitea-First Workflow" section at top of file
- Document 5 core principles for using Gitea effectively
- Provide workflow pattern diagram for development process
- List available Gitea MCP tools for programmatic access
- Explain benefits: reduced context switching, better planning, living docs
ROADMAP.md changes:
- Add "Development Workflow" section referencing Gitea-first approach
- Include 5-step checklist for starting any work
- Link to detailed workflow guidelines in CLAUDE.md
- Emphasize Gitea as single source of truth
Workflow principles:
1. Always check Gitea issues/wiki before starting work
2. Create granular, focused issues for new features/problems
3. Document as you go - update related issues when work affects them
4. If docs mislead, create task to correct/expand them
5. Cross-reference everything - commits, issues, wiki pages
Benefits:
- Avoid re-reading entire codebase by consulting brief issue descriptions
- Reduce duplicate or contradictory work through better planning
- Maintain living documentation that stays current
- Capture historical context and decision rationale
- Improve efficiency using MCP tools for programmatic queries
This establishes best practices for keeping the project organized and
reducing cognitive load during development.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>