Feature: Require characters (new -rc flag)#163
Conversation
clean patch of "Require Umaro" code to upstream/dev for a feature branch that Requires characters to be in the party.
Replace the "require umaro" gag flag with a general challenge flag that
forces 1-4 specified characters to be in the party at all times.
- args/challenges.py: add -rc/--require-characters (1-4 character names),
resolve to ids, compute the SelectParties "unmovable" bitmask
- args/starting_party.py: merge required characters into the starting party
(required characters not already starting characters are added as extra
starting characters; required-only constitutes the party; >4 fails)
- args/misc.py: drop the -rc short option from the deprecated --random-clock
- instruction/field/instructions.py: SelectParties default unmovable mask is
now derived from the required characters
- event/required_characters.py: helpers to pre-place required characters
(mandatory since unmovable characters must already be in a party):
* one-party placement (airship return)
* two-party split for Narshe Battle / Phoenix Cave (last required goes to
party 2 only when every available character is required)
* three-party distribution for Kefka Tower (normal vs skip entrances)
- event/airship.py, narshe_battle.py, phoenix_cave.py, kefka_tower.py:
use the new placement helpers
Generalize --require-umaro flag into -rc / --require-characters challenge flag
REMOVE_ALL_CHARACTERS_FROM_ALL_PARTIES followed by a party select (e.g. the end of the Narshe Battle, Narshe Moogle Defense, and every recruit-and-select event) left required characters unmovable but outside any party, which can softlock the party-select screen. Fix it in the shared select-party subroutines so every current and future caller is covered: - instruction/field/functions.py: REFRESH_CHARACTERS_AND_SELECT_PARTY and REFRESH_CHARACTERS_AND_SELECT_TWO_PARTIES now pre-place required characters before SelectParties. The unused THREE_PARTIES helper is guarded so it fails loudly if ever used while characters are required (Kefka Tower does its own normal/skip distribution via raw SelectParties). - move event/required_characters.py -> instruction/field/required_characters.py so functions.py can use it without a circular import. - event/narshe_battle.py, event/airship.py: drop the now-redundant call-site placement (handled by the shared subroutines). - event/phoenix_cave.py, event/kefka_tower.py: update import path.
Fix required-character softlock at all party-select sites
There was a problem hiding this comment.
Code Review
This pull request introduces a new challenge flag -rc / --require-characters to force specific characters to remain in the party at all times, updating starting party logic, menu options, and various party-selection events (Airship, Kefka Tower, Narshe Battle, Phoenix Cave) to handle required characters and mark them as unmovable. It also resolves a flag conflict with --random-clock and adds support for relic_equip_cond_byte in items. One critical issue was identified in instruction/field/instructions.py where the unmovable default argument is evaluated at import time before command-line arguments are parsed, which would prevent required characters from being marked as unmovable; a dynamic runtime evaluation inside __init__ was suggested to fix this.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- args/starting_party.py, args/challenges.py, args/arguments.py: -rc now accepts random / randomngu. Random required characters are resolved after the rng is seeded (resolve_required_characters), excluding every named starting or required character and any previously chosen random (randomngu also excludes Gogo and Umaro), regardless of order. The unmovable mask and the starting party are finalized there so the event code sees concrete characters. Required characters are no longer written back into the -scN values. - menus/flags_require_characters.py: new flags submenu so the Require Characters entry no longer overflows the menu line (mirrors Remove Spells / Item Rewards).
`-rc` add support for "random", "randomngu" arguments; fix in-game menu
Read the required-character (-rc) unmovable bitmask inside __init__ instead of as a class-level default argument. The previous form worked only because instruction.field happens to be imported after arguments are parsed; reading it per-instance removes that import-ordering dependency.
Evaluate SelectParties unmovable mask at build time
The -rc/--require-characters feature marks required characters as "unmovable" on the party-select (Lineup) screen, locking the menu slot each one occupies. In vanilla the lock is absolute, so when more than one party is shown (entering Kefka's Tower, and the two-party Narshe Battle / Phoenix Cave when every available character is required) the player can neither pick up nor displace a required character and therefore cannot choose which required character goes into which party. Relax the rule so a locked slot may be swapped with another locked slot: two required characters can trade places, while swaps between a locked and an unlocked slot remain forbidden. This preserves the party-membership requirement because swapping two required characters leaves each of them in a forced party slot. Implemented as a small Bank C3 menu patch: - allow picking up a locked slot (NOP the choice-1 lock check) - on placement, fail only when source/destination locked status differs (a like-lock compare subroutine replacing the choice-2 lock read) - recompute the lock array after a swap so swapped characters stay locked The patch is gated on required characters being present, so the vanilla menu is untouched when the feature is not in use. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBquGaXDk5KdoFqgjiAFaj
Exclude *.smc/*.sfc so copyrighted source ROMs and generated output ROMs can never be added to version control. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FBquGaXDk5KdoFqgjiAFaj
Allow player to swap required characters with each other in the menu
- Remove extra .md file - revert .gitignore change (not relevant to this patch)
Implements a new flag, --required-characters (
-rc) that accepts 1–4 characters from the playable roster and forces them to be in the party at all times.-sc1..-sc4. Any characters that are not already a starting character are added; if no-scare given, the required characters become the starting party. More than four total fails the compile.[3,1,2,3], skip[2,3,1,2].Implementation
Pre-placement lives in the shared select-party subroutines (
instruction/field/functions.py), so every caller — includingRecruitAndSelectPartyand theRemoveAll→select events (Narshe Battle end, Moogle Defense) — is handled in one place and can't softlock. Supporting helpers are in the newinstruction/field/required_characters.py; the unmovable mask and starting-party merge are inargs/.-rcis freed from the deprecated--random-clock(still usable by long name).Testing
Built against
FFIII US v1.0; decoded the generated event code to verify the unmovable masks, party distributions, the two-party split (including the all-required edge case), and a clean failure on overflow. Suggested in-game checks: Narshe Battle end, Moogle Defense, and a recruitment with a required character active.Updates 1 (6/15/2026)
-rc.Updates 2 (6/17/2026)