Extract reset, selection, entered-world, and route construction behind LiveSessionHost while preserving the sole LiveSessionController authority. Retain partial route and subscription cleanup for retry, and replace the embedded ACE-only shortcut with the exact named-retail unsigned skill formula. Co-authored-by: Codex <codex@openai.com>
2.8 KiB
Retail skill-formula calculation
Oracle
- Named retail:
SkillFormula::Calculate @ 0x00591960innamed-retail/acclient_2013_pseudo_c.txt. - Retail layout:
SkillFormulainnamed-retail/acclient.h:40199stores six unsigned 32-bit fields in wire order:W,X,Y,Z,Attr1,Attr2.
The signed-looking branches in the recovered x87 code are not signed formula
semantics. They are the compiler's unsigned-32-bit-to-floating-point fix-up:
when the high bit is set, it adds 2^32 after the initial signed conversion.
Pseudocode
bool SkillFormula.Calculate(uint attribute1, uint attribute2, out uint result)
{
uint divisor = Z;
if (divisor == 0)
return false;
// Every operation on this line is uint32 and wraps modulo 2^32.
uint numerator = X * attribute1 + Y * attribute2 + W;
// Formula values are non-negative. Retail rounds to nearest integer,
// with exact halves rounding upward.
result = uint(floor(double(numerator) / double(divisor) + 0.5));
return true;
}
Consequences pinned by the port:
Z == 0is the only failure gate.X == 0remains a valid formula.Wparticipates in the numerator before division; it is not added after division.- multiplication and addition wrap as unsigned 32-bit arithmetic before the floating-point division.
- the division rounds half-up; it does not truncate.
Reference cross-check
ACE's SkillFormula
confirms the unsigned DAT order W, X, Y, Z, Attr1, Attr2. ACE's
AttributeFormula.GetFormula
is only an interpretation aid: it rejects X == 0, assumes unit multipliers,
omits W, and rounds a summed-attribute quotient. That is sufficient for
ordinary stock ACE data but is not the general retail algorithm.
Chorizite DatReaderWriter's generated
SkillFormula
independently confirms the same six-field order and maps its public names to
W, X, Y, and Z. It exposes the four arithmetic words as signed int,
so the retail port must reinterpret their bits as uint. Its summary places
the additive value after division; the named retail function proves that the
actual client adds W to the numerator instead.
Port decision
RetailSkillFormula is the sole App-layer calculation seam. It reinterprets
the DAT words as unsigned, performs the exact unchecked 32-bit numerator, and
uses the retail half-up division. LiveSkillCreditResolver performs only the
skill-table lookup and treats a missing attribute as zero, matching the prior
live-property projection behavior.