Repository navigation
Conversation
Account's tail changed: six zeros before the repeated Server and a bare 03 after it, where it used to be four zeros and 03 09 03. Both forms are read now. The byte before the tail, previously skipped, is read as Faction (1 on a Light server, 2 on a Dark one in every sample seen). Join (39 0D), the server the client picked in the lobby, is read: 00 00 00 then the server ID. Fixtures and tests cover both Account tails, Join, and a Servers list whose last group of four holds only two entries.
…sition The flag byte's 0x08 bit was skipped before; it marks whether the message carries one extra byte. After that, a 16-bit value is always sent twice, then a trailing 01. Verified against a real capture: the value matches across repeats for the same entity and differs between entities, but no sample has shown it change for one entity, so what it represents (heading, most likely) isn't confirmed -- only the byte layout is. 0x371D moves from the wire decoder's family-match fallback to its known list, alongside its 371A-371C siblings; `go generate ./wire` found no fixture drift from the change.
…etimes position 28 37 and 29 37 carry an entity, a flag byte (04 or 02, likely redundant with the opcode), a position, then a shared 15-byte tail: two headings, a speed, a changing u16, and a trailing 01. 2A 37 ends with the same 15-byte tail but has no position -- what comes before it instead varies in length (1 to 3 bytes so far) and isn't understood. Rather than guess the rule behind that variable lead, headingOnly anchors the tail from the end of the frame, using the length the reader already knows. Verified against a real capture: 2A 37's Heading1/Heading2/Speed match the position-carrying 28/29 37 exactly for the same entity at the same moment. Which of Heading1/Heading2 is current vs. a target, if either, and what the two opcodes' difference and the skipped u16 mean, are not confirmed -- only the byte layout is. wire/opcode.go gains 3728/3729/372A in its known list; `go generate ./wire` found no fixture drift.
…t of a session's opcodes Read from a 500 s recording (16111 server messages): decoded 11353 -> 15613, failed 945 -> 0. Fixed, each checked against every sample in the recording: - Turn (1D 37): the flag's low four bits each add one byte before the two headings, and the trailing 01 is sent only with flag bit 0 clear. The old layout failed 945 of 980. New Heading2 field: the two differ on a few. - Spawn (41 36): the mask is two bytes since the patch, four before it; both are read. Positions match the entity's later Move. - Hit (04 38): switch nibble 0 sends no damage varint. - Cast (02 38): the short form is read, and Angle and Duration added. Decoded: - Stats (00 8D): an entity's attributes, a mask then u32 and u64 groups. - Spawn (34 36): entities that never moved, Move (2F 37). Guessed, named and read in game/guess.go, each doc comment saying what the guess rests on: Target, Combo, SkillUse, Windup, Engage, Threat, Attributes, Height, Effect, Area, Cutscene, Script, and the generic Ref, Tagged and Signal. The rest of the types in the recording are named from their family and not read. wire keeps the guessed opcodes in a list of their own: KnownOnly keeps them, and the lock does not count them, as a longer known list made noise look like the game's frames twice as often (internal/score). Fixtures are frames of the recording; the synthetic Turn and Cast ones, whose layouts the recording contradicts, are replaced.
hanios123
force-pushed
the
feat/session2-opcodes
branch
from
October 10, 2026 16:42
96a407b to
dd0a3dc
Compare
Author
|
Superseded by #3: same changes, with the branch renamed and the title and description reworded. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Today's decoding work from a 500 s recording of the game (16,111 server messages): decoded 11,353 → 15,613, failed 945 → 0. The branch holds four commits: the Account/Join, Turn and Heading commits from earlier today, and one that reads the rest of the recording.
Fixed (checked against every sample in the recording)
1D 37Turn01is sent only with flag bit 0 clear. The old layout failed 945 of 980. NewHeading2.41 36SpawnMove.04 38HitDamageis 0, never otherwise).02 38CastAngleandDurationadded. The older fixtures decode with the same tail.New
00 8DStats: an entity's attributes, a mask then u32 and u64 groups. 1392/1392 parse.34 36Spawn (entities that never moved),2F 37Move.Guessed (
game/guess.go)Target, Combo, SkillUse, Windup, Engage, Threat, Attributes, Height, Effect, Area, Cutscene, Script, and the generic Ref, Tagged, Signal. Each doc comment says what the guess rests on. The other types in the recording are named from their family and not read.
a2k statsmarks themguessed, as opposed toknown.wire
Guessed opcodes sit in a
guessedlist of their own.KnownOnlykeeps them; the lock does not count them. Adding them toknowndoubled the noise frames that look like the game's (go run ./internal/score -n 100 -noise 5: 2869 vs 1419 known frames), and with the separate list it is back to 1478, still 0 locks.Tests
TestFight's casts now carry a tail.TestReadsKnownchecks the guessed and known lists stay apart.Notes
🤖 Generated with Claude Code