Est. 2002 Intermediate

Warcraft 3 Jass

JASS, Blizzard's event-driven scripting language for Warcraft III — the compile target of the World Editor's visual triggers, the language DotA was written in, and the on-ramp that turned countless map makers into programmers.

Created by Blizzard Entertainment

Paradigm Procedural, Event-driven
Typing Static, strong; case-sensitive, with a fixed hierarchy of engine handle types
First Appeared 2002
Latest Version JASS2 — the dialect shipped with Warcraft III since 2002, still bundled with the game as of the 2.0 patch era (major 2.0.0 update released November 13, 2024)

JASS — commonly expanded as Just Another Scripting Syntax — is the event-driven, procedural scripting language Blizzard Entertainment built into Warcraft III: Reign of Chaos (2002). Every Warcraft III map is, underneath, a JASS program: the World Editor’s famous point-and-click GUI triggers compile to JASS when a map is saved, Blizzard’s own campaigns and computer-opponent AI are written in it, and the game engine interprets it at runtime. The dialect that shipped with Warcraft III is formally JASS2, and its standard library comes in two layers that every modder learns by name: common.j, which declares the engine’s native functions, and Blizzard.j, a library of convenience wrappers (the “BJ functions”) written in JASS itself. For a generation of map makers, JASS was the first “real” programming language they ever read — usually discovered by converting a GUI trigger to custom text and seeing the code their clicks had been generating all along.

History & Origins

Blizzard designed Warcraft III’s modding stack as a two-layer system. On top sat the Trigger Editor’s visual Events–Conditions–Actions interface, aimed at newcomers. Underneath sat JASS, a complete textual language with functions, typed variables, control flow, and an API of hundreds of native functions reaching into nearly every corner of the engine — units, heroes, items, players, regions, timers, cinematics, terrain, and the camera. The two layers were deliberately connected: every GUI action corresponded to a JASS function call (usually a Blizzard.j wrapper around one or more natives from common.j), and the editor’s Convert to Custom Text command would irreversibly turn a visual trigger into the equivalent JASS, which became the community’s standard gateway from clicking to coding.

The naming hints at internal history: the game’s files identify the language as JASS2, suggesting an earlier in-house iteration, though Blizzard never documented a public “JASS1.” Even the expansion Just Another Scripting Syntax is community lore as much as official branding — it is the universally used expansion of the acronym, but Blizzard published essentially no formal documentation for the language at all. That vacuum shaped everything that followed: JASS’s manuals, tutorials, style rules, and best practices were written entirely by its users, on sites like wc3campaigns, TheHelper, and The Hive Workshop.

The Frozen Throne (July 1, 2003) expanded the native API and the editor together, and the timing was perfect. That same year, the modder Eul built Defense of the Ancients; its successor DotA: Allstars passed to Steve “Guinsoo” Feak in early 2004 and to IceFrog around 2005, growing into what is widely regarded as the most-played custom map on Battle.net and the blueprint for the MOBA genre. As DotA’s complexity grew, its logic migrated from GUI triggers into hand-written JASS — the language’s most famous single program.

Design Philosophy

JASS reads like a language designed to be safe to hand to a game’s entire player base:

  • Verbose, keyword-heavy syntax. Functions are declared function Foo takes nothing returns nothing … endfunction; assignment requires set; calling a function as a statement requires call; blocks end with endif, endloop, endfunction. The style is often compared to Pascal-family languages, and the explicitness makes generated code — which is what most JASS originally was — easy to read.
  • Static typing over engine handles. Beyond the primitives (integer, real, boolean, string, and code for function references), JASS exposes a fixed hierarchy of dozens of handle types — unit, player, timer, trigger, group, location, and so on — references to objects living inside the engine. You cannot define new types in plain JASS; the language’s type system is the game’s object model.
  • Event-driven by design. There is no main function; a map script wires up trigger objects with events (TriggerRegisterUnitEvent, timers, region entry), conditions, and action callbacks, and the engine dispatches. GUI’s Events–Conditions–Actions model is a direct rendering of this API.
  • Deliberate minimalism. No classes, no closures, no user-defined structures, single-pass compilation (functions must be declared before use), one-dimensional arrays only, and loop … exitwhen … endloop as the sole loop construct. The constraints kept the interpreter simple and map scripts sandboxed — and left an enormous amount of room for the community to build higher-level languages on top.

Key Features

A minimal JASS map script fragment — the kind produced by converting a “Hello, World!” GUI trigger — looks like this:

function Trig_Hello_Actions takes nothing returns nothing
    call DisplayTextToForce( GetPlayersAll(), "Hello, World!" )
endfunction

function InitTrig_Hello takes nothing returns nothing
    set gg_trg_Hello = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Hello, function Trig_Hello_Actions )
endfunction

Hand-written JASS shows more of the language: local variables, the loop/exitwhen construct, and the idioms the community developed for working with engine handles. This function counts the living units in a group using the classic FirstOfGroup loop, then nulls its handle locals — the standard discipline for avoiding the reference leaks that could degrade long games:

function CountLiving takes group g returns integer
    local integer total = 0
    local unit u
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g, u)
        if not IsUnitType(u, UNIT_TYPE_DEAD) then
            set total = total + 1
        endif
    endloop
    set u = null
    return total
endfunction

Other notable machinery:

  • Globals blocks. Map-wide variables are declared between globals and endglobals; GUI variables appear there with a udg_ prefix, and generated trigger objects with gg_trg_.
  • Natives and constants. native declarations in common.j bind script names to engine functions; constant marks immutable values and side-effect-free functions.
  • First-class-ish functions via code. function Foo can be passed where a code value is expected — how callbacks reach TriggerAddAction, ForGroup, and timer natives.
  • Cooperative “threads.” Trigger actions can call TriggerSleepAction (the GUI’s Wait action) to pause mid-execution while the game continues — an unusual capability for a 2002 scripting runtime, though its imprecise timing made the community treat waits warily.
  • Hashtables (since patch 1.24, 2009). Native two-key hashtables became the sanctioned way to attach arbitrary data to handles, replacing the notorious exploit they were introduced to kill (see below).

Evolution

JASS’s most dramatic chapter is the return bug. Because of a flaw in the interpreter’s return-type checking, a function could return a value of one type where another was expected — and the community turned this bug into its most important feature, using it to convert handles to integers and back (“H2I typecasting”), which enabled attaching data to units, building data structures, and ultimately the object-oriented systems that powered sophisticated maps. In 2009 the same flaw was shown to enable arbitrary code execution — a genuine security vulnerability, since custom maps are downloaded automatically from other players. Blizzard’s patch 1.24 (August 2009) closed the exploit and shipped native hashtables as the replacement; a large fraction of the ecosystem’s maps and libraries had to be rewritten, one of the more remarkable forced migrations in any language community.

The rest of JASS’s evolution happened largely outside Blizzard. Vexorian’s JassHelper compiler defined vJass, a superset adding libraries with initializers, structs, textmacros, and function interfaces, all compiling to plain JASS — distributed with the JASS NewGen Pack, a community-enhanced World Editor bundle that also included the pjass syntax checker. Vexorian later added Zinc, a terser alternate syntax; others built cJass; and the open-source WurstScript toolchain eventually offered a modern language, package manager, and IDE tooling that still targets JASS. When Blizzard resumed active development, patch 1.31 (2019) added a Lua virtual machine as an official alternative to JASS2, and Warcraft III: Reforged (January 28, 2020) carried both forward — through a rocky launch and into the 2.0.0 anniversary patch of November 13, 2024.

Current Relevance

JASS is still a working language. Reforged’s World Editor compiles GUI triggers to it by default, The Hive Workshop continues to review and host new JASS and vJass resources, and the enormous back catalog of classic custom maps — DotA versions included — is JASS through and through. New projects now weigh JASS against Lua (official since 1.31) and community languages like Wurst, but two decades of tutorials, libraries, and battle-tested systems give JASS an inertia no newcomer language in the ecosystem can match. Community documentation efforts such as the jassdoc project continue to catalogue the behavior — intended and buggy — of every native in the API.

There is no official standalone runtime: JASS runs only inside Warcraft III and its World Editor, so preservation of the language is tied to Blizzard’s stewardship of the game and to the modding community that keeps its tooling alive.

Why It Matters

JASS matters first as the language of consequence hiding inside a best-selling game. Millions of players were one Convert to Custom Text away from real code, and the programs they wrote changed the industry: the MOBA genre — today spanning League of Legends and Dota 2 — began as JASS scripts, and DotA’s maintainers went on to build those successors at Riot and Valve. Second, JASS is a case study in what a community does with a minimal language: given no official documentation, no structs, and a type-checking bug, modders produced manuals, style guides, object systems built on an exploit, full compilers for higher-level dialects, and — when patch 1.24 broke everything — a coordinated ecosystem-wide migration. Third, its architecture proved out a durable pattern: a readable textual language as the compile target of a visual scripting layer, which Blizzard carried into StarCraft II’s Galaxy and which echoes in every modern game editor that pairs visual scripting with real code underneath. Few languages so obscure by mainstream measures can claim so direct a line to so much of modern gaming.

Timeline

2002
Warcraft III: Reign of Chaos ships on July 3, 2002. Its maps, campaigns, and AI are scripted in JASS (the engine's script files identify the dialect as JASS2), and the bundled World Editor compiles every visual GUI trigger into JASS when a map is saved.
2003
The expansion Warcraft III: The Frozen Throne is released on July 1, 2003, substantially enlarging the native function API available to JASS map scripts alongside a much-expanded World Editor.
2003
Modder Eul builds Defense of the Ancients with the World Editor's trigger and scripting system. Its successor DotA: Allstars — maintained by Steve 'Guinsoo' Feak from early 2004 and by IceFrog from around 2005 — becomes what is widely regarded as the most-played custom map in the game's history and the template for the MOBA genre.
Mid-2000s
With Blizzard's active development winding down, community sites such as wc3campaigns and The Hive Workshop become JASS's de facto standards bodies. Vexorian's JassHelper compiler introduces vJass — adding libraries, structs, and textmacros that compile down to plain JASS — and tool bundles like the JASS NewGen Pack graft vJass, the pjass syntax checker, and editor extensions onto Blizzard's World Editor.
2009
After the community's long-exploited 'return bug' typecasting trick is shown to enable arbitrary code execution, Blizzard releases patch 1.24 (August 2009), closing the exploit, adding hashtable natives to replace the lost functionality, and raising the maximum map size from 4 MB to 8 MB. Existing maps that relied on return-bug typecasting have to be rewritten.
2010
StarCraft II ships with Galaxy, a new C-styled map scripting language that serves the same role JASS did in Warcraft III — the direct successor to Blizzard's GUI-triggers-over-script design.
2019
Patch 1.31 modernizes map scripting: Warcraft III gains a Lua virtual machine as an alternative to the JASS2 VM, along with new natives for custom UI frames and native damage-modification events available to both languages.
2020
Warcraft III: Reforged launches on January 28, 2020, replacing the classic client. JASS remains fully supported in the updated World Editor and continues to be what GUI triggers compile to.
2024
Warcraft III patch 2.0.0 arrives on November 13, 2024 during the Warcraft franchise's 30th-anniversary celebration — the game, its World Editor, and the JASS scripts of two decades of custom maps still running.

Notable Uses & Legacy

Defense of the Ancients: Allstars

The map that defined the MOBA genre is a JASS program. While early versions leaned on GUI triggers, later maintainers — especially IceFrog — pushed hero abilities, game rules, and performance-critical systems into hand-written JASS, making DotA Allstars one of the largest and most-played JASS codebases ever written.

Blizzard Entertainment campaigns and melee AI

The single-player campaigns of Reign of Chaos and The Frozen Throne are scripted in JASS via the same World Editor shipped to players, and the game's computer opponents run JASS-based AI scripts — modders could open Blizzard's own code and study it.

The Hive Workshop resource ecosystem

The largest surviving Warcraft III modding community hosts thousands of peer-reviewed JASS and vJass spells, systems, and libraries — damage-detection engines, missile systems, save/load codes — that map makers import into their own projects like packages.

Tower defense and custom-game classics

Battle.net custom-game staples — tower defenses such as Legion TD (whose creators later built the commercial standalone Legion TD 2), hero arenas, and sprawling RPG maps — were built on the World Editor's trigger-and-JASS scripting stack.

Community compiler tooling

JASS became a compile target in its own right: Vexorian's JassHelper (vJass and Zinc), cJass, and the open-source WurstScript toolchain all translate higher-level languages into plain JASS so their output runs inside the unmodified game.

Language Influence

Influenced

vJass Zinc Wurst Galaxy (StarCraft II)

Running Today

Run examples using the official Docker image:

docker pull
Last updated: