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
Every job of the character with the skills it grants. Replace your job table with it; nothing is sent back.
Kind event · Area Game.Job
The character's jobs and, for each, the skills it grants: one JobDescription per job.
WHAT TO DO WHEN YOU RECEIVE IT
1. REPLACE your job table with this one. The client builds a brand-new table keyed by JobDescription.job_id and swaps it in; jobs absent from the message are gone. 2. For each job, keep its skills (SkillAction): a gathering skill tells you how long one use takes and how many resources it yields (Timed, Collect); a crafting skill tells you its success chance (Craft). 3. SEND NONE BACK. The handler builds no request.
Experience and level per job arrive separately (JobExperiencesUpdateEvent); this message says what each job lets the character do.
Builds pad the message with a second, never-walked list of the same record and unread scalars; the real list is the one the client walks.
When you may send it
Requires character_selected inferred Related messages
Unsolicited - nothing you send causes this no job request asks for it; the server pushes the character's job set Fields
#FieldTypeMeaningYou set it 1jobsrepeated JobDescriptionOne entry per job of the character.
A list of JobDescription; the whole set.never
  • summary: Every job of the character with the skills it grants. Replace your job table with it; nothing is sent back.
  • area: Game.Job
  • 44 vues
One job's progress: its level, its experience, and the experience bounds of the level it is on.
Kind struct · Area Game.Job
The progress record for one job. It is never sent on its own: JobExperiencesUpdateEvent carries a list of them for your own character, and the other-player job update carries exactly one for the crafter you are working with.
HOW TO READ THE THREE EXPERIENCE VALUES. They are absolute totals, not amounts within the level. The client draws its job gauge straight from them:
gauge.low = job_xp_level_floor experience at which the current level began gauge.high = job_xp_next_level_floor experience at which the next level is reached gauge.value = job_xp total experience in the job so progress through the level is (job_xp - job_xp_level_floor) out of (job_xp_next_level_floor - job_xp_level_floor).
LEVEL 200 IS SPECIAL-CASED. When JobExperience.job_level is exactly 200 the client ignores all three experience values and draws a full gauge (low 0, high 1, value 1). Do not divide by the floor span without checking for it.
THE FIVE MEMBERS ARE EASY TO SWAP. Two are int32 and three are int64, and their wire numbers are reshuffled on every build. Read them by name from the recovered schema, never by position.
HOW TO USE IT. File it under JobExperience.job_id and overwrite the four other values together; they always travel as one consistent set.
Not sent on its own — it is only ever carried by JobExperiencesUpdateEvent and by the other-player job update. inferred
Used by
JobExperiencesUpdateEvent Fields
#FieldTypeMeaningYou set it 1job_levelint32The character's current level in the job. (level)
At exactly 200 the client draws a full gauge and ignores the experience values.never 2job_xpint64Total experience earned in the job. (experience points)
An absolute total. It is the VALUE of the client's job gauge.never 3job_xp_level_floorint64Total experience at which the current level began. (experience points)
The LOW bound of the client's job gauge.never 5job_idint32Which job this record is about. (job id)
The key the client files the record under; an unknown id creates a new job entry.never 6job_xp_next_level_floorint64Total experience at which the next level is reached. (experience points)
The HIGH bound of the client's job gauge.never
  • summary: One job's progress: its level, its experience, and the experience bounds of the level it is on.
  • area: Game.Job
  • 39 vues
New level and experience figures for one or more of the character's own jobs. Update only the listed jobs; nothing is sent back.
Kind event · Area Game.Job
WHAT TO DO WHEN YOU RECEIVE IT: for each entry, create or overwrite that one job; leave every other job alone. SEND NOTHING BACK - no handler of this message builds a request, and a static walk through everything it notifies reaches none.
WHEN IT ARRIVES. It follows whatever earned the experience - harvesting, crafting - and no request asks for it.
The server's update of the character's own job progress. It carries one JobExperience per job concerned.
IT IS AN UPSERT PER JOB, NOT A SNAPSHOT. For each entry the client looks the job up by JobExperience.job_id, creates the record if it has never seen that job, and overwrites its level, experience and both floors. Jobs that are not listed are left exactly as they were. A message listing one job says nothing about the others - do not clear your state.
ONE NOTIFICATION PER ENTRY. After updating each job the client raises a job-experience notification carrying that job's id, and the crafting and smithmagic windows refresh their gauge when the id is the job they are showing.
THIS IS ONLY YOUR OWN CHARACTER. The progress of another player - the crafter on the other side of a cooperative craft - arrives in a different message that carries a single JobExperience and that player's id.
SEVERAL BUILDS PAD THIS MESSAGE. Beside the real list the schema may declare a second list of the same type, an optional int64, a bool or a string. The client reads none of them; only JobExperiencesUpdateEvent.experiences carries data.
When you may send it
Requires character_selected inferred Related messages
Reply not yet recovered: no request asks for job experience - the job area declares none. It arrives as a consequence of whatever earned the experience, and which messages it follows is not established by any signature here. Fields
#FieldTypeMeaningYou set it 1experiencesrepeated JobExperienceThe jobs whose progress changed, one record each.
A list of JobExperience. Each entry overwrites that one job; jobs not listed are untouched.
Some builds declare a second list of the same type beside it; the client never reads that one and it stays unnamed.never
  • summary: New level and experience figures for one or more of the character's own jobs. Update only the listed jobs; nothing is sent back.
  • area: Game.Job
  • 41 vues
The character's current Kolizeum league, rating and ladder position in one arena mode.
Kind struct · Area Game.Arena
Where the character stands now in one Kolizeum mode: its rating (LeagueRanking.rating), its league (LeagueRanking.league_id, which the client looks up in its arena-league data for the league's name, icon and whether it is the last league) and its ladder position (LeagueRanking.ladder_position).
Carried by ArenaRank.league_ranking. The three members share one wire type and move between field numbers; they are named from where the client copies each one. One build pads the record with a fourth, unread int32.
Not sent on its own — it is a record inside ArenaRank, never sent on its own. inferred
Used by
ArenaRank Fields
#FieldTypeMeaningYou set it 1league_idint32Current league; the client looks it up in its arena-league data.never 2ladder_positionint32Position on the Kolizeum ladder in this mode.never 3ratingint32Current Kolizeum rating in this mode.never
  • summary: The character's current Kolizeum league, rating and ladder position in one arena mode.
  • area: Game.Arena
  • 36 vues
Asks the server to move the character to the neighbouring map after it walked onto an exit cell on that side of the current map.
Kind request · Area Game.Gamemap
Asks the server to move your character to the NEIGHBOURING map, the one beyond the edge of the current map you have walked to. This is how a character leaves a map by its north, east, south or west side.
YOU ARE ASKING, NOT MOVING. The map changes only when the server answers with MapCurrentEvent - or its instanced form MapCurrentInstanceEvent - naming the new map. Until then you are still on the old one.
HOW TO CHANGE MAP - do exactly this, in this order. It is what the official client does, read from its code.
1. BE ON A LOADED MAP IN ROLEPLAY. You are in the roleplay context and the current map has arrived (MapCurrentEvent) and been loaded.
2. PICK THE SIDE AND READ THE TARGET MAP FROM THE MAP DATA. The current map's data gives its four neighbours: topNeighbourId (north), bottomNeighbourId (south), leftNeighbourId (west) and rightNeighbourId (east). The neighbour of the side you leave by is the map_id you will send. Never compute it, never take it from anywhere else.
3. PICK AN EXIT CELL ON THAT SIDE. Only cells on that edge that the map data marks as an exit towards that side can be left by - the cell's mapChangeData bit field holds one bit per direction. The official client takes the exit cell of that side nearest to where the player clicked.
4. WALK ONTO THAT EXACT CELL with the normal movement handshake: MapMovementRequest, follow the path the server grants (MapMovementEvent), MapMovementConfirmRequest when the walk is done. If you already stand on the exit cell, skip the walk.
5. CHECK WHERE THE WALK ENDED. The change goes on ONLY if you are standing on the exit cell you walked to. If the server granted a shorter path, or refused the walk (MapMovementRefusedEvent - then there is no walk to confirm either), the official client does NOT send this request - walk again or give up.
6. WAIT FOR MapMovementConfirmResponse. The client waits until no walk is in progress and the server has confirmed the last one before it sends this request.
7. ONLY NOW SEND THIS REQUEST with map_id = the neighbour of step 2 and auto_pilot = false (leave it absent) - unless you are the client's auto-travel, see AUTO-PILOT. Set nothing else. Send it ONCE: the client forgets the pending change the moment it is sent.
8. WAIT FOR MapCurrentEvent OR MapCurrentInstanceEvent with the new map id - accept either, the client handles both the same way - then do what that message says: forget the old map, load the new one, and send ContextReadyRequest and MapInformationRequest.
WHAT CANCELS A PENDING MAP CHANGE BEFORE IT IS SENT
The client remembers ONE pending change (a target map and its flag) between step 2 and step 7 and drops it, sending nothing, when: - you click a cell to walk somewhere else (an ordinary walk never changes map); - you click an interactive element (unless the client's auto-travel did it); - a new map change replaces it (only the latest target is kept). Choosing a map change also drops any element use that was waiting for a walk to finish (see InteractiveUseRequest): the two never queue together.
AUTO-PILOT
auto_pilot is true only when the client's auto-travel feature drives the map change; every map change a player clicks sends false, which is absent on the wire. Leave it false. What the server does differently for true is not visible in the client.
WHAT COMES BACK
- MapCurrentEvent with the new map id: the change happened. Everything that belonged to the old map is gone. - MapCurrentInstanceEvent instead, when the server announces the new map in its instanced form: the same change, handled the same way, with its map_id. - A refusal: the map area declares no failure message for this request, so what a refused change returns is not established. Do not wait forever for either message; if neither comes, you are still on the old map.
THE MAP ID IS AN int32 HERE. MapCurrentEvent and MapMovementRequest carry map ids as int64; this request carries the neighbour id as int32, which is the type the map data stores neighbour ids in. The client keeps the target as a 64-bit pending value and sends its low 32 bits. Use the same number.
LIVE CAPTURE (3.6.12.16): map_id 154010883 and auto_pilot absent (false), sent when the player clicked towards a side of the map to cross into the neighbouring map.
The current build declares nothing else in this message; other builds pad it with a same-typed int32 or an optional string that no client code ever writes. Never set them.
When you may send it
Requires roleplay_context inferred Raised by: a user action or the client's auto-travel: the player clicks towards a side of the map (or auto-travel picks the next map). The client walks onto an exit cell of that side, waits for MapMovementConfirmResponse, and sends this only if the walk ended on that cell inferred Related messages
You will receive one of MapCurrentEvent inferred — the map change itself: the server places the character on the new map, and the client's whole map-loading chain starts from that event. No capture of the pair recorded yet You will receive one of MapCurrentInstanceEvent inferred — the same map change announced in its instanced form; the client feeds its map id into the same map-loading routine. Whether a walked map change can lead to an instanced map is server data; not observed If you get it wrong
no failure message exists in the map area; a change the server refuses is presumably answered by nothing, leaving the character on the old map. Not observed inferred Fields
#FieldTypeMeaningYou set it 1auto_pilotboolWhether the client's auto-travel is driving this map change.
Observed: absent, i.e. false, for a clicked map change (live capture, 3.6.12.16)
Leave it false. What the server does differently for true cannot be read from the client.true only when the client's auto-travel sends it; false (absent on the wire) for every map change a player clicks 2map_idint32The neighbouring map to move to. (map id)
Observed: 154010883 (live capture, 3.6.12.16)
Read it from the current map's data: the neighbour id of the side you leave by - topNeighbourId (north), bottomNeighbourId (south), leftNeighbourId (west) or rightNeighbourId (east).
Send it only while standing on an exit cell of that side, after the walk there was confirmed.
int32 here although other map ids travel as int64: neighbour ids are int32 in the map data. The client holds the target as a 64-bit pending value and sends its low 32 bits.required
  • summary: Asks the server to move the character to the neighbouring map after it walked onto an exit cell on that side of the current map.
  • area: Game.Gamemap
  • 57 vues
The map the character is on now. Every map change starts here, and it is what makes the client load the map and ask for its contents.
Kind event · Area Game.Gamemap
The server moving the character to a map. MapCurrentEvent.map_id is the map the character is on from now on.
WHAT TO DO WHEN YOU RECEIVE IT
1. Forget the previous map: its actors, interactive elements and movement state. The client drops them too - its entity view, per-map caches and subarea state reset on this message, and once the new map has loaded it sets the map's fight count (MapFightCountEvent) back to 0. 2. Load the map. A script that draws nothing can treat this as immediate. 3. THEN SEND ContextReadyRequest AND MapInformationRequest, both carrying this map id. The official client does this after EVERY MapCurrentEvent whose map it loads - at world entry and on every later map change alike - and never skips it. Whether the server refuses to go on without them is server behaviour, which a client dump cannot show; the ContextReadyRequest record reports that the map's contents only come after it. 4. Fill the map from MapComplementaryInformationEvent when it arrives.
HOW THE REAL CLIENT GETS FROM THIS MESSAGE TO THOSE TWO REQUESTS. Traced in the 3.6.12.16 client:
MapCurrentEvent -> map service: store the id as the current map, announce it internally, start its current-map routine -> wait one frame and until the map display is ready -> map renderer: look the map up, play the map transition, then load the map -> map loaded: the renderer announces the loaded map with its id -> the map service sends ContextReadyRequest -> the roleplay-entities message handler sends MapInformationRequest So the two requests follow this message after the map transition and the load, not in the same instant. Nothing in the chain waits for anything else from the server, and neither handler of the loaded-map notification tests any condition before sending.
TWO CASES WHERE ONE MESSAGE DOES NOT MEAN ONE PAIR OF REQUESTS:
- Back-to-back messages collapse. The map service keeps only the latest map id and runs one current-map routine at a time; a message that arrives while that routine is still waiting just replaces the id. The client then loads - and sends the two requests for - the last map only. - A map the client cannot load produces nothing. When the map asset is missing the renderer never raises the loaded-map notification, so neither request is sent.
THE CLIENT DERIVES SUBAREA CHANGES FROM IT. It looks the new map up in its data centre to find its subarea and compares it with the previous map's. A script that needs subarea transitions can do the same from the map id alone.
INSTANCED MAPS USE A SIBLING: MapCurrentInstanceEvent, carrying the map id and an instance id. The client routes its map id into the very same map-change routine - and so into the same two requests. A script that follows only this message misses the map changes the server announces that way: handle both in one place.
ONE DECLARED MEMBER IS REAL. Builds pad this message with a decoy int64, a string, a bool or a nested decoy message; the client reads only MapCurrentEvent.map_id.
When you may send it
Requires character_loaded inferred Related messages
You must then send ContextReadyRequest inferred — the official client sends it after every map load a MapCurrentEvent starts - not only the first one - with this map id, once the map has loaded; decompiled on 3.6.12.16, no anchor follows the chain You must then send MapInformationRequest inferred — sent from the same map-loaded notification as ContextReadyRequest, with the same map id; it is the request that brings the actors and elements of the new map Arrives after ContextCreationRequest Arrives after MapChangeRequest Reply not yet recovered: besides world entry and a walked map change (MapChangeRequest), the server sends it after a teleport or a zaap; the requests that cause those have no signature here. Fields
#FieldTypeMeaningYou set it 1map_idint64The map the character is now on.
The same map id MapInformationRequest asks with as an int32 and MapComplementaryInformationEvent answers with as an int64. The client narrows it to 32 bits when it stores it; a width difference is not a different map.
The client looks it up in its data centre's subarea table to derive the subarea.never
  • summary: The map the character is on now. Every map change starts here, and it is what makes the client load the map and ask for its contents.
  • area: Game.Gamemap
  • 60 vues
The map the character is on now, announced in its instanced form. Handle it exactly like MapCurrentEvent: load map_id, then ask for its contents.
Kind event · Area Game.Gamemap
The server moving the character to a map, in the form it uses for an INSTANCED map. It is the twin of MapCurrentEvent: same area, same purpose, and the official client feeds its map_id into the very same map-change routine. A script that handles only MapCurrentEvent misses every map change the server announces this way and waits forever for a map that has in fact changed.
WHAT TO DO WHEN YOU RECEIVE IT
1. YOU ARE ON map_id NOW. It plays exactly the role of MapCurrentEvent.map_id: the map to load, and the map your position, cells and interactive elements belong to from now on. 2. FORGET THE PREVIOUS MAP: its actors, interactive elements and movement state. You are on another map. 3. DO WHAT MapCurrentEvent SAYS, WITH THIS map_id: load the map, THEN send ContextReadyRequest and MapInformationRequest carrying it, and fill the map from MapComplementaryInformationEvent when it arrives. The official client does exactly this: it stores map_id as its current map (narrowed to 32 bits), announces the change internally, loads the map, and sends the two requests once the map has loaded - the same chain, in the same order, as for MapCurrentEvent. 4. instantiate_map_id NEEDS NOTHING FROM YOU. No request carries it and the current client never reads it. Keep it only if you want to tell two instances of one map apart.
HANDLE BOTH MESSAGES IN ONE PLACE. Wherever a map change can happen - at world entry after ContextCreationRequest, after MapChangeRequest, after a teleport - accept EITHER MapCurrentEvent or this message as "the map changed", and run the same steps. Which of the two the server sends is its own decision, presumably whether the destination is an instanced copy of a map; the client never has to know in advance, because it treats both the same.
WHAT THE OFFICIAL CLIENT DOES NOT DO HERE. For MapCurrentEvent several other client services react too: the entity view clears itself, the subarea service compares the new map's subarea with the old one, per-map caches reset. In the current client only the map service listens to this message, so none of that happens on it. Step 2 is still right for a script: whatever the official client keeps, the old map's actors are not on the new map. If you track subareas, look the subarea of map_id up yourself here too, as MapCurrentEvent describes.
THE TWO IDS ARE BOTH int64 AND MUST NOT BE SWAPPED
map_id the map to load - the same id space as MapCurrentEvent.map_id, MapInformationRequest and MapComplementaryInformationEvent. It is the one the official client loads. instantiate_map_id which instance of that map; never sent back, never read by the current client. Field numbers are no guide: the builds renumber these two fields, and on the current build map_id is field 2. Use the names, never the numbers.
Some builds pad this message with a decoy int32, an enum or a third int64; the client reads none of them.
When you may send it
Requires character_loaded inferred Related messages
You must then send ContextReadyRequest inferred — the official client feeds map_id into the same map-change routine as MapCurrentEvent's, so the same load follows and the same request is sent once the map has loaded, with this map id; decompiled on 3.6.12.16, no anchor follows the chain You must then send MapInformationRequest inferred — sent from the same map-loaded notification as ContextReadyRequest, with the same map id; it brings the new map's actors and elements Arrives after ContextCreationRequest Arrives after MapChangeRequest Fields
#FieldTypeMeaningYou set it 1instantiate_map_idint64Which instance of that map the character is in. (instance id)
No current client code reads it, and no request carries it back. Older builds (3.2-3.4) read it in a second handler; on 3.2.7.15, where that was traced, it was stored in the map display service and never read back.
Left unnamed on builds that pad the message with another unread int64, where the two cannot be told apart.never 3map_idint64The map the character is now on - the map to load. (map id)
Same id space as MapCurrentEvent.map_id; send it in ContextReadyRequest and MapInformationRequest once the map has loaded.
The official client hands it to the same routine as MapCurrentEvent's map id, which stores it narrowed to 32 bits.never
  • summary: The map the character is on now, announced in its instanced form. Handle it exactly like MapCurrentEvent: load map_id, then ask for its contents.
  • area: Game.Gamemap
  • 52 vues
How many fights are running on the character's map. The client keeps it to enable the spectate button; nothing is sent back unless the spectator window is open.
Kind event · Area Game.Gamemap
The number of fights running right now on the map the character is on. It is an absolute count, not a change: overwrite what you hold.
WHAT TO DO WHEN YOU RECEIVE IT
1. Store the count as the current map's fight count, replacing the previous value. 2. SEND NOTHING BACK. The handler builds no request. The one exception is the spectator window, below: a client that does not show that window never answers this message.
WHAT THE CLIENT DOES. The map-fights service - the one that handles ShowChallengeEvent - turns the value into a client notification that keeps it as a 16-bit number. Two windows listen to it:
- the map information panel stores the count and enables its SPECTATE button only while the count is above zero; - the spectator window, only while it is open, compares the count with the number of fights it lists. When they differ it asks for the list again with MapRunningFightsRequest, an empty request with no signature here yet. When they match, nothing is sent.
THE CLIENT ZEROES THE COUNT TWICE PER MAP. The same notification is raised with 0 when a new map finishes loading after a MapCurrentEvent or MapCurrentInstanceEvent, and again at the end of the handling of the map's contents, MapComplementaryInformationEvent. The fights listed in the map's contents do not set it: this message is the only thing that sets a count above zero. So a count only stands once the map's contents have been handled; one that arrives before them is wiped. That the server therefore sends it after the map's contents whenever the map has fights is inferred from the client, not observed.
It counts; ShowChallengeEvent describes. Track the fights themselves from that message and the map's contents, and use this one for the number the server announces. The two should agree, but nothing in the client reconciles them.
When you may send it
Requires context_ready inferred Related messages
Reply not yet recovered: it follows fights starting and ending on the map - including one your own character starts or leaves - and none of the requests that start or leave a fight has a signature here. Fields
#FieldTypeMeaningYou set it 2fight_countint32How many fights are running on the map now; replaces the previous count.
The client keeps it as a 16-bit number and enables the spectate button while it is above zero.never
  • summary: How many fights are running on the character's map. The client keeps it to enable the spectate button; nothing is sent back unless the spectator window is open.
  • area: Game.Gamemap
  • 43 vues
The server refusing your walk request and telling you the cell you stand on, as map coordinates.
Kind event · Area Game.Gamemap
The server's NO to your MapMovementRequest: you do not walk the path you asked for. Instead the server tells you the cell you stand on, as map coordinates. Exactly one of this message or MapMovementEvent answers a walk request.
WHAT TO DO WHEN YOU RECEIVE IT
1. YOU ARE ON (cell_x, cell_y). Put the character there and stop any walk you were animating or simulating - the official client stops its character's movement and idles it on that cell. Convert the coordinates to a cell id with the client's own formula:
cell_id = floor(14 * cell_x - 13 * cell_y + (cell_x - cell_y) / 2) The pair is outside the map grid when cell_y < -cell_x, cell_y > cell_x, cell_y > 27 - cell_x or cell_y < cell_x - 39. These are the same map coordinates as the |dx| + |dy| distance used by InteractiveUseRequest. 2. DO NOT CONFIRM. There was no walk, so send no MapMovementConfirmRequest for it: the official client sends that only when a walk it was granted ends. 3. YOUR WALK STATE IS RESET. Nothing is in progress any more; you may ask to walk again (the 250 ms spacing of MapMovementRequest still applies). 4. WHAT WAS WAITING ON THE WALK: - a pending MapChangeRequest is NOT sent - you never reached the exit cell; - a pending InteractiveUseRequest IS still sent by the official client, from wherever it now stands; expect it to be refused if that is out of range.
The fight client also handles this message: it resets its own fight movement state, reading neither coordinate.
The members are the cell's map coordinates, not a cell id, and come x first: the official client passes them, in that order, to the routine that builds a map point from (x, y).
When you may send it
Requires context_ready inferred Related messages
Arrives after MapMovementRequest Fields
#FieldTypeMeaningYou set it 2cell_xint32X map coordinate of the cell the character stands on after the refusal. (map cell coordinate)
cell_id = floor(14 * cell_x - 13 * cell_y + (cell_x - cell_y) / 2).
The official client passes it first, then cell_y, to the routine that builds a map point.never 3cell_yint32Y map coordinate of the cell the character stands on after the refusal. (map cell coordinate)
Off the grid when cell_y < -cell_x, cell_y > cell_x, cell_y > 27 - cell_x or cell_y < cell_x - 39.never
  • summary: The server refusing your walk request and telling you the cell you stand on, as map coordinates.
  • area: Game.Gamemap
  • 47 vues
One map, and the NPCs on it that have quests for the character.
Kind struct · Area Game.Npc
One entry of NpcsMapQuestStatusUpdateEvent: a map and its NPCs that have quests. It is declared inside that message and travels nowhere else.
The client uses the entry twice. If MapNpcQuest.map_id is the current map it marks the NPCs of MapNpcQuest.npcs_with_quests over their heads; whatever the map, it places a world-map marker at the map's coordinates when one of those NPCs has a quest to start.
HOW TO USE IT. Compare MapNpcQuest.map_id with the map you are on: the entry for your map tells you which NPCs in front of you have quests; the others tell you which maps are worth travelling to.
Not sent on its own — it is only ever an element of NpcsMapQuestStatusUpdateEvent.map_information. inferred
Used by
NpcsMapQuestStatusUpdateEvent Fields
#FieldTypeMeaningYou set it 1npcs_with_questsrepeated NpcWithQuestThe NPCs on that map that have quests for the character.
A list of NpcWithQuest.never 2map_idint64The map these NPCs are on. (map id)
The same map id as MapCurrentEvent.map_id: the client compares the two to decide whether this entry's NPCs are on screen, and looks the id up in its map table for the world-map marker's coordinates.never
  • summary: One map, and the NPCs on it that have quests for the character.
  • area: Game.Npc
  • 35 vues
The server opening a dialog with an NPC, in answer to a dialog NPC action. The NPC's first line follows in NpcDialogQuestionEvent.
Kind event · Area Game.Npc
The server opening a dialog between your character and an NPC. It is the success answer to an NpcGenericActionRequest whose action is a dialog - talking to an NPC, or using a portal NPC. From now on the server considers you IN A DIALOG with that NPC, until the dialog closes (DialogLeaveEvent).
WHAT TO DO WHEN YOU RECEIVE IT
1. MATCH IT TO YOUR REQUEST. npc_id and map_id are the very ids you sent as npc_id and npc_map_id in NpcGenericActionRequest. 2. YOU ARE IN THE DIALOG NOW. Do not walk away or start another action as if you were free: the dialog stays open until it closes. 3. WAIT FOR NpcDialogQuestionEvent. It follows straight away and carries what the NPC says and the replies you may choose. This message carries no text of its own. 4. ANSWER OR LEAVE. Answer with NpcDialogReplyRequest (one reply_id of the latest question), or close the dialog with DialogLeaveRequest.
WHAT THE OFFICIAL CLIENT DOES WITH IT
- It waits until the NPC whose actor id is npc_id exists on the current map (it looks the actor up by that id, as a 64-bit entity id, and waits while the lookup finds nothing). A dialog event that arrives before the map's actors are known is therefore held, not dropped. - It then builds the dialog window for that NPC - its look, its name - and hands it to the dialog service, which will show the questions. - For a DIMENSION PORTAL (portal_type set) it builds the portal dialog instead, from map_id and portal_type. The dialog service checks that map_id is the map you are on and gives up otherwise ("Required portal cannot be found on map {0}."), then opens the dialog of that dimension's portal. A portal_type it does not know is an error for the client. - It has a path where it does not open the dialog and instead sends DialogLeaveRequest itself, closing the dialog on the server side.
A script that shows nothing can skip the window: keep npc_id, wait for the question, answer or leave.
npc_id IS THE NPC'S ACTOR ID ON THE MAP, not its template id: map NPCs have negative actor ids (your capture: -20001), the ids GameRolePlayShowActorsEvent and MapComplementaryInformationEvent give the map's actors.
LIVE CAPTURE (3.6.12.16): after NpcGenericActionRequest {npc_map_id 153880835, npc_action_id 3, npc_id -20001} on the Incarnam portal NPC, this message arrived with npc_id -20001, map_id 153880835 and no portal type, immediately followed by NpcDialogQuestionEvent.
Builds pad this message with an unread repeated int64 or int32, a second int32, or a nested decoy message; the client reads only the three members above.
When you may send it
Requires character_loaded inferred State it changes
Establishes npc_dialog_open inferred — the client opens its dialog window for this NPC, and the dialog's questions and replies only make sense while it is open Related messages
You will receive one of NpcDialogQuestionEvent observed — the NPC's first line and replies, in the same burst; 1 of 1 capture You will receive one of PrismDialogQuestionEvent inferred — instead of the question when the NPC is an alliance prism: the client opens the dialog in prism mode and this empty event makes it show the prism's fixed text (IDA, 3.7.4.4) Arrives after NpcGenericActionRequest Fields
#FieldTypeMeaningYou set it 1portal_typePortalTypeWhich dimension portal this dialog is about; absent for every other NPC.
Explicit presence: absent is not the same as zero.
Set only for the four dimension portals (PortalType); absent (UNSUPPORTED) for ordinary NPCs, the Incarnam portal NPC included.
When set, the client opens that dimension's portal dialog instead of the NPC's own.never 3map_idint64The map the NPC is on - the npc_map_id of your request. (map id)
Echoes NpcGenericActionRequest.npc_map_id.
For a dimension portal the client checks it against the map you are on and opens nothing when they differ.never 5npc_idint32The NPC you are now talking to, as its actor id on the map. (map actor id (negative for map NPCs))
Echoes NpcGenericActionRequest.npc_id; not the NPC's template id.
The client waits until an actor with this id exists on the map before it builds the dialog.never
  • summary: The server opening a dialog with an NPC, in answer to a dialog NPC action. The NPC's first line follows in NpcDialogQuestionEvent.
  • area: Game.Npc
  • 47 vues
What the NPC says now and the replies you may choose; answer with one reply_id or leave the dialog.
Kind event · Area Game.Npc
What the NPC says now, and the replies you may choose. It arrives right after NpcDialogCreationEvent (the first line) and after each NpcDialogReplyRequest that leads to another line.
WHAT TO DO WHEN YOU RECEIVE IT
1. SHOW OR LOG THE LINE. message_id is the NPC's line of text: an NPC message id of the game data (the NPC data lists the messages it can say; the message table holds the text). Substitute dialog_params, in order, into its placeholders. 2. LIST THE REPLIES. Each entry of visible_replies is one answer you may give: its reply_id names the reply text in the game data (the NPC data lists its replies) and is THE id you send back. Its actions say what picking it does (start a quest, validate a quest step, start a fight...); the official client only uses them to choose each reply's icon. 3. ANSWER WITH ONE OF THEM, OR LEAVE. Send NpcDialogReplyRequest with a reply_id taken from THIS message's visible_replies - never one from an earlier line, never an id you made up - or close the dialog with DialogLeaveRequest. The server then sends the next line (this message again) or closes the dialog (DialogLeaveEvent). 4. AN EMPTY visible_replies means nothing to answer: leave the dialog.
WHAT THE OFFICIAL CLIENT DOES WITH IT
- Its dialog service builds a table reply id -> list of (action id, action argument) from visible_replies, waits until the dialog window opened by NpcDialogCreationEvent is ready (its routine WaitForDialogUi), then shows message_id with dialog_params and one button per reply. - The buttons send NpcDialogReplyRequest with the clicked reply's id.
YOUR CAPTURE (3.6.12.16): message_id 30637, no dialog_params, one reply, reply_id 36979, no actions - the Incarnam portal NPC's single answer.
Builds pad this message, its replies and their actions with unread strings, enums, int64 lists or nested decoys; the client reads only the members above.
When you may send it
Requires npc_dialog_open inferred Related messages
Arrives after NpcDialogCreationEvent Arrives after NpcDialogReplyRequest Fields
#FieldTypeMeaningYou set it 1visible_repliesrepeated VisibleReplyThe replies you may choose now, in display order.
Send one VisibleReply.reply_id back in NpcDialogReplyRequest.
Empty means there is nothing to answer.never 2dialog_paramsrepeated stringValues to substitute, in order, into the line's placeholders.
Often empty. The client copies them into a list and hands them to the dialog window with the message id.never 3message_idint32The NPC's line of text, as an NPC message id of the game data. (NPC message id)
Your capture: 30637 on the Incarnam portal NPC.never
  • summary: What the NPC says now and the replies you may choose; answer with one reply_id or leave the dialog.
  • area: Game.Npc
  • 49 vues
One NPC, the quests it can give and the quests it can take back.
Kind struct · Area Game.Npc
One NPC of a MapNpcQuest entry, with two lists of quest ids.
NpcWithQuest.quests_to_start are quests the NPC can give; NpcWithQuest.quests_to_validate are quests it can take back. When the client picks the NPC's marker it looks at the quests to validate first, then records whether the quest it picked is one to start - which is what decides the marker's kind.
DO NOT GO BY FIELD NUMBER. The two lists are renumbered from build to build and some builds declare a third list of quest ids, a string, an int64 or a nested enum beside them that the client never reads.
HOW TO USE IT. Find the NPC among the map's actors by NpcWithQuest.npc_id. A non-empty quests_to_validate means the NPC can complete a quest of yours now; a non-empty quests_to_start means it can give you a new one. The client shows the validate marker in preference when both are present.
Not sent on its own — it is only ever an element of MapNpcQuest.npcs_with_quests. inferred
Used by
MapNpcQuest Fields
#FieldTypeMeaningYou set it 1quests_to_startrepeated int32Quests this NPC can give. (quest id)
The only list the world map uses: a map gets a marker when one of its NPCs has a quest to start that the client's quest table knows.never 2quests_to_validaterepeated int32Quests this NPC can take back. (quest id)
Looked at before quests_to_start when the client picks the NPC's marker. Never shown on the world map.never 3npc_idint32Which NPC. (npc id)
The contextual id the NPC has on the current map - the one the map's actor list carries and NpcGenericActionRequest expects, routinely negative - not an NPC template id. The client finds the NPC by looking this id up, widened to 64 bits, in its table of the entities on the map.never
  • summary: One NPC, the quests it can give and the quests it can take back.
  • area: Game.Npc
  • 35 vues
Which NPCs have quests for the character, map by map. It drives the quest markers over NPCs and on the world map; nothing is sent back.
Kind event · Area Game.Npc
WHAT TO DO WHEN YOU RECEIVE IT
1. Replace every quest marker you hold, on the current map and on the world map, with what this message says. Anything it does not list has no marker. 2. SEND NOTHING BACK. No handler of this message builds a request, and a static walk through the notifications it raises reaches none. 3. To act on a marked NPC you still use the ordinary NPC actions (NpcGenericActionRequest); this message only tells you which NPCs are worth talking to, and for which quests.
The quest markers the client shows: over the NPCs of the current map, and on the world map for every map listed. One entry per map, each listing that map's NPCs and, for each NPC, the quests it can give (NpcWithQuest.quests_to_start) and the quests it can take back (NpcWithQuest.quests_to_validate).
TREAT IT AS A REPLACEMENT. On arrival the client first removes every quest marker from every entity on the current map, then applies this message, and it rebuilds its world-map markers from this message alone. An NPC or a map the message leaves out has no marker afterwards.
ONLY THE CURRENT MAP'S ENTRY TOUCHES VISIBLE NPCS. The client compares each MapNpcQuest.map_id with the map the character is on and marks NPCs from that entry only. Every other entry is used for the world map, where a map gets a marker at its world coordinates when one of its NPCs has a quest to start that the client's quest table knows. Quests to validate never reach the world map.
A QUEST TO HAND IN WINS. When the client picks the marker for an NPC it looks at NpcWithQuest.quests_to_validate before NpcWithQuest.quests_to_start.
ONE DECLARED LIST IS REAL. Several builds declare a second list of the same entry type beside NpcsMapQuestStatusUpdateEvent.map_information, and some add a string, an int32 or a decoy message; the client reads only the one list.
When you may send it
Requires context_ready inferred Related messages
Reply not yet recovered: no request asks for it - the NPC area declares none - so the server pushes it. When it does (world entry, map changes, quest changes) is not established by any signature here. Fields
#FieldTypeMeaningYou set it 1map_informationrepeated MapNpcQuestOne entry per map that has NPCs with quests for the character.
A list of MapNpcQuest. Some builds declare a second list of the same type beside it; the client never reads that one and it stays unnamed.never
  • summary: Which NPCs have quests for the character, map by map. It drives the quest markers over NPCs and on the world map; nothing is sent back.
  • area: Game.Npc
  • 37 vues
A new item entered the character's inventory. Carries the full item and why it was added.
Kind event · Area Game.Inventory
A NEW item entered the inventory: add it to your item list. It is a new stack, not a quantity change of an item you already hold (that is ObjectQuantityEvent).
WHAT THE CLIENT DOES WITH IT
It adds the item to the inventory. When the origin is a quest, it also prints the "obtained" chat line with the item and its quantity. Nothing is sent back.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server pushes it whenever an item enters the inventory (loot, purchase, quest, exchange, mail) Fields
#FieldTypeMeaningYou set it 1originObjectOriginWhy the item was added (ObjectOrigin). Absent means no particular origin.
The client only acts on the quest origin: it announces the obtained item in chat.never 2objectObjectItemInventoryThe item that was added, with its position in the inventory.never
  • summary: A new item entered the character's inventory. Carries the full item and why it was added.
  • area: Game.Inventory
  • 48 vues
Which dimension a portal dialog leads to: Enutrosor, Srambad, Xelorium, Ecaflipus, or UNSUPPORTED for an ordinary NPC.
Kind enum · Area Game.Npc
Which dimension a portal dialog leads to, carried by NpcDialogCreationEvent.portal_type:
UNSUPPORTED not a dimension portal - the value of every ordinary NPC dialog (absent on the wire). The client's dialog service rejects it as a portal ("Portal type isn't not supported"). ENUTROSOR the Enutrosor dimension. SRAMBAD the Srambad dimension. XELORIUM the Xelorium dimension. ECAFLIPUS the Ecaflipus dimension.
The client converts the value unchanged into its own portal enum. It names each dimension with the localized ui.dimension.<name> text and opens that dimension's own portal dialog. Nothing is sent back because of the value. Treat a value outside these five as a protocol change.
Not sent on its own — an enum is never sent on its own; it is the NpcDialogCreationEvent.portal_type member. inferred
Used by
NpcDialogCreationEvent Values
ValueNumberMeaning UNSUPPORTED0Not a dimension portal: every ordinary NPC dialog.
The default, absent on the wire; the dialog service refuses it as a portal. ENUTROSOR1The Enutrosor dimension portal.
The client names it with ui.dimension.enutrosor. SRAMBAD2The Srambad dimension portal.
The client names it with ui.dimension.srambad. XELORIUM3The Xelorium dimension portal.
The client names it with ui.dimension.xelorium. ECAFLIPUS4The Ecaflipus dimension portal.
The client names it with ui.dimension.ecaflipus.
  • summary: Which dimension a portal dialog leads to: Enutrosor, Srambad, Xelorium, Ecaflipus, or UNSUPPORTED for an ordinary NPC.
  • area: Game.Npc
  • 42 vues
One alliance prism was placed or changed. Carries its full record; upsert it by sub-area id.
Kind event · Area Game.Prism
A prism (alliance territory marker) was placed or its state changed. The message carries the prism's full record.
UPSERT BY SUB-AREA. The client keeps one prism per sub-area id: if it already knows a prism for that sub-area it updates it, otherwise it adds it. The record's sub-area id is the key; PrismRemoveEvent removes by the same key.
WHAT THE CLIENT DOES WITH IT
It stores the record in its prism list and queues the sub-area for a batched refresh of the map/territory display. Nothing is sent back.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server pushes prism changes (placement, state, alliance) as they happen Fields
#FieldTypeMeaningYou set it 2prism_localized_informationtype not documented yetThe prism's full record: its sub-area, map, alliance and state.
Its sub-area id is the key: one prism per sub-area.never
  • summary: One alliance prism was placed or changed. Carries its full record; upsert it by sub-area id.
  • area: Game.Prism
  • 41 vues
Tells the open alliance-prism dialog to show its text. It carries nothing and needs no answer.
Kind event · Area Game.Npc
THE SECOND HALF OF TALKING TO AN ALLIANCE PRISM. It carries nothing: the client builds the prism's text from what it already knows.
WHEN IT ARRIVES
1. You talk to an alliance prism (NpcGenericActionRequest on the prism). 2. The server opens the dialog with NpcDialogCreationEvent, whose npc_id is the prism. The official client opens its NPC dialog in PRISM mode for that entity. 3. This event follows. The client then shows the prism's fixed line (NPC message 15428) filled with the owning alliance and the prism's current state, and offers NO reply.
WHAT TO DO WHEN YOU RECEIVE IT
- Nothing to read and nothing to answer. If your script needs the prism's alliance or state, take them from what you already track about that prism; this message does not carry them. - The dialog stays open and closable. End it the way you end any NPC dialog, with DialogLeaveRequest. - Ignore it if no prism dialog is open: the official client does nothing then.
Do not confuse it with NpcDialogQuestionEvent, which carries a message id and replies for an ordinary NPC, or with NpcGenericActionFailureEvent, the other empty message of the NPC area, which means your action was refused.
When you may send it
Requires npc_dialog_open inferred Related messages
Arrives after NpcDialogCreationEvent
  • summary: Tells the open alliance-prism dialog to show its text. It carries nothing and needs no answer.
  • area: Game.Npc
  • 39 vues
An alliance prism disappeared. Carries the sub-area id of the prism to forget.
Kind event · Area Game.Prism
A prism (alliance territory marker) is gone. Remove the prism you keep for this sub-area id; it is the same key PrismAddOrUpdateEvent stores prisms under.
WHAT THE CLIENT DOES WITH IT
It removes the prism from its list and notifies the territory display. Nothing is sent back.
When you may send it
Requires character_loaded inferred Related messages
Unsolicited - nothing you send causes this the server pushes it when a prism is destroyed or removed Fields
#FieldTypeMeaningYou set it 3sub_area_idint32Sub-area of the prism to remove. (sub-area id)
Named after the store key: the client removes the prism it keeps under this id, the same id PrismAddOrUpdateEvent's record is stored under (that record's sub_area_id).never
  • summary: An alliance prism disappeared. Carries the sub-area id of the prism to forget.
  • area: Game.Prism
  • 39 vues
One completed quest in the journal: which quest, and Ankama's completion counter for it.
Kind struct · Area Game.Quest
One entry of the journal's finished list (QuestsEvent.finished_quests). It is declared inside QuestsEvent and travels nowhere else.
HOW TO USE IT. Only QuestFinished.quest_id matters: the quest is complete. The client appends that id to its finished list and looks it up in the game data to mark every objective of every step of the quest as done - the wire carries no objectives for a finished quest, because they are all done by definition.
QuestFinished.finished_count is never read by any dumped client; do not build logic on it.
The id is narrowed to a signed 16-bit value on the way in.
Not sent on its own — it is only ever an entry of QuestsEvent.finished_quests. inferred
Used by
QuestsEvent Fields
#FieldTypeMeaningYou set it 1finished_countint32Ankama's completion counter for the quest.
Never read by the client on any dumped build; the meaning comes from Ankama's field name only.
Named only where exactly one other int32 is declared, and left obfuscated otherwise.never 2quest_idint32Which quest was completed. (quest id)
The only member the client reads. It is stored as a signed 16-bit value.never
  • summary: One completed quest in the journal: which quest, and Ankama's completion counter for it.
  • area: Game.Quest
  • 36 vues
One objective of a quest step - its id, whether it is done, its progress and its text parameters. The type is recovered; its members are not named yet.
Kind struct · Area Game.Quest
One thing the current step of a quest asks for - talk to someone, bring items, defeat monsters. It is the element of Details.objectives.
WHAT IT CARRIES. Ankama's reference definition is:
objective_id which objective, as a quest-objective id from the game data objective_reached whether it is done dialog_params text parameters substituted into the objective's description completion a progress pair: current and maximum The client uses exactly those four things: it files each objective under its id as done or still to do, keeps the progress pair for the objective's counter, and fills the objective's text with the parameters when there are any.
ITS MEMBERS ARE NOT NAMED IN THIS SCHEMA. This record recovers the type so that the objectives list reads correctly, but no signature yet proves which declared member is which, so every member keeps its obfuscated name in the recovered schema. The shape has moved since the reference build - on recent builds the progress pair is a separate two-number message, declared twice, with a decoy string beside it - so do not map the members by position.
Nothing is sent about an objective when it arrives. Following one on screen is a separate request (QuestObjectiveFollowRequest) that the player triggers.
Not sent on its own — it is only ever an entry of Details.objectives. inferred
Used by
Details No fields you may set.
  • summary: One objective of a quest step - its id, whether it is done, its progress and its text parameters. The type is recovered; its members are not named yet.
  • area: Game.Quest
  • 38 vues
New progress on one objective of an active quest. Update that objective's counter; nothing is sent back.
Kind event · Area Game.Quest
New progress on one objective of a quest the character is doing - "3 of 10 killed". The server pushes it whenever the counter moves; it changes no other part of the quest.
WHAT TO DO WHEN YOU RECEIVE IT
1. Find the quest by QuestObjectiveUpdatedEvent.quest_id among the quests you hold from QuestsEvent / QuestStepInformationEvent, then the objective by QuestObjectiveUpdatedEvent.objective_id inside that quest's current step. 2. Set that objective's progress to Completion.current_completion out of Completion.max_completion. 3. If you do not hold that quest or that objective, ignore the message - the client does exactly that. 4. SEND NOTHING BACK. The handler builds no request.
WHAT THE CLIENT DOES. The quest service looks the quest up in its table of active quests, then the objective in that quest's table of objectives, and overwrites the objective's two progress counters (kept as 16-bit numbers). It then announces the (quest, objective) pair; the quest window refreshes its objective list when that quest is the one selected.
The two ids are the same wire type and change field numbers between builds; they are told apart by which one the client looks up FIRST (the quest) and which one it looks up inside the result (the objective).
When you may send it
Requires character_selected inferred Related messages
Unsolicited - nothing you send causes this the server pushes it as an objective's counter moves; no request asks for it Fields
#FieldTypeMeaningYou set it 1objective_idint32The objective that progressed, looked up inside that quest. (objective id)
Named after the same member of QuestObjectiveValidatedEvent.never 3completionCompletionThe objective's new progress: current count and target.
A Completion, the record QuestObjective carries for the same purpose.never 4quest_idint32The quest whose objective progressed; the client looks it up first. (quest id)
Named after the same member of QuestObjectiveValidatedEvent; no reference build names this message's fields.never
  • summary: New progress on one objective of an active quest. Update that objective's counter; nothing is sent back.
  • area: Game.Quest
  • 35 vues
A quest has just started for the character. Carries the quest id.
Kind event · Area Game.Quest
The character has started a quest. Add the quest id to your list of active quests.
It follows QuestStartRequest when the start succeeds, but also arrives for quests started any other way (an NPC dialog answer, an item, a map trigger), so handle it whether or not you asked.
WHAT THE CLIENT DOES WITH IT
The quest journal records the quest as started and refreshes its quest list. If the player's option "follow a quest when it starts" is on and the quest can be followed, the client also starts following it (the objective tracker shows it). Following is purely client-side: nothing is sent back.
The quest's steps and objectives are not in this message; they come with the journal (QuestsEvent) or on request (QuestStepInformationRequest).
TWIN WARNING: QuestValidatedEvent has exactly the same wire shape (one quest id). This one starts a quest, that one ends it.
When you may send it
Requires character_selected inferred Related messages
Arrives after QuestStartRequest Fields
#FieldTypeMeaningYou set it 1quest_idint32The quest that started. (quest id (DataCenter Quests))never
  • summary: A quest has just started for the character. Carries the quest id.
  • area: Game.Quest
  • 40 vues
A quest of the character has just been completed. Carries the quest id.
Kind event · Area Game.Quest
The character has completed a quest. Move the quest id from your active quests to your finished quests.
WHAT THE CLIENT DOES WITH IT
The journal moves the quest to the finished list, stops following it, and removes it from the player's hidden-quests list. If the quest is the day's Almanax quest, the client shows the "Almanax quest done" message. Nothing is sent back.
TWIN WARNING: QuestStartedEvent has exactly the same wire shape (one quest id). This one ends a quest, that one starts it.
When you may send it
Requires character_selected inferred Related messages
Unsolicited - nothing you send causes this the server announces a completed quest when its last step is validated; no request asks for it Fields
#FieldTypeMeaningYou set it 1quest_idint32The quest that was completed. (quest id (DataCenter Quests))never
  • summary: A quest of the character has just been completed. Carries the quest id.
  • area: Game.Quest
  • 41 vues
The character's whole quest journal: quests under way with their current step, finished quests, and reinitialised ones. A full replacement; nothing is sent back.
Kind event · Area Game.Quest
WHAT TO DO WHEN YOU RECEIVE IT
1. Throw away the journal you hold and rebuild it from this message - see below. 2. SEND NOTHING BACK. No handler of this message builds a request. The one request a static walk reaches from it is the tutorial's own step query, raised by the tutorial screen for its special quests - not something the journal requires. 3. If you need the step of one quest refreshed later, ask with QuestStepInformationRequest; the journal itself is complete.
WHEN IT ARRIVES. The client asks for it - its journal request (QuestsRequest, no signature here) goes out when the quest list or the quest tab opens and when the calendar refreshes.
The server's statement of the character's quest journal. One message carries three lists: QuestsEvent.active_quests, QuestsEvent.finished_quests and QuestsEvent.reinitialized_done_quests_id.
IT IS A SNAPSHOT, NOT A DELTA. The client does not merge it into what it already holds. On every arrival it throws away its list of active quests, its list of finished quests, its list of reinitialised quests and both of its objective lists, and rebuilds all five from this one message. A journal that omits a quest has dropped that quest. Treat each arrival as the complete truth and replace your own state the same way.
WHAT THE CLIENT BUILDS FROM IT, in this order:
1. one journal entry per QuestActive, keyed by its quest id and holding the id of the step the quest is on (Details.step_id); 2. the finished list: the QuestFinished.quest_id of every entry of finished_quests; 3. the reinitialised list: every id of reinitialized_done_quests_id; 4. for each active quest, every QuestObjective of its current step, sorted into still to do and done, with its progress pair and its text parameters when it carries any; 5. for each finished quest, every objective of every step the game data declares for that quest, all marked done; 6. last, the reinitialised ids are APPENDED TO THE FINISHED LIST.
Step 6 is the one to remember. A quest id listed in reinitialized_done_quests_id counts as finished for the client even when finished_quests does not list it; the reinitialised list is kept on its own as well, so the two can still be told apart afterwards.
QUEST IDS ARE 16-BIT ON THE CLIENT. Every id - active, finished, reinitialised - is narrowed to a signed 16-bit value before it is stored, although the wire declares int32.
TWO MEMBERS THE CLIENT NEVER READS: QuestsEvent.player_id and QuestFinished.finished_count. They are part of Ankama's contract and the server may fill them, but nothing in the client depends on either. Do not build logic on a meaning this catalogue cannot observe.
Once the journal is rebuilt the client raises its quest-list-updated notification, which is what refreshes the quest window, the calendar and the group-finder tab. The journal only describes the step each quest is currently on; QuestStepInformationRequest asks for one quest's step again.
When you may send it
Requires character_selected inferred Related messages
Reply not yet recovered: the client asks for the journal with QuestsRequest, which has no signature here. On 3.2.7.15 it sends that request whenever the quest list or the quest tab opens and when the calendar refreshes; whether the server also pushes the journal unasked is not established. Fields
#FieldTypeMeaningYou set it 2reinitialized_done_quests_idrepeated int32Ids of finished quests that have been reinitialised. (quest id)
The client stores these on their own AND appends them to its finished list, so an id listed here counts as finished even when finished_quests does not carry it.never 3player_idint64Whose journal this is.
Explicit presence: absent is not the same as zero. (character id)
Never read by the client on any dumped build, the unobfuscated beta included, so its meaning rests on Ankama's name alone.
Named only on builds that declare a single optional int64; where a second one is declared it stays obfuscated rather than being picked by position.never 5finished_questsrepeated QuestFinishedEvery quest the character has completed.
A list of QuestFinished. The client keeps only each entry's quest id, and rebuilds its finished list from scratch on every journal.never 6active_questsrepeated QuestActiveEvery quest the character has under way, each with the step it is on.
A list of QuestActive. Some builds declare a second list of the same type beside it; the client never reads that one and it stays unnamed.never
  • summary: The character's whole quest journal: quests under way with their current step, finished quests, and reinitialised ones. A full replacement; nothing is sent back.
  • area: Game.Quest
  • 45 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.