Skip to content

Latest commit

 

History

History
302 lines (262 loc) · 17.2 KB

File metadata and controls

302 lines (262 loc) · 17.2 KB

OT6 Design

FF6 content with Octopath's combat systems.

Vanilla's bugs — useless stats, the Sketch bug, row jank — stay; OT6 only touches vanilla behavior where a pillar requires it.

Pillars

  1. Distinct characters. Every character is one job: exactly 8 active skills (the 8th is a divine-tier finisher) plus up to 4 passives. There is no universal magic pool, and nobody learns everything. Each character's vanilla signature (Slots, Steal, Runic, Sketch, Rage, the first Tool/Blitz/SwdTech/Dance…) is skill #1, free, from the moment they join. The divine slot holds a new top-end ability for that character, never the signature itself.
  2. Shields and weaknesses. Every enemy has shields and a hidden weakness set (elements + weapon classes). Chip shields by hitting weaknesses; at 0 the enemy Breaks, loses its turn, and takes double damage.
  3. Boost Points. Start each battle with 1, +1 at the end of each action, bank up to 5, spend up to 3 to boost an action. A boosted action earns no BP.
  4. Magicite are second jobs. Equipping a magicite grants its spells and a small stat package while equipped; nothing is taught permanently. One copy of each magicite exists, so kitting the party is a puzzle, the same way Octopath allows one shrine license at a time.

The cast as jobs

Character Job read Weapon class Element lean 8-skill kit
Terra Mage Sword Fire 8 spells; divine: Ultima
Locke Thief Dagger Wind Steal grows into a full thief kit: Steal, Mug, armor/attack corrode
Edgar Machinist Spear Lightning the 8 Tools, verbatim
Sabin Monk Claw Fire/Holy the 8 Blitzes, selected from a menu
Cyan Samurai Katana — the 8 SwdTech, priced in BP (see below)
Celes Rune Knight Sword Ice/Holy Runic from the start (signature) + spells (see below)
Gau Beast Tamer Fangs (innate) Earth Rage learned without limit on the Veldt, 8 equipped (see below)
Setzer Gambler/Merchant Cards & dice — Slot from the start (signature), with Coin Toss and Hired Help (paid in gil) behind it; divine: Jackpot, a Fixed-Dice triple, never Slot itself (kits.md)
Strago Scholar Rod Fire/Ice/Lightning 8 Lores, Aqua Breath as the free signature; Analyze (reveals shields and weaknesses) cheap at #2 -- planned, not in the game
Relm Painter Brush — Sketch stays as signature
Shadow Assassin Dagger (thrown) Dark Throw (signature); divine: Assassinate, once a battle: the hit of his that breaks an enemy kills it outright, as does a hit on one already Broken; a boss is only Broken
Mog Dancer Spear varies by dance the 8 Dances, verbatim
Umaro / Gogo Berserker / Mime — — bonus characters; Gogo has access to every job and masters none

Break classes (4): Slash (swords, katanas, claws), Pierce (spears, daggers, thrown edges, bolts, darts), Bludgeon (fists, staves, rods, flails, boomerangs) and Special ¤ (dice, cards, brushes), OT6_SLASH .. OT6_SPECIAL in ot6_class.asm; Ot6WeapClassTbl gives every weapon one. Elements (8): FF6's native fire, ice, lightning, wind, earth, water, holy, poison. That is two more than Octopath's six, which makes the weakness matrix larger.

Break system

Data. Each enemy gets shield_max (1–3 for trash, 4–12 for bosses) and two weakness bytes — one elemental (enemy records already store elemental weakness bits in vanilla), one weapon-class (new side table in expanded ROM).

