Tutorial GUI -> vJASS

Cohadar

master of fugue
Reaction score
209
I will now demonstrate how to switch from GUI to vJASS.

For those of you who think that it might be better to first learn JASS and then go for vJASS - you are wrong.

This is jass:
Code:
//===========================================================================
function InitTrig_HeroDiesJ takes nothing returns nothing
    set gg_trg_HeroDiesJ = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HeroDiesJ, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_HeroDiesJ, Condition( function Trig_HeroDiesJ_Conditions ) )
    call TriggerAddAction( gg_trg_HeroDiesJ, function Trig_HeroDiesJ_Actions )
endfunction

This is vJASS:
JASS:
//===========================================================================
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( trig, Condition( function Trig_HeroDiesJ_Conditions ) )
    call TriggerAddAction( trig, function Actions )
endfunction


First thing you notice is that jass does not have colors, this is only one of many reasons jass sux.
So lets all just forget about old rusty jass and go straight for vJass.

First of all you will need to download and learn how to use NewGen
It's all explained there.
When you download NewGen try to compile some of your GUI maps with it,
when you do it, come back here.

//===========================================================================

Now lets try converting some triggers from GUI to vJASS

Before we continue remember this:
You will NEVER be able to convert all GUI triggers in your map to jass,
it is impossible, GUI code generator is ugly like hell, it makes a ton of unnecessary gibberish and above all it does it with BJ's
GUI also mainly uses globals, while in jass you use locals.

Differences are simply too big, so basically GUI to JASS conversion is practically impossible for triggers longer than 5 actions.

Once you learn enough jass do NOT waste your time converting old GUI triggers, instead write them again in jass starting from zero.
It will be faster and easier.

Ok lets look at a simple GUI trigger:
Code:
HeroDies
    Events
        Unit - A unit Dies
    Conditions
        ((Triggering unit) is A Hero) Equal to True
    Actions
        Hero - Instantly revive (Dying unit) at (Center of (Playable map area)), Show revival graphics
When hero dies, revive him instantly at center of map.
This trigger might be simple but it has all we need, it has an Event, an Action and a Condition.

Lets see how it looks when we convert it to text:
(Select the trigger and go to Edit->Convert to Custom Text)
JASS:
function Trig_HeroDies_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_HeroDies_Actions takes nothing returns nothing
    call ReviveHeroLoc( GetDyingUnit(), GetRectCenter(GetPlayableMapRect()), true )
endfunction

//===========================================================================
function InitTrig_HeroDies takes nothing returns nothing
    set gg_trg_HeroDies = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HeroDies, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_HeroDies, Condition( function Trig_HeroDies_Conditions ) )
    call TriggerAddAction( gg_trg_HeroDies, function Trig_HeroDies_Actions )
endfunction


It looks ugly doesn't it?
Well check this out: WE does not know how to generate vJASS, what you are actually looking at is old stupid jass.
So all you can do is convert GUI to jass, if you want vJASS you have to do it yourself.

//===========================================
The First thing we need to do is put a scope around that jass to make it vJASS:
JASS:
scope HeroDies // <---------<<

function Trig_HeroDies_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_HeroDies_Actions takes nothing returns nothing
    call ReviveHeroLoc( GetDyingUnit(), GetRectCenter(GetPlayableMapRect()), true )
endfunction

//===========================================================================
function InitTrig_HeroDies takes nothing returns nothing
    set gg_trg_HeroDies = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HeroDies, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_HeroDies, Condition( function Trig_HeroDies_Conditions ) )
    call TriggerAddAction( gg_trg_HeroDies, function Trig_HeroDies_Actions )
endfunction

endscope // <---------<<

Advice: Making scope name same as your trigger name will save you a lot of trouble when hunting for errors.
There is one problem here. vJASS cannot have spaces or underscores in scope names (jet). So you will have to rename your triggers from:
"Do Some Stuff" to "DoSomeStuff"

//===========================================
Lets see how stupid WE generates code:
It converted this:
Code:
((Triggering unit) is A Hero) Equal to True

to this:
JASS:
function Trig_HeroDies_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true ) ) then
        return false
    endif
    return true
endfunction


But we will convert it to vJass now:
JASS:
private function Conditions takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) == true
endfunction

Who's my pretty boy :)
As you can see vJASS pwnz GUI generated jass.

//===========================================
Ok lets do the action now:
Code:
Hero - Instantly revive (Dying unit) at (Center of (Playable map area)), Show revival graphics

jass:
JASS:
function Trig_HeroDies_Actions takes nothing returns nothing
    call ReviveHeroLoc( GetDyingUnit(), GetRectCenter(GetPlayableMapRect()), true )
endfunction


vJASS:
JASS:
private function Actions takes nothing returns nothing
    call ReviveHero(GetDyingUnit(), 0, 0, true)
endfunction

Ok what happened now?
First of all we removed the whole GetRectCenter(GetPlayableMapRect()) thing.
We know that center of map is (0, 0) so instead of using ReviveHeroLoc we use ReviveHero function
{this also prevented location leak :)}
Ok but where did ReviveHero function come from?
How did I know what are it's arguments? Omg cohadar knows all jass functions :nuts:
Not even close.
What I know is how to use function list:
attachment.php

It is a cool feature in vJASS TESH editor,
you just type in few letters and it lists all functions that have that letters in name.
So it is even easier than finding functions inside GUI editor lists.

There is also a cool feature called autocompletion.
You type in a few first letters of a function inside a trigger: Rev
attachment.php

and a small pop-up window appears telling you what could be proper function names. :eek:
Damn this vJASS shit is easy.

But wait, it gets even better.
You type in the function name and a first bracket: ReviveHero(
attachment.php

and it pops up again showing you the arguments of the function.
Omg this vJASS shit is easier than GUI.

//========================================================
Lets get back to our trigger, we have one more thing to change, this:
JASS:
//===========================================================================
function InitTrig_HeroDies takes nothing returns nothing
    set gg_trg_HeroDies = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_HeroDies, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_HeroDies, Condition( function Trig_HeroDies_Conditions ) )
    call TriggerAddAction( gg_trg_HeroDies, function Trig_HeroDies_Actions )
endfunction

Ok where did this come from, there was no such thing in GUI?

Actually there was, it is the event:
Code:
Unit - A unit Dies
+ connecting all together.

Lets convert this to vJASS before we continue:
JASS:
//===========================================================================
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( trig, Condition( function Conditions ) )
    call TriggerAddAction( trig, function Actions )
endfunction


Create the trigger:
JASS:
local trigger trig = CreateTrigger()


Add event to the trigger:


Add condition to the trigger:
JASS:
 call TriggerAddCondition( trig, Condition( function Conditions ) )


Add action to the trigger:
JASS:
call TriggerAddAction( trig, function Actions )


So basically what Init does here is connects unit dies event with our functions.
Very important: vJass does not automatically know what is triggers InitTrig function so you have to specify it after scope declaration.
JASS:
scope HeroDies initializer Init 
// initializer function can have any name, I just personally prefer Init



This whole Init part might sound complicated but the fact is you don't have to learn it.

What you do is create a simple trigger with only an event:
For example spell effect:
Code:
StealLife
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
        (Ability being cast) Equal to StealLife 
    Actions

Convert it to jass:
JASS:
function Trig_StealLife_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A000' ) ) then
        return false
    endif
    return true
endfunction

function Trig_StealLife_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_StealLife takes nothing returns nothing
    set gg_trg_StealLife = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_StealLife, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_StealLife, Condition( function Trig_StealLife_Conditions ) )
    call TriggerAddAction( gg_trg_StealLife, function Trig_StealLife_Actions )
endfunction


and then to vJASS:
JASS:
scope StealLife initializer Init //<---<< don't forget to specify Init function

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

private function Actions takes nothing returns nothing
    // Add spell code here
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( trig, Condition( function Conditions ) )
    call TriggerAddAction( trig, function Actions )
endfunction

endscope


And than simply code the spell.
You do not have to remember how to do the whole TriggerAddCondition( trig, Condition( function Conditions ) ) stuff.

//======================================================
I attached a map with 2 simple triggers. Triggers are in GUI.
Your job is to convert them to vJASS as a practise.
All info you need to do that is in this tutorial,
and if you bump into any problems came here and tell us about it.

//======================================================
You might have noticed that a lot of things in this tutorial are not explained,
what is a scope, what is public, what is private?
why you change things the way you do?

This tutorial was meant to show you how to start coding vJASS the quickest way possible.

In order to learn why things are done they way the are,
and what do they mean you will have to learn yourself.

I do not believe that vJASS can be learned from tutorials,
you will simply have to code in vJASS every day and learn how and why to do things every day.
That is how you learned GUI didn't you?

//======================================================
TIP: There is a file jasshelper.html somewhere in NewGen directory, find it.
WARNING: When using NewGen always save map before you test it or it will not work.
ADVICE: Keep practising.
 

