Achievements
phantom.aj.achievementsYou and your animal
Achievements and stats.
Scripts and plugins
A script has all of it, as phantom.aj.achievements, and so does a plugin, from ctx.phantom(): the SDK runs in the plugin's own frame. Each call is marked with what it needs: game:read for what the area knows and hears, which "game": "read" in the manifest grants, and game:act for doing things in it as the player, which needs "game": "act" (see Permissions).
Overview
| Member | What it does | Plugins |
|---|---|---|
all() | Every achievement there is to earn, named, in the client's book order (by group): not anyone's copies but one entry each, with the client's own filter (one with no icon or description is left out, as the book leaves it out). | game:read |
book() | The whole book in one object: every achievement named, described and grouped as the client's screen groups them, with the player's progress on each and the totals. | game:act |
earn() | Asks for one achievement the way the game earns it: the stat behind it set to its threshold, through the client's own requestSetUserVar (zs), as a minigame sets a score. | game:act |
get() | One achievement by its def id (AchievementManager.getAchievementDef), its words read through the client's own translation; null when the client has no such def, as before the def packs. | game:read |
held() | The achievements the client holds for a player, named (UserInfo.achievements): the player's own when no name is given. | game:act |
of() | Asks the server for a player's achievements (requestAchievements, za), and resolves with them. | game:act |
showNew() | Shows the achievements the client is holding, one after another in its own award popup (displayNewAchievements), and resolves with how many once the popup is up: 0, sending nothing, when none are waiting. | game:act |
types() | Every group of achievements with its name (typeNamesTranslatedAndSorted), by name. | game:read |
unseen() | How many achievements the client holds and has not shown yet (_newAchievements). | game:read |
onEarned() | Hears each achievement the player earns, with the stat change that earned it (zs). | game:read |
onList() | Hears every answer about a player's achievements (za), whoever asked: of, a buddy card. | game:read |
achievements.stats: The player's stats, the server's user variables: phantom.aj.achievements.stats.
| Member | What it does | Plugins |
|---|---|---|
all() | Every stat the client holds (playerUserVars), with the kind the server gave each. | game:read |
get() | A stat's value (getUserVarValueById), or null for one the client has not got. | game:read |
isBitSet() | Whether one bit of a stat is set (UserVarCache.isBitSet), for the stats that are rows of switches. | game:read |
refresh() | Asks the server for every stat again (requestAllUserVars, zg), and resolves with them once the client has taken them in. | game:act |
set() | Sets a stat, as the client's settings, tutorials and daily gifts do (requestSetUserVar, zs), and resolves with the value the server kept, which may not be the one asked for, and the achievements it earned. | game:act |
setBit() | Sets or clears one bit of a stat that is a row of switches, as the settings toggles and the Journey Book's pages do (requestSetUserVar(id, bit, null, on)), and resolves with the row as the server keeps it. | game:act |
type() | What kind of value a stat holds (getUserVarTypeById), or null for one the client has not got. | game:read |
onChange() | Hears each stat the server changes (zs): by the game as the player plays, by the client's settings, and by set. | game:read |
onList() | Hears the server's whole list of stats (zg): at login, and after refresh. | game:read |
achievements.viewer: The trophy viewer inside the avatar editor.
| Member | What it does | Plugins |
|---|---|---|
isShown() | Whether the trophy viewer is showing. | game:read |
select() | Shows one achievement in the viewer, by definition id, as pressing it does. | game:act |
setShown() | Shows or hides the trophy viewer. | game:act |
onShown() | Hears an achievement shown in the viewer. | game:read |
Methods
all
all() => Promise<Achievement[]>Every achievement there is to earn, named, in the client's book order (by group): not anyone's copies but one entry each, with the client's own filter (one with no icon or description is left out, as the book leaves it out). Read from the client's own copy, or from the def pack before the book has built one: nothing is built or loaded. Empty before the def packs have loaded.
Returns
Promise<Achievement[]>
Types
book
book() => Promise<AchievementBook>The whole book in one object: every achievement named, described and grouped as the client's screen groups them, with the player's progress on each and the totals. It asks the client only, but is the same work as all; keep what it gives rather than calling it in a loop.
Returns
Promise<AchievementBook>
Types
earn
earn(defId: number, options?: ActOptions) => Promise<Earned>Asks for one achievement the way the game earns it: the stat behind it set to its threshold, through the client's own requestSetUserVar (zs), as a minigame sets a score. Use at your own risk. Resolves once the server gave it; throws AchievementRefused (a REFUSED) with what the server kept when it gave nothing, NOT_READY for a def the client has not got, and REFUSED for one resting on a setting rather than something done.
Parameters
| Name | Type | |
|---|---|---|
defId | number | |
options optional | ActOptions |
Returns
Promise<Earned>
Types
get
get(defId: number) => Promise<Achievement | null>One achievement by its def id (AchievementManager.getAchievementDef), its words read through the client's own translation; null when the client has no such def, as before the def packs.
Parameters
| Name | Type | |
|---|---|---|
defId | number |
Returns
Promise<Achievement \| null>
Types
held
held(userName?: string | undefined) => Promise<HeldAchievement[]>The achievements the client holds for a player, named (UserInfo.achievements): the player's own when no name is given. Empty for a player the client has heard nothing about; of asks.
The client holds none of the player's own until something asks the server, which only the achievement screen does. So the first time, when the client has never asked (achievementsIndexed is null), this asks once, as that screen would.
Parameters
| Name | Type | |
|---|---|---|
userName optional | string | undefined |
Returns
Promise<HeldAchievement[]>
Types
of
of(userName: string, options?: ActOptions) => Promise<PlayerAchievements>Asks the server for a player's achievements (requestAchievements, za), and resolves with them. The client asks only about a player it holds a record for (one in the room or on the buddy list), which throws NOT_READY otherwise; inside its own ten seconds between asks about one player, this answers from what the client already holds.
Parameters
| Name | Type | |
|---|---|---|
userName | string | |
options optional | ActOptions |
Returns
Promise<PlayerAchievements>
Types
ActOptions · PlayerAchievements · AchievementEntry
Example
const { achievements, archived } = await phantom.aj.achievements.of('friend');showNew
showNew(options?: ActOptions) => Promise<number>Shows the achievements the client is holding, one after another in its own award popup (displayNewAchievements), and resolves with how many once the popup is up: 0, sending nothing, when none are waiting. It does not wait for the player to dismiss them.
Parameters
| Name | Type | |
|---|---|---|
options optional | ActOptions |
Returns
Promise<number>
Types
types
types() => Promise<AchievementType[]>Every group of achievements with its name (typeNamesTranslatedAndSorted), by name.
Returns
Promise<AchievementType[]>
Types
unseen
unseen() => Promise<number>How many achievements the client holds and has not shown yet (_newAchievements).
Returns
Promise<number>
Events
onEarned
onEarned(listener: (earned: EarnedAchievement) => void) => () => voidHears each achievement the player earns, with the stat change that earned it (zs). Several earned by one change are told one by one.
Parameters
| Name | Type | |
|---|---|---|
listener | (earned: EarnedAchievement) => void |
Returns
() => void. Call it to stop listening.
Types
onList
onList(listener: (answer: PlayerAchievements) => void) => () => voidHears every answer about a player's achievements (za), whoever asked: of, a buddy card.
Parameters
| Name | Type | |
|---|---|---|
listener | (answer: PlayerAchievements) => void |
Returns
() => void. Call it to stop listening.
Types
achievements.stats
The player's stats, the server's user variables: phantom.aj.achievements.stats. Counts the game keeps (a minigame's best, a pet's count), rows of switches (the settings, the tutorials seen, the facts found) and the game's bookkeeping. Read from the client's own cache (userInfo.userVarCache), which it has had since login.
all
all() => Promise<Stat[]>Every stat the client holds (playerUserVars), with the kind the server gave each.
Returns
Promise<Stat[]>
Types
get
get(userVarId: number) => Promise<number | null>A stat's value (getUserVarValueById), or null for one the client has not got.
Parameters
| Name | Type | |
|---|---|---|
userVarId | number |
Returns
Promise<number \| null>
isBitSet
isBitSet(userVarId: number, bit: number) => Promise<boolean>Whether one bit of a stat is set (UserVarCache.isBitSet), for the stats that are rows of switches. A stat the client has not got reads as all zeroes, as the client reads it.
Parameters
| Name | Type | |
|---|---|---|
userVarId | number | |
bit | number |
Returns
Promise<boolean>
refresh
refresh(options?: ActOptions) => Promise<Stat[]>Asks the server for every stat again (requestAllUserVars, zg), and resolves with them once the client has taken them in. The client has this request and never sends it, so a server that no longer answers it throws TIMEOUT.
Parameters
| Name | Type | |
|---|---|---|
options optional | ActOptions |
Returns
Promise<Stat[]>
Types
set
set(userVarId: number, value: number, options?: ActOptions) => Promise<StatChange>Sets a stat, as the client's settings, tutorials and daily gifts do (requestSetUserVar, zs), and resolves with the value the server kept, which may not be the one asked for, and the achievements it earned. The server decides which stats a client may set. Throws REFUSED while invisible, as the client sends nothing then.
Parameters
| Name | Type | |
|---|---|---|
userVarId | number | |
value | number | |
options optional | ActOptions |
Returns
Promise<StatChange>
Types
StatChange · StatUpdate · ActOptions
Example
const change = await phantom.aj.achievements.stats.set(packets.USER_VAR.lastSeenNewspaper, 1);
console.log('kept', change.value, 'was', change.previous);setBit
setBit(userVarId: number, bit: number, on: boolean, options?: ActOptions) => Promise<StatChange>Sets or clears one bit of a stat that is a row of switches, as the settings toggles and the Journey Book's pages do (requestSetUserVar(id, bit, null, on)), and resolves with the row as the server keeps it. Only for such a stat: the client never sends a bit to a count.
Parameters
| Name | Type | |
|---|---|---|
userVarId | number | |
bit | number | |
on | boolean | |
options optional | ActOptions |
Returns
Promise<StatChange>
Types
type
type(userVarId: number) => Promise<number | null>What kind of value a stat holds (getUserVarTypeById), or null for one the client has not got.
Parameters
| Name | Type | |
|---|---|---|
userVarId | number |
Returns
Promise<number \| null>
onChange
onChange(listener: (update: StatUpdate) => void) => () => voidHears each stat the server changes (zs): by the game as the player plays, by the client's settings, and by set. The client's cache has the new value by the time it is read again.
Parameters
| Name | Type | |
|---|---|---|
listener | (update: StatUpdate) => void |
Returns
() => void. Call it to stop listening.
Types
onList
onList(listener: (stats: Stat[]) => void) => () => voidHears the server's whole list of stats (zg): at login, and after refresh.
Parameters
| Name | Type | |
|---|---|---|
listener | (stats: Stat[]) => void |
Returns
() => void. Call it to stop listening.
Types
achievements.viewer
The trophy viewer inside the avatar editor.
isShown
isShown() => Promise<boolean>Whether the trophy viewer is showing.
Returns
Promise<boolean>
select
select(defId: number, options?: ActOptions) => Promise<void>Shows one achievement in the viewer, by definition id, as pressing it does.
Parameters
| Name | Type | |
|---|---|---|
defId | number | |
options optional | ActOptions |
Returns
Promise<void>
Types
setShown
setShown(shown: boolean, options?: ActOptions) => Promise<void>Shows or hides the trophy viewer. The avatar editor has to be open: the first time, its own trophy button builds the viewer.
Parameters
| Name | Type | |
|---|---|---|
shown | boolean | |
options optional | ActOptions |
Returns
Promise<void>
Types
onShown
onShown(listener: (shown: AchievementShown) => void) => () => voidHears an achievement shown in the viewer.
Parameters
| Name | Type | |
|---|---|---|
listener | (shown: AchievementShown) => void |
Returns
() => void. Call it to stop listening.
Types
Types
The types the calls above take and give, with every field. Import any of them in a plugin from @phantomclient/plugin/sdk, or use them as they are in a script.
Achievement
An achievement that exists, its words read: what get, all and the book are made of.
| Field | Type | |
|---|---|---|
defId | number | |
name | string | Its name in the player's own language. |
description | string | What it says the player did. |
type | number | Which group it belongs to, as the client's achievement screen buckets them. |
typeName | string | null | That group's name in the player's language; null for a group the client has not named. |
userVarId | number | null | The stat that earns it (stats.get takes it); null for one with no stat behind it. |
target | number | What that stat has to reach (triggeredAmount); 0 for one with no threshold. |
iconMediaId | number | Its icon, and the medal, ribbon or trophy behind it. |
baseMediaId | number | |
extraText | string | null | Whatever the definition carries beside the words, such as the number on the medal. |
AchievementType
A group of achievements, as the client's own screen names it.
| Field | Type | |
|---|---|---|
type | number | |
name | string |
HeldAchievement
An achievement somebody holds, as the client keeps it with its words already read.
| Field | Type | |
|---|---|---|
defId | number | |
invId | number | Their own copy of it, which the server numbers. |
name | string | |
description | string | |
type | number | |
userVarId | number | null | |
iconMediaId | number | |
baseMediaId | number | |
mediaText | string | null | What the client drew on it, such as a count; null for nothing. |
ActOptions
How long something that acts may take, and what may end it first.
| Field | Type | |
|---|---|---|
timeoutMs optional | number | undefined | 10 seconds by default. |
signal optional | AbortSignal | undefined |
PlayerAchievements
What the server said about a player's achievements (za).
| Field | Type | |
|---|---|---|
userName | string | |
archived | boolean | The account is archived, and the list empty. |
achievements | AchievementEntry[] |
AchievementEntry
An achievement a player holds: its place in their list and which achievement it is.
| Field | Type | |
|---|---|---|
invId | number | The achievement's place in the player's list. |
defId | number | Which achievement it is: its definition id. |
Earned
What earn came to, once the server gave the achievement.
| Field | Type | |
|---|---|---|
defId | number | |
userVarId | number | The stat behind it, the value asked for (its threshold), and the value the server kept. |
asked | number | |
kept | number | |
achievements | AchievementEntry[] | Every achievement the answer listed: this one, and any others the same stat passed. |
AchievementBook
The whole achievement book: what the player has earned, what is left, by group.
| Field | Type | |
|---|---|---|
total | number | |
earned | number | |
left | number | |
fraction | number | How much is done, 0 to 1; 0 before the def packs have loaded. |
entries | BookEntry[] | Every achievement, in the screen's group order and then by name. |
groups | BookGroup[] |
BookEntry
One achievement in the book, with where the player stands on it.
type BookEntry = Achievement & {
/** What the stat reads now, from the client's cache; 0 when it has never been set. */
value: number;
/** Whether the player holds it. */
earned: boolean;
/** How far along, 0 to 1: 1 once earned, 0 for one with no threshold. */
fraction: number;
}BookGroup
One group of the book.
| Field | Type | |
|---|---|---|
type | number | |
name | string | null | Its name in the player's language; null for a group the client has not named. |
total | number | |
earned | number | |
left | number | |
entries | BookEntry[] |
EarnedAchievement
An achievement just earned, with the stat change that earned it.
type EarnedAchievement = AchievementEntry & { userVarId: number; value: number }Stat
One of the server's user variables as the client caches it.
| Field | Type | |
|---|---|---|
userVarId | number | |
value | number | |
type | number |
StatChange
A stat this client set: the update, and the value the client held before it.
type StatChange = StatUpdate & { previous: number | null }StatUpdate
A stat the server changed, and the achievements the change earned.
| Field | Type | |
|---|---|---|
userVarId | number | |
value | number | |
achievements | AchievementEntry[] |
AchievementShown
An achievement shown in the trophy viewer.
| Field | Type | |
|---|---|---|
type | number | |
index | number | |
name | string | |
description | string | |
progress | string |