A one-page guide for anyone changing the map. For where things are, read docs/SYSTEMS.md.
- Warcraft III Reforged and its World Editor.
- JassHelper on: in the Trigger Editor, open the JassHelper menu and tick Enable JassHelper
and Enable vJass. The map is vJass: libraries,
globalsblocks andstatic if. Without JassHelper it does not compile. - Python 3 (any recent version), for the checks in
tools/. - pjass:
tools/check_map.pyuses it to compile-check the script. Putpjass.exe(orpjasson Linux/macOS) intools/bin/next tocommon.jandblizzard.j. - Git (optional, but recommended): it records each change, so a bad one can be undone.
For edits to existing source modules, use build.ps1 instead of manually assembling a playable map:
.\build.ps1 -Stage AB. It runs the complete development
gates and records a new map/report/manifest without overwriting outputs. See docs/BUILDS.md for
requirements and the handling of new modules, object data, header/global changes and historical drift.
Keep .j sources in CRLF. After every build, add one STAGES.md row (one sentence) and update HANDOFF.md only if the current state changed;
play-test changed gameplay. Commit only the files belonging to your change.
For World Editor changes:
- Open the Reforged master in
baseline/Reforged/or the newest Reforged build inrelease/. - Make the change and Save As under a new name, for example
FFERPG_0.9.7.3-r16.w3x. Never overwrite the only working copy. - Run the checks:
python tools/check_map.py <your map>.w3x --baseline baseline/Reforged/FFERPG_0.9.7.3-r16.w3x. All must say PASS. Check 6 compares startup with the baseline, so expect it to report the triggers you added or removed on purpose. - Play test what you changed, plus a quick save code (
-save, then-loadin a new game). - Record it:
python tools/export_sources.py <your map>.w3x- Review exported source differences and stage only the intended changes.
git commit -m "what changed"
- Generate its classic copy:
.\make_129.ps1 -Map <your map>.w3x; test both clients. Promote a new paired baseline deliberately, updating its manifest and build-config hash.
| You are adding … | Put it … |
|---|---|
| A trigger for an existing system | In that system's module (one World Editor trigger per module, e.g. Arena_Rounds). |
| A new system | A new custom-text trigger in the right folder, starting with library T<Name> (no underscores in the library name). |
| A trigger that starts at map start | Create it in a Register_<Trigger> function. Add a call to it in that module's RegisterTriggers_<Module> function at the bottom of the module. |
| A variable only your module uses | Declare it in the module's globals block at its top. |
| A variable several modules share | Add it in the Variable Editor (Ctrl+B), in the matching "Shared variables" sub-folder. |
| Long text (quest log, help, dialogue over ~1000 characters) | Use GUI actions (string table), not custom script. Very long script strings break loading saved games. |
| A new spell | Copy a small Spell_* module. |
| A new boss | Copy a small Boss_* module. See docs/BOSSES.md. |
- Modules: a module
Foois the triggerFoowithlibrary TFoo. Its triggers aregg_trg_Foo_*and its functions areTrig_Foo_*. - Startup helpers:
Register_<Trigger>creates one trigger: its events, conditions and actions.RegisterTriggers_<Module>lists them in startup order. - Variables: shared variables use the
udg_prefix in code. The Variable Editor shows them without the prefix. - Object IDs: add the object's name as a comment, e.g.
'A0B3' // 'A0B3': ability "Cover". - Calculation comments: only for calculations with some complexity (a formula with several steps,
e.g. a damage or reward formula). Don't comment
+5, a random roll or a single multiplication: the code already says it. Prefer saying why (what the formula is for) over restating the math.tools/refactor/trim_calc_comments.pyremoved the old word-for-word ones on simple lines.
- Save codes: don't reorder
udg_JobUnitType, the item table, or anythingSave_WriteCodewrites. Readdocs/SAVE_CODES.mdfirst. - Calling another module: a module that calls into another needs
requires T<Other>, orrequires optional T<Other>with astatic if LIBRARY_T<Other>guard. Then that module can be switched off (docs/DISABLING.md). - The damage formula: it lives in
Damage, asTrig_Damage_Engine_Step01_Setup…Step19_Apply. Keep a hit's values in theDmgCtx_*arrays (slotc), never in plain globals. Hits can nest. - Player numbers:
Player(0)–Player(7)are the humans,Player(8)holds the town NPCs, andPlayer(11)is the enemy.
| Command | Use it to |
|---|---|
python tools/disable_check.py MAP Module |
Check whether a module can be switched off. |
python tools/gen_docs.py |
Refresh docs/TRIGGER_INDEX.md, GLOBALS.md and DEAD_CODE.md after changes. |
python tools/rename_module.py BASE OUT Old New |
Rename a module everywhere. |
Worked new-content examples: CONTENT_DEVELOPMENT.md.