# Legacy Constraint System This document describes the constraint framework used to validate command preconditions. References include `legacy/hwe/sammo/Constraint/Constraint.php` and `legacy/hwe/sammo/Constraint/ConstraintHelper.php`. ## Core Concepts Constraints are reusable predicate classes that validate a command’s inputs and state. They are built per-command and executed in order: - Each constraint extends `Constraint` and implements `test()`. - `Constraint::testAll()` iterates a list of constraints and returns the first failure `[constraintName, reason]` or `null` for success. - `BaseCommand::hasFullConditionMet()` uses these to decide command validity. ## Required Input Flags Constraints declare required inputs using bit flags: - `REQ_GENERAL`, `REQ_CITY`, `REQ_NATION` - `REQ_DEST_GENERAL`, `REQ_DEST_CITY`, `REQ_DEST_NATION` - `REQ_ARG` with typed sub-flags: - `REQ_STRING_ARG`, `REQ_INT_ARG`, `REQ_NUMERIC_ARG`, `REQ_BOOLEAN_ARG`, `REQ_ARRAY_ARG`, `REQ_BACKED_ENUM_ARG` `Constraint::checkInputValues()` enforces these expectations and throws if inputs are missing or malformed. Some constraints expect `general.aux` to be preloaded as `auxVar`. Command evaluation calls `General::unpackAux()` before constraint checks to satisfy these requirements. ## Constraint Helper DSL `ConstraintHelper` provides factory-style helpers used in command definitions: - Examples: `AllowWar()`, `NearCity($distance)`, `ReqGeneralGold($amount)`, `NotOccupiedDestCity()`, `AllowDiplomacyStatus(...)`, etc. - These helpers return `[ConstraintName, arg]` tuples consumed by `Constraint::testAll()`. ## Common Constraint Classes Constraints are organized by domain: - **Diplomacy**: `AllowDiplomacyStatus`, `AllowDiplomacyBetweenStatus`. - **Nation/City**: `OccupiedCity`, `NotCapital`, `RemainCityCapacity`. - **General**: `ReqGeneralCrew`, `ReqGeneralGold`, `MustBeTroopLeader`. - **Routing**: `HasRoute`, `HasRouteWithEnemy`. Each constraint sets a failure reason string used by UI and logs. ## Rewrite References Rewrite constraint contracts and runtime split details live in `docs/architecture/rewrite-constraints.md`. ## Open Questions / Follow-ups - Some constraints rely on `env` values (`turnterm`, `year`, etc.); document each command’s exact `env` payload when porting.