Ra-Seru levels, Orb and Jette's Clone
Three community-reported oddities, read against the game's own code: why Meta, Terra and Ozma can arrive at Palma's level, why the Orb summon's legs sometimes stay folded inside its sphere, and why Jette's Clone sometimes hands him a full MP bar in a different seat. The first two carry observations from a running game, made on poked states - a value written by hand to set the situation up, named in each section. Jette's Clone is read from the disassembly and disc data alone. Each section says what is proven and what is only predicted.
SCUS_942.54) unless a Japanese (SCPS_100.59) or French (SCES_019.44) one is named. A character's record is 0x80084708 + character * 0x414 (Vahn 0, Noa 1, Gala 2; see the save record). In battle, ctx is the context the word at 0x8007BD24 points to, and the actor table at 0x801C9370 holds eight seats: 0-2 the party, 3-6 monsters, 7 the summon creature (see battle).
Meta, Terra and Ozma inherit Palma's level
- Reported as
- Getting Meta, Terra or Ozma sets their level to Palma's level (community report)
- Cause
- The three Ra-Seru summons are inserted from the same per-character "stash slot 0" that stores Palma's level when the Earth Talisman is taken off
- Where
FUN_80042558inSCUS_942.54: threeclear a2at0x800427AC,0x800427CC,0x800427E8- Affects
- Meta, Terra, Ozma only; the donor is always Palma, on the same character. The same on the Japanese and French discs
- Status
- Explained - from the disassembly; the level copy captured on a poked state
Summons that come from equipment are not learned for good. Every time the game rebuilds a character's stats it looks at the eight equipment bytes and makes sure the matching summon is in the spell list. When a Talisman comes off, its summon is removed and its level and experience are parked in a small per-character stash, so they return when the Talisman goes back on.
Each summon has a stash slot number, written as a literal in the code. Palma uses slot 0, Mule 1, Horn 2, Jedo 3 and the Evil Talisman's summon 4. The three arms that add Meta, Terra and Ozma also pass slot 0.
Each Ra-Seru grows through story scenes, and the scene that gives it its last form is also the moment its summon appears: Meta under Sol Tower, Terra on Mt. Rikuroa, Ozma in East Voz Forest. The summon is inserted with the level and experience out of the stash that only Palma ever fills. It arrives with whatever Palma had on that same character, the last time the Earth Talisman was taken off them. If that never happened, the stash is still zero and the insert routine turns level 0 into level 1 - the ordinary result.
That makes the precise statement narrower than the report: the summon inherits the stashed Palma level of the same character, not the live level of a Palma currently equipped on someone.
The level half of this is observed in a running game, captured on a poked state: with Vahn's stash level byte written to 7 and his Ra-Seru byte written to the final form, Meta appeared at the head of his spell list at level 7. The details are under Verifying it.
Where the bytes live
Not to scale: the fields of the 0x414-byte character record this glitch touches. Stash slot 0's level byte is 0x800849BD for Vahn, 0x80084DD1 for Noa, 0x800851E5 for Gala.
| Equipped item | Summon inserted | Stash slot | Where the slot is set |
|---|---|---|---|
0x72 Earth Talisman | 0x9A Palma | 0 | 0x80042808 |
0x73 Water Talisman | 0x9B Mule | 1 | 0x80042824 |
0x74 Light Talisman | 0x9C Horn | 2 | 0x80042844 |
0x75 Dark Talisman | 0x9D Jedo | 3 | 0x80042860 |
0x76 Evil Talisman | 0x99 Evil Seru Magic | 4 | 0x80042878 |
0x09 Ra-Seru Meta, form 9 of 9 | 0x9E Meta | 0 | 0x800427AC |
0x11 Ra-Seru Terra, form 8 of 8 | 0x9F Terra | 0 | 0x800427CC |
0x19 Ra-Seru Ozma, form 7 of 7 | 0xA0 Ozma | 0 | 0x800427E8 |
Instruction-level walkthrough
The grant scan in FUN_80042558 loops over the eight equipment bytes (lbu v1,0x196(v0) at 0x80042718). Each arm first asks FUN_800431FC whether the spell is already in the list, and only if not falls to the shared jal 0x800432bc at 0x8004287C. The Meta arm:
80042794 jal 0x800431fc ; delay slot: li a1,0x9e
8004279c bne v0,zero,0x80042884
800427a4 li a1,0x9e
800427a8 j 0x8004287c ; delay slot: clear a2 (stash slot 0)
FUN_800432BC(character, spell, slot) inserts at the head of the list, taking level and experience from the slot:
800432f4 lbu t1,0x2b5(v0) ; level = stash byte +5
8004331c bne t1,zero,0x80043328
80043324 addiu t1,t1,0x1 ; level 0 becomes 1
80043378 sb t3,0x13d(t0) ; id
8004337c sb t1,0x161(t0) ; level
80043380 sw t2,0x8(t0) ; experience
8004338c sb v0,0x13c(t0) ; count + 1
The only writer of a stash slot is FUN_80042DBC (level through lbu v0,0x161(v0) at 0x80042E64 and sb v0,0x2b5(v1) at 0x80042E6C). Its one caller is the revoke scan of the same function (jal at 0x80042978), which dispatches id - 0x99 through a five-entry jump table at 0x800151D0, bounded by sltiu v0,v1,0x5 at 0x800428BC. The table stops at 0x9D, so Meta, Terra and Ozma are never removed and never write a stash. The insert reads the stash and leaves it as it was.
Where the final form is written
A Ra-Seru changes form when a scene script runs the field script's "set equipment slot" opcode, 0x3B (script VM). The opcode stores the item id into the equipment byte and rebuilds the character's stats in the same step, so the scene that writes the final form is the one that inserts the summon. Every Ra-Seru stage on the disc is one such opcode, and each final form is written at exactly one place:
| Scene | Script bytes | Meaning |
|---|---|---|
korb3, Sol Tower underground | 3B 03 09 | Vahn, slot 3: Ra-Seru Meta form 9. Grants Meta |
rikuroa, Mt. Rikuroa | 3B 12 11 | Noa, slot 2: Ra-Seru Terra form 8. Grants Terra |
vozz, East Voz Forest | 3B 23 19 | Gala, slot 3: Ra-Seru Ozma form 7. Grants Ozma |
Noa's Ra-Seru sits in equipment slot 2, Vahn's and Gala's in slot 3. The scan reads all eight bytes, so the slot makes no difference to it.
The opcode, instruction by instruction
The arm is 0x801E07DC..0x801E081C of FUN_801DE840 in the field overlay (PROT entry 0897). The store sits in the delay slot of the call to the stat rebuild:
801e07e4 lbu v0,0x0(s6) ; selector
801e07e8 lbu v1,0x1(s6) ; item id
801e07ec srl s2,v0,0x4 ; character
801e07f0 andi s7,v0,0xf ; slot
801e0810 jal 0x80042558 ; the stat rebuild, grant scan included
801e0814 sb v1,0x75e(v0) ; delay slot: record +0x196 + slot = item
The stat rebuild has other callers. One runs when a battle returns to the field (the call at 0x8003B2B8), so an equipment byte changed by any means takes effect at the latest at the next battle exit.
The other discs
The Japanese and French executables pass slot 0 for all three Ra-Seru summons as well, so this is not something the USA release introduced.
| Build | Meta, Terra, Ozma slot arguments | Shared insert |
|---|---|---|
USA SCUS_942.54 | clear a2 at 0x800427AC, 0x800427CC, 0x800427E8 | 0x800432BC |
Japan SCPS_100.59 | move a2,zero in the delay slot of each arm's j 0x80043a88; arms end at 0x800439B8, 0x800439D8, 0x800439F4 | 0x800440EC |
France SCES_019.44 | move a2,zero at 0x800430F8, 0x80043118, 0x80043134 | 0x80043C08 |
On the Japanese disc Palma's arm (0x80043A14) passes slot 0 too, Mule 1, Horn 2, Jedo 3, the Evil Talisman 4, and the removal scan is bounded at five entries at 0x80043AC0. The French executable is the USA code relocated. All read from the disassembly.
Addresses
| Address | Image | What | Evidence |
|---|---|---|---|
0x80042558 | SCUS | FUN_80042558, stat and equipment aggregator. Grant scan 0x80042714..0x8004288C, revoke scan 0x80042894..0x80042990 | disassembly |
0x800427AC, 0x800427CC, 0x800427E8 | SCUS | The three clear a2 giving Meta, Terra, Ozma slot 0 | disassembly |
0x800432BC | SCUS | FUN_800432BC, insert from a stash slot; level floor at 0x8004331C..0x80043324. Seen entered with character 0, spell 0x9E, slot 0 | disassembly; capture (poked) |
0x80042DBC | SCUS | FUN_80042DBC, remove a spell and park it | disassembly |
0x800431FC, 0x80043264 | SCUS | "Spell already listed?" and "item in accessory bytes +0x19B..+0x19D?" | disassembly |
0x800151D0 | SCUS, file offset 0x59D0 | Five-word jump table of the revoke scan | disc data |
0x801E07DC..0x801E081C | PROT 0897 | Opcode 0x3B arm of FUN_801DE840: equipment-byte store at 0x801E0814, in the delay slot of the stat-rebuild call at 0x801E0810 | disassembly |
0x8003B2B8 | SCUS | Stat-rebuild call on the return from battle to the field | capture (poked) |
3B 03 09, 3B 12 11, 3B 23 19 | scene scripts of korb3, rikuroa, vozz | The three final-form writes | disc data |
0x800849BD, 0x80084DD1, 0x800851E5 | RAM | Stash slot 0 level byte: Vahn, Noa, Gala. Experience is the four bytes below each | disassembly; capture (poked, Vahn) |
0x800848A1, 0x80084CB4, 0x800850C9 | RAM | The Ra-Seru equipment byte of Vahn (slot 3), Noa (slot 2), Gala (slot 3) | disc data; capture |
item ids 0x01..0x09, 0x0A..0x11, 0x13..0x19 | SCUS item-name table | The nine forms of Ra-Seru Meta, eight of Terra, seven of Ozma. 0x12 and 0x1A are unnamed gaps; 0x1B is the Ra-Seru Blade | disc data |
0x80084844, 0x80084845, 0x80084869, 0x80084710 | RAM | Vahn's spell count, first id, first level, first experience word | disassembly |
One thing is inference rather than proof: that nothing else touches the stash rests on a search of the dumped functions, not of every overlay byte.
What else follows
- Experience is copied with the level, so the summon is also as far from its next level as the parked Palma was. This half is read from the disassembly only; the stash experience was zero in the captured run.
- It is per character: a Palma levelled on Vahn does nothing for Noa's Terra.
- It needs a Palma removal first. A Palma that is still equipped has not been parked.
- It is one-way. Meta's progress never flows back to Palma, and Mule, Horn, Jedo and Evil Seru Magic keep their own slots.
- The widely circulated cheat codes "Activate Terra at Lv9" and "Activate Ozma at Lv9" write
0x12to0x80084CB4and0x1Bto0x800850C9. Neither is a Ra-Seru form -0x12is an unnamed gap and0x1Bis the Ra-Seru Blade - so neither inserts a summon this way. The Meta code writes0x09to0x800848A1, which does. All three values are "first form + 8", which is the final form for Meta alone.
Verifying it
Observed, captured on a poked state. The run starts from a retail save state in Rim Elm with Vahn alone: Gimard at level 2, stash slot 0 all zero, Ra-Seru Meta form 1. Two bytes are written by hand - 0x800849BD = 0x07 (stash slot 0 level) and 0x800848A1 = 0x09 (the final form). At the next battle exit the stat rebuild runs, FUN_800432BC is entered with character 0, spell 0x9E, slot 0, and on the next frame Vahn's list reads ids 9E 81, levels 07 02, with the stash unchanged. Since both bytes were written by hand, this shows the read side on live code. The battle in that run is a forced formation, which touches nothing in the character record.
The write side shows in played saves with nothing poked: records where the Earth Talisman has been taken off read level 1 in stash slot 0, records where it never was read zero. No save examined carries a parked Palma above level 1, so they are consistent with the mechanism without proving it on their own.
To repeat it:
- Equip the Earth Talisman on Vahn, raise Palma, unequip it.
0x800849BDnow holds Palma's level. - With Meta not yet listed, set Vahn's Ra-Seru byte
0x800848A1to0x09(Noa:0x80084CB4to0x11; Gala:0x800850C9to0x19). A poke alone does nothing until the stat rebuild runs: on an equipment change, the script opcode, or the next return from a battle. Afterwards0x80084845reads0x9Eand0x80084869equals the stash byte. - Control: zero
0x800849B9..0x800849BDfirst, and Meta arrives at level 1. - A breakpoint at
0x8004287Cshowsa1 = 0x9E,a2 = 0.
Open: the experience half of the copy is not observed (repeat the capture with a non-zero counter in 0x800849B9..0x800849BC), and a fully played instance - Talisman worn, Palma levelled, Talisman removed, then the story scene - is not captured.
Orb's legs sometimes do not unfold
- Reported as
- Orb's animation can glitch sometimes: now and then the legs of the player's Orb summon do not come out of its sphere during the summon animation. Hard to recreate; seen in Rogue's Tower among other places (community report)
- Cause
- A "return to idle" flag left set on the summon creature's actor makes the animation code throw away Orb's queued unfold, and Orb only queues it once. What sets the flag in ordinary play is not found
- Where
- Queued at
0x801F7410..0x801F741C(Orb cast module, PROT entry 0911); discarded at0x80047B30..0x80047B58inSCUS_942.54 - Affects
- The player's Orb summon (spell
0x89). Cosmetic: the heal, captions and timing are unchanged - Status
- Partially explained - mechanism read end to end and the symptom reproduced on a poked state; the trigger in play is open
Orb's creature arrives curled inside its sphere, drops to the ground, and on the frame it lands the game queues the "legs unfold" animation to start when the current animation finishes. Nothing forces it to start; it waits its turn.
The game also has a per-actor "go back to idle when this animation ends" switch, which a hit reaction uses so the actor returns to its standing pose afterwards. The summon creature's actor is reused from one summon to the next, and that switch is not reset when a new creature is put in it.
If the switch is on, the queued unfold is thrown away at the very moment it should start, and idle - the curled pose - plays instead. Orb asks for the unfold only once, so the creature stays in its sphere for the rest of the spell while the heal, the captions and the timing all play normally.
Turning the switch on by hand reproduces exactly the reported picture. That is a capture on a poked state: it shows what the switch does, not who flips it. What turns it on during ordinary play is not found, which is why this case is partially explained and not explained.
It is the same stale switch, read by the same instructions, that causes the Gaza camera-orbit softlock. There Kemaro's put-back leaves it set on a monster and the monster's walk-in is replaced by idle; here something leaves it set on the summon seat and Orb's unfold is replaced by idle.
The mechanism, step by step
The creature is battle seat 7. Three bytes of its actor steer its clip: +0x1D9 the clip playing, +0x1DA the clip queued to play next, and +0x1DC the animation flags, whose bit 0x4 means "exit to idle at the end of this clip". Clip 0 is the curled pose (18 frames, legs part-way out near its end); clip 1 is the full unfold (29 frames), ending with the creature standing.
- SeatAfter pulling sixteen light motes in to the caster, the module seats the creature (
jal 0x801f19ecat0x801F70B0), presets the clip cursor to0x30of clip 0's 288 units (0x801F70E4) and puts it at height-0x320(0x801F70F0). - DropA descent, not a timer: each pass adds the frame delta times a speed scalar to the height (
0x801F73DC..0x801F7400) and holds while it is negative. - Landing frameOn the pass the height reaches zero the module adds one to the queued-clip byte (
0x801F7410..0x801F741C) and sets no commit flag. This is its only write to+0x1DA. - The curled clip endsThe animation tick
FUN_80047430tests bit0x4of+0x1DC(0x80047B30..0x80047B3C). If set, it zeroes the queued clip (0x80047B44). Then it commits whatever is queued and clears the low three flag bits (0x80047B50..0x80047B58). - Two outcomesBit clear: clip 1 is committed and the legs unfold. Bit set: clip 0 is committed again and loops, and nothing queues clip 1 a second time.
What lets the bit survive into a new summon: the seat routine FUN_801F19EC clears the playing clip (0x801F1DD8) and writes two other bytes, but has no store to +0x1DC. Of the three bytes that steer the creature's clip, it is the one a new summon inherits from whatever was done to seat 7 before.
The two instruction sequences
The landing frame in the Orb module (PROT entry 0911):
801f7408 bltz v0,0x801f7fb4 ; still above the ground: hold
801f7410 lbu v0,0x1da(s4)
801f7414 sh zero,0x36(s4) ; height = 0
801f7418 addiu v0,v0,0x1
801f741c sb v0,0x1da(s4) ; queued clip = queued clip + 1
The natural end of a clip in the animation tick (SCUS_942.54):
80047b30 lbu v0,0x1dc(s2)
80047b38 andi v0,v0,0x4
80047b3c beq v0,zero,0x80047b48
80047b44 sb zero,0x1da(s2) ; bit 0x4 set: queued clip = 0 (idle)
80047b50 andi v0,v0,0xf8
80047b54 jal 0x8004ad80 ; commit whatever is queued
80047b58 sb v0,0x1dc(s2) ; +0x1DC &= 0xF8
What the captures show
Every cast below is injected: where a party member's action is seeded, the queued action is rewritten to Orb, and the game then loads and runs the spell itself. Where something else was written by hand, the table says so.
| Cast | Written by hand | At the end of the curled clip | Rest of the cast |
|---|---|---|---|
| Reference | nothing | +0x1DC 0; clip 1 committed | Unfolds and stands |
| Bit set early | seat 7 +0x1DC = 4, before the creature is seated | the bit is still 4 after the seat; +0x1DA goes 1 to 0, the cursor wraps | Stays in its sphere to the end |
| Bit set late | seat 7 +0x1DC = 4, four frames after the landing | the same | The same |
| Stale clip ids | seat 7 +0x1D9, +0x1DA, +0x1DB set to 1, and to 2, before the seat | both read 0 again by the landing | Unfolds and stands |
| Forced frame step | frame-step byte 0x1F800393 held at 1, 2, 3, 4 and 6 | landing always at cursor 120 of 288 | Unfolds and stands, every time |
In the two bit-set casts the creature lands with its legs part-way out, snaps back inside the sphere when the curled clip wraps, and stays folded through the "Holy Orb" close-up, the ring burst and the white-out.
What it is not
- A disc loading race. The unfold is queued by a byte increment on the pass the creature's height reaches zero, about 100 frames after a seat that itself runs only once the creature is installed. A late load delays the seat and everything after it together.
- Frame-rate dependence. The descent and the clip cursor scale with the same frame delta, so they cannot drift apart; the forced-step casts all land at the same cursor and unfold.
- Leftover clip ids from the previous summon. Stale
+0x1D9/+0x1DAvalues are cleared before the landing. - A failed sparkle spawn. The module moves its sixteen motes through pointers it stores without testing them (
0x801F6EC0,0x801F7064), and the pool spawnFUN_80050ED4returns 0 when its 96 usable slots are taken. That does not happen in ordinary play: the game releases every retired effect each battle frame (0x8004814C..0x80048184inFUN_800480D8), a state taken going into an Orb cast reads 0 slots used and 123 free actors against the 20 needed, and in two live casts - one a random battle in Rogue's Tower with three party members and two enemies - all sixteen spawns return actors. A failed spawn would cost one mote, not the creature's pose. - The effect-pool clean-up overrunning the pool.
FUN_80050E74walks0x80words where the allocator fills0x60, but the array really is0x80words (battle init zeroes that many at0x8005603C..0x80056050) and no code on the disc references the last 32, so they stay zero and are skipped. - Rogue's Tower itself. One Orb cast in a Rogue's Tower random battle, with screenshots through the whole animation, matches a reference cast on the plains. One clean cast does not clear a location for a fault that happens "sometimes".
Where the flag could come from
Not found. Measured so far: battle setup leaves seat 7 all zero; eighteen other player summons followed to their end (0x81, 0x83, 0x84, 0x86..0x88, 0x8A..0x8C, 0x8E..0x90, 0x92..0x95, 0x98) and six more from other runs (0x82, 0x85, 0x8D, 0x89, 0x96, 0x99) all finish with the flag byte at 0; seven long ones (0x91, 0x9A, 0x9B, 0x9D..0xA0) read 0 as far as they were followed but were not followed to their last phase; and one Rogue's Tower enemy special cast before the party's Orb leaves it at 0.
What remains is inference: a routine outside the spell modules that stages a reaction on whatever actor it is pointed at. After a summon ends, seat 7 keeps a non-zero HP and is no longer animated, so a flag set on it then is never used up by a clip ending and is still there at the next seat. Code outside the spell modules that sets the bit includes the hit flinch at 0x80042144 (the item and Spirit flinch), 0x8004F8D0 and 0x8004BF08 in SCUS_942.54, and 0x801E19DC, 0x801E4868, 0x801E5E9C, 0x801EEC84 in the battle overlay (PROT entry 0898). The list comes from a pattern scan and is a floor; which of them can be handed seat 7 is not traced.
Addresses
| Address | Image | What | Evidence |
|---|---|---|---|
0x801F69D8 | PROT 0911 | FUN_801F69D8, the Orb cast tick; phase byte ctx[+0x279] | disassembly |
0x801F70B0 | PROT 0911 | The seat call, jal 0x801f19ec | disassembly |
0x801F70E4, 0x801F70F0 | PROT 0911 | Cursor preset 0x30; height -0x320 | disassembly; capture |
0x801F73DC..0x801F7408 | PROT 0911 | The descent and its "still above the ground" hold | disassembly |
0x801F7410..0x801F741C | PROT 0911 | Landing frame: +0x1DA incremented, no commit flag | disassembly; capture |
0x801F7420..0x801F7440 | PROT 0911 | Countdown seed for the next phase | disassembly |
0x80047B30..0x80047B58 | SCUS | Natural clip end in the animation tick FUN_80047430: bit 0x4 zeroes the queued clip, then the commit FUN_8004AD80 | disassembly; capture (poked) |
0x801F19EC | PROT 0898 | FUN_801F19EC, the summon seat routine. Clears +0x1D9 at 0x801F1DD8; no store to +0x1DC | disassembly; capture (poked) |
0x801C938C, 0x800EDDB4 | RAM | Actor table entry 7, and the seat 7 actor record it points to in battle | disassembly; capture |
0x800EDF8D, 0x800EDF8E, 0x800EDF90 | RAM | Seat 7's playing clip, queued clip and flags (+0x1D9, +0x1DA, +0x1DC). Writing 4 to the last reproduces the symptom | capture (poked) |
0x1F800393 | scratchpad | The frame-step byte (move VM) | repo doc |
0x801F6EC0, 0x801F7064 | PROT 0911 | The two unchecked stores of a mote spawn result, into the table at 0x801F85E0 | disassembly |
0x80050ED4, 0x80050E74 | SCUS | Pool spawn (searches 0x60 words) and pool flush (walks 0x80) | disassembly |
0x8004814C..0x80048184 | SCUS | FUN_800480D8: per-frame release of retired pool slots, 0x80 words | disassembly |
0x8005603C..0x80056050 | SCUS | FUN_80055B6C: pool zeroed at battle init, 0x80 words | disassembly |
0x801C90F0 | RAM | Part pool: 0x80 words, of which the allocator uses 0x60 | disassembly; capture |
0x80042144, 0x8004F8D0, 0x8004BF08 | SCUS | Code outside the spell modules that sets bit 0x4 of an actor's +0x1DC | disassembly |
0x801E19DC, 0x801E4868, 0x801E5E9C, 0x801EEC84 | PROT 0898 | The same, in the battle overlay | disassembly |
What else follows
- Any summon that queues its next clip once, without a commit flag, shares the exposure. Which others do is not enumerated.
- The enemy Orb is a different animation path and is not examined; neither are the Japanese and PAL discs for this case.
Verifying it
- To reproduce: start an Orb cast and write 4 to
0x800EDF90at any time from before the creature is seated to the end of the curled clip, about 187 frames after the seat. The creature stays in its sphere. - To recognise a real occurrence: log seat 7's
+0x1D9,+0x1DA,+0x1DCand the clip cursor (+0x68of the node at actor+0x22C) every frame of an Orb cast. In the fault+0x1DChas bit0x4set between the seat and the end of the curled clip, and+0x1DAgoes from 1 to 0 at the wrap. - The measurement that would settle it: a write breakpoint on
0x800EDF90that records the program counter whenever bit0x4becomes set while no cast is running - or a save state taken during a bad cast, or just before one with the preceding action known.
Open: what sets the bit on seat 7 in ordinary play; the endings of the seven long summons; and which other summon modules queue a clip once without a commit flag.
Jette's Clone refills his MP and moves him
- Reported as
- Jette restores full MP when using Clone, and the real Jette moves to a new slot (community report)
- Cause
- Clone builds a brand-new monster from Jette's record, copies only his current HP onto it, then a coin flip decides which of the two becomes the 1 HP decoy
- Where
FUN_801F78B8in PROT entry 0940; coin at0x801F8134..0x801F8140- Affects
- Jette only for Clone; the Divide spell shares the "fresh copy" half
- Status
- Explained - from the disassembly; not captured live
The two observations are one event. Clone does not copy Jette. It builds a new monster in the next free seat from Jette's monster record, exactly as the game does when a battle loads: full HP, full MP, fresh stats. Then it overwrites only the newcomer's current HP with the caster's current HP.
Then a coin flip picks which of the two becomes the decoy, and the loser is set to HP 1, MP 0, attack 1 and a small action gauge.
So the MP refill happens exactly when, and because, the real Jette changes seat. It is not a separate restore, and it does not happen on the even roll.
| On the "real" Jette after an odd roll | Result |
|---|---|
MP (+0x150) | Record maximum, 1000 - a new actor, not a restore |
HP (+0x14C) | Not reset: copied from the caster at 0x801F809C. Maximum HP is the record's 34567 |
Ailments (+0x16E) | Empty; they stay on the old seat, now the decoy |
| Attack, defences, intelligence, speed, action gauge | Record values plus the usual battle-load boost; changes made during the fight stay on the decoy |
| Seat | Seat 3 to seat 4 on the first Clone, to seat 5 on the second |
When Jette picks Clone
The choice is made in Jette's arm of the monster AI, FUN_801E9FD4 in the battle overlay (PROT entry 0898), at 0x801EB894..0x801EB90C. All four must hold:
- It is JetteMonster id byte equals
0xAA(0x801EB8A0). - Fewer than three monsters
ctx[+1]is not 3 (0x801EB8B8) - so at most two Clones per fight. - One in three
rand() % 3 == 0(0x801EB8C4..0x801EB8EC). - MP is not zero
+0x150 != 0(0x801EB8F4..0x801EB8FC) - so a decoy, whose MP is 0, can never Clone.
Instruction-level walkthrough of the cast
Clone (0xAE) and Divide (0x50) share FUN_801F78B8. s2 is the caster.
801f7e08 lbu v0,0x1(v1) ; s3 = ctx[+1], old monster count = new seat index
801f7e1c sb v0,0x1(v1) ; ctx[+1] + 1
801f7e3c sb v0,0x0(v1) ; monster id copied to the new seat
801f7e70 sw v0,0x0(a2) ; record pointer copied to the new seat
801f7f18 jal 0x80054cb0 ; full monster init of the new seat
FUN_80054CB0 is the normal battle-load initialiser. Its copy block 0x8005516C..0x8005520C fills HP (+0x14C / +0x14E / +0x172), MP (+0x150 / +0x152 / +0x174) and the other stats from the record. It does not write the ailment word +0x16E. The only caster-to-newcomer copy is HP:
801f8090 lhu v0,0x14c(s2) ; caster's current HP
801f8098 sh v0,0x172(v1) ; newcomer HP mirror
801f809c sh v0,0x14c(v1) ; newcomer current HP
The Clone-only tail (li v0,0xae / bne at 0x801F80F0..0x801F80F4) names the new seat from the string at 0x801F8644, then flips the coin:
801f8134 jal 0x80056798 ; rand
801f813c andi v0,v0,0x1
801f8140 beq v0,zero,0x801f8164
801f8148 sh v0,0x14c(s2) ; odd: caster HP = 1
801f814c sh v0,0x158(s2) ; caster attack = 1
801f8154 sh zero,0x150(s2) ; caster MP = 0
801f8158 sh v0,0x156(s2) ; caster action gauge = 0x20
801f8160 sh v0,0x154(s2)
The even branch at 0x801F8164 makes the same five stores on the newcomer (0x801F816C, 0x801F8178, 0x801F8184, 0x801F8190, 0x801F819C).
The new seat starts clean because battle init FUN_80055B6C zero-fills the whole actor arena (0x80055F14..0x80055F24) and seats are only ever appended. That nothing else dirtied the unused record earlier in the fight is inference.
Addresses
| Address | Image | What | Evidence |
|---|---|---|---|
0x801EB820..0x801EB90C | PROT 0898 | Jette's arm of FUN_801E9FD4; Clone conditions from 0x801EB894; id 0xAE at 0x801EB90C | disassembly |
0x801EB9AC | PROT 0898 | Target store: the caster's own seat | disassembly |
0x801F78B8..0x801F8224 | PROT 0940 | FUN_801F78B8, the Divide / Clone body (router at 0x801F8228) | disassembly |
0x801F7E08..0x801F7E70 | PROT 0940 | Seat allocation: count bump, id copy, record-pointer copy | disassembly |
0x801F7F18 | PROT 0940 | Call to the monster initialiser for the new seat | disassembly |
0x801F8090..0x801F809C | PROT 0940 | The HP-only copy | disassembly |
0x801F8134..0x801F8140 | PROT 0940 | The coin | disassembly |
0x801F8148..0x801F8160 | PROT 0940 | Odd: the caster becomes the decoy | disassembly |
0x801F816C..0x801F819C | PROT 0940 | Even: the newcomer becomes the decoy | disassembly |
0x801F8644 | PROT 0940, file offset 0x1C6C | Name string given to the new seat | disc data |
0x80054CB0 | SCUS | FUN_80054CB0, monster init; stat copy 0x8005516C..0x8005520C | disassembly |
0x80055B6C | SCUS | FUN_80055B6C, battle init; arena clear at 0x80055F14 | disassembly |
0x801C9370, 0x801C9348, 0x8007BD0C | RAM | Actor pointers, monster-record pointers, monster id bytes | disassembly |
monster 170 (0xAA) | PROT 0867 | Jette's record: HP 34567 at +0x0C, MP 1000 at +0x10 | disc data |
spells 0xAE, 0x50 | SCUS spell table | Clone and Divide, MP cost 0 each (spell table) | disc data |
What else follows
- Divide uses the same routine, so every Divide copy is also a fresh actor with record MP and stats carrying the caster's current HP. Divide has no coin and no weakening.
- Clone has exactly one user: no monster record lists
0x50or0xAEamong its magic-attack bytes; both are chosen by AI code. - Each Clone has an even chance of refilling MP and shedding stat changes and ailments. Over the two possible casts, the chance of at least one refill is three in four.
Verifying it
- In the Jette fight, break at
0x801F8134and step to0x801F8140:v0 = 0makes the new seat the decoy,v0 = 1the caster. - For seats 3 and 4, read the actor pointer
pfrom0x801C9370 + 4 * seat, thenp + 0x14C(HP),p + 0x150(MP),p + 0x158(attack),p + 0x16E(ailments), before and after. Predicted odd result: seat 3 reads 1 / 0 / 1; seat 4 reads the old HP,0x03E8, the boosted record attack, 0. - Replacing the
andi v0,v0,0x1at0x801F813Cwith a constant forces either outcome. - With Jette's MP at 0, the gate at
0x801EB8FCnever selects Clone.
Open: whether any targeting or display state still points at the old seat after an odd roll; whether the reset is an intended part of the shell game or a side effect of reusing the monster initialiser (the code reads as the latter, but intent is inference); and the Japanese and PAL releases, which are not examined for this case.