원클릭으로
wurst-beginner
Getting started with WurstScript for Warcraft 3 map development including project structure, first map, and basic spell creation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Getting started with WurstScript for Warcraft 3 map development including project structure, first map, and basic spell creation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
WurstScript community resources including example maps, libraries, frameworks, and project showcases for Warcraft 3 modding
WurstScript language reference covering syntax, types, classes, modules, generics, lambdas, and all language features for Warcraft 3 modding
WurstScript installation, project setup, build configuration, dependency management, and VSCode extension usage for Warcraft 3 modding
WurstScript standard library reference including closures, data structures, vectors, object editing, dummy units, and utility packages
WurstScript tutorials covering spell creation, legacy map migration, save/load systems, hot code reload, and advanced techniques
| name | wurst-beginner |
| description | Getting started with WurstScript for Warcraft 3 map development including project structure, first map, and basic spell creation |
This guide helps you get started with WurstScript for Warcraft III map development.
>wurst: New Wurst ProjectOr use CLI:
grill generate my-wurst-project
my-project/
_build/ # Generated content (don't edit)
.vscode/ # VSCode settings
imports/ # Files to import into map
wurst/ # Your .wurst code files
.gitignore
ExampleMap.w3x # Your terrain map
wurst_run.args # Run configuration
wurst.build # Project configuration
wurst.dependencies # Generated dependency links
Create wurst/Hello.wurst:
package Hello
init
print("Hello World")
Run with F1 -> >runmap
Every .wurst file contains exactly one package:
package MyPackage
import SomeLibrary // import other packages
// Global variables
let myGlobal = 42
// Functions
function myFunction()
print("Hello")
// Init block runs on map start
init
myFunction()
The stdlib provides wrappers and utilities. Example:
package SpellExample
import ClosureTimers
import ClosureForGroups
import ClosureEvents
init
EventListener.onPointCast(MY_SPELL_ID) (caster, targetPos) ->
flashEffect("Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", targetPos)
doAfter(0.5) ->
forUnitsInRange(targetPos, 300) u ->
if u.isEnemyOf(caster)
caster.damageTarget(u, 100)
// Jass style (avoid)
local integer id = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
// Wurst style (preferred)
let id = GetTriggerUnit().getOwner().getId()
// Instead of
let u = createUnit(player, UNIT_ID, pos, angle)
SetUnitX(u, newX)
SetUnitY(u, newY)
u.addAbility(ABILITY_ID)
// Use cascade
createUnit(player, UNIT_ID, pos, angle)
..setX(newX)
..setY(newY)
..addAbility(ABILITY_ID)
// Explicit (verbose)
unit u = CreateUnit(...)
// Inferred (preferred)
let u = createUnit(...)
var health = u.getHP()
Wurst has built-in vector types:
import Vectors
let pos = vec2(100, 200)
let pos3d = vec3(100, 200, 50)
// Operations
let sum = pos + vec2(10, 10)
let scaled = pos * 2
let length = pos.length()
let normalized = pos.norm()
let angle = pos.angleTo(otherPos)
package MySpell
import ClosureEvents
import DamageSystem
public constant MY_SPELL_ID = 'A000'
init
EventListener.onCast(MY_SPELL_ID) caster ->
let target = EventData.getSpellTargetUnit()
caster.damageTarget(target, 100, ATTACK_TYPE_MAGIC)
package TimedSpell
import ClosureTimers
import ClosureEvents
init
EventListener.onPointCast(SPELL_ID) (caster, pos) ->
var ticks = 0
doPeriodically(0.5) cb ->
ticks++
flashEffect(FX_PATH, pos)
if ticks >= 10
destroy cb
Create WC3 objects without the World Editor:
package MyObjects
import AbilityObjEditing
@compiletime function createSpell()
new AbilityDefinitionFireBolt('A001')
..setName("Super Bolt")
..setTooltipNormal(1, "Super Bolt")
..setTooltipNormalExtended(1, "Deals 100 damage")
..setDamage(1, 100)
..setCooldown(1, 10)
..setManaCost(1, 50)
>runmap>buildmap_build/ folderAdd a library:
grill install https://github.com/some/library
Update dependencies:
grill install
print() for quick debuggingLog.info(), Log.warn(), Log.error() for structured loggingimport ClosureEvents
init
EventListener.add(EVENT_PLAYER_UNIT_DEATH) ->
let dying = GetTriggerUnit()
let killer = GetKillingUnit()
// handle death
import ClosureTimers
init
doPeriodically(1.0) cb ->
// runs every second
doAfter(5.0) ->
// runs once after 5 seconds
import HashMap
let unitData = new HashMap<unit, MyData>()
function saveData(unit u, MyData data)
unitData.put(u, data)
function getData(unit u) returns MyData
return unitData.get(u)