Tutorial What happens to JASS

yes9111

New Member
Reaction score
8
What happens to JASS?
Introduction

We all have heard of JASS and what it is. Some of us have even used it and are pretty good at coding with it.

This tutorial will explain what happens to the JASS code that you write in WE and how you might take advantage of this "what happens behind the scenes" knowledge.

Limited JASS

Sure- We all know how much more powerful JASS is than GUI triggering. It allows the use of local variables, your own functions, more control over global variables etc...

However, as you get to know JASS, or have some programming background, you'll see that JASS is almost extremely limited in comparison with almost any other programming language. (C, Java, Python, anything)

Especially if you have some C, C++ experience, you'll see that JASS is almost completely different. (well maybe not)

A slice of JASS

To really see what happens behind the the scene, go type in some erroneous code anywhere in the trigger editor ( as custom text/JASS ).

Then try to SAVE the map.

In NewGenEditor (almost everyone uses that now anyways), you'll see that you can move up and down in the code.

What you have in front of you is the complete map script.

JASS isn't just what YOU use to program spells, triggers, systems but it's what Warcraft 3 actually uses code all maps. When people say JASS, it's usually the programming language you can use to make your own scripts but everything in a map is JASS. (Except data like unit attacks, hp, and other things)

So a complete map script. (That has no triggers in it)
JASS:
globals
    // Generated
    trigger                 gg_trg_Melee_Initialization = null

endglobals
//===========================================================================
// 
// Just another Warcraft III map
// 
//   Warcraft III map script
//   Generated by the Warcraft III World Editor
//   Date: Tue Oct 30 15:36:26 2007
//   Map Author: Unknown
// 
//===========================================================================

//***************************************************************************
//*
//*  Global Variables
//*
//***************************************************************************


function InitGlobals takes nothing returns nothing
endfunction

//***************************************************************************
//*
//*  Custom Script Code
//*
//***************************************************************************
//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************
//===========================================================================
function InitCustomTriggers takes nothing returns nothing
endfunction
//===========================================================================
//***************************************************************************
//*
//*  Players
//*
//***************************************************************************

function InitCustomPlayerSlots takes nothing returns nothing

    // Player 0
    call SetPlayerStartLocation( Player(0), 0 )
    call SetPlayerColor( Player(0), ConvertPlayerColor(0) )
    call SetPlayerRacePreference( Player(0), RACE_PREF_HUMAN )
    call SetPlayerRaceSelectable( Player(0), true )
    call SetPlayerController( Player(0), MAP_CONTROL_USER )

endfunction

function InitCustomTeams takes nothing returns nothing
    // Force: TRIGSTR_002
    call SetPlayerTeam( Player(0), 0 )

endfunction

//***************************************************************************
//*
//*  Main Initialization
//*
//***************************************************************************

//===========================================================================
function main takes nothing returns nothing
    call SetCameraBounds( -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )
    call SetDayNightModels( "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )
    call NewSoundEnvironment( "Default" )
    call SetAmbientDaySound( "LordaeronSummerDay" )
    call SetAmbientNightSound( "LordaeronSummerNight" )
    call SetMapMusic( "Music", true, 0 )
    call InitBlizzard(  )

//! initstructs

//! initdatastructs
    call InitGlobals(  )
    call InitCustomTriggers(  )
    call RunInitializationTriggers(  )

endfunction

//***************************************************************************
//*
//*  Map Configuration
//*
//***************************************************************************

function config takes nothing returns nothing
    call SetMapName( "Just another Warcraft III map" )
    call SetMapDescription( "Nondescript" )
    call SetPlayers( 1 )
    call SetTeams( 1 )
    call SetGamePlacement( MAP_PLACEMENT_USE_MAP_SETTINGS )

    call DefineStartLocation( 0, -576.0, -1024.0 )

    // Player setup
    call InitCustomPlayerSlots(  )
    call SetPlayerSlotAvailable( Player(0), MAP_CONTROL_USER )
    call InitGenericPlayerSlots(  )
endfunction


This may be the first time you see the function MAIN, plus all these other functions that you have never declared. These are JASS code automatically made for every map.

Here, you'll see that JASS is NOT so different from C =D

JASS:
function main takes nothing returns nothing
    call SetCameraBounds( -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )
    call SetDayNightModels( "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl", "Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )
    call NewSoundEnvironment( "Default" )
    call SetAmbientDaySound( "LordaeronSummerDay" )
    call SetAmbientNightSound( "LordaeronSummerNight" )
    call SetMapMusic( "Music", true, 0 )
    call InitBlizzard(  )

//! initstructs

//! initdatastructs
    call InitGlobals(  )
    call InitCustomTriggers(  )
    call RunInitializationTriggers(  )

endfunction


IT'S A MAIN FUNCTION!.
That's right. It's a main() function.

Just a review for programmers.
main functions are always the first function executed when the map starts. Nono, it's not a trigger. It's a function that is SUPPOSED to be run when the map starts!

Ever wondered why those InitTrig_XXXXXXX functions ALWAYS run at the start of the map? Here is where the mystery unfolds.

JASS:
    call InitCustomTriggers(  )


This function was defined way up in the map script.

JASS:
//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************
//===========================================================================
function InitCustomTriggers takes nothing returns nothing
endfunction


As of now, the function is empty because there were no triggers in the map when I saved it.
But!
Watch what happens when you actually add triggers.

JASS:
//***************************************************************************
//*
//*  Triggers
//*
//***************************************************************************

//===========================================================================
// Trigger: newtrig
//===========================================================================
function Trig_newtrig_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_newtrig_Actions takes nothing returns nothing
    call DoNothing(  )
endfunction

//===========================================================================
function InitTrig_newtrig takes nothing returns nothing
    set gg_trg_newtrig = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_newtrig, Player(0), EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_newtrig, Condition( function Trig_newtrig_Conditions ) )
    call TriggerAddAction( gg_trg_newtrig, function Trig_newtrig_Actions )
endfunction

//===========================================================================
// Trigger: haha
//===========================================================================
function Trig_haha_Actions takes nothing returns nothing
    call AdjustPlayerStateBJ( 1000, Player(0), PLAYER_STATE_RESOURCE_GOLD )
endfunction

//===========================================================================
function InitTrig_haha takes nothing returns nothing
    set gg_trg_haha = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_haha, 2 )
    call TriggerAddAction( gg_trg_haha, function Trig_haha_Actions )
endfunction

//===========================================================================
function InitCustomTriggers takes nothing returns nothing
    call InitTrig_newtrig(  )
    call InitTrig_haha(  )
endfunction


When you save the map, it automatically ADDS the two InitTrig function from my two triggers and calls it in the InitCustomTriggers function which in turn
was called from the main function which was called when the map started.

So that's the magic behind InitTrig functions which also explains why WE demands a InitTrig in every trigger block that you write.

To sum up everything so far.

  1. "Trigger blocks" that you create in the map through the trigger editor is actually only a small portion of JASS.
  2. the Map's code is complete with your JASS for triggers and the maps complete code


So, you learn that the building blocks of your maps aren't triggers, it's FUNCTIONS. Everything about triggers - the actions, and even the conditions are all just functions.

Based on what I know, I don't think there is a tool that allows you to edit the map scripts besides the triggers, but having this sort of fundamental knowledge is useful.

For example, those Map Initialization triggers that we use
Some of us may have taken advantage of the this one-time fire event right at the beginning of this map to initialize values. For example, Save/Load codes. You might initialize the values of the variables by creating a trigger, making it fire with the Map Initialization event, and then add the code as the trigger action that sets up all the variables for you.

NOTE - This does NOT work when manipulating Game elements like units or players. This is strictly for manipulation of things that can be manipulated even before map has loaded. This is before the preplaced units have been placed, and before the players start playing.

Why bother creating the trigger at all, honest? The InitTrig function automatically runs when the map is being loaded, so why not just call the Initialization function from that function?

JASS:

function InitTrig_INITIALIZE_VARS takes nothing returns nothing
    set NUM_HEROES = 5
    set NUM_PLAYERS = 4
    set INITIALIZEVAR = 3    
endfunction


Make sure the trigger block is titled "INITIALIZE VARS" of course. That way the map script automatically produced will call this InitTrig function.

One more note about what WE does for your triggers and how it changes it into JASS.

Have you also wondered how the InitTrig's always seem to have a global trigger variable available for use? It's not that surprising to see that WE automatically declares a global trigger variable for each trigger block that you create in the Trigger Editor.

JASS:

globals
    // Generated
    trigger gg_trg_Random_Trigger_1 = null
    trigger gg_trg_Random_Trigger_2 = null
    trigger gg_trg_HAHA_HOHO = null
    trigger gg_trg_Trigger_001 = null
endglobals


Note, trigger variables are handles and handles by themselves don't take up that much memory. When you use the CreateTrigger() function, the trigger is actually created and that takes up more memory.

