eAthena Script
The C-like NPC scripting language of the eAthena Ragnarok Online server emulator - a tab-delimited, sigil-scoped dialect that taught a generation of private-server admins to program, and that survives today inside rAthena and Hercules.
Created by The Athena development community - inherited from the Japanese Athena (jAthena) project begun in late 2002, and carried into eAthena after AppleGirl, Akaru and RoVeRT forked AppleMod in early 2004
eAthena Script is the NPC scripting language of eAthena, the open-source Ragnarok Online server emulator that dominated the private-server scene from the mid-2000s onward. It is a small, C-flavored, event-driven language with exactly two data types, no user-defined structures, and a variable-scoping system expressed entirely through punctuation prefixes. It was never designed as a general-purpose language and never escaped its host application - but because eAthena is generally credited with powering a large share of Ragnarok Online private servers, an enormous amount of code was written in it, much of it by hobbyists running game servers from home.
The language is interesting less for its design than for its role: it is a case study in how an embedded content-authoring DSL, written by volunteers to serve one game, becomes a durable programming culture with its own idioms, reference manual, style conventions and multi-generation lineage.
History and Origins
The story begins not with eAthena but with Athena, a Ragnarok Online server emulation project started in late 2002 by Japanese developers. Non-Japanese speakers came to call it jAthena. Athena was written in C and split the server into three cooperating processes - a login server, a character server and a map server - with the map server carrying the interpreter for NPC scripts.
In late 2003, a developer using the handle AppleGirl created AppleMod, originally an English translation of the Athena codebase together with a set of modifications. Translating Athena meant translating the script engine’s command names, documentation and bundled NPC content - the point at which the language began to diverge into its own English-language dialect.
In early 2004, AppleGirl, Akaru and RoVeRT merged their work on the AppleMod base and renamed the result eAthena - short for English Athena - establishing it as a collectively maintained fork rather than a downstream patch set. This 2004 rename is the conventional birth date of eAthena and of eAthena Script as a named thing, though the engine’s roots reach back to the 2002 Athena codebase.
eAthena was open source, distributed under the GNU General Public License, and written in C with zlib and MySQL among its principal dependencies. The project described itself as cross-platform and reportedly shipped build files for both Unix-like systems and Microsoft Visual Studio, though its own documentation concerns itself with configuration rather than publishing a formal list of supported operating systems or architectures.
Design Philosophy
eAthena Script exists to answer one question: how does a non-programmer describe what an NPC does? Everything about the language follows from that.
Content lives in text files, not in the database. An NPC is a line of tab-delimited text in a .txt file under npc/, loaded at server start. There is no separate compile step visible to the author, no build system, and no packaging - you edit a file, reload the scripts, and talk to your NPC.
Two types, and no more. The reference manual is blunt on this point: values are either integers or strings, distinguished by whether the variable name ends in $. There are no floats, no records, no objects. Arithmetic on fractions simply is not available, which shapes how game formulas get written - everything becomes integer math with scaling factors.
Scope is punctuation. Rather than declarations, lifetime and visibility are encoded in a sigil prefix on the variable name. This is the single most distinctive feature of the language and the thing every eAthena author internalizes first.
The interpreter is the game. Script commands are not a general standard library; they are verbs about the game world - getitem, warp, mes, set Zeny, monster, announce. The language’s vocabulary is the game’s feature set, which is why the command reference grew continuously as the emulator chased the commercial client’s features.
Key Features
The NPC object header
Every script object is introduced by a tab-delimited header line. The manual gives the form:
<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
with an extended variant adding a trigger area:
<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
Reusable functions get their own object form:
function%TAB%script%TAB%<function name>%TAB%{<code>}
The %TAB% notation in the documentation is literal: the separators must be actual tab characters, not spaces. This is one of the language’s most notorious beginner traps, since the distinction is invisible in most editors and produces a load error rather than a syntax error.
Variable scoping by sigil
The reference manual’s scope table is the canonical summary:
| Prefix | Scope and extent |
|---|---|
| (none) | Permanent character variable |
@ | Temporary character variable |
$ | Global permanent variable |
$@ | Global temporary variable |
. | NPC variable |
.@ | Scope variable (local to the current function or event invocation) |
# | Permanent local account variable |
## | Permanent global account variable, shared across servers in a group |
A trailing $ on the name makes the variable a string rather than an integer - so .@name$ is a script-local string, while #cashpoints is an integer persisted per account. Permanent variables are written through to the character or account database automatically; there is no explicit save call.
Event labels
Execution entry points are named labels with an On prefix, and the server invokes them rather than the player:
OnInit- runs once when scripts are loaded, typically used to set up shop stock, hide NPCs or seed stateOnTouch- fires when a player walks into the NPC’s declared trigger areaOnClock<HHMM>- fires at a wall-clock time, giving scripts a cron facilityOnAgitStart/OnAgitEnd- fire at the start and end of War of Emperium, the game’s guild-siege mode
This label-as-callback convention is how a fundamentally procedural language expresses a reactive, always-on game world.
Control flow and dialogue
Control structures are deliberately familiar to anyone who has seen C: if/else, switch/case, for, while, do-while, and goto for jumping to labels (which the manual discourages). Functions can be invoked as separate script objects via callfunc or as local labels via callsub, with arguments retrieved through getarg(index).
The dialogue primitives are what most scripts spend their time on. mes prints a line into the NPC’s dialogue window, next renders a “Next” button and waits, and close renders “Close” and ends the conversation. Item transactions use getitem <item id>,<amount>; and delitem <item id>,<amount>;. A complete, useful NPC can be written with those five commands alone - which is precisely the point, and precisely why the language spread.
Evolution
The language grew by accretion rather than by design revisions. There were no numbered releases of “eAthena Script”; instead, the bundled doc/script_commands.txt served as both specification and changelog, and its version string is the closest thing the language has to a version number. The copy in the repository reads 3.50.20120416 and describes itself as “a reference manual for the eAthena scripting language,” with commands sorted by functionality.
That document is also an honest artifact of how the language was specified. It states plainly that its information comes from reading server source code written by many developers over time, and warns that “anything written in here might not be correct, it is only correct to the best of our knowledge, which is limited.” Its credits list reads as a roster of the project’s scripting-side contributors, naming community handles such as Lupus, Skotlex, FlavioJS, ultramage and L0ne_W0lf among many others. The language, in other words, was documented by archaeology of its own implementation - an unusually literal example of the practice.
Upstream development wound down in the early 2010s; the project’s repositories are reported to have received their last trunk revisions in 2012. Fork discussion had already appeared on community boards by then, and rAthena emerged as the continuation of the codebase. Hercules then diverged from rAthena in early 2013, pursuing greater stability, a plugin architecture and its own scripting extensions.
Both descendants inherited the script engine essentially intact. rAthena’s doc/script_commands.txt is recognizably the same document, still opening with the same disclaimer about not being a tutorial, still carrying the same tab-delimited NPC header syntax and the same sigil scope table - extended with an additional ' prefix for instance variables introduced by the instancing system. That continuity is the reason a quest script written for eAthena in 2008 will, more often than not, still load on a modern server.
Current Relevance
eAthena itself is dormant. Its website has continued to serve the archived source tree and HTML readme pages as a kind of standing monument, but no new commits arrive. There is no official Docker image, no package-manager presence, and no standards body; the only way to run eAthena Script is to build the C server or one of its descendants.
The dialect, however, is very much alive. Anyone writing NPC content for rAthena or Hercules in 2026 is writing eAthena Script with extensions, using the same tab-delimited headers, the same mes/next/close dialogue rhythm and the same .@ scope prefix that eAthena settled on. Scripts continue to circulate on community boards, and the accumulated corpus from eAthena’s dominant years remains a live dependency for servers that never migrated their custom content.
Why It Matters
eAthena Script is a good argument that a language’s importance is not the same as its sophistication. By any conventional measure it is unremarkable: weakly typed, two-typed, tab-sensitive, specified by a document that admits it might be wrong, and inseparable from a single game. Yet it was the authoring interface for a large share of Ragnarok Online private servers during that game’s most active years, and for a large number of people it was the first language they wrote anything real in - not a tutorial exercise, but a working system other people used every day.
It also demonstrates a pattern common to game-modding languages and rare elsewhere: survival by fork. The original project stopped in 2012, but because the language was open source and its user base had content they refused to abandon, the community carried the interpreter forward twice - into rAthena and then into Hercules - preserving source compatibility as the explicit constraint. The language outlived its implementation because the scripts outlived the server.
Timeline
Notable Uses & Legacy
Ragnarok Online private servers
eAthena was, in the early period of Ragnarok Online emulation, widely reported as the most influential and popular server software, and is generally credited with powering a large share of RO private servers. Every quest chain, NPC dialogue tree, warp portal, shop and event on those servers was written in eAthena Script, making it one of the most widely written game-scripting dialects of its era despite never appearing outside the RO ecosystem.
The bundled npc/ script library
eAthena ships a large tree of official-content scripts under npc/, loaded by the map server through conf/map_athena.conf and npc/scripts_main.conf. These files reimplement the commercial game's town NPCs, job-change quests, guild siege (War of Emperium) logic and item-exchange systems entirely in the script language, and served as the de facto style guide and worked-example corpus for everyone learning the dialect.
rAthena
rAthena continues the eAthena codebase and its scripting engine. Its doc/script_commands.txt is a direct lineal descendant of the eAthena manual, retaining the same NPC header syntax, sigil-based variable scoping and event-label conventions - which is why scripts written for eAthena a decade ago still largely load on modern rAthena servers.
Hercules
Hercules forked from rAthena in early 2013 and extended the same script language, adding its own scripting facilities alongside a plugin architecture for the C server core. It represents the second surviving branch of the eAthena scripting lineage.
Community script archives and tooling
A cottage industry of mirrored command references, script-release boards and third-party editors grew up around the dialect - independent copies of the eAthena script command reference were widely mirrored, and community sites hosted large collections of user-contributed NPC scripts. For many hobbyists running a server in the mid-2000s, eAthena Script was the first programming language they ever wrote.