Chip. Any damaging hit that matches a weakness removes 1 shield, and a multi-hit action chips per hit (one boosted Fight chips four shields off one guard — multi-hit.md §1, probe_multihit.lua, deleted in b18643d7). Multi-hit is deliberately scarce: tools/audit_multihit.py (which exits nonzero if it goes stale) enumerates six multi-hit abilities in the whole game, spread over the three physical kits. Cyan's are vanilla's — Quadra Slam ×4 and Quadra Slice ×4 (MagicProp $58/$5b effect $32, AttackerEffect_32 at battle_main.asm:10794-10796) and Empowerer ×2. Sabin's Pummel ×2 and Bum Rush ×4 and Edgar's Drill ×2 come from Ot6HitCountTbl (ff6/src/battle/ot6_hitcount.asm), which adds to the same $3a70 counter; each of those three has its power divided by its hit count, so the extra hits buy break rate rather than damage. Edgar's AutoCrossbow hits the whole enemy side rather than hitting one target several times: ItemProp $aa sets no extra-attack effect and has no table row, so it lands one hit per body and exactly one chip against a solo boss. Breadth and rate are separate levers and are priced separately; design/multi-hit.md is the survey.

Break. At 0 shields (Ot6Chip / Ot6ClassChip) the enemy is Broken for the length of a private timer at $3e88,y; no ATB cell is written. While the timer runs Ot6Gate refuses to queue its turns (vanilla Stop is not used) and Ot6BrokenTurn empties a turn it had already queued, so its gauge refills and waits; all damage it takes is ×2. A break reveals no weaknesses. On recovery (Ot6Tick), shields reset to shield_max. OT6_BREAK_TICKS is $10 (ot6_break.asm:1), which measures 2159 frames — about 36 s of battle time — for an on-stage monster (probe_ifritbreak.lua, deleted).

Shielded resistance. While an enemy still has shields and is not broken it takes reduced damage (×0.5), so the swing from shielded to broken is ×4, and ×4 on-weakness too rather than ×2: vanilla's weakness ×2 (asl $f0 at battle_main.asm:1899) lands before Ot6HitJoin (:1901) applies the shielded/broken factor, so the two stack. The full range against an unbroken-unweak baseline is 8 (broken+weak) : 4 (broken) : 2 (shielded+weak) : 1. The published 4:2:1 damage-per-BP measurement samples the broken-and-unweak case, so it never measures the strongest state. Either way the conclusion holds: boosting into an unbroken, non-weak target is the worst return on BP, which is intended.

Reveal. Weaknesses start hidden. Chipping one reveals that entry (Ot6RevealCommit, for every monster of the species) and it stays revealed, across battles too: the per-save codex seeds it at the next battle's start (Ot6SeedShields). Nothing reveals everything at once; Strago's planned Analyze (the role Cyrus fills in Octopath) is not in the game.

Display ships with the break system, not as later polish: the shield count and revealed-weakness icons are how an Octopath battle reads to the player. First pass rides the existing battle text engine: shield count beside each name in the monster list window and weakness glyphs on target-select. The battle font already contains weapon icon glyphs (dirk/sword/spear/… from item names).

Sources of chip by character. This is what makes party composition a puzzle: weapon attacks chip by weapon class; spells chip by element; each Blitz, Tool, Lore, and Dance carries an assigned class or element (Aura Cannon is holy, Drill is spear-class, Fire Dance is fire, ...).

BP economy

  • +1 BP at the end of each of a character's actions (Ot6ActionEnd), capped at 5, unless that action was boosted (Octopath's no-regen rule). Every character opens a battle with 1 BP (Ot6InitBP).
  • Spend up to 3 BP when confirming an action. Attack: +1 hit per BP. Skills: potency tier per BP. Buffs/debuffs: duration per BP.
  • Enemies don't have BP, same asymmetry as Octopath: bosses get shields and telegraphs, players get the economy.
  • Boosting also costs MP, when the boost is buying damage. A boosted ability pays max(base, min(99, floor(base × 2.5^boost + 0.5))) (Ot6BoostPriceFor) — x1 / x2.5 / x6.25 / x15.625, capped at 99 and never below the base — so a boost is a trade of two currencies rather than a free multiplier. The rule is one test: a price escalates exactly when the boost multiplies the action. So Fight and Capture stay free (the boost buys swings), tier-family magic and SwdTech are unchanged (the boost already buys a dearer tier), and the chance verbs — Steal, Rage and Slot — stay flat at every level, because their boost buys certainty across a spread of outcomes rather than magnitude, and the BP it costs is what pays for that. MP scales with magnitude; BP alone pays for certainty. mp-economy.md's "Boosting costs MP" has the rule, the table and the rulings.

Boost tiers replace spell tiers. Terra learns Fire, once. Boosted once it casts as Fira; twice, Firaga. This keeps every spell list at 8 without losing the power curve, and it gives boosting a use on every kit rather than only on attackers.

The canon rule: on damage verbs boost multiplies; on chance verbs boost guarantees. A verb that rolls dice — Steal, Dance, and their family (Sketch, Slot, Rage) — has no "potency" to tier, so BP buys certainty instead, expressed in that verb's own vocabulary. Each point narrows the gamble and the full 3-BP spend removes it. Steal is the shipped example (Locke): 0 BP is vanilla to the byte, with the level roll, the 1/8 rare slot, and the Sneak Ring doubling all untouched; each BP raises both the success chance and the rare bias; 3 BP is a guaranteed steal that takes the rare item if the enemy has one, since boost buys certainty rather than creating loot the enemy never had. It deals no damage and takes no multiplier, because a chance verb answers to guarantee rather than potency, and keeping the two axes disjoint is what keeps the rule easy to follow. Steal's tier table and the full ruling live in design/kits.md.

The third category: on reactive verbs, boost buys duration. A verb that does not act but waits — Runic, and every reactive verb after it — has neither a potency to tier nor a die to load. What it has is a window, so BP buys window. This follows from a rule already stated above: buffs/debuffs get duration per BP, and a stance is a buff cast on the situation. Runic is the shipped example: 1/2/3 BP buys 1/2/3 of Celes's own turns during which the stance stands and she acts normally.

Those two halves are one lever and not two tiers, which is worth stating because it is not obvious from outside the code: vanilla ends the stance the moment she takes a turn, so letting her still act requires making the stance outlive her action, which is duration. There is no 1-BP option that buys the free turns without the window.

Duration is counted in turns, not absorbs. A turn count is something the player can read ("three turns of shield"); an absorb count is visible only to the fight. It also bounds the economy: the BP an absorb pays is capped at one per round, the same cap #37 put on the True Knight cover, which was itself mirrored from Runic's own machinery. With the cap, a 3-BP Runic is BP-neutral against three ordinary turns and costs exactly one action. Without it the earn scales with absorbs, and therefore with how many things are casting and how long the stance stands, so it grows most in the fights the stance is bought for. Measured (battle_runic.lua): four absorbable casts into one round of a standing stance bank +1 with the cap and +2 on a control build without it, on a fixture with a single caster.

Cyan demonstrates the BP system. The charge gauge, widely disliked in vanilla, is deleted. The 8 techniques are priced in BP:

# Tech BP
1 Dispatch 0
2 Retort (counter stance) 1
3 Slash 1
4 Quadra Slam (4 hits — strips four shields) 2
5 Empowerer 2
6 Stunner 3
7 Quadra Slice 3
8 Cleave 3, usable only on a Broken enemy (divine)

Boost selects the tech, the way it folds a mage's spell tier, and vanilla's own count of techs known clamps the range to the best one Cyan has learned. Every SwdTech carries a 1-BP floor: Ot6BushidoTech (ff6/src/battle/ot6_bushido.asm) opens with cmp #$01 / bcs :+ / lda #$01, so a stray 0 is clamped up to the cheapest tier rather than allowed to name a tech, and the menu never offers boost 0 at all. The mapping is base = max(0, ceiling-2), tech = min(base + boost-1, ceiling) (its @auto block, with Ot6BushidoCeil), so boost 1/2/3 selects Cyan's top three learned techs, weakest to strongest. The per-tech BP numbers in the table are therefore not fixed prices; what a given tier costs slides as he learns more, so read the column as the relative ordering it was drawn for. Pricing consequences are in design/kits.md and design/mp-economy.md.

There is also a direct SwdTech submenu — Ot6BushidoListOpen (ot6_cmdmenu.asm), dispatched from btlgfx_main.asm, with per-row greying by Ot6BushidoRowGrey (ot6_cmdmenu.asm) and a field-configurable loadout word at $1e1d. Boost selects the tech when the loadout is on AUTO; the submenu is an additional surface, not a replacement.

Cleave is in the ladder and divine-gated: Ot6BushidoOblivion (ot6_bushido.asm) places tech 7 at boost 3 and drops a spent divine back to Quadra Slice for the rest of the battle; the resolution-time Broken gate is Ot6Oblivion (ot6_divine.asm), hooked after ChooseTarget in CalcAttackEffect, because the target does not exist when the command is entered. Mapping, consequences, and the reasoning: design/kits.md.

Celes converts defense into economy. Runic still swallows the next spell; as well as negating it, it grants her +1 BP. Boosted, it stops being a spent turn and becomes a standing magic shield: 1/2/3 BP holds the stance for that many of her turns, and she fights through them. Against a caster boss that is a different fight, and it is the one job nobody else has. The earn stays capped at one BP per round so the shield cannot pay for itself, and vanilla's quirk that Runic eats ally spells is kept: with the stance standing for three turns it will eat a lot of Terra's Cures, which is both the charm and the price.

Gau, controlled. Gau is the Ochette model — learn many, equip 8 — with Rage kept as the verb: Veldt learning stays unlimited and the 8 slots are the equip layer (Ot6RageCost in ot6_boost.asm; Ot6RageLearned / Slot / Nth / List / Show in ot6_rage.asm, with the model stated in that file's header). Leap keeps its name, because CONTRIBUTING's vocabulary rule rules out Capture, which FF3-US already prints as a battle command ($06, the Thief Glove). Leap is also free: it shares the Fight row on the Veldt (Ot6VeldtRow, called from battle_main.asm) and costs nothing (Ot6RageCost). There is no stable. design/kit-gau.md is the canonical Gau document.

Turn structure

ATB is vanilla's: Wait or Active as the player sets it in Config (a new game starts on Wait, menu_sram.asm); OT6 does not force either. "A turn" for BP purposes is each action a character finishes. BP math is per-character and does not need global rounds.

Magicite as sub-jobs

Equipping a magicite grants, only while equipped:

  • its spell/skill list (castable through the same boost-tier rules),
  • its passives, one of them a stat bump — a fixed, constant upgrade, never a per-level bonus — learned for keeps by carrying the esper long enough (the one deliberate exception to while-equipped: design/magicite.md),
  • its summon, once per battle, as the sub-job's divine skill.

Vanilla esper records already store a spell list with learn rates; we reuse the list and ignore the rates. Uniqueness needs no code: there is one of each magicite.

Skill learning

Planned, not in the game: no JP exists (esper learn rates are all zero, and a battle's magic points feed only Terra's Morph). The plan: magic AP is rebadged as JP. Skill #1 — the signature — is free and known on join. The remaining seven are bought in any order at escalating costs (e.g. 80/200/450/800/1400/2200; divine: 3000 and requires the other seven). Passives unlock at 2/4/6/8 skills learned.

Difficulty transform

Enemy difficulty numbers are an OT6 tuning surface. The current broad HP pass is applied as a runtime transform: at monster seed time (the same bank-F0 hook that seeds shields), each non-authored species' battle HP — current and max copies — is multiplied by a per-species-range value in 16ths (Ot6HpMulTbl), clamped at 16 bits. Authored Ot6ShieldTbl species are exempt (boss difficulty is bosses-wob.md's job), as are scene-change battles whose monsters carry HP over. Stamina stays derived from vanilla HP; fraction-of-HP attacks read the transformed cells and scale with the monster.

Shielded resistance is the difficulty lever, not the HP dial. Ot6HpMulTbl ships 1x in every species range. A flat HP bump lengthens every fight equally whether or not the player engages the loop. Resistance is selective: it halves only off-weakness damage, so weakness-exploiters stay vanilla-fast while players who ignore the loop take longer. Measured damage-per-BP comes out 4:2:1 (broken : weak+chips : unbroken-unweak), and a boost-into-sponge policy performs the same as never boosting. See design/balance-metrics.md for the measurements.

The encounter economy carries its own pair, unrelated to HP: Ot6DangerMulW = $0008 (0.5x per-step danger, i.e. fewer fights) and Ot6RewardMulW = $0020 (2x xp+gil on random battles), so XP- and gil-per-step stay ≈ vanilla. XP/gil are not vanilla per battle; they are scaled by the inverse of the rate so the level curve keeps vanilla's pacing.