| name | New Rule Completeness Validator |
| description | Validates that all necessary code changes are implemented when adding new game rules; use when adding new game rules or variants to ensure no files are missed. |
New Rule Completeness Validator
Purpose
When adding a new game rule or rule variant to Sanmill, you need to modify multiple files (typically 70-80 files, including ~60 localization files). This skill provides a completeness checklist to ensure no necessary code changes are missed.
Reference: docs/guides/ADDING_NEW_GAME_RULES.md
Use Cases
- Adding a new game rule variant
- Adding new game mechanics to existing rules (e.g., new capture rules)
- Modifying rule structure or parameters
- Reviewing rule-related pull requests
Architecture Philosophy
Sanmill is configuration-based, not inheritance-based. Rule variants are expressed as data (Rule in C++, RuleSettings in Flutter) and toggled at runtime. Any new mechanics must be gated by booleans/params so existing variants remain untouched and fast.
Quick Overview
- Estimated time: Simple parameter rule 2-4 hours; new mechanics 6-8 hours
- Complexity: ⭐⭐⭐ Medium-High
- Touched files: ~70-80 total (incl. ~60 ARB localization files)
Core Validation Checklist (Required Modifications)
1. C++ Engine Rule Definition
File: src/rule.cpp
Example structure:
{
"Your Rule Name",
"Short description",
9, 3, 3,
false,
MillFormationActionInPlacingPhase::removeOpponentsPieceFromBoard,
false,
false,
false,
kDefaultCaptureRuleConfig,
kDefaultCaptureRuleConfig,
kDefaultCaptureRuleConfig,
true,
100,
100,
true
}
File: src/rule.h
constexpr auto N_RULES = 12;
2. Flutter UI Models
File: lib/rule_settings/models/rule_settings.dart
Example:
enum RuleSet {
// ... existing variants
yourNewVariant, // new
}
class YourNewVariantRuleSettings extends RuleSettings {
const YourNewVariantRuleSettings({
// All params must match C++ Rule fields
}) : super(/* ... */);
}
3. Flutter UI Selection Interface
File: lib/rule_settings/widgets/modals/rule_set_modal.dart
4. Localization (Internationalization)
Files: lib/l10n/intl_*.arb (~60 files)
Key strings:
- Rule name
- Rule description
- Any new UI labels or hints
Conditional Validation Checklist (Based on Mechanic Type)
5. Game Logic Modifications (If Gameplay Changed)
File: src/position.cpp (C++ side)
File: lib/game_page/services/engine/position.dart (Flutter side)
Important: User-visible game logic must be symmetrically implemented in both C++ and Dart. Move generation (movegen) is C++ only.
6. Move Generation (C++ Only)
File: src/movegen.cpp
7. Mill Formation
File: src/mills.cpp
8. Engine Options (If Added New Rule Fields)
File: lib/game_page/services/engine/engine.dart
File: src/ucioption.cpp
Example:
{"YourNewOption", "false", "bool", {}, on_your_new_option}
void on_your_new_option(Option &o) {
rule.yourNewField = o.get<bool>();
}
9. FEN Format Extension (Only If Dynamic State Persistence Needed)
When to extend FEN: Only when you must persist dynamic state that cannot be recomputed from the board.
Need to extend if:
Do NOT extend for:
- ✗ Static rule params (piece counts,
hasDiagonalLines, etc.)
- ✗ Anything derivable from board (piece counts, mills)
- ✗ Global flags (
mayFly, mayRemoveMultiple)
Files: src/position.h, src/position.cpp
File: lib/game_page/services/engine/position.dart
Files: tests/test_position.cpp, Flutter integration tests
10. Evaluation and Search (Rare)
File: src/evaluate.cpp
File: src/search.cpp
Testing Validation Checklist
11. C++ Tests
Files: tests/test_*.cpp
Run tests:
cd src
make build all
make test
12. Flutter Tests
Widget tests
Engine mirror tests
Integration tests
Run tests:
cd src/ui/flutter_app
flutter test
13. Performance Benchmarks
Build, Format, and Generate
14. Code Formatting
./format.sh
15. Localization Generation
cd src/ui/flutter_app
flutter gen-l10n
16. Full Build
cd src
make build all
cd ../src/ui/flutter_app
flutter build apk
flutter build ios
flutter build windows
Quality & Safety Assurance Checklist
17. Backward Compatibility
18. Performance Parity
19. Code Symmetry
20. Documentation and Comments
21. Localization Completeness
Complete QA Checklist (Summary)
Before submitting PR, confirm all of the following:
Validation Workflow
Phase 1: Planning (1 hour)
- Determine specific requirements for rule variant
- Determine if simple parameter adjustment or new mechanics needed
- List files that need modification
Phase 2: C++ Implementation (2-3 hours)
- Modify
src/rule.h and src/rule.cpp
- If new mechanics needed, modify
src/position.cpp, src/movegen.cpp, etc.
- If new fields added, update
src/ucioption.cpp
- Run C++ tests, ensure they pass
Phase 3: Flutter Implementation (2-3 hours)
- Modify
rule_settings.dart (enum + subclass + mappings)
- Modify
rule_set_modal.dart (UI selection)
- If game logic modified, mirror to
position.dart
- Update
engine.dart's setRuleOptions()
- Run Flutter tests, ensure they pass
Phase 4: Localization (30 minutes)
- Update
intl_en.arb and intl_zh_CN.arb
- Batch update other ARB files (can use English initially)
- Run
flutter gen-l10n
Phase 5: Testing & Validation (1-2 hours)
- Run all C++ tests
- Run all Flutter tests
- Manually test new rule behavior in UI
- Check performance benchmarks
- Verify backward compatibility
Phase 6: Code Review & Documentation (30 minutes)
- Run code formatting
- Review all changes
- Update docs and comments
- Complete QA checklist
Common Pitfalls and Notes
❌ Common Mistakes
-
Forgot to increment N_RULES
- Symptom: Runtime crash or rule loading failure
- Fix: Ensure
N_RULES in src/rule.h matches RULES[] length
-
C++ and Flutter fields don't match
- Symptom: UI-set rule parameters don't take effect
- Fix: Ensure
RuleSettings fields match Rule struct 1-to-1
-
Missing UCI options
- Symptom: New Rule field values always default
- Fix: Add corresponding options and handlers in
ucioption.cpp
-
Didn't mirror game logic to Dart
- Symptom: UI preview inconsistent with actual game
- Fix: Ensure
position.dart mirrors position.cpp logic
-
Incomplete localization
- Symptom: Some languages show placeholders or English
- Fix: At minimum complete English and Chinese, others can use English placeholder
-
Performance regression
- Symptom: Game slower even when not using new feature
- Fix: Use conditional guards, ensure early exits
-
Over-extended FEN
- Symptom: FEN strings too long, hard to debug
- Fix: Only extend FEN when must persist dynamic state
✓ Best Practices
- Incremental development: Implement C++ first, test, then do Flutter
- Frequent testing: Run relevant tests after each file modification
- Use conditional guards: Ensure new code doesn't affect existing rules
- Maintain symmetry: C++ and Dart logic should be readable side-by-side
- Documentation first: Write comments and docs before code
- Reference existing rules: Look at other rules in
RULES[] as templates
Reference Files and Resources
Core Documentation
docs/guides/ADDING_NEW_GAME_RULES.md - Official guide for adding rules (must read)
C++ Files
src/rule.h - Rule struct definition
src/rule.cpp - RULES[] array
src/position.h/.cpp - Game position and logic
src/movegen.cpp - Move generation
src/ucioption.cpp - UCI options
src/mills.cpp - Mill formation logic
include/config.h - Default config (rarely modified)
Flutter Files
lib/rule_settings/models/rule_settings.dart - Rule models
lib/rule_settings/widgets/modals/rule_set_modal.dart - UI selection
lib/game_page/services/engine/position.dart - Position mirror
lib/game_page/services/engine/engine.dart - Engine communication
lib/l10n/intl_*.arb - Localization files
Test Files
tests/test_*.cpp - C++ unit tests
test/ - Flutter unit and widget tests
integration_test/ - Flutter integration tests
Output Format
Validation results should be reported clearly:
✓ [Complete] Core File Modifications
✓ src/rule.cpp - RULES[] added
✓ src/rule.h - N_RULES incremented
✓ rule_settings.dart - RuleSet enum added
...
⚠ [Warning] Conditional File Modifications
✓ src/position.cpp - Logic updated
✗ position.dart - Logic not mirrored (needs fix)
...
✓ [Complete] Test Validation
✓ C++ tests all passed (25/25)
✓ Flutter tests all passed (42/42)
...
✗ [Failed] Localization
✓ intl_en.arb - Updated
✓ intl_zh_CN.arb - Updated
✗ Other ARB files - Not updated (needs completion)
...
📊 Completion: 75% (15/20 checks passed)
💡 Recommendation: Priority fix position.dart mirror and localization
Summary
Adding a new game rule is a systematic effort requiring careful coordination between the C++ engine and Flutter UI. Using this checklist ensures:
- ✓ No necessary file modifications are missed
- ✓ C++ and Flutter stay synchronized
- ✓ Backward compatibility is not broken
- ✓ Performance is not affected
- ✓ Test coverage is adequate
- ✓ Localization is complete
Remember: When in doubt, refer to docs/guides/ADDING_NEW_GAME_RULES.md and existing rule implementations.