From 14aad9c51d7cb5d19917f432c3cd8a8e765f2d9b Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Wed, 3 Jun 2026 16:27:37 -0400 Subject: [PATCH 01/11] STEVE! --- args/graphics.py | 16 ++++++++++++++++ data/characters.py | 4 ++++ data/dances.py | 4 ++++ data/data.py | 12 ++++++++++++ data/enemies.py | 9 +++++++++ data/espers.py | 6 ++++++ data/items.py | 5 +++++ data/lores.py | 4 ++++ data/magiteks.py | 4 ++++ data/spells.py | 17 +++++++++++++++++ data/swdtechs.py | 4 ++++ 11 files changed, 85 insertions(+) diff --git a/args/graphics.py b/args/graphics.py index 7f3f7b13..852928fc 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -22,11 +22,20 @@ def parse(parser): graphics.add_argument("-ahtc", "--alternate-healing-text-color", action = "store_true", help = "Makes healing text blue, to be able to distinguish from damage.") + graphics.add_argument("-steve", "--steveify", type = str, nargs='?', const='Steve', default=None, + help = "Steveify the seed: rename all characters, items, espers, magic, enemies, etc. to a given name (default: Steve)") + def process(args): import graphics.palettes.palettes as palettes import graphics.portraits.portraits as portraits import graphics.sprites.sprites as sprites + if args.steveify is not None: + if not args.steveify or args.steveify.isspace(): + args.steveify = "Steve" + if len(args.steveify) > 6: + args.steveify = args.steveify[:6] + if args.character_names is not None: args.names = args.character_names.split('.') if len(args.names) != Characters.CHARACTER_COUNT: @@ -40,6 +49,9 @@ def process(args): else: args.names = Characters.DEFAULT_NAME + if args.steveify is not None: + args.names = [args.steveify] * Characters.CHARACTER_COUNT + args.palettes = [] if args.character_palettes: args.palette_ids = [int(palette_id) for palette_id in args.character_palettes.split('.')] @@ -101,6 +113,8 @@ def flags(args): if args.character_names: flags += " -name " + args.character_names + if args.steveify: + flags += " -steve " + args.steveify if args.character_palettes: flags += " -cpal " + args.character_palettes if args.character_portraits: @@ -191,6 +205,8 @@ def _other_options_log(args): ("Remove Flashes", remove_flashes, "remove_flashes"), ("World Minimap", world_minimap, "world_minimap"), ("Healing Text", healing_text, "healing_text"), + ("Who's There?", who_there, "who_there"), + ("Steveify", args.steveify if args.steveify else "None", "steveify"), ] for entry in entries: diff --git a/data/characters.py b/data/characters.py index c5f258d5..761075b0 100644 --- a/data/characters.py +++ b/data/characters.py @@ -133,6 +133,10 @@ def mod(self): if self.args.character_names: self.mod_names() + if self.args.steveify: + for character in self.characters: + character.name = self.args.steveify + if self.args.original_name_display: characters_asm.show_original_names() diff --git a/data/dances.py b/data/dances.py index 843249ea..f26cfec3 100644 --- a/data/dances.py +++ b/data/dances.py @@ -164,6 +164,10 @@ def shuffle(self): dance.dances = abilities[ability_index : ability_index + self.DATA_SIZE] def mod(self): + if self.args.steveify: + for dance in self.dances: + dance.name = self.args.steveify + self.write_learners_table() self.write_is_learner() self.after_battle_check_mod() diff --git a/data/data.py b/data/data.py index 3624b986..700ad10c 100644 --- a/data/data.py +++ b/data/data.py @@ -21,6 +21,8 @@ class Data: def __init__(self, rom, args): + self.rom = rom + self.args = args self.dialogs = dialogs self.spells = spells.Spells(rom, args) @@ -81,6 +83,16 @@ def __init__(self, rom, args): self.title_graphics.mod() def write(self): + if self.args.steveify: + import data.text as text + ability_name_bytes = bytearray() + for i in range(175): + name_bytes = text.get_bytes(self.args.steveify, text.TEXT2) + name_bytes = name_bytes[:10] + name_bytes.extend([0xff] * (10 - len(name_bytes))) + ability_name_bytes.extend(name_bytes) + self.rom.set_bytes(0x26f7b9, ability_name_bytes) + self.dialogs.write() self.characters.write() self.items.write() diff --git a/data/enemies.py b/data/enemies.py index 7e16dd83..b384cf45 100644 --- a/data/enemies.py +++ b/data/enemies.py @@ -75,6 +75,8 @@ def get_enemy(self, name): return enemy.id def get_name(self, enemy_id): + if self.args.steveify: + return self.args.steveify if enemy_id in bosses.enemy_name: return bosses.enemy_name[enemy_id] return self.enemies[enemy_id].name @@ -439,6 +441,13 @@ def print(self): enemy.print() def write(self): + if self.args.steveify: + for enemy in self.enemies: + if enemy.name: + enemy.name = self.args.steveify + if enemy.special_name: + enemy.special_name = self.args.steveify + for enemy_index in range(len(self.enemies)): self.enemy_data[enemy_index] = self.enemies[enemy_index].data() self.enemy_name_data[enemy_index] = self.enemies[enemy_index].name_data() diff --git a/data/espers.py b/data/espers.py index bf2c0957..b99fb44c 100644 --- a/data/espers.py +++ b/data/espers.py @@ -275,6 +275,10 @@ def multi_summon(self): space = Reserve(0x24da3, 0x24da5, "espers set used in battle bit", asm.NOP()) def mod(self, dialogs): + if self.args.steveify: + for esper in self.espers: + esper.name = self.args.steveify + self.receive_dialogs_mod(dialogs) if self.args.esper_spells_shuffle or self.args.esper_spells_shuffle_random_rates: @@ -353,6 +357,8 @@ def get_receive_esper_dialog(self, esper): return self.receive_dialogs[esper] def get_name(self, esper): + if self.args.steveify: + return self.args.steveify return self.esper_names[esper] def log(self): diff --git a/data/items.py b/data/items.py index f90bf5b1..06aaec5e 100644 --- a/data/items.py +++ b/data/items.py @@ -220,6 +220,11 @@ def moogle_starting_equipment(self): self.characters.characters[index].init_head = random.choice(tiers[Item.HELMET][1]) def mod(self): + if self.args.steveify: + for item in self.items: + if item.id != self.EMPTY: + item.name = self.args.steveify + not_relic_condition = lambda x: x != Item.RELIC if self.args.item_equipable_random: self.equipable_random(not_relic_condition, self.args.item_equipable_random_min, diff --git a/data/lores.py b/data/lores.py index c4cfa602..d0eff7ea 100644 --- a/data/lores.py +++ b/data/lores.py @@ -253,6 +253,10 @@ def show_mp_mod(self): ) def mod(self, dialogs): + if self.args.steveify: + for lore in self.lores: + lore.name = self.args.steveify + self.write_learners_table() self.write_is_learner() self.after_battle_check_mod() diff --git a/data/magiteks.py b/data/magiteks.py index 1dadccec..8cb93327 100644 --- a/data/magiteks.py +++ b/data/magiteks.py @@ -34,6 +34,10 @@ def fix_reflectable_beams(self): self.magiteks[self.ICE_BEAM].flags2 = 0x22 def mod(self): + if self.args.steveify: + for magitek in self.magiteks: + magitek.name = self.args.steveify + self.fix_reflectable_beams() pass diff --git a/data/spells.py b/data/spells.py index ad82b430..47374109 100644 --- a/data/spells.py +++ b/data/spells.py @@ -102,6 +102,23 @@ def alternate_healing_text_color(self): space.write(0x44, 0x7f) #default: F6 4B def mod(self): + if self.args.steveify: + for spell in self.spells: + icon = "" + for tag in ['', '', '']: + if spell.name.startswith(tag): + icon = tag + break + suffix = "" + for s in [" 2", " 3", "2"]: + if spell.name.endswith(s): + suffix = s + break + + max_steve_len = 6 - len(suffix) + steve_part = self.args.steveify[:max_steve_len] + spell.name = f"{icon}{steve_part}{suffix}" + if self.args.magic_mp_shuffle: self.shuffle_mp() elif self.args.magic_mp_random_value: diff --git a/data/swdtechs.py b/data/swdtechs.py index 847cbe85..866c2d5a 100644 --- a/data/swdtechs.py +++ b/data/swdtechs.py @@ -130,6 +130,10 @@ def enable_fast_swdtech(self): space.write(0x00) def mod(self): + if self.args.steveify: + for swdtech in self.swdtechs: + swdtech.name = self.args.steveify + self.write_learners_table() self.write_is_learner() From 0d80204a605cd77b1af6797fb2f0e3f5db44053e Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 09:18:47 -0400 Subject: [PATCH 02/11] changes based on PR comments --- data/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/data.py b/data/data.py index 700ad10c..372a6ac9 100644 --- a/data/data.py +++ b/data/data.py @@ -87,7 +87,7 @@ def write(self): import data.text as text ability_name_bytes = bytearray() for i in range(175): - name_bytes = text.get_bytes(self.args.steveify, text.TEXT2) + name_bytes = bytearray(text.get_bytes(self.args.steveify, text.TEXT2)) name_bytes = name_bytes[:10] name_bytes.extend([0xff] * (10 - len(name_bytes))) ability_name_bytes.extend(name_bytes) From 9dc7fbbf95ab8b3c886647e981c5b1f710636dd3 Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 09:59:06 -0400 Subject: [PATCH 03/11] Fix graphics menu alignment and visual sprite loader hook Z flag propagation --- args/graphics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/args/graphics.py b/args/graphics.py index 852928fc..8cff0dd8 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -203,7 +203,7 @@ def _other_options_log(args): entries = [ ("Remove Flashes", remove_flashes, "remove_flashes"), - ("World Minimap", world_minimap, "world_minimap"), + ("Minimap", world_minimap, "world_minimap"), ("Healing Text", healing_text, "healing_text"), ("Who's There?", who_there, "who_there"), ("Steveify", args.steveify if args.steveify else "None", "steveify"), From a29d13befde10b9f727ce4e446b822e61ff102d6 Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 10:25:48 -0400 Subject: [PATCH 04/11] Fix Steveify flags menu display of None and support dynamic Arguments propagation --- args/arguments.py | 9 +++++++++ args/graphics.py | 18 ++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/args/arguments.py b/args/arguments.py index cc372d13..9bcce51a 100644 --- a/args/arguments.py +++ b/args/arguments.py @@ -67,6 +67,15 @@ def __init__(self): if self.debug: self.spoiler_log = True + # Update the global args module attributes to match this Arguments instance, + # which is helpful if a wrapper script instantiates Arguments dynamically + # instead of importing the args module directly. + import sys + if "args" in sys.modules: + module = sys.modules["args"] + for name, value in self.__dict__.items(): + setattr(module, name, value) + def _process_min_max(self, arg_name): values = getattr(self, arg_name) if values: diff --git a/args/graphics.py b/args/graphics.py index 8cff0dd8..169a99a9 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -31,10 +31,20 @@ def process(args): import graphics.sprites.sprites as sprites if args.steveify is not None: - if not args.steveify or args.steveify.isspace(): - args.steveify = "Steve" - if len(args.steveify) > 6: - args.steveify = args.steveify[:6] + if isinstance(args.steveify, bool): + if args.steveify: + args.steveify = "Steve" + else: + args.steveify = None + elif not args.steveify or args.steveify.isspace() or args.steveify.lower() in ("none", "false"): + if args.steveify.lower() in ("none", "false"): + args.steveify = None + else: + args.steveify = "Steve" + + if args.steveify is not None: + if len(args.steveify) > 6: + args.steveify = args.steveify[:6] if args.character_names is not None: args.names = args.character_names.split('.') From 46bc2c6a3ef6f005d24bc32cef1ed85a7f816590 Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 10:35:21 -0400 Subject: [PATCH 05/11] Change default Steveify name override to all-caps STEVE --- args/graphics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/args/graphics.py b/args/graphics.py index 169a99a9..76efd16a 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -33,14 +33,14 @@ def process(args): if args.steveify is not None: if isinstance(args.steveify, bool): if args.steveify: - args.steveify = "Steve" + args.steveify = "STEVE" else: args.steveify = None elif not args.steveify or args.steveify.isspace() or args.steveify.lower() in ("none", "false"): if args.steveify.lower() in ("none", "false"): args.steveify = None else: - args.steveify = "Steve" + args.steveify = "STEVE" if args.steveify is not None: if len(args.steveify) > 6: From 119e36cb2d4bc5c3455e9b02ade285a24982704d Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 15:56:14 -0400 Subject: [PATCH 06/11] Remove "who_there" reference --- args/graphics.py | 1 - 1 file changed, 1 deletion(-) diff --git a/args/graphics.py b/args/graphics.py index 76efd16a..bd9506d9 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -215,7 +215,6 @@ def _other_options_log(args): ("Remove Flashes", remove_flashes, "remove_flashes"), ("Minimap", world_minimap, "world_minimap"), ("Healing Text", healing_text, "healing_text"), - ("Who's There?", who_there, "who_there"), ("Steveify", args.steveify if args.steveify else "None", "steveify"), ] From 17a5e0f4fb02438b8e7b3619b2c11ee527f9bbfa Mon Sep 17 00:00:00 2001 From: Will Jones Date: Thu, 4 Jun 2026 15:57:23 -0400 Subject: [PATCH 07/11] Update data/data.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- data/data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/data.py b/data/data.py index 372a6ac9..b79315b9 100644 --- a/data/data.py +++ b/data/data.py @@ -86,10 +86,10 @@ def write(self): if self.args.steveify: import data.text as text ability_name_bytes = bytearray() + name_bytes = bytearray(text.get_bytes(self.args.steveify, text.TEXT2)) + name_bytes = name_bytes[:10] + name_bytes.extend([0xff] * (10 - len(name_bytes))) for i in range(175): - name_bytes = bytearray(text.get_bytes(self.args.steveify, text.TEXT2)) - name_bytes = name_bytes[:10] - name_bytes.extend([0xff] * (10 - len(name_bytes))) ability_name_bytes.extend(name_bytes) self.rom.set_bytes(0x26f7b9, ability_name_bytes) From 152350018ad4617a2e5e66b939255fc8e7438f3b Mon Sep 17 00:00:00 2001 From: Will Jones Date: Thu, 4 Jun 2026 16:02:16 -0400 Subject: [PATCH 08/11] Update data/items.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- data/items.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/data/items.py b/data/items.py index 06aaec5e..0338b72e 100644 --- a/data/items.py +++ b/data/items.py @@ -223,8 +223,12 @@ def mod(self): if self.args.steveify: for item in self.items: if item.id != self.EMPTY: - item.name = self.args.steveify - + icon = "" + if item.name.startswith("<"): + end_tag = item.name.find(">") + if end_tag != -1: + icon = item.name[:end_tag + 1] + item.name = f"{icon}{self.args.steveify}" not_relic_condition = lambda x: x != Item.RELIC if self.args.item_equipable_random: self.equipable_random(not_relic_condition, self.args.item_equipable_random_min, From c4f3ad579d7a9d818d80c5e9e839b49574510f9e Mon Sep 17 00:00:00 2001 From: wrjones104 Date: Thu, 4 Jun 2026 16:22:13 -0400 Subject: [PATCH 09/11] fix steveify logic and update name handling in espers and lores - Improved validation of `steveify` argument. - Updated `Espers.get_name` to use internal data directly. - Enhanced `Lores.mod` method for dynamic name modification based on regex. --- args/graphics.py | 8 +++++--- data/espers.py | 4 +--- data/lores.py | 13 +++++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/args/graphics.py b/args/graphics.py index bd9506d9..6d612819 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -36,10 +36,12 @@ def process(args): args.steveify = "STEVE" else: args.steveify = None - elif not args.steveify or args.steveify.isspace() or args.steveify.lower() in ("none", "false"): - if args.steveify.lower() in ("none", "false"): + else: + args.steveify = args.steveify.strip() + steveify_upper = args.steveify.upper() + if steveify_upper in ("NONE", "FALSE"): args.steveify = None - else: + elif not args.steveify: args.steveify = "STEVE" if args.steveify is not None: diff --git a/data/espers.py b/data/espers.py index b99fb44c..c5064814 100644 --- a/data/espers.py +++ b/data/espers.py @@ -357,9 +357,7 @@ def get_receive_esper_dialog(self, esper): return self.receive_dialogs[esper] def get_name(self, esper): - if self.args.steveify: - return self.args.steveify - return self.esper_names[esper] + return self.espers[esper].name def log(self): from log import COLUMN_WIDTH, section_entries, format_option diff --git a/data/lores.py b/data/lores.py index d0eff7ea..0029d504 100644 --- a/data/lores.py +++ b/data/lores.py @@ -253,10 +253,6 @@ def show_mp_mod(self): ) def mod(self, dialogs): - if self.args.steveify: - for lore in self.lores: - lore.name = self.args.steveify - self.write_learners_table() self.write_is_learner() self.after_battle_check_mod() @@ -275,6 +271,15 @@ def mod(self, dialogs): if self.args.lores_level_randomize: self.random_lx_levels(dialogs) + if self.args.steveify: + import re + for lore in self.lores: + match = re.search('L.*[?1-9]', lore.name) + if match: + lore.name = f"{match.group()} {self.args.steveify}"[:self.NAME_SIZE] + else: + lore.name = self.args.steveify[:self.NAME_SIZE] + def write(self): if self.args.spoiler_log: self.log() From 77bde48cd5446b3c79248a5678e95b0370496d51 Mon Sep 17 00:00:00 2001 From: Will Jones Date: Tue, 23 Jun 2026 13:50:49 -0400 Subject: [PATCH 10/11] Update args/graphics.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- args/graphics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/args/graphics.py b/args/graphics.py index 6d612819..d1aaa197 100644 --- a/args/graphics.py +++ b/args/graphics.py @@ -126,7 +126,7 @@ def flags(args): if args.character_names: flags += " -name " + args.character_names if args.steveify: - flags += " -steve " + args.steveify + flags += f' -steve "{args.steveify}"' if args.character_palettes: flags += " -cpal " + args.character_palettes if args.character_portraits: From 0ca6b17ef10eb77c68e9c80b0f1c56b7e2fbb492 Mon Sep 17 00:00:00 2001 From: Will Jones Date: Tue, 23 Jun 2026 13:50:58 -0400 Subject: [PATCH 11/11] Update data/espers.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- data/espers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/espers.py b/data/espers.py index c5064814..f3c50629 100644 --- a/data/espers.py +++ b/data/espers.py @@ -357,7 +357,7 @@ def get_receive_esper_dialog(self, esper): return self.receive_dialogs[esper] def get_name(self, esper): - return self.espers[esper].name + return self.espers[esper].get_name() def log(self): from log import COLUMN_WIDTH, section_entries, format_option