Tutorial Working Twyddli's Basic Functions

T

Twyddli

Guest
[Tutorial] Working Twyddli's Basic Functions
Table Of Contents
Before the Tutorial.
Messaging.
Moving Units
Creating Units
Units Facing Angles
Resources.

Before The Tutorial
Before you start this tutorial, you should know that the functions i use, I have created already. Go to the link at the Bottom of the tutorial to get them.
Getting The Functions In your game.
Ok, after you have downloaded my functions, they are in a notepad. Open up the note pad, and copy everything in there. Then open up your map editor, create the map you want, and click the trigger editor. The only trigger in there is called the name of your map, and it has a little map editor icon at the start of its name, click on this, then click on the bottom box, and push Ctrl + V that will past all the functions in there. Then save your map. Now you can begin this tutorial.

You should know that it is for beginners, and that i have posted another thread called [Functions] Twyddli's Basic Functions.
In the thread, you are able to download a Nate Pad file with a bunch of new functions. Go there if you want to read this tutorial. Also! This tutorial is for beginners I think.
Let us begin!

Lets open up World editor if you haven't already.
NOTE: Your Jass will not have any coloring in it.
Messaging
To make a trigger that messages a Single player, you need to type in what function to use, and what player to send it to. This is done with a single name, Msg1 to send a message to Player 1, and Msg12 to send a message to Player 12.
Create a new Trigger called My Message, then go to the Edit tab up in the top left corner. Click on it and go down to Convert To Custom Text.
You should now see something that looks like this -

JASS:
function Trig_My_Message_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_My_Message takes nothing returns nothing
    set gg_trg_My_Message = CreateTrigger(  )
    call TriggerAddAction( gg_trg_My_Message, function Trig_My_Message_Actions )
endfunction


Ok. lets add an Event first. Some this that triggers this off. Lets make it when a player types a certain message. The message will be "Hello?" To add this you first need to call a function. But what do we call? Well. It's a Chat event. And, it's a player doing it. But where does it go?
It goes in between set gg_trg_My_Message and call TriggerAddActions.
So its a PlayerChatEvent. We need to tell the game to register it. Type in this.
call TriggerRegisterPlayerChatEvent(. Now what? What needs to go in after the Bracket? That would be the actual event. You need to first specify what trigger. So straight after the Bracket, type in gg_trg_My_Message, and then a comma. Now who is triggering this trigger? We want it to be player 1.
NOTE: When specifying a player, you need to type in Player(0) where 0 is the player number. 0 is player 1, and 11 is player 12.
So what goes after this Bracket? Player 1. Lets type that in. so it should now be, call TriggerRegisterPlayerChatEvent(gg_trg_My_Message,Player(0), and there needs to be the comma after Player(0). Now, what do we want Player 1 to type, that triggers this trigger? We want it to be Hello?.
NOTE: When using a String, you need to put quotation marks “ around it.
So right after out comma, we need Hello? As a string. And we need to close it with another bracket.

JASS:
function Trig_My_Message_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_My_Message takes nothing returns nothing
    set gg_trg_My_Message = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent(gg_trg_My_Message,Player(0),Hello?”)
    call TriggerAddAction( gg_trg_My_Message, function Trig_My_Message_Actions )
endfunction


This is what it should look like now. All this does is, when player 1 types Hello? It will do nothing.
Lets add the Action. Ok, in your trigger up the top, there should be a line something like this. function My_Message_Actions takes nothing returns nothing
endfunction
What this does is nothing. You need to add something in between function_My_Message_Actions and endfunction. But what do we type? Well we want a message. And I have gone and created a hole bunch of message functions to make it easy on you. When you are adding an action, you need to call it. Do this by typing call. And then what next? We need to add the function. To message some one. You need to Type in Msg1, that will message Player 1 with something. If you change the 1 to a 2 it will message player 2 and so on up to 12. Then we need to add in the Message. Put an opening Bracket to the end of Msg1. Now we want to just add a little message. Messages are strings. And when using a string, remember to use Quotation marks “. Lets make it say Hello! I'm a computer. So just after the Bracket, what do you think we would type?
If you said “Hello! I'm a computer.” Then you are correct. Though if you typed in anything, as long as it was rapped in quotation marks, it wouldn't really matter. It would just show a different message. Then lastly you need to close the Bracket).
This is what your trigger should now look like.
JASS:
function Trig_My_Message_Actions takes nothing returns nothing
    call Msg1("Hello! I'm a Computer.")
endfunction

//===========================================================================
function InitTrig_My_Message takes nothing returns nothing
    set gg_trg_My_Message = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My_Message, Player(0), "Hello?", true)
    call TriggerAddAction( gg_trg_My_Message, function Trig_My_Message_Actions )
