1. Head to the 33rd Modeling Contest Poll and drink to your heart's desire.
    Dismiss Notice
  2. Choose your means of doom in the 17th Mini Mapping Contest Poll.
    Dismiss Notice
  3. A slave to two rhythms, the 22nd Terraining Contest is here.
    Dismiss Notice
  4. The heavens smile on the old faithful. The 16th Techtree Contest has begun.
    Dismiss Notice
  5. The die is cast - the 6th Melee Mapping Contest results have been announced. Onward to the Hive Cup!
    Dismiss Notice
  6. The glory of the 20th Icon Contest is yours for the taking!
    Dismiss Notice
  7. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] What's wrong with BJ ?

Discussion in 'Triggers & Scripts' started by Narg666, May 17, 2011.

  1. Narg666

    Narg666

    Joined:
    Aug 30, 2009
    Messages:
    112
    Resources:
    0
    Resources:
    0
    I've been looking for some spells and I realized the most qualified makers never use BJ like

    Code (vJASS):
    SetUnitPositionLocFacingBJ
    , they usually do this:

    Code (vJASS):
    SetUnitPosition
    SetUnitPositionLoc


    So, it drives me to one question, whats wrong with BJ ? Is there any problem using it? Once it's much easier than normal codes?

    I'm having some lag stuffs into spells that use 0.05 seconds interval...

    I did everything right, I cleaned all leaks, I change the time to 0.05 instead of 0.02, but yet, it does lag when it draggs much units, I wanna know if BJ codes are somehow related to it...

    Can someone give me some hints about?

    Here is only ONE of the spells wich lags

    Code (vJASS):
    function Trig_Dragula_Conditions takes nothing returns boolean
        if ( not ( GetSpellAbilityId() == 'A0FM' ) ) then
            return false
        endif
        return true
    endfunction

    function Trig_Dragula_Func003002003001 takes nothing returns boolean
        return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) != true )
    endfunction

    function Trig_Dragula_Func003002003002001001 takes nothing returns boolean
        return ( IsUnitAliveBJ(GetFilterUnit()) == true )
    endfunction

    function Trig_Dragula_Func003002003002001002 takes nothing returns boolean
        return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true )
    endfunction

    function Trig_Dragula_Func003002003002001 takes nothing returns boolean
        return GetBooleanAnd( Trig_Dragula_Func003002003002001001(), Trig_Dragula_Func003002003002001002() )
    endfunction

    function Trig_Dragula_Func003002003002002 takes nothing returns boolean
        return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Spell_Dragula_Dummy)) == true )
    endfunction

    function Trig_Dragula_Func003002003002 takes nothing returns boolean
        return GetBooleanAnd( Trig_Dragula_Func003002003002001(), Trig_Dragula_Func003002003002002() )
    endfunction

    function Trig_Dragula_Func003002003 takes nothing returns boolean
        return GetBooleanAnd( Trig_Dragula_Func003002003001(), Trig_Dragula_Func003002003002() )
    endfunction

    function Trig_Dragula_Func009A takes nothing returns nothing
        call KillDestructable( GetEnumDestructable() )
    endfunction

    function Trig_Dragula_Timer_Func001A takes nothing returns nothing
        local unit E = GetEnumUnit()
        local location L = GetUnitLoc(E)
        local location L3 = GetUnitLoc(udg_Spell_Dragula_Dummy)
        local location L2 = PolarProjectionBJ(L, 5.00, AngleBetweenPoints(L, L3))
        call SetUnitPositionLoc( E, L2 )
        call RemoveLocation(L)
        call RemoveLocation(L2)
        call RemoveLocation(L3)
        set E = null
    endfunction

    function DragulaPush takes nothing returns nothing
        local location L = GetUnitLoc(udg_Spell_Dragula_Dummy)
        local group G = GetUnitsInRangeOfLocMatching(875.00, L, Condition(function Trig_Dragula_Func003002003))
        call ForGroupBJ( G, function Trig_Dragula_Timer_Func001A )
        set G = null
        call DestroyGroup(G)
        call RemoveLocation(L)
    endfunction

    function Trig_Dragula_Actions takes nothing returns nothing
        local trigger T = CreateTrigger()
        local location L = GetSpellTargetLoc()
        call CreateNUnitsAtLoc( 1, 'u00R', GetOwningPlayer(GetTriggerUnit()), L, bj_UNIT_FACING )
        set udg_Spell_Dragula_Dummy = GetLastCreatedUnit()
        call PlaySoundOnUnitBJ( gg_snd_PossessionMissileLaunch1, 100, GetLastCreatedUnit() )
        call UnitAddAbilityBJ( 'A0FN', GetLastCreatedUnit() )
        call SetUnitAbilityLevelSwapped( 'A0FN', GetLastCreatedUnit(), GetUnitAbilityLevelSwapped('A0FM', GetTriggerUnit()) )
        call UnitApplyTimedLifeBJ( 7.00, 'BTLF', GetLastCreatedUnit() )
        call EnumDestructablesInCircleBJ( 875.00, L, function Trig_Dragula_Func009A )
        call TriggerRegisterTimerEventPeriodic( T, 0.05 )
        call TriggerAddAction( T, function DragulaPush )
        call UnitDamageTargetBJ( GetTriggerUnit(), GetTriggerUnit(), ( 100.00 + ( 100.00 * I2R(GetUnitAbilityLevelSwapped('A0FM', GetTriggerUnit())) ) ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
        call TriggerSleepAction( 6.00 )
        call DestroyTrigger(T)
        call PlaySoundOnUnitBJ( gg_snd_SoulPreservation, 100, GetLastCreatedUnit() )
        call KillSoundWhenDoneBJ( GetLastPlayedSound() )
        call RemoveLocation(L)
    endfunction

    //===========================================================================
    function InitTrig_Dragula takes nothing returns nothing
        set gg_trg_Dragula = CreateTrigger(  )
        call DisableTrigger( gg_trg_Dragula )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Dragula, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Dragula, Condition( function Trig_Dragula_Conditions ) )
        call TriggerAddAction( gg_trg_Dragula, function Trig_Dragula_Actions )
    endfunction
     


    OBS: The Dummy unit used in this spell is just an effect and has nothing to do with it. Before you say something, I have another trigger that runs a few seconds after the map initializing wich I made the preload of the Dummy spell, the Hero Spell and the Dummy ability (just another visual effect).
    I don't know if it's nescessary to make a preload of the sounds.

    Thank you, for your time.
     
  2. Stranger

    Stranger

    Joined:
    Feb 8, 2011
    Messages:
    31
    Resources:
    0
    Resources:
    0
    BJ functions are non-native functions that are usually used to perform other actions inside of them (the only exception I can think of is DoNothing, which does nothing). Native functions are also faster than BJ functions. Keep in mind that any function you make is technically a BJ function when based on my above statement, but BJ actually stands for Blizzard Jass. All BJ functions are also stored in a jass file called blizzard.j.

    I guess the best answer to your question is that most BJ functions use extra function calls to make coding simpler for users. Since function calls in JASS are rather slow, it's better to use native functions. Using many BJ functions per second can cause a significant drop for your FPS depending on which ones you're using.

    Edit:

    On a side note, I've read somewhere that SetUnitPosition (or SetUnitPositionLoc) causes a drop in FPS because of spammed stop orders (it might also be because pathing is considered). I've never tested that, but you should be using SetUnitX/SetUnitY anyway. Moving many units at one time will generally cause an FPS drop anyway, so try to keep the amount of moving units small when using SetUnitX/SetUnitY or SetUnitPosition.
     
  3. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
  4. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    its because BJs waste function calls... BJs cost at least one more function call...

    and that code you have there is utterly unoptimized...
     
  5. Narg666

    Narg666

    Joined:
    Aug 30, 2009
    Messages:
    112
    Resources:
    0
    Resources:
    0
    So, if I want to do a spell like Enigma's Black Hole from DotA, what should I do?
     
  6. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    SetUnitX/Y... he already said that... that would be the best thing to use... but anyways, a lot of units moving will still cause lag no matter what you use... but SetUnitX/Y will have the least lag...
     
  7. Alain.Mark

    Alain.Mark

    Joined:
    Apr 27, 2011
    Messages:
    185
    Resources:
    1
    JASS:
    1
    Resources:
    1
    You should search the spell resources instead if you want to save time...
     
  8. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,413
    Resources:
    1
    JASS:
    1
    Resources:
    1
    [troll] Blizzard [/troll]
     
  9. elfian

    elfian

    Joined:
    Jun 28, 2008
    Messages:
    350
    Resources:
    2
    Maps:
    2
    Resources:
    2
    BJ is actually Blizzard Junction, not Blizzard JASS. And there is no problem with using BJ functions in triggers that you call once or twice throughout the whole game. The problems come when you use them in big loops or timers with 0.03 timeout or something. It could drag down your performance a lot then. But if you are not gonna post your code on hive, don't worry about BJs, cause the onliest real reason to remove them is to not get scolded by the elite users eheheh
     
  10. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    actually, if you want to give your players the smoothest possible gameplay, avoid BJs if you can...
     
  11. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,270
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    Only a few BJs are considered okay to use in today's jass standards.

    Code (vJASS):
    TriggerRegisterAnyUnitEventBJ()
    is a common one.

    Edit: To answer the original question (although it's been answered already), BJ functions are frowned upon because the vast majority of them don't do anything more than call 1 native.

    So you can either use a BJ which calls a native which does some cpp in the backend

    Or you can use a native which does some cpp in the backend.

    Each function call takes processing power - that's why we try to stick to natives.
     
  12. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    your spell spammed the GetLastCreatedUnit() a lot...In JASS, even in GUI, if you use your reference a lot, you should store it to a variable for better performance...

    In JASS however we use locals, like this...

    Code (vJASS):

     local unit u = GetTriggerUnit()
     local unit dummy
     local real x = GetSpellTargetX()
     local real y = GetSpellTargetY()
     set dummy = CreateUnit(GetOwningPlayer(u), 'u00R', x, y, 0)
     


    Making the variable editor 95% useless and completely useless in vJASS...