This runbook covers TODOS.phase-72.72.13.2.2: allowing any hold action to be
set to toggle, including hold-to-aim becoming toggle-aim and hold-to-sprint
becoming toggle-sprint.
Runtime Surface#
Hold-to-toggle conversion extends the V2Input accessibility profile model:
- profile:
FV2HoldToToggleConversionProfile - action rule:
FV2HoldToToggleActionRule - player preference:
FV2HoldToTogglePreference - resolved action:
FV2ResolvedHoldToToggleAction - source library:
UV2InputBlueprintLibrary - config asset:
UV2InputConfigAsset - UI config:
FV2AccessibilityMotorAssistConfig - persistence snapshot:
FV2PlayerSettingsSnapshot - save game:
UV2SaveGame - persistence subsystem:
UV2PersistenceSubsystem - contract:
V2/ue/Content/V2/Input/Accessibility/HoldToToggleConversion_V2_Contract.json - focused checker:
V2/ue/Tools/check-v2-hold-to-toggle-conversion.py
Behavior#
FV2HoldToToggleActionRule defines a hold action, its toggle alternative, and
the mapping slot or settings row that owns the action. The default rules include
aim, sprint, block, grapple, Blazin, submission grid, pin press, and run. Other
hold actions can be added by data using the same rule struct.
FV2HoldToToggleConversionProfile stores player-authored preferences per
action. Resolution returns the hold input action by default and switches to the
toggle input action only when a validated preference requests toggle mode.
Validation#
Preferences are applied to a candidate profile first. A candidate is rejected if it targets an unknown action, a non-hold action, a duplicated action, or a rule without a toggle alternative. Rejected preferences do not replace the last valid profile.
Persistence#
FV2PlayerSettingsSnapshot stores HoldToToggleProfile with startup flags.
UV2SaveGame::SaveHoldToToggleProfile persists a validated profile per player,
GetStartupHoldToToggleProfile resolves it on startup, and
MarkHoldToToggleAppliedOnStartup records the before-gameplay apply time.
ValidateSave rejects profiles whose account id does not match the save header.
Verification#
Run these checks after changing hold-to-toggle conversion:
python3 V2/ue/Tools/check-v2-hold-to-toggle-conversion.py
python3 V2/ue/Tools/check-v2-input-mapping-contexts.py
python3 V2/ue/Tools/check-v2-profile-save-game.py
python3 V2/ue/Tools/check-v2-persistence-module.py
python3 V2/ue/Tools/check-v2-accessibility-feature-set.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 V2/tools/validate-v2-docs.py
python3 -m py_compile V2/ue/Tools/check-v2-hold-to-toggle-conversion.py V2/ue/Tools/check-v2-ci-workflow.py
python3 -m json.tool V2/ue/Content/V2/Input/Accessibility/HoldToToggleConversion_V2_Contract.json
Automation coverage:
V2.Input.ModuleV2.Persistence.ModuleV2.Persistence.ProfileSave.AssetContractV2.UI.Module
Horde Gates#
hold-to-toggle-sourcehold-to-toggle-any-hold-actionhold-to-toggle-aim-sprinthold-to-toggle-reject-non-holdhold-to-toggle-per-player-persistencehold-to-toggle-startup-applyhold-to-toggle-ci-wired