Aller au contenu
Afficher dans l'application

Une meilleure façon de naviguer. En savoir plus.

Asterobot

Une application plein écran sur votre écran d'accueil avec notifications push, badges et plus encore.

Pour installer cette application sur iOS et iPadOS
  1. Appuyez sur Icône de partage dans Safari
  2. Faites défiler le menu et appuyez sur Ajouter à l'écran d'accueil.
  3. Appuyez sur Ajouter dans le coin supérieur droit.
Pour installer cette application sur Android
  1. Appuyez sur le menu à trois points (⋮) dans le coin supérieur droit du navigateur.
  2. Appuyez sur Ajouter à l'écran d'accueil ou Installer l'application.
  3. Confirmez en appuyant sur Installer.

Protocole Dofus

Le protocole Dofus actuellement pris en charge par Asterobot
New characteristics for one fighter of the current fight: its id and its full fight stats record.
Kind event · Area Game.Fight
Replaces what you know about one fighter's characteristics during a fight: life, action and movement points, resistances and the rest, plus its summon and invisibility state.
WHAT TO DO WHEN YOU RECEIVE IT
1. Find the fighter by FightRefreshCharacterStatsEvent.fighter_id - the per-fight fighter id, the same id as ActorPositionInformation.actor_id in FightFighterShowEvent. Ignore the message if you do not know the fighter. 2. Take its characteristics from FightRefreshCharacterStatsEvent.stats: a list of CharacterCharacteristic entries keyed by characteristic id. Update every entry the list carries. 3. SEND NOTHING BACK. The handler builds no request.
WHAT THE CLIENT DOES. Its fight-sequence service converts the stats' characteristic list into its own characteristic objects, publishes them for the fighter together with the fighter id, and hands the same list and id to the routine that updates that fighter. It also reads the record's invisibility state to decide one display flag.
IT IS THE FIGHT FORM. Outside fights the character's own characteristics arrive in CharacterCharacteristicsEvent; in a fight every fighter, yours included, is updated through this message.
PADDING. Builds may add unread members. Read the two recovered members only.
When you may send it
Requires context_ready inferred Related messages
Unsolicited - nothing you send causes this the server pushes it when a fighter's characteristics change during the fight; no request asks for it Fields
#FieldTypeMeaningYou set it 1statsFightCharacteristicsThe fighter's full fight characteristics: a list of CharacterCharacteristic plus summon and invisibility state.
A FightCharacteristics record (no signature here yet). Proven as the only message member read, whose type directly carries the recovered CharacterCharacteristic list.never 2fighter_idint64The fighter whose characteristics changed: its per-fight fighter id. (fighter id)
Proven as the only int64 the handler reads; it travels with the characteristic list into the fighter-update routine.never
  • summary: New characteristics for one fighter of the current fight: its id and its full fight stats record.
  • area: Game.Fight
  • 45 vues
Asks to watch the fight a given player (a friend, guild or alliance member) is in, wherever it is.
Kind request · Area Game.Fight.Preparation
Watches the fight of one player, named by id. Unlike FightJoinRequest with fighter id 0, you do not need to be on the fight's map or know the fight id: the server finds the fight from the player.
HOW TO SEND IT
1. PUT THE PLAYER'S CHARACTER ID in FightSpectatePlayerRequest.player_id: a friend, a guild member or an alliance member who is currently fighting. Nothing else. 2. Expect to enter the fight as a spectator if the server allows it (the fight may be closed to spectators).
WHERE THE CLIENT SENDS IT. The friends list, the guild members list, the alliance members list and the alliance fight list each have a Spectate action for a member in a fight; they all raise one client action carrying the member's id, and the fight-join service (the one that also sends FightJoinRequest) turns it into this message.
When you may send it
Requires character_loaded inferred Raised by: the player clicks Spectate on a friend, guild member or alliance member who is fighting (friends, guild and alliance windows, and the alliance fight list) proven Related messages
Reply not yet recovered: If the server accepts, you enter the fight as a spectator (FightSpectatorJoinEvent, no signature yet). Fields
#FieldTypeMeaningYou set it 1player_idint64The character whose current fight you want to watch. (character id)required
  • summary: Asks to watch the fight a given player (a friend, guild or alliance member) is in, wherever it is.
  • area: Game.Fight.Preparation
  • 42 vues
Placement is over and the fight itself begins. The message is empty.
Kind event · Area Game.Fight.Preparation
The end of the placement phase. The fight announced by FightStartingEvent and joined with FightJoinEvent stops being a preparation and becomes a running fight.
WHAT TO DO WHEN YOU RECEIVE IT
1. Leave your placement state. Placement requests - FightPlacementPositionRequest to move to another starting cell, FightReadyRequest to say you are ready - no longer apply. 2. Stop the placement countdown you started from FightJoinEvent.time_max_before_fight_start. 3. SEND NOTHING BACK. The handler builds no request. 4. Wait for the turn loop: FightTurnEvent says whose turn it is, and FightTurnStartPlayingEvent tells you when your own fighter may act.
There is nothing to read: the message is empty, and the client reacts to its arrival only. The handler that receives it is the one that also handles FightStartingEvent and FightJoinEvent; it switches its fight state out of preparation and publishes an internal notification for the rest of the client.
DO NOT CONFUSE IT WITH FightStartingEvent. That one opens the fight, before placement; this one closes placement. A fight you join after placement is over sends no placement phase at all (FightJoinEvent.is_fight_started is then true).
When you may send it
Requires context_ready inferred Related messages
Unsolicited - nothing you send causes this the server decides when placement ends (every fighter ready, or the placement countdown elapsed) and announces it on its own
  • summary: Placement is over and the fight itself begins. The message is empty.
  • area: Game.Fight.Preparation
  • 41 vues
