wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Tutorials > JASS/AI scripts tutorials
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 08-01-2008, 02:10 AM   #1
Themerion
Brahms-fan
 
Themerion's Avatar
 
Join Date: Jan 2006
Posts: 641

Submissions (2)

Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)

Default [JASS] Making safe and effective code

About

This tutorial is beyond beginner level. I assume that you feel confident in the basic syntax of JASS and vJASS before proceeding. Also, you should know what leaks and what does not.

I won't add any sources for my claims (since I don't feel for scanning wc3campaigns for hours to find them). If you have links to relevant test results or the like, please post them here.

Index
  • Brief Safety Info
  • Unit Groups
    - Creating / Destroying
    - Looping
  • Dynamic Triggers
    - Safety Concerns
    - Action vs. Condition
.....................: Brief Safety Info :.....................
  • Using UnitDamagePoint or UnitDamagePointLoc will desync mac users.
  • The 8192:th slot in all arrays will be forgotten if the game is saved and loaded. This means we can safely use array[0] to array[8190].
  • TriggerSleepAction (normal Wait) doesn't care if the game is paused by Waiting for players-window.
  • Destroying a timer and then setting its variable to null might sometimes cause a crash. But you know this, right? :)
  • Functions returning nothing shouldn't be passed to Filters/Conditions because that can cause desyncs.

.....................: Unit Groups :.....................

-- Creating / Destroying --

We've all learned that when dealing with local unit groups, you have to destroy them to prevent leaks. That's true. The problem is that creating a unit group takes time a small amount of time. This matters if you, for instance, want to use a lot of groups periodically.

Also, destroying unit groups in certain situations might cause leaks. It's better if you use a global group instead:

Collapse JASS:
scope GroupEx

globals
    private group tempGroup
endglobals

function DoSomething takes nothing returns nothing
// Empty group before usage
    call ClearGroup(tempGroup)

// Use tempGroup for whatever you need!
// *** EXAMPLE ***
    call GroupEnumUnitsInRange(tempGroup,X,Y,500,null)
    call GroupIssuePointOrder(tempGroup,0,0,"attack")
endfunction

public function InitTrig takes nothing returns nothing
    //....
    set tempGroup=CreateGroup()
endfunction

endscope

Sometimes, just 1 group might not be enough. You can then implement your own group-stack with the help of whatever struct you might be using:

Collapse JASS:
 // Instead of destroying the group,
// just empty it, and leave it for the next struct.

struct Data
    group g

    method create takes nothing returns Data
        local Data d=Data.allocate()
        if d.g==null then
            set d.g=CreateGroup()
        endif
        return d
    endmethod

    method onDestroy takes nothing returns nothing
        call GroupClear(.g)
    endmethod
endstruct


-- Looping --

The equivalent of Pick all units in Group... is ForGroupBJ(), which is a wrapper around ForGroup(). If you already have a group, the fastest way to loop through it is indeed ForGroup(). Use temporary globals if you need to.

Collapse JASS:
globals
    private player temp
endglobals

private function Loop takes nothing returns nothing
    call SetUnitOwner(GetEnumUnit(),temp,true)
endfunction

function GroupChangeOwner takes group g, player newOwner returns nothing
    set temp=newOwner
    call ForGroup(g,function Loop)
endfunction


If you only want to loop through a group once, you don't have to use ForGroup. This is very common for spell-making. You can do the loop directly in the GroupEnum-call:

Collapse JASS:
globals
    private unit tempUnit
    private integer tempInt
    private group tempGroup
    private boolexpr cond
endglobals
//======================================================

private function Loop takes nothing returns boolean
    if IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(tempUnit)) then
        call UnitDamageTarget(tempUnit, GetFilterUnit(), tempInt, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    endif
    return false
endfunction

function AOEDamage takes unit attacker, real x, real y, integer damage returns nothing
    set tempUnit = attacker
    set tempInt = damage
    call GroupEnumUnitsInRange(tempGroup,x,y,RADIUS,cond)
endfunction

//======================================================
private function Init takes nothing returns nothing
    set tempGroup=CreateGroup()
    set cond=Condition(function Loop)
endfunction

.....................: Dynamic Triggers :.....................

-- Safety Concerns --
A trigger which has it's attributes (event/condition/action) modified by a script not running at map init is called a dynamic trigger. If you do not know about triggers in JASS, I'd recommend Vexorian's tutorial.

Since you can create triggers on-the-fly, you will also want to destroy the triggers, in order to prevent memory leaks. This is bad because destroying the trigger under certain conditions (having waits in any code used by, or called by the trigger) may cause two handles to get the same id.

Usually you can work your way around using dynamic triggers in your scripts. For Damage Detection, you have to use a dynamic trigger. The solution here is to never destroy the trigger, and accept the fact that it will leak a bit. After all, you would rather have a leaking trigger than a corrupted game. For auras and other enter range events, you can use periodical GroupEnums.

-- Conditions vs. Actions --
Trigger Conditions are faster than Trigger Actions, but you cannot use waits in conditions.
Collapse JASS:
// Custom Charm.

private function Actions takes nothing returns boolean
    if GetSpellAbilityId() == 'char' then
       call SetUnitOwner(GetSpellTargetUnit(),GetOwningPlayer(GetSpellAbilityUnit()),true)
    endif
    return false
enfunction

public function InitTrig takes nothing returns nothing
    local trigger trg=CreateTrigger()
    call TriggerRegisterAnyUnitEvent(trg,PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(trg, Condition(function Actions))
    set trg=null
endfunction
__________________
Submissions::
(v)JASS Tutorial
Covers how to make fast and safe coding for common tasks in vJASS/JASS.
Creep Respawn System
It has never been easier to respawn creep groups...

Last edited by Themerion : 12-18-2009 at 03:48 PM.
Themerion is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 08-01-2008, 07:12 AM   #2
darkwulfv
Alpha Male of Wc3c
 
darkwulfv's Avatar


Official Map Reviewer
 
Join Date: Mar 2006
Posts: 3,646

Submissions (6)

darkwulfv is just really nice (270)darkwulfv is just really nice (270)

Send a message via AIM to darkwulfv
Default

Quote:
The problem is that creating a unit group takes time. Also, destroying unit groups in certain situations might cause leaks. It's better if you use a global group instead:
Like, .0045 seconds? If that? Only crucial if every single nanosecond counts for something. Using a global can overcomplicate things since you'll sometimes need to use special systems just to make things MUI (in some situations)
And could you explain how destroying a group leaks?

That bit of information about performing actions on units from groups directly in the filter is pretty nifty, though.
__________________
The Spell Request Thread
Quote:
Originally Posted by Joe-Black-5
a dota like map but with unique stuff
(There was no map attached, and that was all the thread said.)
Spells I've Made

Darkwulfv's Lightning Grapple || Tritanis' Lazy Bolt


Last edited by darkwulfv : 08-01-2008 at 07:14 AM.
darkwulfv is offline   Reply With Quote
Old 08-01-2008, 03:35 PM   #3
Themerion
Brahms-fan
 
Themerion's Avatar
 
Join Date: Jan 2006
Posts: 641

Submissions (2)

Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)

Default

Quote:
Like, .0045 seconds? If that? Only crucial if every single nanosecond counts for something. Using a global can overcomplicate things since you'll sometimes need to use special systems just to make things MUI (in some situations)
It's important if you want to have, for instance, something periodically creating and destroying a lot of groups. I'll add that mention...

Quote:
And could you explain how destroying a group leaks?
I cannot. But I've learned to trust in what ever Vexorian says ^^

Collapse CSSafety Intro:
//* CSSafety 15.2
//* ŻŻŻŻŻŻŻŻ
//* [.......]
//*
//*  Eventually, we also added a group stack, the justification is different though, there
//* are just memory leak related issues when using DestroyGroup on groups that were handled
//* by certain natives, thus it is good to recycle them. Replace CreateGroup with NewGroup
//* and DestroyGroup with ReleaseGroup.
__________________
Submissions::
(v)JASS Tutorial
Covers how to make fast and safe coding for common tasks in vJASS/JASS.
Creep Respawn System
It has never been easier to respawn creep groups...
Themerion is offline   Reply With Quote
Old 09-17-2008, 08:30 AM   #4
xyzie
User
 
Join Date: Aug 2008
Posts: 15

xyzie has little to show at this moment (0)

Default

I wish I had seen this thread sooner :D
It has covered about all the uncertainties I have about JASS in the last couple weeks and some new information too.

Quote:
The 8191:th slot in all arrays will be forgotten if the game is saved and loaded.

Isn't that the 8192:th slot that is trimmed? So to be on the absolute safe side we should only use some_array[0]...some_array[8190]?

Thanks for the thread. Really helpful!

Last edited by xyzie : 09-17-2008 at 08:34 AM.
xyzie is offline   Reply With Quote
Old 09-18-2008, 07:12 AM   #5
Pyrogasm
Lackadaisically Absent.
 
Pyrogasm's Avatar


Respected User
 
Join Date: Sep 2006
Posts: 4,514

Submissions (9)

Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)Pyrogasm is a splendid one to behold (638)

Hero Contest - Fourth place

Send a message via ICQ to Pyrogasm Send a message via AIM to Pyrogasm Send a message via MSN to Pyrogasm Send a message via Yahoo to Pyrogasm
Default

Quote:
Originally Posted by xyzie
Isn't that the 8192:th slot that is trimmed? So to be on the absolute safe side we should only use some_array[0]...some_array[8190]?
That is correct.
__________________
Quote:
Originally posted by Rising_Dusk
Your spells are mostly ignored because they are not very cool so we aren't very excited to review/approve them, but you are incredibly persistent and won't give us an excuse to graveyard it. That is generally what results in a resource being ignored for a long time.

The Spell Request Thread — Done for, unless someone else wants to revive it...
It lasted a damn long time.

Please; Ask for Help Appropriately














Quote:
Originally posted by Kyrbi0
Huh. Almost makes me wish I had a girlfriend, to take advantage of today (wait, no, that's not what I meant... I mean, take advantage of the fact that it is international women's day... gah, never mind).
Quote:
Originally posted by Pyrogasm
Rome may not have been built in a day, but the Romans sure as hell didn't say "look at this great city we built guys!" when they had nothing more than a bit of stone and some cottages.
Pyrogasm is offline   Reply With Quote
Old 10-08-2008, 06:29 PM   #6
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,087

Submissions (19)

Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)Anitarf has a brilliant future (888)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

Destroying triggers won't cause the game to crash, it just may cause two handles to get the same handle id for some reason. Sure, dynamic triggers are still "evil", but there's no need to exaggerate how bad they really are.

Otherwise, this is a nice tutorials, it covers many useful coding details, but you really should provide links to threads, you can probably find most of them in the Known bugs in Jass sticky in the T&S forum, as for the others invest some effort and look for them.
__________________
Anitarf is offline   Reply With Quote
Old 12-05-2008, 02:53 PM   #7
PitzerMike
Alcopops
 
PitzerMike's Avatar


Tools & Tutorials Moderator
 
Join Date: Jan 2003
Posts: 2,791

Submissions (12)

PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)PitzerMike is a splendid one to behold (643)

Approved Map: Pitzer's Minesweeper

Default

Yes this is great. I have an addition to the Safety Info section.
Functions returning nothing shouldn't be passed to Filters/Conditions because that can cause desyncs. The latest pjass should catch those however.

Approved!
__________________
Zoom (requires log in)
PitzerMike is offline   Reply With Quote
Old 12-18-2008, 01:06 AM   #8
MaD[Lion]
MaD Da ViNci
 
MaD[Lion]'s Avatar


Respected User
 
Join Date: Apr 2003
Posts: 1,699

Submissions (10)

MaD[Lion] is a jewel in the rough (225)MaD[Lion] is a jewel in the rough (225)MaD[Lion] is a jewel in the rough (225)MaD[Lion] is a jewel in the rough (225)

Default

very useful summary :) Eventho i knew those things already but sometime u forget when u do much of only 1 problem for long time, so nice to refresh the other problems :)
__________________
Current Projects:
MaDOS (outdated)System for object movements & effects - NEW VERSION IS UNDER W.I.P
Cinematic SystemSystem for making better cinematics and with fancy effects
Timing SystemTiming system that simulates the usage of PolledWait just with 0.01 accuracy
MaD[Lion] is offline   Reply With Quote
Old 12-27-2008, 03:27 PM   #9
Themerion
Brahms-fan
 
Themerion's Avatar
 
Join Date: Jan 2006
Posts: 641

Submissions (2)

Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)Themerion has a spectacular aura about (110)

Default

Quote:
Originally Posted by xyzie
Isn't that the 8192:th slot that is trimmed? So to be on the absolute safe side we should only use some_array[0]...some_array[8190]?

You are right, of course. With array[0] being the first slot, and array[8190] being the 8191:th...

Quote:
Originally Posted by Anitarf
Destroying triggers won't cause the game to crash, it just may cause two handles to get the same handle id for some reason. Sure, dynamic triggers are still "evil", but there's no need to exaggerate how bad they really are.

Aye. I'll change that.

Quote:
Otherwise, this is a nice tutorials, it covers many useful coding details, but you really should provide links to threads, you can probably find most of them in the Known bugs in Jass sticky in the T&S forum, as for the others invest some effort and look for them.

Muuh... *grumble* it'd take me more time to find links than it took to write the tutorial itself...

Quote:
Originally Posted by PitzerMike
I have an addition to the Safety Info section.
Functions returning nothing shouldn't be passed to Filters/Conditions because that can cause desyncs. The latest pjass should catch those however.

Hum, but why would somebody pass a return nothing function to a filter?

Quote:
Approved!
\O/
__________________
Submissions::
(v)JASS Tutorial
Covers how to make fast and safe coding for common tasks in vJASS/JASS.
Creep Respawn System
It has never been easier to respawn creep groups...

Last edited by Themerion : 12-27-2008 at 03:37 PM.
Themerion is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 12:58 AM.


Donate

Affiliates
The Hubb http://bylur.com - Warcraft, StarCraft, Diablo and DotA Blog & Forums The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2014, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services