summaryrefslogtreecommitdiff
path: root/doc/CONTRIBUTING.md
AgeCommit message (Collapse)Author
28 hoursfeat(build): Add FINAL_STRIP mode for maximum size optimizationskal
Implemented systematic fatal error checking infrastructure that can be stripped for final builds. This addresses the need to remove all error checking (abort() calls) from the production binary while maintaining safety during development. ## New Infrastructure ### 1. CMake Option: DEMO_FINAL_STRIP - New build mode for absolute minimum binary size - Implies DEMO_STRIP_ALL (stricter superset) - NOT included in DEMO_ALL_OPTIONS (manual opt-in only) - Message printed during configuration ### 2. Header: src/util/fatal_error.h - Systematic macro-based error checking - Zero cost when FINAL_STRIP enabled (compiles to ((void)0)) - Full error messages with file:line info when enabled - Five macros for different use cases: - FATAL_CHECK(cond, msg, ...): Conditional checks (most common) - FATAL_ERROR(msg, ...): Unconditional errors - FATAL_UNREACHABLE(): Unreachable code markers - FATAL_ASSERT(cond): Assertion-style invariants - FATAL_CODE_BEGIN/END: Complex validation blocks ### 3. CMake Target: make final - Convenience target for triggering final build - Reconfigures with FINAL_STRIP and rebuilds demo64k - Only available when NOT in FINAL_STRIP mode (prevents recursion) ### 4. Script: scripts/build_final.sh - Automated final build workflow - Creates build_final/ directory - Shows size comparison with STRIP_ALL build (if available) - Comprehensive warnings about stripped error checking ## Build Mode Hierarchy | Mode | Error Checks | Debug Features | Size Opt | |-------------|--------------|----------------|----------| | Debug | ✅ | ✅ | ❌ | | STRIP_ALL | ✅ | ❌ | ✅ | | FINAL_STRIP | ❌ | ❌ | ✅✅ | ## Design Decisions (All Agreed Upon) 1. **FILE:LINE Info**: ✅ Include (worth 200 bytes for debugging) 2. **ALL_OPTIONS**: ❌ Manual opt-in only (too dangerous for testing) 3. **FATAL_ASSERT**: ✅ Add macro (semantic clarity for invariants) 4. **Strip Hierarchy**: ✅ STRIP_ALL keeps checks, FINAL_STRIP removes all 5. **Naming**: ✅ FATAL_* prefix (clear intent, conventional) ## Size Impact Current: 10 abort() calls in production code - ring_buffer.cc: 7 checks (~350 bytes) - miniaudio_backend.cc: 3 checks (~240 bytes) Estimated savings with FINAL_STRIP: ~500-600 bytes ## Documentation Updated: - doc/HOWTO.md: Added FINAL_STRIP build instructions - doc/CONTRIBUTING.md: Added fatal error checking guidelines - src/util/fatal_error.h: Comprehensive usage documentation ## Next Steps (Not in This Commit) Phase 2: Convert ring_buffer.cc abort() calls to FATAL_CHECK() Phase 3: Convert miniaudio_backend.cc abort() calls to FATAL_CHECK() Phase 4: Systematic scan for remaining abort() calls Phase 5: Verify size reduction with actual measurements ## Usage # Convenience methods make final # From normal build directory ./scripts/build_final.sh # Creates build_final/ # Manual cmake -S . -B build_final -DDEMO_FINAL_STRIP=ON cmake --build build_final ⚠️ WARNING: FINAL_STRIP builds have NO error checking. Use ONLY for final release, never for development/testing. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
29 hoursdocs: Add script maintenance requirements after hierarchy changesskal
Added new section "Script Maintenance After Hierarchy Changes" to CONTRIBUTING.md documenting the requirement to review and update scripts in scripts/ directory after any major source reorganization. Key points: - Lists when script review is required (file moves, renames, etc.) - Identifies scripts that commonly need updates (check_all.sh, gen_coverage_report.sh, build_win.sh, gen_assets.sh) - Provides verification steps to ensure scripts remain functional - Includes recent example (platform.cc → platform/platform.cc) - References automated verification via check_all.sh This prevents issues like the coverage script failing on moved files or verification scripts missing compilation failures in tools. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
30 hoursfix(ci): Update verification script to catch tool compilation failuresskal
Problem: The spectool.cc include path bug was not caught by the test suite because check_all.sh only built tests, not tools. Root Cause Analysis: - check_all.sh used -DDEMO_BUILD_TESTS=ON only - Tools (spectool, specview, specplay) are built with -DDEMO_BUILD_TOOLS=ON - CTest runs tests but doesn't verify tool compilation - Result: Tool compilation failures went undetected Solution: Updated scripts/check_all.sh to: 1. Enable both -DDEMO_BUILD_TESTS=ON and -DDEMO_BUILD_TOOLS=ON 2. Explicitly verify all tools compile (spectool, specview, specplay) 3. Add clear output messages for each verification stage 4. Document what the script verifies in header comments Updated doc/CONTRIBUTING.md: - Added "Automated Verification (Recommended)" section - Documented that check_all.sh verifies tests AND tools - Provided manual verification steps as alternative - Clear command examples with expected behavior Verification: - Tested by intentionally breaking spectool.cc include - Script correctly caught the compilation error - Reverted break and verified all tools build successfully This ensures all future tool changes are verified before commit. Prevents regression: Similar include path issues will now be caught by pre-commit verification.
30 hourstest(gpu): Add automatic validation for effect test coverageskal
Problem: When new effects are added to demo_effects.h, developers might forget to update test_demo_effects.cc, leading to untested code. Solution: Added compile-time constants and runtime assertions to enforce test coverage: 1. Added EXPECTED_POST_PROCESS_COUNT = 8 2. Added EXPECTED_SCENE_COUNT = 6 3. Runtime validation in each test function 4. Fails with clear error message if counts don't match Error message when validation fails: ✗ COVERAGE ERROR: Expected N effects, but only tested M! ✗ Did you add a new effect without updating the test? ✗ Update EXPECTED_*_COUNT in test_demo_effects.cc Updated CONTRIBUTING.md with mandatory test update requirement: - Added step 3 to "Adding a New Visual Effect" workflow - Clear instructions on updating effect counts - Verification command examples This ensures no effect can be added without corresponding test coverage. Tested validation by intentionally breaking count - error caught correctly.
2 daysdocs: Update project documentation and regenerate assetsskal
Updated PROJECT_CONTEXT.md and TODO.md to include new critical tasks and reflect changes in task prioritization. Modified doc/3D.md to adjust task descriptions. Modified doc/CONTRIBUTING.md to incorporate the new in-memory replacement rule. Regenerated asset files (src/generated/assets.h, src/generated/assets_data.cc, src/generated/test_assets.h, src/generated/test_assets_data.cc) to reflect any changes in asset definitions. Removed temporary changes to GEMINI.md and HANDOFF.md.
3 daysfeat(audio): Complete Phase 4 - Cleanup and Documentation (Task #56)skal
Completed final cleanup phase of Audio Lifecycle Refactor. Removed backwards compatibility shims and updated documentation to reflect new AudioEngine-based initialization patterns. Changes: 1. Removed Backwards Compatibility: - Removed synth_init() call from audio_init() in audio.cc - Added comment explaining AudioEngine is the preferred initialization method - All tests already explicitly call synth_init() or use AudioEngine 2. Documentation Updates: - Updated HOWTO.md with AudioEngine usage examples and best practices - Updated CONTRIBUTING.md with audio subsystem initialization protocols - Documented when to use AudioEngine vs direct synth API calls - Clarified that AudioEngine is a lifecycle manager, not a complete facade 3. Size Verification: - Size-optimized build: 5.0MB (vs 6.2MB debug) - AudioEngine overhead: <500 bytes (within acceptable limits) - No size regression from refactor Results: - All 20 tests pass (100% pass rate) - Demo runs successfully - No backwards compatibility issues - Clear documentation for future development - Binary size impact negligible Design Philosophy: - AudioEngine manages initialization order (synth before tracker) - Direct synth API calls remain valid for performance-critical paths - Low-level tests can still use synth_init() directly if needed - Preferred pattern: Use AudioEngine for lifecycle, direct APIs for operations handoff(Claude): Completed Task #56 Phase 4 - All phases complete! Audio Lifecycle Refactor is fully implemented, tested, and documented. The fragile initialization order dependency has been eliminated. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
4 daysfeat: Audio playback stability, NOTE_ parsing fix, sample caching, and debug ↵skal
logging infrastructure MILESTONE: Audio System Robustness & Debugging Core Audio Backend Optimization: - Fixed stop-and-go audio glitches caused by timing mismatch - Core Audio optimized for 44.1kHz (10ms periods), but 32kHz expected ~13.78ms - Added allowNominalSampleRateChange=TRUE to force OS-level 32kHz native - Added performanceProfile=conservative for 4096-frame buffers (128ms) - Result: Stable ~128ms callbacks, <1ms jitter, zero underruns Ring Buffer Improvements: - Increased capacity from 200ms to 400ms for tempo scaling headroom - Added comprehensive bounds checking with abort() on violations - Fixed tempo-scaled buffer fill: dt * g_tempo_scale - Buffer maintains 400ms fullness during 2.0x acceleration NOTE_ Parsing Fix & Sample Caching: - Fixed is_note_name() checking only first letter (A-G) - ASSET_KICK_1 was misidentified as A0 (27.5 Hz) - Required "NOTE_" prefix to distinguish notes from assets - Updated music.track to use NOTE_E2, NOTE_G4 format - Discovered resource exhaustion: 14 unique samples → 228 registrations - Implemented comprehensive caching in tracker_init() - Assets: loaded once from AssetManager, cached synth_id - Generated notes: created once, stored in persistent pool - Result: MAX_SPECTROGRAMS 256 → 32 (88% memory reduction) Debug Logging Infrastructure: - Created src/util/debug.h with 7 category macros (AUDIO, RING_BUFFER, TRACKER, SYNTH, 3D, ASSETS, GPU) - Added DEMO_ENABLE_DEBUG_LOGS CMake option (defines DEBUG_LOG_ALL) - Converted all diagnostic code to use category macros - Default build: macros compile to ((void)0) for zero runtime cost - Debug build: comprehensive logging for troubleshooting - Updated CONTRIBUTING.md with pre-commit policy Resource Analysis Tool: - Enhanced tracker_compiler to report pool sizes and cache potential - Analysis: 152/228 spectrograms without caching, 14 with caching - Tool generates optimization recommendations during compilation Files Changed: - CMakeLists.txt: Add DEBUG_LOG option - src/util/debug.h: New debug logging header (7 categories) - src/audio/miniaudio_backend.cc: Use DEBUG_AUDIO/DEBUG_RING_BUFFER - src/audio/ring_buffer.cc: Use DEBUG_RING_BUFFER for underruns - src/audio/tracker.cc: Implement sample caching, use DEBUG_TRACKER - src/audio/synth.cc: Use DEBUG_SYNTH for validation - src/audio/synth.h: Update MAX_SPECTROGRAMS (256→32), document caching - tools/tracker_compiler.cc: Fix is_note_name(), add resource analysis - assets/music.track: Update to use NOTE_ prefix format - doc/CONTRIBUTING.md: Add debug logging pre-commit policy - PROJECT_CONTEXT.md: Document milestone - TODO.md: Mark tasks completed Verification: - Default build: No debug output, audio plays correctly - Debug build: Comprehensive logging, audio plays correctly - Caching working: 14 unique samples cached at init - All tests passing (17/17) handoff(Claude): Audio system now stable with robust diagnostic infrastructure. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6 daysflesh out extra details in the MD filesskal
6 daysfix(repo): Revert accidental changes to third_party libsskal
- Reverted modifications made to files within the 'third_party/' directory. - Updated CONTRIBUTING.md to explicitly forbid any automated or manual changes to third-party code.
6 daysrefactor(build): Centralize generated files and clean up project layoutskal
- Task A: Centralized all generated code (assets, timeline) into a single directory to create a single source of truth. - Task A: Isolated test asset generation into a temporary build directory, preventing pollution of the main source tree. - Task B: Vertically compacted all C/C++ source files by removing superfluous newlines. - Task C: Created a top-level README.md with project overview and file descriptions. - Task D: Moved non-essential documentation into a directory to reduce root-level clutter.