Attachments

  • flist.JPG
    flist.JPG
    12 KB · Views: 3,179
  • autoc1.JPG
    autoc1.JPG
    9.8 KB · Views: 3,112
  • autoc2.JPG
    autoc2.JPG
    14.4 KB · Views: 3,108
  • GUI2vJASS.w3x
    9.7 KB · Views: 401

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
>><UNDER CONSTRUCTION, DO NOT DISTURB>
LoL, why are you posting a half complete tutorial..??

Just asking another thing, why GUI to vJass but not Jass to vJass? :p
It looks like twise as harder for a GUI-er to switch from GUI to vJass without knowledge of vJass...
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
Going from GUI to JASS to then go to vJASS would be rather stupid.

Why not learn vJASS syntax from day 1, so you won't have to learn vJASS later on?
 

Ninja_sheep

Heavy is credit to team!
Reaction score
64
Why people only make tutorials for complet jass newbs? there are like 5 on this website and only 1-2 for something little more advanced.:mad::mad:
You could at least teach about some points that aren't teached in the tutorials: how to use conditions/events.

@tutorial:
Why should I learn vJass and not normal Jass? The features I get too by using jasscraft.
What is a 'public' and a 'privat'?


Whatever since the tutorial isn't finished my critism might be bad since you maybe wanted to add a few of the things above :<
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
Public = You can name it whatever you want and it won't collide with other functions/variables named that way outside the library/scope.

Upside: No "ggTrig_extremely_long_fucking_ugly_name_Actions" but "Actions"
Downside: to access it from outside the scope/library, you need to put the scope name and an underscore before it: "LibName_Actions"


Private = same upside as public, but you cannot(!!) access it from outside the library/scope



Why use privates? For easily making systems or spells that don't require their functions to be usable outside the library: In other words: to make using easy names over and over possible and to protect people from theirselves when using a spell/system of yours.
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
>>What is a 'public' and a 'privat'?
Private members

With the adition of libraries it was a good idea to add some scope control, private members are a great way of protecting users from themselves and to avoid collisions.
JASS:
library privatetest
    globals
        private integer N=0
    endglobals
    private function x takes nothing returns nothing
        set N=N+1
    endfunction

    function privatetest takes nothing returns nothing
        call x()
        call x()
    endfunction
endlibrary

library otherprivatetest
    globals
        private integer N=5
    endglobals
    private function x takes nothing returns nothing
        set N=N+1
    endfunction

    function otherprivatetest takes nothing returns nothing
        call x()
        call x()
    endfunction
endlibrary


Notice how both libraries have private globals and functions with the same names, this wouldn't cause any syntax errors since the private preprocessor will make sure that private members are only available for that scope and don't conflict with things named the same present in other scopes. In this case private members are only to be used by the libraries in which they are declared.

Sometimes, you don't want the code to go to the top of your script (it is not really a function library) yet you' still want to use the private keyword for a group of globals and functions. This is the reason we defined the scope keyword

The scope keyword has this syntax: scope NAME [...script block...] endscope

So, functions and other declarations inside an scope can freely use the private members of the scope, but code outside won't be able to. (Notice that a library is to be considered to have an internal scope with its name)

There are many applications for this feature:

JASS:
scope GetUnitDebugStr

    private function H2I takes handle h returns integer
        return h
        return 0
    endfunction

    function GetUnitDebugStr takes unit u returns string
        return GetUnitName(u)+&quot;_&quot;+I2S(H2I(u))
    endfunction
endscope


In this case, the function uses H2I, but H2I is a very common function name, so there could be conflicts with other scripts that might declare it as well, you could add a whole preffix to the H2I function yourself, or make the function a library that requires another library H2I, but that can be sometimes too complicated, by using an scope and private you can freely use H2I in that function without worrying. It doesn' matter if another H2I is declared elsewhere and it is not a private function, private also makes the scope keep a priority for its members.

It is more important for globals because if you make a function pack you might want to disallow direct access to globals but just allow access to some functions, to keep a sense of encapsullation, for example.

The way private work is actually by automatically prefixing scopename(random digit)__ to the identifier names of the private members. The random digit is a way to let it be truly private so people can not even use them by adding the preffix themselves. A double _ is used because we decided that it is the way to recognize preprocessor-generated variables/functions, so you should avoid to use double __ in your human-declarated identifier names. Being able to recognize preprocessor-generated identifiers is useful when reading the output file (for example when PJass returns syntax errors).