Opens the fight the character is entering: fight id, fight type, who attacked, whether a boss is in it and which monsters take part.
Kind event · Area Game.Fight.Preparation
The first fight message of a fight. It tells you which fight you are in and how it started. It arrives once per fight, while the fight is still in its placement phase.
WHAT TO DO WHEN YOU RECEIVE IT
1. Start a new fight record. Forget the previous fight's state: fighters, turn order, placement cells. Key the record by FightStartingEvent.fight_id. 2. Store FightStartingEvent.fight_type (FightType). It decides what the rest of the fight looks like (PvM, arena, challenge, ...). 3. Store FightStartingEvent.attacker_id. When you attacked a monster group it is your own character id. 4. Read FightStartingEvent.monsters if you need to know what you are fighting: it lists the monster template ids taking part, before any fighter is shown. 5. SEND NOTHING BACK. No handler of this message builds a request. 6. Wait for FightJoinEvent, which comes right behind it and says whether you are placing, ready-checking or already fighting.
WHAT THE CLIENT DOES. Its fight-state object takes the fight type (through the client's own fight-type conversion), the attacker id and, on builds from 3.5 on, the fight id. It sets a boss flag from FightStartingEvent.contain_boss and walks FightStartingEvent.monsters, checking each id against one monster race of the game data to set a second flag.
THE DEFENDER. The canonical message also carries the defender id - the attacked entity, the monster group id when you attack monsters (the same negative id you put in AttackMonsterRequest.monster_group_id). The client never reads it, so it is named here only on builds where it is the one int64 left besides the attacker; a build that pads the message with another int64 leaves it unnamed.
OBSERVED (one capture, PvM): attacker = own character id, defender = the attacked monster group's id (-20002), fight_type = PvM, monsters = the two monster template ids of the group, fight_id = 3089, the id the fight team updates (FightTeamUpdateEvent) for the same fight had carried a few milliseconds earlier. It arrived about 30 ms after ContextReadyRequest for the fight map, then FightJoinEvent and one FightFighterShowEvent per fighter followed in the same burst.
IT IS NOT ONLY AN ANSWER TO YOUR ATTACK. It follows AttackMonsterRequest when you attack a monster group, but it also opens the fight when another player attacks you or when you join a fight on the map (FightJoinRequest).
PADDING. Builds add decoys: a repeated string (3.7), a nested message (3.4), a third int64 (3.6.12.16). Unnamed members are padding; leave them unset.
When you may send it
Requires context_ready inferred Related messages
You will then receive FightJoinEvent observed — travelling companion: arrived in the same frame burst right after it, 1 of 1 observation (attack on a monster group) Arrives after AttackMonsterRequest Arrives after FightJoinRequest Fields
#FieldTypeMeaningYou set it 1attacker_idint64Id of the entity that started the fight: your own character id when you attacked. (entity id)
The one int64 the client reads and keeps; the unobfuscated beta handler names it attackerId.never 3monstersrepeated int32Template ids of the monsters taking part in the fight. (monster template id)
Observed: [4046, 4047]
The client walks the list and checks each id against one monster race of the game data.never 4defender_idint64Id of the entity that was attacked: the monster group id when you attacked monsters. (entity id)
Observed: -20002
The client never reads it. Named only where it is the one int64 left beside the attacker; padded builds leave it unnamed.never 5contain_bossboolTrue when a boss monster takes part in the fight.never 6fight_typeFightTypeThe kind of fight that is starting.
A FightType; the client converts it to its own fight-type value and keeps it for the whole fight.never 7fight_idint32Id of the fight, the key every later message about this fight refers to. (fight id)
Observed: 3089
Stored by the client from 3.5 on; older handlers ignore it.never
  • summary: Opens the fight the character is entering: fight id, fight type, who attacked, whether a boss is in it and which monsters take part.
  • area: Game.Fight.Preparation
  • 46 vues
The full, authoritative state of every fighter (position, look, characteristics), sent to resynchronize the fight.
Kind event · Area Game.Fight
A snapshot of every fighter, as ActorPositionInformation records: actor id, disposition (cell and direction) and the fighter information with its characteristics.
WHAT TO DO WHEN YOU RECEIVE IT
1. Treat it as authoritative for every fighter it lists: replace each listed fighter's cell, direction and characteristics (life, AP, MP, ...) with what the record says. 2. Apply it IN ORDER with the fight's action sequences. The client queues it as a step of its fight-sequence player rather than applying it on arrival, so it lands after the actions that precede it on the wire. 3. SEND NOTHING BACK.
DO NOT CONFUSE IT WITH THE ROLEPLAY SPAWN. GameRolePlayShowActorsEvent carries the same record type, but it adds actors to a map and is applied immediately; this one belongs to the fight file and describes fighters.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server sends it on its own to resynchronize the fighters; no request asks for it Fields
#FieldTypeMeaningYou set it 1fightersrepeated ActorPositionInformationEvery fighter's current state.
Element type ActorPositionInformation.never
  • summary: The full, authoritative state of every fighter (position, look, characteristics), sent to resynchronize the fight.
  • area: Game.Fight
  • 46 vues
One team of one fight: which side it is, its leader, its alignment side, its team type, its wave count and its members.
Kind struct · Area Game.Fight
One team of one fight, as the server describes it to everyone who can see the fight: which side of the fight it is, who leads it, its alignment side, what kind of team it is, how many waves it has, and either its full member list or only a summary.
HOW TO READ IT
1. FightTeamInformation.team (Team) says which side of the fight this team is. Two records of the same fight differ here; key teams by it. 2. FightTeamInformation.leader_id is the team leader. FOR A MONSTER TEAM IT IS THE MONSTER GROUP'S MAP ID, which is negative - the id you put in AttackMonsterRequest.monster_group_id - not a fighter id. Fighters get their own per-fight ids (FightFighterShowEvent). 3. FightTeamInformation.side (Alignment) is the team's alignment side. 4. FightTeamInformation.type (TeamType) is what the team is made of: players, monsters, a tax collector, a prism and so on. 5. FightTeamInformation.waves is the team's wave count. It was 0 for both teams of the ordinary monster fight captured. 6. Exactly one branch of team_information is set: - FightTeamInformation.team_members (FightTeamMembersInformation): every member, one entry each; - FightTeamInformation.light_information: a summary only (counts, average level, a few flags), sent when the full list is not given. Check which branch is set before reading either.
WHERE IT ARRIVES. Inside FightTeamUpdateEvent (one team at a time; MERGE the members into the team you hold) and as each entry of FightCommonInformation.teams_information (a fight shown on the map). The client converts both with the same routine.
OBSERVED (one capture, 3.7.8.7, attacking a monster group): two records for fight 3089. Your team: leader = your character id, side WITHOUT, team and type at their defaults, team_members listing you. The monster team: leader -20002 (the attacked group), team 1 and type 1 on the wire, team_members present but empty.
PADDING. Builds add unread members: a second int64 (3.7), a map (3.6.12.16). They stay unnamed; leave them unset.
Not sent on its own — it travels inside FightTeamUpdateEvent and as an entry of FightCommonInformation.teams_information. proven
Used by
FightCommonInformation FightTeamUpdateEvent Fields
#FieldTypeMeaningYou set it 1typeTeamTypeWhat the team is made of: players, monsters, a tax collector, a prism...
A TeamType. Proven as the one enum the converters read besides team and side.never 3wavesint32The team's wave count; 0 in an ordinary fight. (count)never 5sideAlignmentThe team's alignment side.
An Alignment.never 6teamTeamWhich side of the fight this team is (challengers or defenders).
A Team. Two teams of one fight differ here.never 8leader_idint64The team's leader. For a monster team: the monster group's negative map id, not a fighter id. (entity id)never 2light_informationtype not documented yetA summary of the team (counts, average level, flags) instead of its member list.
A FightTeamLightInformation (no signature here). Branch of team_information.never 4team_membersFightTeamMembersInformationThe full member list, when the server sends it.
A FightTeamMembersInformation. Branch of team_information.never
  • summary: One team of one fight: which side it is, its leader, its alignment side, its team type, its wave count and its members.
  • area: Game.Fight
  • 48 vues
The full member list of one fight team: the branch of a team record that names every fighter.
Kind struct · Area Game.Fight
The detailed form of a team: one entry per member. It is the FightTeamInformation.team_members branch; the other branch, FightTeamInformation.light_information, only summarises a team without listing it.
HOW TO READ IT
1. Walk FightTeamMembersInformation.team_members. Each entry is one FightTeamMemberInformation; the client converts every entry into its own team-member object and keeps them in the order received. 2. Merge, do not replace, when the record comes from FightTeamUpdateEvent: that event adds members to a team the client already knows. 3. Ignore FightTeamMembersInformation.alliance_relation. The client never reads it.
THE MONSTER TEAM OF A FIGHT YOU JUST STARTED MAY BE EMPTY. In one capture (3.7.8.7) the monster team of a fresh PvM fight arrived with no entries while the player team listed the attacker. The fighters themselves arrive later, one FightFighterShowEvent each.
PADDING. Builds may declare a second list of the same element type beside the real one. The client walks one list only; the other stays unnamed. Read the recovered list.
Not sent on its own — it travels only as the FightTeamInformation.team_members branch. proven
Used by
FightTeamInformation Fields
#FieldTypeMeaningYou set it 1alliance_relationAllianceRelationHow the viewer's alliance relates to this team; the client never reads it.
Explicit presence: absent is not the same as zero.
Named from its stable explicit-presence declaration across every dumped build, not from client behaviour.
Ignore it: no client code consults it.never 2team_membersrepeated FightTeamMemberInformationThe team's members, one entry each, in the order the server lists them.
Proven as the list the client walks; a second list of the same element type is padding.never
  • summary: The full member list of one fight team: the branch of a team record that names every fighter.
  • area: Game.Fight
  • 45 vues
One member left one team of one fight: the fight, the team and the member's id.
Kind event · Area Game.Fight.Preparation
The removal counterpart of FightTeamUpdateEvent: that one only ever ADDS members, this one takes one member out.
WHAT TO DO WHEN YOU RECEIVE IT
1. Find the fight under FightTeamRemoveMemberEvent.fight_id among the fights you know (the map's fights from ShowChallengeEvent and MapComplementaryInformationEvent, or the fight you are preparing). 2. In the team FightTeamRemoveMemberEvent.team names, REMOVE the member FightTeamRemoveMemberEvent.character_id. Leave every other member alone. 3. SEND NOTHING BACK. No handler of this message builds a request.
WHAT THE CLIENT DOES. Two services react: - the map's entity service takes the three values together and drops the member from that fight's team on the map; - the fight-preparation service removes the id from its own list of team members.
IF YOU ONLY HANDLE FightTeamUpdateEvent, YOUR TEAMS ONLY GROW. Members who leave a fight during placement stay in your model until the fight ends.
PADDING. Builds may add unread members beside the three; read the recovered ones only.
When you may send it
Requires context_ready inferred Related messages
Unsolicited - nothing you send causes this the server pushes it when a member leaves a team, whoever caused it; no request asks for it Fields
#FieldTypeMeaningYou set it 1fight_idint32The fight whose team lost a member. (fight id)never 2character_idint64The member that left the team. (entity id)never 3teamTeamWhich team of that fight the member left (challengers, defenders or spectators).
The enum type (beta's Team) has no signature yet, so its values stay obfuscated.never
  • summary: One member left one team of one fight: the fight, the team and the member's id.
  • area: Game.Fight.Preparation
  • 40 vues
One team of a fight gained members. Add the record's new members to that fight's team; nobody is removed.
Kind event · Area Game.Fight.Preparation
Updates one team of one fight. fight_id says which fight; team is the team record: which side of the fight it is (challengers or defenders), its leader, its alignment side, its team type and its members.
WHAT TO DO WHEN YOU RECEIVE IT
1. Look the fight up under fight_id among the fights you know on the current map (from ShowChallengeEvent and MapComplementaryInformationEvent). If you do not know it, ignore the message: the client does nothing either. 2. In that fight, take the team the record names (its side). 3. ADD the record's members that the team does not have yet, keyed by member id. Nobody is removed here: a member leaving arrives in its own message, FightTeamRemoveMemberEvent. Do not replace the team. 4. Send nothing back.
WHO ELSE LISTENS. Besides the map's fight list, the fight preparation side reads the same message: one handler keeps the team's leader id, another walks its members.
WHEN IT ARRIVES. In one capture the character attacked a monster group (AttackMonsterRequest) and about 70 ms later two of these arrived back to back, both for the new fight (3089), before the fight context started:
- the character's team: led by the character, the character as its only member; - the monster team: led by -20002 - the id of the monster group that was attacked - with an empty member list.
It also arrives while you stand on a map where other players fight, whenever a team changes.
A MONSTER TEAM IS LED BY ITS GROUP ID, which is negative. It is not a fighter id: the monsters themselves get their own fighter ids (see FightFighterShowEvent).
When you may send it
Requires context_ready inferred Related messages
Arrives after AttackMonsterRequest Fields
#FieldTypeMeaningYou set it 1fight_idint32Which fight: the id that FightCommonInformation.fight_id announced. (fight id)
Observed: 3089never 2teamFightTeamInformationThe team record: its side of the fight, leader, alignment side, team type and members.
A FightTeamInformation: the same record as each entry of FightCommonInformation.teams_information. Its member list is what the client merges into the team.never
  • summary: One team of a fight gained members. Add the record's new members to that fight's team; nobody is removed.
  • area: Game.Fight.Preparation
  • 44 vues
A fighter's turn is over; carries that fighter's id and the extra time it banked for its next turn.
Kind event · Area Game.Fight
Closes one fighter's turn.
WHAT TO DO WHEN YOU RECEIVE IT
1. Mark FightTurnEndEvent.character_id's turn as over. Stop sending actions for that fighter: if it is yours, your turn is finished, whether you ended it or the server did. 2. Record FightTurnEndEvent.extra_time for that fighter. It is the time the fighter banked by ending its turn early, and the server adds it to that fighter's next turn. 3. Expect FightIsTurnReadyEvent next. That is the message you must answer (with FightTurnReadyRequest); this one needs no answer.
WHAT THE CLIENT DOES. The battle message handler stores the fighter id as the fighter whose turn just ended, publishes a "turn ended for this entity" notification with that id, refreshes the entity, and publishes a separate notification carrying the extra time. The end-turn widget listens to the latter in a handler Ankama named OnPlayerGivenExtraTime, which is where the meaning of the int32 comes from.
THE TURN LENGTH OF THE NEXT TURN IS NOT HERE. The next turn's duration arrives with the event that starts it; the extra time is already folded into it there.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server ends turns on its own (turn finished, timer elapsed, fighter died); no request asks for this message Fields
#FieldTypeMeaningYou set it 1extra_timeint32Time the fighter banked by ending its turn early; the server adds it to that fighter's next turn.
Named after the client's own handler for it, OnPlayerGivenExtraTime on the end-turn widget. Beta does not declare this member.
Unit not proven here: the turn-start event's durations are deciseconds (the client multiplies them by 100 to get milliseconds); this value is presumably in the same unit.never 2character_idint64The fighter whose turn just ended. (entity id)never
  • summary: A fighter's turn is over; carries that fighter's id and the extra time it banked for its next turn.
  • area: Game.Fight
  • 38 vues
A fighter's turn starts: whose turn it is and how much of it remains.
Kind event · Area Game.Fight
Opens one fighter's turn.
WHAT TO DO WHEN YOU RECEIVE IT
1. Record FightTurnEvent.character_id as the fighter whose turn it is. Every turn-scoped thing that follows (actions, the turn end) is about this fighter. 2. If it is your character, it is your turn: you may act until the server closes the turn with FightTurnEndEvent. Do not act on another fighter's turn. 3. Work out how long the turn lasts: FightTurnEvent.wait_time + FightTurnEvent.extra_time, in deciseconds (the client multiplies the sum by 100 to get milliseconds). wait_time is the fighter's base turn time; extra_time is the time it banked by ending its previous turn early (the FightTurnEndEvent.extra_time of that turn). 4. If FightTurnEvent.remaining_time is present, the turn is already under way (you joined or reconnected mid-turn): it is what is left of the turn, in deciseconds. When it is absent the turn starts now.
WHAT THE CLIENT DOES. The battle message handler logs "Start turn for entity", stores the fighter id as the current turn's fighter, refreshes the playable entity, cancels any pending turn timer and publishes a turn-start notification carrying the fighter id, the length in milliseconds and the remaining time in milliseconds. The fight UI's buffs panel and the fight-turn service listen to the same message.
FROM 3.7 the message also carries FightTurnEvent.order, the fighter's place in the round, and an optional FightTurnEvent.additional_id; the client files both in its turn value with the current round.
THE CURRENT ROUND NUMBER is also on the wire (captures: it equals the last FightNewRoundEvent's round), in one of two int32 members the client never reads. Nothing in the client tells it from the other one, so it stays unnamed here.
NOTHING IS SENT IN REPLY. The answer the server waits for comes later, at the end of the turn (FightIsTurnReadyEvent -> FightTurnReadyRequest).
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server starts each turn on its own once the previous one is closed; no request asks for it Fields
#FieldTypeMeaningYou set it 1remaining_timeint32What is left of a turn already under way, sent when you join or come back mid-turn.
Explicit presence: absent is not the same as zero. (deciseconds)
Absent when the turn starts now. The client multiplies it by 100 to get milliseconds.never 2wait_timeint32The fighter's base turn time, before any banked extra time. (deciseconds)
Observed: 300
Constant per kind of fighter in captures: 300 for a character, 290 for a monster, 150 for a summon, 10 for a dead fighter.
The client only ever adds it to FightTurnEvent.extra_time.never 3character_idint64The fighter whose turn starts. (entity id)never 4extra_timeint32Time this fighter banked by ending its previous turn early, added to this turn. (deciseconds)
Observed: 211
Equals the FightTurnEndEvent.extra_time of the fighter's previous turn in every capture; 150 at a first turn.
Same name as that field. The client adds it to FightTurnEvent.wait_time and also hands it on its own to the turn-start notification.never 5additional_idstringAn optional extra identifier of the turn (3.7 and later).
Explicit presence: absent is not the same as zero.
Named after the additionalId parameter of the client's FightTurn(round, order, additionalId) constructor, which receives it on 3.7. Its meaning beyond that is not proven here.never 6orderint32The fighter's position inside the current round (3.7 and later).
Named after the order parameter of the client's FightTurn(round, order, additionalId) constructor, which receives it on 3.7. Not read before 3.7.never
  • summary: A fighter's turn starts: whose turn it is and how much of it remains.
  • area: Game.Fight
  • 50 vues
Ends the turn of the fighter the client plays, before its timer runs out.
Kind request · Area Game.Fight
Ends your turn now instead of waiting for the timer.
HOW TO USE IT
1. Send it only during YOUR turn, after FightTurnEvent named your character and before the turn ended. It is not the placement-phase "ready" message and not the end-of-turn acknowledgement (FightTurnReadyRequest), which have the same one-bool shape. 2. Set FightTurnFinishRequest.is_afk to false when the player chose to end the turn. The official client fills it from its own turn-service state rather than from the button; it does not hard-code it. 3. Send it once. The client clears its own "turn finish pending" flag right after sending. 4. Then wait for FightTurnEndEvent for your character. Its extra time is what ending early banked for your next turn.
When you may send it
Requires character_loaded inferred Raised by: the player presses the end-turn ("ready / skip") button of the fight's end-turn widget during their own turn; the widget raises a signal that the fight-turn service turns into this request inferred Related messages
Nothing answers it - send it and move on no handler waits for a reply; the server closes the turn with the usual turn-end event, which also arrives when the timer elapses Fields
#FieldTypeMeaningYou set it 1is_afkboolWhether the turn is ended because the player is inactive rather than by choice.
The official client computes it from its fight-turn service state; it is never a constant. Send false when the player ends the turn.required
  • summary: Ends the turn of the fighter the client plays, before its timer runs out.
  • area: Game.Fight
  • 38 vues
Tells the server the client is ready for the next fight turn (is_ready = true).
Kind request · Area Game.Fight
Sent at the end of every fighter's turn, once the client has finished playing what that turn did. It tells the server the client can go on to the next turn.
IT ANSWERS FightIsTurnReadyEvent. Send it when that question arrives; if an action sequence is still being played back, send it as soon as the sequence ends. The server then starts the next turn with FightTurnEvent.
The official client always sends is_ready = true. Not sending it stalls the fight until the server's own timeout.
TWIN WARNING: FightReadyRequest (placement phase, "ready" button) has the same shape. This one is about turns, during the fight.
When you may send it
Requires character_loaded inferred Raised by: the client finishes processing the end of the current fighter's turn (animations and pending turn-end work) proven Related messages
Answers FightIsTurnReadyEvent Fields
#FieldTypeMeaningYou set it 1is_readyboolAlways true from the official client.required
  • summary: Tells the server the client is ready for the next fight turn (is_ready = true).
  • area: Game.Fight
  • 44 vues
Tells the client that the turn of the fighter it plays has really begun: it may act now.
Kind event · Area Game.Fight
An empty "go" signal for the fighter you control.
WHAT TO DO WHEN YOU RECEIVE IT
1. Treat it as the moment your turn is open for actions. FightTurnEvent says whose turn it is and how long it lasts; this message says the client playing that fighter may start acting. 2. SEND NOTHING BACK. The handler builds no request.
There is nothing to read: the message is empty, and the client reacts to its arrival only. Its battle message handler publishes an internal "start playing" notification; one listener turns it into the desktop notification the client shows when your turn starts while its window is not focused.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server sends it on its own when the played fighter's turn begins; no request asks for it
  • summary: Tells the client that the turn of the fighter it plays has really begun: it may act now.
  • area: Game.Fight
  • 41 vues
What kind of fight a fight is: challenge, aggression, PvM, arena, breach and others. Eleven values.
Kind enum · Area Game.Common
The kind of a fight, carried by FightCommonInformation.type.
The client does not branch on it where the fight record is converted - it keeps the value on its fight object as it arrives. Treat the names as Ankama's labels: every value is named from the reference build's numbering, and the dumps show no client code that gives any one value a behaviour of its own.
The enum has had exactly these eleven values on every dumped build.
Not sent on its own — an enum is never sent on its own; it is the FightCommonInformation.type member. inferred
Used by
FightCommonInformation FightJoinEvent FightStartingEvent Values
ValueNumberMeaning FIGHT_TYPE_CHALLENGE0A challenge between players. FIGHT_TYPE_AGGRESSION1A player attacking another player. FIGHT_TYPE_PvMA2Named PvMA in Ankama's reference build. FIGHT_TYPE_MXvM3Named MXvM in Ankama's reference build. FIGHT_TYPE_PvM4Players against a monster group. FIGHT_TYPE_PvT5Named PvT in Ankama's reference build (player versus tax collector, by the name). FIGHT_TYPE_PvMU6Named PvMU in Ankama's reference build (player versus mutant, by the name). FIGHT_TYPE_PVP_ARENA7An arena fight between players. FIGHT_TYPE_KOH8Named KOH in Ankama's reference build. FIGHT_TYPE_PvPr9Named PvPr in Ankama's reference build (player versus prism, by the name). FIGHT_TYPE_BREACH10A breach fight.
  • summary: What kind of fight a fight is: challenge, aggression, PvM, arena, breach and others. Eleven values.
  • area: Game.Common
  • 47 vues
Tells the server the client has finished playing a fight action sequence.
Kind request · Area Game.Game.Action
Sent by the client when it has finished playing back a fight action sequence the server announced. It carries that sequence's id - the action_id of the SequenceEndEvent that closed it - and valid = true.
SEND IT ONCE PER SEQUENCE, after playing it. The official client sends it only while a sequence is pending and forgets the sequence right after. It never sends valid = false.
When you may send it
Requires character_loaded inferred Raised by: the client finishes playing back a fight action sequence (spell, movement...) it was waiting on proven Related messages
Answers SequenceEndEvent Nothing answers it - send it and move on the client clears the pending sequence right after sending and waits for nothing Fields
#FieldTypeMeaningYou set it 2action_idint32Id of the fight action sequence being acknowledged. (sequence id (from the server's sequence announcement))required 3validboolAlways true from the official client: the sequence was played.required
  • summary: Tells the server the client has finished playing a fight action sequence.
  • area: Game.Game.Action
  • 46 vues
Casts one of the played fighter's spells on a fighter, named by its id, during its turn.
Kind request · Area Game.Game.Action
Casts a spell of the fighter you play on a FIGHTER, named by its id. Use GameActionFightCastRequest to cast on a map cell.
HOW TO SEND IT
1. Only during your own turn, in a fight. 2. spell_id = the spell's data-centre id (the spell template id, NOT a spell level id and NOT the action-bar slot), exactly as in GameActionFightCastRequest. 3. target_id = the fighter's id (players are positive, monsters and summons in a fight are negative). The official client sends it when the player clicks a fighter the fight preview accepts, and with the played fighter's own id for a cast on self from the action bar. 4. Nothing else is written. One request per cast.
WHAT COMES BACK
The same as for a cell cast: the server plays the cast as an action sequence (sequence start, fight action events, sequence end), and each finished sequence is acknowledged with GameActionAcknowledgementRequest.
DO NOT CONFUSE WITH THE ITEM REQUEST. GameActionItemConsumeRequest (same protocol file, no signature yet) also carries an int32 and an int64; it consumes an item action for a player and has nothing to do with spells.
When you may send it
Requires context_ready inferred Raised by: the player casts a spell on a fighter: a spell selected in the action bar, then a click on a fighter the fight preview accepts, or the action bar's cast-on-self shortcut (the target is then the played fighter) proven Related messages
Reply not yet recovered: The server answers with the fight action sequence of the cast (a sequence start, the action events, a sequence end) and the client acknowledges it with GameActionAcknowledgementRequest. A refused cast is reported by a no-cast event that has no signature yet. Fields
#FieldTypeMeaningYou set it 2target_idint64The fighter the spell is cast on. (fighter id)
Proven as the int64 the caller hands to the cast service; the client passes the clicked fighter's id, or the played fighter's own id for a cast on self.required 3spell_idint32The spell to cast: its data-centre spell id. (spell id)
Proven as the member the client fills from the spell record's id (a getter returning the Spell data id).required
  • summary: Casts one of the played fighter's spells on a fighter, named by its id, during its turn.
  • area: Game.Game.Action
  • 54 vues
Casts one of the played fighter's spells on a map cell during its turn.
Kind request · Area Game.Game.Action
Casts a spell of the fighter you play on a map CELL. Use GameActionFightCastOnTargetRequest instead to cast on a fighter by its id.
HOW TO SEND IT
1. Only during your own turn, in a fight. 2. spell_id = the spell's data-centre id (the spell template id, NOT a spell level id and NOT the action-bar slot). The official client reads it straight off the spell's data record. 3. cell = the target cell id, 0 to 559. The official client refuses anything outside the 560-cell map before building the request, and only sends a cell its fight preview considers castable (range, line of sight, free cell rules). 4. Nothing else is written. One request per cast.
WHAT COMES BACK
The server plays the cast as an action sequence: a sequence start, the fight action events (damage, effects, deaths ...), and a sequence end. Answer each finished sequence with GameActionAcknowledgementRequest; the official client does it after playing the sequence back.
A CELL, NOT A FIGHTER. Casting on the cell a fighter stands on works for spells that target cells, but the client itself uses the on-target request when the player clicks a fighter (or casts on itself).
When you may send it
Requires context_ready inferred Raised by: the player casts a spell on a map cell: a spell selected in the action bar, then a click on a cell the fight preview accepts (cell id inside the 560-cell map, spell castable there) proven Related messages
Reply not yet recovered: The server answers with the fight action sequence of the cast (a sequence start, the action events, a sequence end) and the client acknowledges it with GameActionAcknowledgementRequest. A refused cast is reported by a no-cast event that has no signature yet. Fields
#FieldTypeMeaningYou set it 1spell_idint32The spell to cast: its data-centre spell id. (spell id)
Proven as the member the client fills from the spell record's id (a getter returning the Spell data id).required 2cellint32The map cell the spell is cast on. (cell id)
Range: 0 to 559
Proven as the int32 the caller hands to the cast service (the other member is computed from the spell); the caller checks it against the 560-cell map first.required
  • summary: Casts one of the played fighter's spells on a map cell during its turn.
  • area: Game.Game.Action
  • 58 vues
Which kind of game context the character is in: roleplay or fight.
Kind enum · Area Game.Context
The kind of game context carried by ContextCreationEvent:
ROLE_PLAY the ordinary world - maps, NPCs, movement, interactive elements. The client's roleplay context is the one built on its roleplay entity service and its movement service. FIGHT a fight. The client's fight context switches on its fight services instead.
A context of one kind replaces a context of the other; the client never holds both. It maps these two values onto its own context kinds and treats any other value as "no context", so a value added by a later server would leave an unmodified client outside any context.
Nothing is sent in reaction to either value: the value decides which client services run, not what the client sends.
Not sent on its own — an enum is never sent on its own; it is the ContextCreationEvent.context member. inferred
Used by
ContextCreationEvent Values
ValueNumberMeaning ROLE_PLAY0The ordinary world: maps, NPCs, movement and interactive elements.
The value at world entry and after every fight.
The client enters the context built on its roleplay entity and movement services. FIGHT1A fight: the client switches its roleplay services off and its fight services on.
The context stays FIGHT until the server destroys it or names ROLE_PLAY again.
  • summary: Which kind of game context the character is in: roleplay or fight.
  • area: Game.Context
  • 39 vues
Leaves the tutorial (guided mode) for the current character. No payload.
Kind request · Area Game.Quest
CARRIES NOTHING. Sending it asks the server to end the tutorial for this character.
WHEN TO SEND IT
Only while the character is in the tutorial. The official client sends it when the player clicks the tutorial's exit button and then picks "Quit" in the confirmation popup ("Leave the tutorial?"). Picking "Resume" sends nothing - the first click alone never sends this.
The client can also send it by itself: when the character arrives on a map outside the tutorial area while the tutorial is still running, it ends the tutorial the same way.
WHAT COMES BACK
No reply has been captured yet. React to what follows (the map change and quest updates) rather than waiting for a dedicated answer.
When you may send it
Requires character_loaded observed Raised by: the player clicks the tutorial's exit button and confirms "Quit" in the "leave the tutorial?" popup proven Related messages
Reply not yet recovered: The server takes the character out of the tutorial. What it sends back - a map change, quest updates - has not been captured yet, so no reply is tied to it.
  • summary: Leaves the tutorial (guided mode) for the current character. No payload.
  • area: Game.Quest
  • 48 vues
A timed interaction is over: the element is free again and, if it was yours, you may use elements and walk again.
Kind event · Area Game.Interactive
A TIMED interaction is over: the use that InteractiveUsedEvent started with a duration above zero has finished. It closes the busy period of InteractiveUseRequest.
WHAT TO DO WHEN YOU RECEIVE IT
1. IF element_id IS THE ELEMENT YOU ARE USING, YOU ARE FREE AGAIN. Clear your busy state: you may send InteractiveUseRequest again, for any element, and walk again. The official client clears its busy flag, forgets which element its character was using, and lets its movement service accept walks again. 2. THE ELEMENT IS FREE. Remove element_id from your record of "who is using which element" (the official client keeps one, filled by element id from every timed InteractiveUsedEvent, and removes the entry here). 3. THE RESULT IS ELSEWHERE. This message only says the interaction ended. What it changed - the resource harvested, the element's new state - arrives as InteractiveElementUpdatedEvent / StatedElementUpdatedEvent and the inventory and job messages.
CHECK element_id BEFORE CLEARING YOUR BUSY STATE. Whether the server sends this only to the character that used the element, or to everyone on the map, is not established, and the client's code points both ways. It clears its own busy state on every one, without comparing the element with the one its character was using: that only makes sense if it receives nothing but its own. It also removes the element from the table that every timed InteractiveUsedEvent fills, other characters' uses included: that only makes sense if it receives theirs too. If element_id is not the element you are using, apply step 2 only.
skill_id echoes which action ended (the action's skill_id, not an offer's skill_instance_uid). The official client never reads it; where a build pads the message with another unread int32 it stays unnamed.
3.6.12.16 pads this message with an int64 the client never reads. Never rely on it.
FROM 3.7.1.0 THE TYPED HANDLERS READ NO FIELD: they clear the busy flag and let the movement service accept walks again, unconditionally, and the table of elements in use is gone, so step 2 has no counterpart in that client. Its interaction filter still compares element_id with the element the character started using, which is how this signature names both members on every build.
When you may send it
Requires roleplay_context inferred Related messages
Arrives after InteractiveUseRequest Fields
#FieldTypeMeaningYou set it 1element_idint32The element whose interaction ended. (interactive element id)
The same id as InteractiveUsedEvent.element_id that started the interaction.
The official client removes this element from its table of elements in use.
The client's interaction filter compares it with the element the character started using; that comparison names it on every build.never 2skill_idint32Which action ended, as a skill id. (skill id)
The action's skill_id (same id space as InteractiveElementSkill.skill_id), not a skill_instance_uid.
No official client code reads it; left unnamed where a build pads the message with another unread int32.never
  • summary: A timed interaction is over: the element is free again and, if it was yours, you may use elements and walk again.
  • area: Game.Interactive
  • 46 vues
The server refusing your InteractiveUseRequest: names the element it will not let you use. Nothing started.
Kind event · Area Game.Interactive
The server's NO to your InteractiveUseRequest: it will not perform that use. Exactly one of this message or InteractiveUsedEvent answers a use request.
WHAT TO DO WHEN YOU RECEIVE IT
1. MATCH IT BY element_id - the element you asked to use. That is the only member the official client reads. 2. THE REQUEST IS ANSWERED. Clear your "requested" mark for that element: you may ask again later. The official client does exactly this - it drops its record of the unanswered request when the refusal names that element. 3. NOTHING HAPPENED. No interaction started, nothing is timed, you are not busy. The official client prints the localized ui.popup.impossible_action line in chat and, in its movement service, releases the "use in flight" state so the character may walk again. Its queue of pending interactions, if any, drops the refused one and moves on to the next. 4. DO NOT RETRY BLINDLY. The message does not say why. Likely causes: you were out of range, the action is not currently offered, the element is in use, or it is not on your map. Re-check InteractiveUseRequest's procedure before asking again.
skill_instance_uid echoes which offer was refused. The official client never reads it, so it carries no client-side meaning; use element_id. Some builds pad this message with another int32 the client does not read either; where the two cannot be told apart, skill_instance_uid stays unnamed.
The current build declares nothing else.
When you may send it
Requires roleplay_context inferred Related messages
Arrives after InteractiveUseRequest Fields
#FieldTypeMeaningYou set it 2element_idint32The element whose use the server refused. (interactive element id)
The element_id you sent in InteractiveUseRequest. Match the refusal to your request with it.
The only member the official client reads: it compares it with the element it is waiting on and clears that wait when they are equal.never 3skill_instance_uidint32Which offer of that element was refused - the skill_instance_uid of the request. (skill instance uid)
No official client code reads it on any dumped build; rely on element_id.
Left unnamed on builds that pad the message with another unread int32, where the two cannot be told apart.never
  • summary: The server refusing your InteractiveUseRequest: names the element it will not let you use. Nothing started.
  • area: Game.Interactive
  • 49 vues
Asks the server to perform one action of one interactive element on the current map: harvest, open a door, take a zaap, use a workshop.
Kind request · Area Game.Interactive
Asks the server to perform ONE action of ONE interactive element on the map you are standing on: harvest a resource, open a door, take a zaap, open a crafting workshop, the smithmagic table, the auction house, the crafter list or the guild creator, enter or manage a house.
YOU ARE ASKING, NOT ACTING. Nothing has happened until the server answers: success arrives as InteractiveUsedEvent with you as its entity_id, a refusal as InteractiveUseErrorEvent. Exactly one of the two answers each request.
HOW TO USE AN ELEMENT - do exactly this, in this order. It is what the official client does, read from its code.
1. BE ON THE MAP. You are in the roleplay context and have received the map's interactive snapshot (InteractiveMapUpdateEvent, kept current by InteractiveElementUpdatedEvent). Only use elements whose InteractiveElement.on_current_map is true.
2. PICK AN ENABLED ACTION. Take it from the element's InteractiveElement.enabled_skills - never from disabled_skills, and never a directional sign (skill_id 360, 361 or 362: signs are read, not used). Keep both of its ids: skill_instance_uid is what you send, skill_id is what you look up in the game data.
3. EXIT POINTERS ARE WALKED ONTO, NOT USED. If the element's only enabled action is "Point Out an Exit" (skill_id 339), do not send this message: walk onto the element's own cell instead - that cell is the exit.
4. READ THE ALLOWED DISTANCE FROM THE GAME DATA. Look up every enabled action of the element in the skill table by its skill_id: - an action whose use_range_in_client is set allows its range; - an action without it allows 1. The allowed distance is the SMALLEST of those values over the element's enabled actions. Distance is |dx| + |dy| between your cell and the element's cell in map coordinates (the coordinates derived from the cell id), so 1 means one of the four cells that share an edge with the element's cell.
5. WALK UNTIL YOU ARE THAT CLOSE - if you already are, skip this step. Choose a free cell within the allowed distance (for a distance of 1, the free cell next to the element on your side of it) and walk there with the normal movement handshake: MapMovementRequest, follow the path the server grants (MapMovementEvent), MapMovementConfirmRequest when the walk is done, and WAIT FOR MapMovementConfirmResponse. Never send two walk requests less than 250 ms apart. If the server refuses the walk (MapMovementRefusedEvent), send no confirm, take the cell it names as your position and carry on: the official client still sends the use request, from wherever it stands.
6. ONLY NOW SEND THIS REQUEST, with element_id, skill_instance_uid, and specific_instance_id for a house action only (see HOUSE DOORS). Set nothing else.
7. WAIT FOR THE ANSWER before touching that element again: - InteractiveUsedEvent for that element: accepted. It does NOT echo your request: recognise it by its element_id (the element you used), its entity_id (your character) and its skill_id - the skill_id of the action you picked, not the skill_instance_uid you sent. If it names YOU and its duration is above zero, the use lasts duration x 100 ms (duration is in tenths of a second: 30 is three seconds) and you are BUSY: send no use request at all, for any element, until InteractiveUseEndedEvent for the element you are using arrives - or a new StatedMapUpdateEvent snapshot. When its can_move is false (absent on the wire), do not walk until the use is over either. - InteractiveUseErrorEvent for that element: refused. Nothing started and you are not busy. The official client prints the ui.popup.impossible_action line in chat and forgets the request; nothing else changes. Never send a second request for an element whose first request is still unanswered.
DO YOU HAVE TO BE NEXT TO THE DOOR? Yes - within the allowed distance of step 4, which is one cell unless the skill data says otherwise, and only after the server has confirmed the walk. Whether the server REJECTS a request sent from further away cannot be read from the client; following these steps is the safe contract.
THE TWO IDS ARE BOTH int32 AND MUST NOT BE SWAPPED
element_id InteractiveElement.element_id of the element. skill_instance_uid InteractiveElementSkill.skill_instance_uid of the chosen action in THAT element's InteractiveElement.enabled_skills. NOT InteractiveElementSkill.skill_id: skill_id says WHAT the action is and is shared by every element offering it; skill_instance_uid says WHICH offer on this element. HOUSE DOORS AND specific_instance_id
Leave specific_instance_id ABSENT for everything except a house action on a house door. A house door can lead to several house instances; the house actions are:
84 Enter any instance 97 Buy an instance for sale that is not yours 98 Sell an instance of yours that is not for sale 108 Change the price an instance of yours that is for sale 81 Add a code an instance of yours with no code lock 100 Change the code an instance of yours locked with a code "Yours" means the instance's owner account (name and tag) is the account you are logged in with. Send the id of the house instance you act on. That is what the official client sends when the action is picked from the door's menu: the chosen instance, or the door's only instance. It also sends 0 when no instance suits the action, and sends no instance at all when the door is used by a direct click (one usable action, at most one instance). Never send -1: it is the client's internal "no instance" and means "leave the field unset".
WHAT THE GAME DATA DECIDES (skill table, by skill_id)
range, use_range_in_client the allowed distance (step 4) level_min, parent_job_id the job and job level a job action needs; the client uses them to explain a disabled action. Whether an action is usable is decided by the server's enabled_skills, not by this check cursor, name_id, use_animation presentation only (cursor, menu label, the animation played when the use starts) LIVE CAPTURES (3.6.12.16)
requests element 489389 with skill instance 14033, and element 489333 with skill instance 14004; between them they showed an in-game message and opened a door. Neither carried specific_instance_id. acceptance an InteractiveUsedEvent for a character: element 537803, skill_id 68, duration 30 (three seconds), can_move absent (false). The request it answered is not part of that capture. The official client also ships developer console commands that send this message directly with fixed ids and no walk (a command literally named sendInteractiveUseRequest, and shortcuts that open the auction house, the craft and smithmagic windows, the crafter list and the guild creator). They are not part of a normal session and prove nothing about what the server accepts.
The current build pads this message with an optional int32 and a nested decoy message that no client code ever writes. Never set them.
When you may send it
Requires roleplay_context inferred Raised by: a user action: the player picks one enabled action of an interactive element (a click on an element with one usable action, an entry of the element's action menu, or the client's auto-travel). The client first walks into the action's range and, when it walked, waits for MapMovementConfirmResponse before sending. Never for directional signs (skills 360-362) and never for an element whose only enabled action is Point Out an Exit (skill 339), which is walked onto instead inferred Related messages
You will then receive InteractiveUseEndedEvent inferred — only after an acceptance whose duration is above zero (a timed use): it closes the use, and the client ends its busy state when it arrives. An untimed use gets none. Not captured yet You will then receive TeleportDestinationsEvent observed — when the element is a zaap, zaapi or prism: its destination list, right after the acceptance. Captured once on 3.7.4.4 (same millisecond as the acceptance) You will receive one of InteractiveUsedEvent inferred — the acceptance, with you as entity_id, the used element_id and the action's skill_id (not the skill_instance_uid you sent); the client clears its pending request for that element when it arrives. One acceptance was captured live (duration 30, can_move false), but not together with its request You will receive one of InteractiveUseErrorEvent inferred — the refusal, naming the element_id you sent; the client clears its pending request for that element and prints the localized ui.popup.impossible_action line in chat. Not captured yet If you get it wrong
a use the server will not perform (out of range, an action the element does not currently offer, another map's element) is answered by [[InteractiveUseErrorEvent]]; the client's only reaction is the chat line and dropping its pending request inferred Fields
#FieldTypeMeaningYou set it 1skill_instance_uidint32Which of that element's offered actions to perform. (skill instance uid)
Observed: 14033, 14004 (live capture, 3.6.12.16)
Copy InteractiveElementSkill.skill_instance_uid of one action in that element's InteractiveElement.enabled_skills - NOT InteractiveElementSkill.skill_id. Both are int32: skill_id says WHAT the action is, skill_instance_uid says WHICH offer on this element.
Never an action from disabled_skills, never a directional sign (skill_id 360-362), and never the lone Point Out an Exit action (skill_id 339), which is walked onto instead.required 2specific_instance_idint32The house instance a house-door action applies to.
Explicit presence: absent is not the same as zero. (house instance id)
Leave it absent unless you are acting on a house. Absent means no particular instance.
Send the house instance you act on: Enter (84) any; Buy (97) one for sale that is not yours; Sell (98) one of yours not for sale; Change the price (108) one of yours for sale; Add a code (81) one of yours without a code; Change the code (100) one of yours with a code.
The official client sends the instance picked in the door's menu or the door's only instance, sends 0 when no instance suits the action, and sends none on a direct click. Never send -1: it is the client's internal 'no instance' and leaves the field unset.only for a house action on a house door (Enter, Buy, Sell, Change the price, Add a code, Change the code); absent for every other use 3element_idint32The interactive element to use, by its id on the current map. (interactive element id)
Observed: 489389, 489333 (live capture, 3.6.12.16)
Copy InteractiveElement.element_id of an element in the current map's snapshot (InteractiveMapUpdateEvent, kept current by InteractiveElementUpdatedEvent) whose InteractiveElement.on_current_map is true.
Send it unchanged, and only once you stand within the action's allowed distance of this element's cell.required
  • summary: Asks the server to perform one action of one interactive element on the current map: harvest, open a door, take a zaap, use a workshop.
  • area: Game.Interactive
  • 51 vues
Toggles the character's listing in the crafter directory (job book) for each job id it carries.
Kind request · Area Game.Exchange
Lists the character in, or removes it from, the crafter directory (the "job book" other players search to find a crafter) for the given jobs.
IT IS A TOGGLE, NOT A SET. The message carries only job ids; it does not say "on" or "off". The client sends exactly the jobs whose state must FLIP:
- the switch of one job sends that one job id; - the switch that applies to every job sends only the jobs that are not yet in the wanted state (switching everything on skips the jobs already listed).
So before sending, know the current state of each job (the server reports it in its job-book subscription event). Sending an id twice flips it twice.
THE CLIENT ALSO SENDS IT BY ITSELF (every 3.x build since 3.3). The game remembers, per server, which jobs the player keeps listed. When the account options become available on a server, the job service sends this request once with those remembered job ids, so the listing survives a reconnection. Jobs ticked "for this session only" are dropped from that memory the first time the player joins the server again, so they are not re-sent.
WHAT COMES BACK
A job-book subscription event with the new state of the jobs. It is not recovered yet.
When you may send it
Requires character_loaded inferred Raised by: the player flips the "public craft" switch of a job in the job window (tooltip "add to / remove from the crafter list"), or the switch that applies to every job proven Related messages
Reply not yet recovered: The server answers with a job-book subscription event (one entry per job: job id + subscribed flag) that updates the switches. It has no signature yet. Fields
#FieldTypeMeaningYou set it 1jobs_idrepeated int32Ids of the jobs whose crafter-directory listing flips. (job id)
Each id flips that job's listing; the client only sends jobs whose state must change. An empty list does nothing.required
  • summary: Toggles the character's listing in the crafter directory (job book) for each job id it carries.
  • area: Game.Exchange
  • 47 vues
One job of the character and the skills it grants.
Kind struct · Area Game.Job
One job (JobDescription.job_id) and every skill it grants (JobDescription.skills, a list of SkillAction) - what the character can gather or craft with that job.
Carried as a list by JobDescriptionEvent, and singly by another job event that has no signature yet. Builds pad the record with a second, never-walked list of skills or an unread repeated int32; the real list is the one the client walks.
Not sent on its own — it is a record inside job messages, never sent on its own. inferred
Used by
JobDescriptionEvent Fields
#FieldTypeMeaningYou set it 1job_idint32Which job this is; the key the client files the job under. (job id)never 2skillsrepeated SkillActionEvery skill the job grants.
A list of SkillAction.never
  • summary: One job of the character and the skills it grants.
  • area: Game.Job
  • 42 vues

Compte

Navigation

Recherche

Recherche

Configurer les notifications push du navigateur

Chrome (Android)
  1. Appuyez sur l'icône de cadenas à côté de la barre d'adresse.
  2. Tap Autorisations → Notifications.
  3. Ajustez vos préférences.
Chrome (Desktop)
  1. Cliquez sur l'icône représentant un cadenas dans la barre d'adresse..
  2. Select Paramètres du site.
  3. Find Notifications et ajustez vos préférences.