Wrapping Up
Have fun with this knowledge, whether you knew about it or not. I myself only saw JASS for triggering until I stumbled onto this. There may not be many practical uses for this, but it's always good to know how something works. :D
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
>>What the hell would I want to know this for?
You need to know this for hacking a map. >.>

Well, I personally don't feel bad about this tutorial, it gives knowledge to other people.
 

chovynz

We are all noobs! in different states of Noobism!
Reaction score
130
Sorry. The tutorial didn't make any sense to me. There were some bits in there that did, but they were so simply...obvious I was wondering why yes9111 even bothered to mention them. I don't know what its for, so I dont need to know. I'm quite happy obliviously making functions the normal way.

Edit: I decided to comment. I don't know if it'll help the tutorial in anyway but...here goes.

"...you'll see that JASS is almost extremely limited in comparison with almost any other programming language." - So what? You're not coding in those other languages.

"In NewGenEditor (almost everyone uses that now anyways)," - BS***. I wish they would.

"...everything in a map is JASS. (Except data like unit attacks, hp, and other things)." Actually I think you're not right there. Everything in a map is JASS. Including unit attacks, hp

"So, you learn that the building blocks of your maps aren't triggers, it's FUNCTIONS. Everything about triggers - the actions, and even the conditions are all just functions." - Are you talking to Jassers or GUIers in this tutorial? Because this sentence sounds like your talking to GUIers. Who absolutely have no need for any of this information. If you are talking to JASSers then they already know this.

"Based on what I know, I don't think there is a tool that allows you to edit the map scripts besides the triggers, but having this sort of fundamental knowledge is useful." - Useful tools section. You'll find some MPQ editors. In fact, a number of JASSers just use Notepad.

"Have you also wondered how the InitTrig's always seem to have a global trigger variable available for use? It's not that surprising to see that WE automatically declares a global trigger variable for each trigger block that you create in the Trigger Editor." - That is because globals are the way to go. Go global!

Sorry. This tutorial isn't doing anything for me. I can see no point to it, JASSers will already know certain parts of it, and GUIers have no need of it. However I'll +rep you for it because you seem to have spent a bit of time on it and your grammar and spelling and attitude about it is great.
 

yes9111

New Member
Reaction score
8
Sorry. The tutorial didn't make any sense to me. There were some bits in there that did, but they were so simply...obvious I was wondering why yes9111 even bothered to mention them. I don't know what its for, so I dont need to know. I'm quite happy obliviously making functions the normal way.

Edit: I decided to comment. I don't know if it'll help the tutorial in anyway but...here goes.

"...you'll see that JASS is almost extremely limited in comparison with almost any other programming language." - So what? You're not coding in those other languages.

"In NewGenEditor (almost everyone uses that now anyways)," - BS***. I wish they would.

"...everything in a map is JASS. (Except data like unit attacks, hp, and other things)." Actually I think you're not right there. Everything in a map is JASS. Including unit attacks, hp

"So, you learn that the building blocks of your maps aren't triggers, it's FUNCTIONS. Everything about triggers - the actions, and even the conditions are all just functions." - Are you talking to Jassers or GUIers in this tutorial? Because this sentence sounds like your talking to GUIers. Who absolutely have no need for any of this information. If you are talking to JASSers then they already know this.

"Based on what I know, I don't think there is a tool that allows you to edit the map scripts besides the triggers, but having this sort of fundamental knowledge is useful." - Useful tools section. You'll find some MPQ editors. In fact, a number of JASSers just use Notepad.

"Have you also wondered how the InitTrig's always seem to have a global trigger variable available for use? It's not that surprising to see that WE automatically declares a global trigger variable for each trigger block that you create in the Trigger Editor." - That is because globals are the way to go. Go global!

Sorry. This tutorial isn't doing anything for me. I can see no point to it, JASSers will already know certain parts of it, and GUIers have no need of it. However I'll +rep you for it because you seem to have spent a bit of time on it and your grammar and spelling and attitude about it is great.

I agree that knowing this doesn't allow the same possibilities as it did with many other tutorials/systems (The XXCache systems/Handle Vars)

But I'm a loser obsessed with why things work so
=D

Sorry it did not help you much. =(
 

chovynz

We are all noobs! in different states of Noobism!
Reaction score
130
Code:
But I'm a loser obsessed with why things work so =D
:D Hilarious! Believe it or not, I understand. I dont think your a loser though. You've obviously taken some time in researching it to make this tutorial and it's well written.

Even if it is retentive in its attention to detail ;)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top