In order to use private members ExecuteFunc or real value change events you have to use SCOPE_PRIVATE (see bellow)

Hint:In a similar way to libraries, scopes used to have a syntax that required //! , that old syntax is still supported but it is being deprecated.
Public members

Public members are closely related to private members in that they do mostly the same, the difference is that public members don't get their names randomized, and can be used outside the scope. For a variable/function declared as public in an scope called SCP you can just use the declared function/variable name inside the scope, but to use it outside of the scope you call it with an SCP_ preffix.

An example should be easier to understand:

JASS:
library cookiesystem
        public function ko takes nothing returns nothing
            call BJDebugMsg(&quot;a&quot;)
        endfunction

        function thisisnotpublicnorprivate takes nothing returns nothing
             call ko()
             call cookiesystem_ko() //cookiesystem_ preffix is optional
        endfunction
    endlibrary

    function outside takes nothing returns nothing
         call cookiesystem_ko() //cookiesystem_ preffix is required
    endfunction


Public function members can be used by ExecuteFunc or real variable value events, but they always need the scope prefix when used as string:

JASS:
    library cookiesystem
        public function ko takes nothing returns nothing
            call BJDebugMsg(&quot;a&quot;)
        endfunction

        function thisisnotpublicnorprivate takes nothing returns nothing
             call ExecuteFunc(&quot;cookiesystem_ko&quot;) //Needs the prefix no matter it is inside the scope

             call ExecuteFunc(&quot;ko&quot;) //This will most likely crash the game.
             call cookiesystem_ko() //Does not need the prefix but can use it.
             call ko() //since it doesn&#039;t need the prefix, the line works correctly.
        endfunction
    endlibrary


Alternatively, you may use SCOPE_PREFIX (see bellow)

Note: If you use public on a function called InitTrig, it is handled in an special way, instead of becoming ScopeName_InitTrig it will become InitTrig_ScopeName, so you could have an scope/library in a trigger with the same scope name and use this public function instead of manually making InitTrig_Correctname.

>>Why should I learn vJass and not normal Jass?
Because you will rather learn vJass than normal Jass when you know the advantages of it.

>>there are like 5 on this website and only 1-2 for something little more advanced
You are allowed to post thread and ask for it.


Edit -
>>It is a cool feature in vJASS TESH editor,
Eh, TESH has nothing to do with vJass syntax. Hmm, can't say nothing but it just perform the trick to highlight the syntax only. It is also the the for it. "Trigger Editior Syntax Highlighter"

>>Damn this vJASS shit is easy.
Okay, I got messed up by you, isn't that normal Jass? Why call it vJass?.. :rolleyes:
 

Hatebreeder

So many apples
Reaction score
381
Hmm... I always thought, private functions are used in librarys... Anyways, very helpfull tutorial, great conntibution to this community (Also, very good thing that's not just 'Jass', we have so little 'vJass' tuts here...)
+Rep from me =)
 

Ninja_sheep

Heavy is credit to team!
Reaction score
64
I meant it more as a suggestion for the tutorial and not a real question :>
however no I know more xD (+Rep)
 

Sim

Forum Administrator
Staff member
Reaction score
534
> WE does not know hot to generate vJASS

how

I like how anyone can understand this tutorial, except if he doesn't understand GUI. Although... it doesn't really give enough stuff to the reader which would make it possible for him to switch to vJASS permanently. Even if it is a basic tutorial, I think you should still add some more stuff. Hell, you would need to explain a bit how JASS works, give some more examples, because let's be honest: vJASS is only different JASS (And not that different...).
 

hell_knight

Playing WoW
Reaction score
126
Yeah kay I can convert them but whats a function?
Do they run in order?
I thought it was something you called?
Im still ??????
 

Cohadar

master of fugue
Reaction score
209
This tutorial's purpose is not meant to teach people vJASS.
That is impossible.

What it was meant to do is show people that there could be some real benefit from switching, and make them interested to try.

And let's face it, noone who has learned jass ever went back to coding in GUI.
 

Sim

Forum Administrator
Staff member
Reaction score
534
>What it was meant to do is show people that there could be some real benefit from switching, and make them interested to try.

If you really want people to switch, show them another example of vJass's greatness. :) There must be some... trigger in GUI that is about 50 lines long while converted to vJass, it becomes like... a quarter of that length. I'd have to investigate.
 

Cohadar

master of fugue
Reaction score
209
This tutorial's purpose is not meant to teach people vJASS.
That is impossible.

What it was meant to do is show people that there could be some real benefit from switching, and make them interested to try.

And let's face it, noone who has learned jass ever went back to coding in GUI.

That is simple.
Any trigger with if statement is like that.

GUI:
Code:
LamerGUI
    Events
    Conditions
    Actions
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                ((Triggering unit) is A structure) Equal to True
            Then - Actions
            Else - Actions

generated jass:
JASS:
function Trig_LamerGUI_Func001C takes nothing returns boolean
    if ( not ( IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_LamerGUI_Actions takes nothing returns nothing
    if ( Trig_LamerGUI_Func001C() ) then
    else
    endif
endfunction

//===========================================================================
function InitTrig_LamerGUI takes nothing returns nothing
    set gg_trg_LamerGUI = CreateTrigger(  )
    call TriggerAddAction( gg_trg_LamerGUI, function Trig_LamerGUI_Actions )
endfunction


vJASS:
JASS:
scope LamerGUI

function Actions takes nothing returns nothing
    if IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) then
    else
    endif
endfunction

//===========================================================================
public function InitTrig takes nothing returns nothing
    local trigger trig = CreateTrigger(  )
    call TriggerAddAction( trig, function Actions )
endfunction

endscope
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Actually it does help people who don't know what the difference between vJASS and JASS is. I left a while back, and I know JASS. However, when I came back, I looked through the JASS forums only to see all kinds of weird words in there like private, public, and scope.

However, I still do not see how this is supposed to be much easier than regular JASS. The only differences I see are a few easier ways to sort function names and put them into categories. Sure it may help when you have a huge map, with tons of scripting in the Map Header, but for a lot of people who don't use JASS except to remove leaks, create slides, create custom spells, and create a few systems, it just seems like a lot of extra time to put in for not much use.
 

Romek

Super Moderator
Reaction score
963
Most of this isn't actually vJass.
For example, you say vJass has colours.
Thats just the Jass tags and the Code tags.
One has colours. The other doesn't.

And if you're talking about using NewGen for the colours, you don't necessarily have to use vJass in Newgen.

You can also use local triggers and the 'better' conditions in normal Jass. The 'bad' one is the converted Jass from GUI. Which sucks.

You're also just explaining about how to use NewGen in the Pictures.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Great tut Cohadar. :)

Hmm... I always thought, private functions are used in librarys... Anyways, very helpfull tutorial, great conntibution to this community (Also, very good thing that's not just 'Jass', we have so little 'vJass' tuts here...)
+Rep from me =)

They are not used in libraries, (technically, yes they can) but they are more used in scopes.

However, I still do not see how this is supposed to be much easier than regular JASS. The only differences I see are a few easier ways to sort function names and put them into categories. Sure it may help when you have a huge map, with tons of scripting in the Map Header, but for a lot of people who don't use JASS except to remove leaks, create slides, create custom spells, and create a few systems, it just seems like a lot of extra time to put in for not much use.

Yup, so much has changed. Categorization, optimization, performance, and all that is what vJass brings to us. Actually, more than that. Structs, methods, and the easy globals are really easy to use. It makes life really easier, but takes a while to learn and become accustomed to unless previous programming knowledge. (Cohadar seemed to learn vJass in a second xP)

vJass actually saves time. As plenty have said, who wants to go through and click a bunch of windows which takes about 30 seconds for a complex function, while you can do it in JASS in 10 seconds. :p

JASS is still fine to use, vJass is just the new generation. JASS isn't completely obsolete imho though because vJass is more of an addon.

Most of this isn't actually vJass.
For example, you say vJass has colours.
Thats just the Jass tags and the Code tags.
One has colours. The other doesn't.

And if you're talking about using NewGen for the colours, you don't necessarily have to use vJass in Newgen.

You can also use local triggers and the 'better' conditions in normal Jass. The 'bad' one is the converted Jass from GUI. Which sucks.

You're also just explaining about how to use NewGen in the Pictures.

He means TESH for NewGen. Regular WE has no color coding. And by "JASS", I think he means sloppy JASS. GUI converted...

Almost no natives in GUI except a few like TSA, which still sucks. xD
 

Insane!

Shh I didn't edit this, go away.
Reaction score
122
i hear vjass is the crem della crem for spell makers

but now i fell more obliged to learn vjass :D
 

Kazuga

Let the game begin...
Reaction score
110
Love the tutorial, finally one that you actually understand^^
However when I try to open your demo map it's opened with normal we and not newgen, how do I open it with the newgen we?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top