endfunction

click save on your map. And then test it, and type in Hello? See what happens.

Ok that was our first function.
When creating a message for a player, you can use Msg1 through to 12, and you can also do MsgAll. That sends the same message to everyone.

Moving A Unit
Let us try something a little more complicated. Keep your event, but delete the call Msg1(“Hello, I'm a computer.”) and lets create a new action.

Lets make the Action, order a unit to move to a new location. We have our event, so we need to call a function again. Type in call, now what action do we use? My simple walk function, is WalkLoc. So you should type that in, and it now looks like this.
call WalkLoc(. What is next? What unit do we want to move? Go to your unit panel, in the world editor and place a blood mage some where on your map. Also put a region down. To get the name of your triggering unnit, create a new trigger and leave the naem, create an action that involes your unit. I used Move unit instantly and for the unt i changd it to my Hero. Then i converted it, it looked like this -

JASS:
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
    call SetUnitPositionLoc( gg_unit_Hblm_0000, GetRectCenter(GetPlayableMapRect()) )
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction


Go to your trigger, and lets add some more to our action. We need a unit to get ordered, Our units name is in the other trigger, Mine was gg_unit_Hblm_0000. So now our action look some what like this now call WalkLoc(gg_unit_Hblm_0000, with a comma too. So that selects what unit will be walking.
Now where do we want to walk to? Your region. Ok find your region, and it would be defaulted on Region 000 or if you have other regions, the number will be different. So we now need to type in the region name. Remember to swap spaces with Underscores _ . So it become Region_000.
NOTE: When using regions, you need to have gg_rct_ infront of your region name.
Lets add that to our trigger. You should now have the action like this. call WalkLoc(gg_unit_Hblm_0000, gg_rct_Region_000)
This will order your blood mage to move to the center of the region Region 000.
But does it leak? No it doesn't. The function I created, WalkLoc, removes the leak for you.
If you want to order the Triggering you to move to a loc just use WalkTLoc, this gets the triggering unit, and all you need to do is specify what region you want it to move to.
This is what your new trigger should look like.
JASS:
function Trig_My_Message_Actions takes nothing returns nothing
    call WalkLoc( gg_unit_Hblm_0000, gg_rct_Region_000)
endfunction

//===========================================================================
function InitTrig_My_Message takes nothing returns nothing
    set gg_trg_My_Message = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My_Message, Player(0), "Hello?", true)
    call TriggerAddAction( gg_trg_My_Message, function Trig_My_Message_Actions )
endfunction

Test your trigger. When you type in Hello? You blood mage should walk to your region.

Notes On issued Orders.
I have created a few different orders, There is Move, Attack Move and Stop.
Using Attack move is exactly the same as Move, except for the functions name, It has an A at the start, so it would be AWalkLoc. And then Stop, just takes a Unit. Or you can do TStop, witch would stop the triggering unit.

Creating a Unit.
How do we do this. Create a new Trigger. Lets add the Event Player 1 Types Make a Footman.
Try and do this without my help.
Ok, Creating a unit, this will be the action, up the top. The action name is SpwnUnitLoc. This meens it Spawns a Unit at a Region. Ok, type in SpwnUnitLoc( with the Bracket. Now Who will we be spawning it for? You, player 1. You do this by typing in Player(0), with the comma. What Unit do you want to make? NOTE: this is a string, you need to type in a Unit types name, like footman, and because its a string, we need our handy little Quotation marks “. So it would be “footman”. Lets add these two things to our action it should now be call SpwnUnitLoc(Player(0), “footman”, Where does he get created? You need to specify a region. Either create a new region, or use your old one. Remember, you need the gg_rct_ in front of your regions name, and spaces are replaced with underscores _ . I'm going to use my old region, so my action will look like this now. Spwn(Unit(Loc(Player(0), “foorman”,gg_rct_Region_000, And now one last thing, where is he facing? I want my unt to face to the west, witch is left on my screen. So i need to add a real number. 180.00 is what I'm making it.
Ok, this is what my new trigger looks like.
JASS:
function Trig_My_Unit_Actions takes nothing returns nothing
    call SpwnUnitLoc(Player(0), "footman", gg_rct_Region_000, 180.00)
endfunction

//===========================================================================
function InitTrig_My_Unit takes nothing returns nothing
    set gg_trg_My_Unit = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My_Unit, Player(0), "Make a Footman.", true)
    call TriggerAddAction( gg_trg_My_Unit, function Trig_My_Unit_Actions )
endfunction


How about we add a little message, that gets sent to you when you create this footman. Remember the action Msg1? We will use that again. Type it in, and me the message You have Created a Unit.

So now your Trigger should be like this.

JASS:
function Trig_My_Unit_Actions takes nothing returns nothing
    call SpwnUnitLoc(Player(0), "footman", gg_rct_Region_000, 180.00)
    call Msg1(You have Created a Unit.”)
endfunction

//===========================================================================
function InitTrig_My_Unit takes nothing returns nothing
    set gg_trg_My_Unit = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_My_Unit, Player(0), "Make a Footman.", true)
    call TriggerAddAction( gg_trg_My_Unit, function Trig_My_Unit_Actions )
endfunction

Lets test it now.
When you type Make a Footman., it should create a footman at your region, and then give a message to you. Ok. Now we have learnt how to use Messages how to order Units, and how to create Units.

Facing Angles
Maybe we want to change the way a unit is facing. Lets make this trigger!

Facing angle.
Create a new trigger, call it Change Face, and then convert it.
First we want an action, lets make it that when a unit enters a region. First we need a new region, Place one Down, and then place a Circle of Power on top of it, so where know where to walk. Keep your blood mage on the map. Now then, What kind of event is it? When a unit enters a region. It is entering a region, so i think it would be a EnterRectSimple event, but we also need to tell the trigger to register it. So it should look like this for now. call TriggerRegisterEnterRectSimple(. Now we need to say what trigger its on. Ok, we need gg_trg_Change_Face, with the comma, now wer need a region that will trigger it. Remember to add the gg_rct_ to the front of your regions name, and swap spaces with underscores _ . and then close it with a closed Bracket ). Now for the Action.
We need to call a function, It's called TUnitFaceSouth. This means that the Triggering unit will Face south. We don't need to type in anything after that. But after we type it we need a () infront of it. So it looks like this TUnitFaceSouth(). This is what it should all look like.

JASS:
function Trig_Change_Face_Actions takes nothing returns nothing
    call TUnitFaceSouth()
endfunction

//===========================================================================
function InitTrig_Change_Face takes nothing returns nothing
    set gg_trg_Change_Face = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple(gg_trg_Change_Face, gg_rct_Region_000)
    call TriggerAddAction( gg_trg_Change_Face, function Trig_Change_Face_Actions )
endfunction


But this is a pretty boring function. Lets change it and make it so, when he walks onto the region, that it makes him face North, wait 1 second, then face west, wait 1 second, face south, wait 1 second, face east. And then have a message come on. It will say, There no Units in sight Sir!

Before making him do anything, the very first action you need is local unit a = GetTriggerUnit() this will store our triggering unit to a local variable, allowing us to access him when we use a wait.
We already have our event, and one of the actions. To make him face north. Left just change the first action we have. So instead of TUnitFaceSouth(), change that to TUnitFaceNorth(). Now that he faces north, we can use one of my Waits,
Ok, so now we have our first action,
lets add this Action, Wait(. How long will it wait? Well I'm going to make mine wait for 1 second. So mine will look like this wait( 1.00 ). Now we have lost the function GetTriggerUnit, as we have used a sleep action. But we have stored the triggering unit Into a local unit variable, and that is called a, so we can still use Triggering Unit in our actions.
Lets make him face west now. We need the function UnitFaceWest(. Now all we need to do is tell it what unit to make face west, it is our local variable a that we want to face west. Lets put it in. Now it looks like this, UnitFaceWest(a). Ok now our triggering unit will be facing west. Lets put in another wait. call Wait( 1.00 ) .
Now for the next facing angle. We want him to face south, so we add the action UnitFaceSouth(. And again we need to add the Triggering Unit to our action. Put it in and close the bracket. UnitFaceSouth(a) and then we need one last wait action, Wait( 1.00 ) and then the last UnitFace action, witch is UnitFaceEast(. And when we add the triggering unit it looks like so UnitFaceEast(a). So now our function looks much more interesting. Here is how it should look.
JASS:
function Trig_Change_Face_Actions takes nothing returns nothing
    local unit a = GetTriggerUnit()
    call TUnitFaceNorth()
    call Wait(1.00)
    call UnitFaceWest(a)
    call Wait(1.00)
    call UnitFaceSouth(a)
    call Wait(1.00)
    call UnitFaceEast(a)
endfunction

//===========================================================================
function InitTrig_Change_Face takes nothing returns nothing
    set gg_trg_Change_Face = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple(gg_trg_Change_Face, gg_rct_Region_000)
    call TriggerAddAction( gg_trg_Change_Face, function Trig_Change_Face_Actions )
endfunction

What about the message function? Well, lets put that in now, Lets pretened that There is a player 2 playing as well, and lets also pretend that the unit that is facing all different directions is looking for enemies. Player 2 is your ally.
Lets add one last wait, before we add in the messages, so it is like the unit is still looking for units while facing east. Just a simple Wait(0.50)
So now we add the function Msg1, so it would be call Msg1(“There are no Enemy units in sight, Sir!”)
we also want to add another function Msg2 and this will look the same as the first one. Call Msg2(“There are no Enemy units in sight, Sir!”)

So now our wonderful trigger will look like this -

JASS:
function Trig_Change_Face_Actions takes nothing returns nothing
    local unit a = GetTriggerUnit()
    call TUnitFaceNorth()
    call Wait(1.00)
    call UnitFaceWest(a)
    call Wait(1.00)
    call UnitFaceSouth(a)
    call Wait(1.00)
    call UnitFaceEast(a)
    call Wait(0.50)
    call Msg1(There are no Enemy units in sight, Sir!”)
    call Msg2(There are no Enemy units in sight, Sir!”)
endfunction

//===========================================================================
function InitTrig_Change_Face takes nothing returns nothing
    set gg_trg_Change_Face = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple(gg_trg_Change_Face, gg_rct_Region_000)
    call TriggerAddAction( gg_trg_Change_Face, function Trig_Change_Face_Actions )
endfunction


And now we have our new trigger, lets test it and see what happens.
Yay! He looks around, and then we get a message saying that there are no units in range.

Notes On Facing Angles
I have created a hole bunch of Set facing angles, you can make you unit face all these directions.
E, NEE, NE, NNE, N
NNW, NW, NWW, W
SWW, SW, SSW, S
SSE, SE, SEE, E

Those are all the directions i have made. To face North south east or west type in UnitFaceNorth, and just change north to the direction. To face any of the other directions, use just the first letter of each direction. So you would type in UnitFaceNE to face north east, and so on. If you want it to make the triggering unit to face the direction, just put a T on the front of the name, and remember. You don't need to specify anything if you use TUnitFace. You just need to have () at the end of it.


Last But Not Least
Resources


Giving and taking Resources.
To give recourses you need to type AddGold1 to add gold to player 1, and change the number 1 to the player you want to give the gold to. There is also AddGoldAll, witch gives gold to every player. Once you type in AddGold1, you need to open a bracket, and put in there an integer, this integer is how much gold do you want to give your player?
Then you can change Gold to Lumber, and its all the same. Lets make a simple starting recourses trigger.

Create a new Trigger called Resources.
Convert it, and lets add an event. It will be elapsed game time is 0.01 seconds. Write this like -
TriggerRegisterTimerEventSingle(gg_trg_Resources, 0.01) don't forget that you need to call this. Now you need to add the actions. Lets make it give every player 500 gold, and 500 Lumber.
We will use the function AddGoldAll( how much gold do you want to give? 500.
call AddGoldAll(500). Now we do the same just change the word Gold to Lumber.
call AddLumberAll(500)
So your trigger should look like this.
JASS:
function Trig_Resources_Actions takes nothing returns nothing
    call AddGoldAll(500)
    call AddLumberAll(500)
endfunction

//===========================================================================
function InitTrig_Resources takes nothing returns nothing
    set gg_trg_Resources = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Resources, 0.01 )
    call TriggerAddAction( gg_trg_Resources, function Trig_Resources_Actions )
endfunction


Summary

And this Brings us to the end of my Tutorial on Twyddli's Simple Functions.
Today, you have learnt how to Make a message come up for a single player or for All players. How to Move a unit. How to create a New Unit for a player. How to change a units facing angle, and How to add gold or lumber to any or all players, and how to take gold from any or all players.

Feed back is good, if you have some trouble, or wish to know something about the tutorial, or working some of the functions, Post it here. If you have an idea for another Function, or a few functions, post it on the other thread, where you download the functions. I may or may not do them. Do not expect me to. I will possibly update the functions every now and again.

Hope this helps some people. ;)
Good Luck
Get the functions Here http://www.thehelper.net/forums/showthread.php?p=521103#post521103
 

WarLuvr3393

Hmmm...too many things to play (WoW, COD4, WC3)
Reaction score
54
Wow, there's WAY too many JASS tutorials out there. After scimming stuff, I saw an error in this script:

JASS:
function Trig_Change_Face_Actions takes nothing returns nothing
    local unit a = GetTriggerUnit()
    call TUnitFaceNorth()
    call Wait(1.00)
    call UnitFaceWest(a)
    call Wait(1.00)
    call UnitFaceSouth(a)
    call Wait(1.00)
    call UnitFaceEast(a)
    call Wait(0.50)
    call Msg1(There are no Enemy units in sight, Sir!”)
    call Msg2(There are no Enemy units in sight, Sir!”)
endfunction

//===========================================================================
function InitTrig_Change_Face takes nothing returns nothing
    set gg_trg_Change_Face = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple(gg_trg_Change_Face, gg_rct_Region_000)
    call TriggerAddAction( gg_trg_Change_Face, function Trig_Change_Face_Actions )
endfunction


Take a look at this line:

JASS:
call TUnitFaceNorth()


There's "T" in that, you may want to remove that.

Anyways, good tutorial. +Rep
 
T

Twyddli

Guest
Nope, its meant to have T in it, because it means Triggering unit. But to use this tutorial you will need to go to the link at the bottom of the post, and then down load the note pad file, and follow what it says. It's not like a normal Jass tut, it's a jass tut using extra functions i have created. ;)

Edit: Some of the other funcitons i created have a T in then, like MoveTUnitLoc, move the triggering unit to a region. :cool:
 

WarLuvr3393

Hmmm...too many things to play (WoW, COD4, WC3)
Reaction score
54
Why would you need a "T" if you already set the triggering unit to a variable?
 
T

Twyddli

Guest
Because it's main use is for other triggers, that don't require you to use a wait, and so you don't set the triggering unit to a variable. It also probably saves about .1 of a second time lol. Saves you having to type either a, or if you caled the variable something different, then you dont have to type in as much.
I made two different functions, there are the normal ones that don't have a T and then there are ones with a T. If it has a T then it's a Triggering unit. And I used the Triggering one for the first one because i could, And then after that i couldn't, as i had used a sleep action.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
I guess this is kind of helpful. Seeing as though your functions take a lot of thought to understand what the variables stand for.

I don't mean to be harsh, but really. All these functions can be easily implemented and really simplified. Sorry, but this has leaks and the ones with "Msg#", it really can just be:
JASS:
function Msg takes player toPlayer, string text returns string
    call DisplayTextToPlayer(toPlayer,0.,0.,text)
endfunction


Or, if you really want it like the other way. It would be simpler to get vJASS and just do this:
JASS:
//! textmacro Msg takes INT
function Msg takes player toPlayer, string text returns string
    call DisplayTextToPlayer(toPlayer,0.,0.,text)
endfunction
//! endtextmacro

//! runtextmacro Msg("1")
//! runtextmacro Msg("2")
//! runtextmacro Msg("3")
//! runtextmacro Msg("4")
//! runtextmacro Msg("5")
//! runtextmacro Msg("6")
//! runtextmacro Msg("7")
//! runtextmacro Msg("8")
//! runtextmacro Msg("9")
//! runtextmacro Msg("10")
//! runtextmacro Msg("11")
//! runtextmacro Msg("12")


Yes, I know. The thing above is confusing. :p

These functions, I guess are helpful to really new people. But I think that you should fix the leaks. btw:

Your code syntaxes at line 665 or something because it has a typo where you put "-+" instead of "-".

:D
 
T

Twyddli

Guest
:( Sounds like this was a bad idea...
Edit: Fixed the syntax thing, could you tell me where it leaks? I have gone through and i thought i got them.
Edit2: Hmm. Is there a way that i can get this removed from the forum? I feel like it's a pointless wast of space. So if there is please tell me.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Oh... Sorry, I didn't mean to offend you. In fact, these functions are helpful, I was just pointing out that it is mainly for new users. I don't want you to remove this because it may actually be helpful to certain people. :)

After removing/destroying an object, you must null it. Though there are some exceptions to these variables:
JASS:
- codes
- strings
- players
- integers
- reals
- booleans


And other permanent handles. The locations you have must be nulled. If you want, I can try to optimize and fix your code. :)
 
T

Twyddli

Guest
Ok, i wont get this removed. And that would be good if you could optimize my code ;)
Thanks.
 

Sim

Forum Administrator
Staff member
Reaction score
534
Actually, these functions could be renamed to the following:

Additional BJs (as in function).

BJ functions are what? Functions which call a native, while you could call the native directly and save a (or some) function call(s).

Your functions do exactly what the BJ functions do: You take the arguments given, and call a native function with them.

If we tell everybody to avoid BJs, then... we tell them to avoid functions such as yours ;)
 
T

Twyddli

Guest
*Sigh* :eek:
Well, Yeah. You would tell them to not use mine. Yup.
You know, I was actually thinking to my self while i was doing this, if it was actually wise.. I to came to the conclution that they worked the same as BJ functions, and so you will be better off not to use them. Dunno why i still posted them. Ah well.. ya win some, ya loose some.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Actually, these functions could be renamed to the following:

Additional BJs (as in function).

BJ functions are what? Functions which call a native, while you could call the native directly and save a (or some) function call(s).

Your functions do exactly what the BJ functions do: You take the arguments given, and call a native function with them.

If we tell everybody to avoid BJs, then... we tell them to avoid functions such as yours ;)

Which is exactly why I don't use CSCache.

BUT... I may use my own sometimes. Every function is a BJ, in a certain sense. :rolleyes:
 

Sim

Forum Administrator
Staff member
Reaction score
534
Yes, but if it is useful then why not use it? ;)

If it isn't, like the Swapped functions, then you don't use it.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Yes, but if it is useful then why not use it? ;)

If it isn't, like the Swapped functions, then you don't use it.

Cuz I can write them myself. The thing about CSCache is that it has functions that people don't know how to do. So CSCache is like a guide IMO. But it is still useful to use the functions. :D
 
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