Skip to content

Add BeastmasterGauge - #1947

Open
wangel wants to merge 3 commits into
aers:mainfrom
wangel:beastmaster-gauge
Open

Add BeastmasterGauge#1947
wangel wants to merge 3 commits into
aers:mainfrom
wangel:beastmaster-gauge

Conversation

@wangel

@wangel wangel commented Sep 9, 2026

Copy link
Copy Markdown

Adds BeastmasterGauge (ClassJobId 43).

Mapped at runtime on 7.56 with a dalamud plugin I wrote that dumps every frame and
tracks per-byte min/max/distinct, then confirmed each field against the HUD or the combat log.

Offset Field Notes
0x08 TPGauge 0-250. No passive regen; granted by weaponskill combo bonuses. Instinctual skills spend the whole pool.
0x09 FamiliarTPGauge 0-250. One pool shared across Battlehorn slots, not per-familiar. Arrives in +12 steps from the familiar's auto-attacks.
0x0A FamiliarTPAtLastUse Familiar TP immediately before the last familiar action, which scales its potency.
0x0B ActiveBattlehorn 0-3. The slot, not the creature.
0x0C InstinctualComboState Affinity, then 7 while Wavering Heart (Status 4643) locks out further combo advancement.
0x0D CurrentAffinity BeastmasterAffinity, 0-6. Clears ~7s after it is applied.
0x0E ChainCount Chained instinctual skills, matching the number drawn under the Inner Compass.
0x0F KinshipState Two nibbles: kin type high, Battlehorn slot low.
0x10 InstinctState Two 2-bit counters: Natural Instinct low, Mastered Instinct high. Trait-gated, reads 0 below level 28.

BeastmasterAffinity has six values the four compass affinities plus the two combo results:

None 0  Volant 1  Rampant 2  Durant 3  Eldritch 4  Sunstrider 5  Moonstalker 6

The compass runs clockwise Volant -> Rampant -> Durant -> Eldritch -> Volant, and a clockwise pair inside the 7s window is what makes a combo.

Sunstrider and Moonstalker are the results are the affinity you started from. Odd = Sunstrider, Even = Moon.

The Status sheet backs this up. The six statuses the job applies are in this order (4595-4600).

The upgrade only lands if the target survives the combo.

0x10 holds two resources in one byte. Mastered Instinct (bits 2-3, trait Wild Heart III at
level 28) is gained when a you complete a combo...ie; You use tricks and then an axe skill. Rally is the spender.

Natural Instinct (bits 0-1, Wild Heart IV at level 40) is gained when a pet completes a combo....ie; you use an axe skill, then tricks. It's spent using Rallying Cheer.

Each caps at 3, each spender clears only its own bits.

Thanks to @Taurenkey for identifying the 0x0C 7 as Wavering Heart, and to @Haselnussbomber
for XBMManager and ActionManager.BeastmasterPets, which is where the familiar's identity
lives - the gauge only exposes the slot.

@Taurenkey

Copy link
Copy Markdown
Contributor

The part you're not sure about should relate to the status you get as a player, when it's set to 7 you have the "Wavering Heart" status which prevents further advancement to the combo until it's cleared. Most likely to prevent triple weaving shenanigans breaking the gauge or something.

Beastmaster (ClassJobId 43) had no gauge struct. Mapped at runtime on patch
7.56 by watching JobGaugeManager while playing the job, with every offset
confirmed against the in-game display, ability tooltips or the combat log.

Fields, CS 0x08 through 0x0F:

  TPGauge               player TP; granted by weaponskill combo bonuses
                        (Axeblade Bite +13, Shieldsplitter +15), not regen
  FamiliarTPGauge       familiar TP; one pool shared across Battlehorn
                        slots, arriving in +12 steps from auto-attacks
  FamiliarTPAtLastUse   familiar TP at the last familiar action, which
                        scales its potency; actions spend the whole pool
  ActiveBattlehorn      summoned Battlehorn slot, not the creature
  InstinctualComboState active affinity, or 7 while the Wavering Heart
                        status locks out further combo advancement
  CurrentAffinity       BeastmasterAffinity
  ChainCount            chained instinctual skills
  KinshipState          packed (kin type << 4) | Battlehorn slot, latched
                        when Borrow grants a Kinship

Adds BeastmasterAffinity, whose six values match the contiguous status rows
4595 Volant Heart through 4600 Moonstalker. An intentional combo is the next
affinity clockwise, and which of the two extra affinities it yields is the
parity of the affinity it started from, so no lookup table is needed. The
upgrade requires the target to survive the combo.

Adds BeastmasterKinType, whose eight values match the Kinship status rows
4602 Beast through 4609 Ash. All eight were observed directly in the gauge
and cross-checked against the Kinship each familiar actually granted.
@wangel

wangel commented Sep 9, 2026

Copy link
Copy Markdown
Author

That's it exactly, thank you!!!!

"Otherwise engaged. Unable to perform combos with your familiar."

It also explains something that had been nagging me. I'd measured that hold at 2.22–2.23s and got the same number on every combo across three different pairings, which felt far too clean for a resolution delay. It isn't one, it's a fixed status duration.

Chasing it turned up a related bit of behaviour worth recording: if the second skill kills the target, you still get Wavering Heart and the ChainCount increment, but the affinity never upgrades to Sunstrider/Moonstalker. That had me convinced I had something broken.

Pointing me at the status side was worth doing twice over, because going back to the sheet turned up two more things.

First, the six affinities are contiguous and in the same order as the gauge values (4595 Volant Heart → 4600 Moonstalker), which independently confirms Rampant = 2 — the one value I had gotten from the compass position rather than actually observed. Sunstrider and Moonstalker also each say that using a skill with the other's affinity triggers an "infinitive combo", so there's a tier above intentional that pairs 5 against 6.

Second, and bigger: I'd written 0x0F off as a timer that goes up. It isn't a timer at all — I was reading it as a decimal. In hex it's two nibbles, high is the familiar's kin type and low is the Battlehorn slot it came from. I summoned one familiar of each kin and used Borrow:

0x11 Beast/1   0x12 Beast/2   0x83 Ash/3     0x51 Wave/1
0x32 Cloud/2   0x73 Soul/3    0x62 Scale/2   0x41 Seed/1
0x21 Vile/1

All eight kin types, each matching the familiar I had out and the Kinship status I actually got, numbered the same as the Kinship block at 4602–4609. So the branch now carries KinshipState and a BeastmasterKinType enum — kin type is in the gauge after all, which the original body said it wasn't.

While I was at it I also had to correct both TP fields, since neither gauge regenerates: player TP comes from the weaponskill combo bonuses (Axeblade Bite +13, Shieldsplitter +15), which averages neatly to the "~14 a tick" I had wrongly written down.

Branch and body are both updated.

@wangel

wangel commented Sep 9, 2026

Copy link
Copy Markdown
Author

Two updates and a thank-you.

Rampant = 2 is no longer inferred. I hooked UseAction in my dump plugin and attributed
each 0x0D transition to the press just before it. Avalanche Axe applies 2 directly, so every
value in the enum has now been seen in the gauge rather than derived from Status sheet ordering.
I've corrected that line in the description above.

The same attribution mapped the four standalone axes, one per compass affinity:

action affinity
44884 Avalanche Axe Rampant (2)
44887 Mistral Axe Durant (3)
44888 Spinning Axe Eldritch (4)
44889 Gale Axe Volant (1)

These are fixed per action — the affinity is shown on the actions in game, and only the
familiar's varies. Nothing this PR needs, but it is independent confirmation that the enum
ordering is real rather than a coincidence of the Status sheet: the four axes cover all four
affinities, so there is always one at beast affinity + 1 and an intentional combo is available
whatever familiar is out.

The familiar's side resolves through the XBMPet sheet rather than the creature: affinity is a
property of the pet's AutoAttack action (see the sheet columns below), not of the pet
or its kin. Cu Sith and Puk share
AutoAttack 45187 and both apply Rampant despite differing in kin, Pet id and notebook
slot. Roughly 15 action ids cover all 50 pets. The unnamed 0x1A is not the affinity - Cu Sith
is 3 and Puk is 2, and both give Rampant.

Thanks @Haselnussbomber for XBMManager (4aa267b) — that joined up two things I had been
poking at separately. Some runtime detail back, in case it is useful to whoever writes the
binding for ActionManager::GetBeastmasterPet (0x1408F0590, named in the same commit):

  • the argument is a Battlehorn slot, 0-based — 0, 1, 2. (Correction to an earlier draft of this:
    it is bounds-checked and returns 0 above index 2. I had called it through a 64-bit signature and
    was reading stale register bits above the returned byte.)
  • the return is the Monster Notebook position, 1-based: 1 for a familiar sitting at notebook
    slot 1, 20 for one at slot 20.
  • those values are the id IsPetUnlocked takes, and the bit index is petId - 1.
  • BNpcBase BaseId = petId + 18915 held on all five familiars I tried, across petId 1–20.
    PetBuddy.DataID does not track it consistently — one familiar is off by one, so BaseId
    is the field that stays in step.

On XBMPet (51 rows, row 0 null): I had worked out some columns by matching the sheet against
familiars I had summoned, but nt153133 kindly sent me the SaintCoinach definition, which names
them properly and corrects two of my guesses. In dump order:

Description, TrickDescription, TemperedReleaseDescription, Icon, Pet, AutoAttack,
NaturalHabitat, Classification, two unnamed bytes at 0x19 and 0x1A, NaturalHabitatType.

Pet is the link to the Pet sheet - that is the id IBuddyList.PetBuddy.DataID gives you.
AutoAttack is an Action row. NaturalHabitat is a complexlink: PlaceName when
NaturalHabitatType is 1, ContentFinderCondition when it is 2. What I had taken for a tier was
the habitat type, and what I had taken for a text reference was the icon.

Classification is the kin type, 1-8 Beast/Vile/Cloud/Seed/Wave/Scale/Soul/Ash - that one I had
right, and it matches the gauge's 0x0F high nibble exactly.

One correction I guessed XBMModule was where the
slot→creature mapping lived. GetBeastmasterPet is the actual answer.

Mastered Instinct and Natural Instinct share one byte at 0x10, two bits
each. Both are trait-gated, so the byte reads 0 below level 28 and only
the upper pair moves until level 40 - which is why an earlier revision of
this PR reported everything from 0x10 on as unused.
@github-actions github-actions Bot added the requested changes Changes requested through comments label Sep 10, 2026
Size was 0x10, which only allows offsets up to 0x0F, so the new field at
0x10 tripped CExporter. Rounded up to the next 8-byte boundary to match
the other gauges in this file.
@github-actions github-actions Bot removed the requested changes Changes requested through comments label Sep 10, 2026
@wolfcomp wolfcomp added the AI This PR has been created with an AI summary and/or AI commits. label Sep 10, 2026
@wangel

wangel commented Sep 11, 2026

Copy link
Copy Markdown
Author

Rewrote the description in my own words - the original was written by AI was slop, I was being lazy with it. The data was all gathered from a plugin I wrote, that I used while testing and playing. If you any of you want the plugin to see it, hit me up and I'll share it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI This PR has been created with an AI summary and/or AI commits.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants