The scripted world of Arkesia
The scripted world of Arkesia: what Lost Ark's client ships about its own logic
Every number in this article is measured from the NAEU client build
naeu-2026-08-03.
The game writes its own event scripts — and ships them to you
Most players assume an MMO's scripted moments — a town's welcome scene, a
boss's phase transitions, the cutscene that plays when you pick your advanced
class — live on the server. In Lost Ark, a surprising amount of that wiring
ships inside the client: one TriggerMapData.loa file per map, holding the
game's own visual-scripting format.
We parsed all of them. The corpus: 837 maps with triggers, 22,617 scripted units, 96,514 nodes across 112 distinct node classes. Each unit is one scripted event with three sections — conditions (when it fires), checks (gates), actions (effects):
Condition_VolumeProp "Enter"→10 "Leave"→11 # walk into/out of a zone
Check_PlayerClass "Yes"→21 "No"→22 # gate by class
Action_SceneEvent "Trision_Transfer_Berserker_01" # play cutscene
That last line is real data: every state string in a node is immediately followed by the index of the node it branches to, which makes the whole corpus a directed graph — 218,496 labelled branch edges that anyone can traverse. And the edges have shape: they wire predominantly same-class chains — each volume's On/Off states link sibling volume checks, each NPC condition's Event1–5 links its siblings — meaning every entity group runs its own little state machine, with cross-class dispatch only at unit entry. Lost Ark's designers built an event system out of per-entity state machines long before "visual scripting" was a buzzword.
What the graph knows about you
The single most revealing unit sits in map 10001 — Trixion, the tutorial island. One condition ("player signals ShipWreck") dispatches through 28 sequential class checks, each pairing a cutscene action with a prop change:
Check_PlayerClass → Yes → Action_SceneEvent "Trision_Transfer_<Class>_01"
→ No → next check
The class list recovered from those scene names is a museum piece: alongside every shipped advanced class sit Soulmaster, Stryker, Holyknight_F, Alchemist, Elemental_Master, YinYangShi, WeatherArtist — class identities that exist in the transfer wiring but not in this build's playable roster (the full 32-token list ships side-by-side with the roster; several are obvious rebrands).
Cut content doesn't get deleted from a shipped client; it just stops being reachable.
Timers and destinations, in plain floats
Once the field stream is readable, parameters fall out. Action_Delay nodes
carry their wait as an IEEE-754 float hidden inside the integer stream —
corpus-wide the values resolve to clean durations: 2.0 s (×944), 1.0 s (×932),
3.0 s, 0.5 s, out to 30 s. And Action_TeleportPlayer carries where it sends
you: a consecutive float triple of world-space coordinates, validated inside
the host map's bounds for 41 of 42 nodes. Scripted teleports frequently cross
maps entirely — the destination sits thousands of units outside the current
world's extent — which is how a quest walks you from one continent to another
without a loading screen lie. One thousand fifty-six such destinations are now
decoded.
What the client refuses to tell you
The same census that mapped the graph also measured its blind spot. Trigger
actions reference props and NPCs by small per-map actor indices — "actor
#12 of this map", never a global identity. And the placement files
(DeployData.loa) name only a sliver of their actors: across 434,943 actors
in 1,015 maps, exactly 1,139 identity references exist in the entire corpus.
Maps with 6,610 actors reference none.
This isn't a decode we're missing — there is nothing to decode. The client runs anonymous puppets and receives their identities from the server at runtime. Our placement layer captures every nameable actor (1,203 PK-validated edges, browsable on every zone page); the rest are permanently anonymous in any client copy.
Method notes (for the skeptics)
- Join claims carry hit-rates validated two independent ways; the mob→drop chain resolves 93.8% of drop-table refs by two different code paths.
- The extractor is guarded by a canary that fails on corpus drift after a silent string-loss bug was caught exactly this way.
- Everything unobtainable is labeled unobtainable: market prices, live drop rolls, quest state, and now bulk actor identity.