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.
  • Monovertex Monovertex:
    How are you all? :D
    +1
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though

      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