Skip to content

Feature: Require characters (new -rc flag)#163

Open
HansGR wants to merge 17 commits into
ff6wc:devfrom
HansGR:feature/require_characters
Open

Feature: Require characters (new -rc flag)#163
HansGR wants to merge 17 commits into
ff6wc:devfrom
HansGR:feature/require_characters

Conversation

@HansGR

@HansGR HansGR commented Jun 15, 2026

Copy link
Copy Markdown

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.

  • Starting party: required characters merge with -sc1..-sc4. Any characters that are not already a starting character are added; if no -sc are given, the required characters become the starting party. More than four total fails the compile.
  • Every party select: required characters are marked unmovable and pre-placed into a party any time the party is reformed. For multi-party events:
    • Two parties (Narshe Battle, Phoenix Cave): all required characters go into party 1, unless every available character is required, in which case the last one goes to party 2 so neither party is empty.
    • Kefka Tower (three parties): distributed by entrance — normal [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 — including
RecruitAndSelectParty and the RemoveAll→select events (Narshe Battle end, Moogle Defense) — is handled in one place and can't softlock. Supporting helpers are in the new instruction/field/required_characters.py; the unmovable mask and starting-party merge are in args/. -rc is 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)

  • Added handling for "random" and "randomngu" arguments with -rc.
  • Fixed in-game menu display

Updates 2 (6/17/2026)

  • Added a small ASM edit to allow swapping required characters with each other in the party formation menus. The required characters are initially distributed as described above, but the player can choose to swap e.g. which required character is in which lane of KT.

HansGR and others added 8 commits June 14, 2026 16:51
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

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread instruction/field/instructions.py Outdated
claude and others added 9 commits June 15, 2026 09:10
- 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants