• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Warcraft III - Patch 1.31 PTR

Status
Not open for further replies.
Level 19
Joined
Aug 16, 2007
Messages
881
Does the current Warcraft III run at 144Hz with unique, interpolated frames? Or is it duplicating frames?
No idea.
Also I notice that you have two displays, one of which is 60Hz. Try unplugging that and see if a 144Hz video mode is displayed, after confirming the desktop is running at 144Hz. If running in any sort of screen sharing mode the desktop may be limited to 60Hz, the slower of the two displays.
It made no difference. Unplugged the slower monitor, double-checked that the refresh rate of the primary monitor was set to 144 Hz and I'm still limited to 60 in game (both x86 and x86_64 builds).

The issue must be with the patch, as I've no issues with the live version. I asumed the issue could be the new "Integrated Direct3D 11 graphics API", but I tried to launch the game with the "-graphicsapi Direct3D9" command line. No difference.

Try window mode and turn vsync off.
I've tried every single combination with Fullscreen, Windowed Fullscreen and Windows Mode with and without VSync, same results.
 
Level 8
Joined
Jun 13, 2012
Messages
336
sometimes insane ai when given tons of resources and fast build via cheats (human primarily) doesn't go expansion when everyone else does. Also changing brightness doesnt work?


Also generic unit takes damage is where in gui exactly?
 
Last edited:
Level 18
Joined
Jan 1, 2018
Messages
728
ShadowFox04 said:
Did anyone noticed/mentioned that the BlzSpecialEffectsOrientation, roll, etc. natives are also bugged?

Technically, these natives were bugged before patch 1.31, and they simply fixed them now.
The native BlzSpecialEffectsOrientation now correctly takes yaw, pitch, and roll (before it was roll, pitch, yaw, so yaw and roll were swapped).
Additionally, the order in which the rotations are applied has been inverted (intrinsic vs. extrinsic rotation).

For anyone who used my code from this thread, you can update it for 1.31 like this:

Replace GetRotationsYXZ() with GetRotationsZXY():

JASS:
        method GetRotationsZXY takes nothing returns Vector
            local Vector v = Vector.create()
            if this.m12 < 1 - EPSILON then
                if this.m12 > EPSILON - 1 then
                    set v.x = Atan2( -1 * this.m12, SquareRoot( this.m10 * this.m10 + this.m11 * this.m11 ) )
                    set v.y = Atan2( this.m02, this.m22 )
                    set v.z = Atan2( this.m10, this.m11 )
                else
                    debug call BJDebugMsg( "-Pole (ZXY)" )
                    set v.x = bj_PI / 2
                    set v.y = -1 * Atan2( -1 * this.m01, this.m00 )
                    set v.z = 0
                endif
            else
                    debug call BJDebugMsg( "+Pole (ZXY)" )
                    set v.x = bj_PI / -2
                    set v.y = Atan2( -1 * this.m01, this.m00 )
                    set v.z = 0
            endif
            return v
        endmethod


Then you can use call BlzSetSpecialEffectOrientation( effect, v.y, v.x, v.z ).
Note that the Vector contains pitch, yaw, roll, while the native takes yaw, pitch, roll.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
What kind of benefits does LUA offer over vJASS? Aside from syntax.
It is "Lua".

The dynamic nature of the language is the main benefit. For example there is no array size limit in Lua, neither is there a limit to the number of mapping data structures. One can also freely pass around functions without hacky work arounds. Then there are the native libraries to do stuff that was not easily or quickly possible with JASS before.
x86_64 crashed when I tried to open a melee map, x86 is just laggy as hell
You do not really meet what I would think are the minimum requirements. Integrated GPU on a very low end CPU with only 2GB of memory. Adding more memory, eg to 4 GB, would likely fix the crashes to some extent.
The issue must be with the patch, as I've no issues with the live version. I asumed the issue could be the new "Integrated Direct3D 11 graphics API", but I tried to launch the game with the "-graphicsapi Direct3D9" command line. No difference.
You need to confirm that the live version does produce unique frames at 144Hz. It could be producing 60 frames per second and duplicating them to be at 144Hz. Maybe something like OBS could be used to record at 144Hz (if resources allow) to check for differences between frames.
Couldn't performance issues be intentional on Blizzard's part? So as to push everyone to Reforged?
Unlikely. More likely is that they are intentional for the PTR as the build has fewer optimizations to make debugging easier. In any case it is important to make them aware that there has been significant performance regression in case they need to do some optimization work.

Also important to note that the 64 bit build might inherently be slower than the 32 bit build purely because of larger pointer sizes. However since more registers helps to combat this to some extent usually the difference should be a few percent at most (either positive or negative) and not the massive reductions people are reporting.
Lua is an actual programming language.

On the side note, does the Lua module system aka Lua's "require" work in Wc3? or all scripts are loaded? I might make my Lua libraries Wc3-compatible if it doesn't work.
Currently you can either select to run JASS2 or Lua only. However if Lua is selected then a JASS2Lua transpiler is run to convert all JASS into Lua for execution by the Lua virtual machine. This transpiler has bugs but hopefully they will be resolved before release. It also technically means that, when it is working, one could get a pure JASS map and at a flip of a button convert it to Lua and start writing and replacing triggers with Lua as desired.
 

~El

Level 17
Joined
Jun 13, 2016
Messages
556
On the side note, does the Lua module system aka Lua's "require" work in Wc3? or all scripts are loaded? I might make my Lua libraries Wc3-compatible if it doesn't work.

Nope. `require` isn't even available as a function in WC3, they disabled it. Just like with JASS, all code is compiled into a single file, "war3map.lua" and then distributed like that.
 
Level 4
Joined
May 17, 2008
Messages
75
What kind of benefits does LUA offer over vJASS? Aside from syntax.
I've never used LUA.

In addition to what Dr Super Good said, among other things, there's the ability to have functions return multiple values, and garbage collection. The garbage collection alone is a long time coming, since you practically have to beat JASS2 with a superconducting magnet to prevent it from leaking memory.
 

~El

Level 17
Joined
Jun 13, 2016
Messages
556
In addition to what Dr Super Good said, among other things, there's the ability to have functions return multiple values, and garbage collection. The garbage collection alone is a long time coming, since you practically have to beat JASS2 with a superconducting magnet to prevent it from leaking memory.

Just keep in mind that you still have to manually manage WC3 API objects, such as Forces, Locations, etc. by calling the appropriate Remove/Destroy functions.

However, one of the blizzard devs in discord mentioned that eventually they plan to auto-reclaim most of these objects as well, and generally improve on the leak situation. Lua should help with that a great deal too.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
The garbage collection alone is a long time coming, since you practically have to beat JASS2 with a superconducting magnet to prevent it from leaking memory.
According to Will there is going to be more garbage collection in future versions. Currently in 1.31 using either JASS2 or Lua one still has to explicitly destroy complex types such as locations. That said Lua is not prone to the local declared local handle variable reference counter leak on return bug, but that might also eventually be fixed for JASS2.
 
Sounds like using Lua instead of JASS in the future is a no-brainer, unless JASS is significantly improved which seems unlikely.
Also seems like it won't be that hard to convert existing JASS systems/scripts to Lua if that conversion tool isn't too buggy.

Although if I'm being honest, I've gotten used to (v)JASS's clunky syntax and the manual garbage collection doesn't bother me that much. But I guess using Lua would significantly reduce the amount of time and effort you need to invest to code something, and make it more manageable.
 
Level 20
Joined
Apr 12, 2018
Messages
494
I don't know. It sounds to me like Lua is going to be hamstrung to limitations imposed by JASS if all they're doing is converting Lua to JASS at runtime.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
I don't know. It sounds to me like Lua is going to be hamstrung to limitations imposed by JASS if all they're doing is converting Lua to JASS at runtime.
No they are not converting Lua to JASS2.

Warcraft III has 2 modes of operation. One with the historic JASS2 virtual machine and the other with the new Lua virtual machine. For compatibility with JASS scripts, when a map is set to use the Lua virtual machine then all JASS is transpiled to Lua using JASS2Lua on map save. The opposite does not happen since there is and will never be a Lua2JASS converter. The Lua virtual machine also reads the same natives and constants as the JASS2 virtual machine to help with this process.

The Lua implementation in Warcraft III is a full Lua implementation minus IO. This means you have full control over tuning the garbage collectors, full control over metatables and full control over error processing.
 
Last edited:
Nope. `require` isn't even available as a function in WC3, they disabled it. Just like with JASS, all code is compiled into a single file, "war3map.lua" and then distributed like that.

Now that is disappointing.

Either I have to write a module system for Wc3 Lua or write an IIFE bundler to turn my libraries Wc3-compatible

Currently you can either select to run JASS2 or Lua only. However if Lua is selected then a JASS2Lua transpiler is run to convert all JASS into Lua for execution by the Lua virtual machine. This transpiler has bugs but hopefully they will be resolved before release. It also technically means that, when it is working, one could get a pure JASS map and at a flip of a button convert it to Lua and start writing and replacing triggers with Lua as desired.

This doesn't really answer my question.
 
Last edited:
Level 6
Joined
Jul 16, 2008
Messages
35
Invalid magic number in map header.
 

Attachments

  • 2019-04-28_072857.jpg
    2019-04-28_072857.jpg
    134.1 KB · Views: 148
Level 5
Joined
May 10, 2018
Messages
129
1. Cannot convert ability to integer.

2. Cannot get/set bufftip or bufftooltip, even if buff extends ability.

Still,

3. Still no way to capture a normal attack (I mean weapon attack) with accuracy.

4. Still no way to get the order id of an ability.
(Well, in 1.31 we can obtain channel abilities' order id.
I don't know what ABILITY_SLF_BASE_ORDER_ID_ANS5/ABILITY_SLF_BASE_ORDER_ID_SPB5 are. However, only ABILITY_SLF_BASE_ORDER_ID_NCL6 returns the order string of a specific channel ability.)

5. Still no way to manipulate cool down of a cooling-down ability. (SetUnitAbilityCooldownRemaining)
(There should be a way! Because 'Aspb' can make it)

6. Still no native support for ability with charges. Like the owl ability of huntress or like ones in MOBA (slightly different but either will be good).


Overall, 1.31 is good! Especially damage detection and type ability is 'revived'!

Edit:
7. Still no way to turn off computer auto-casting!!!
 
Last edited:
Level 6
Joined
Jul 16, 2008
Messages
35
Some kind of nonsense from my map was completely erased base of import, when it was opened in the editor and after editing I tried to save my map, but I wrote that it was impossible to save, I paid attention to the way C \ which I opened was completely removed without my permission by the editor, it was only possible to save the version that was opened in the editor to the desktop, however, it was saved without import, it is partially missing. NEGATIVE .

Pay attention in the old version, everything is fine, but the new one is ruined by imports and not only.

communication is broken if you open it, then my hero for some reason shoots buildings.

And buildings that were neutral became enemy units. All he did was open the map in the new version of the editor and re-save. And the original map from where it opened the editor for some reason deleted it and erased it from the C drive where it lay. why does the editor take action without my approval?
 

Attachments

  • Enfo CE v3.5.w3x
    3.2 MB · Views: 121
  • Enfo CE v3.5 Patch 1.31.w3x
    682.1 KB · Views: 150
Last edited:
Level 6
Joined
Jul 16, 2008
Messages
35
The editor deleted my working version of my map without errors from the C drive and left me a broken version of the map with errors, which for some reason refused to save at the beginning when I saved not just re-save the map.


Disgusting version of the editor. The editor is constantly knocking out. There is not even a syntax highlighting code. JNGP is much better and fewer departures when
 
3. Still no way to capture a normal attack (I mean weapon attack) with accuracy.
In most maps no unit uses attacktype spell as attack and attacks allways have damage type normal. Therefore with the restriction to not use attacktype spell for attacks one should be able to detect damage from attacks by something like that:

JASS:
function OnDamage takes nothing returns nothing
   //not attacktype spell and damage Normal.
   if BlzGetEventAttackType  () != ATTACK_TYPE_NORMAL and BlzGetEventDamageType() == DAMAGE_TYPE_NORMAL then
//Debug Print msg
       call BJDebugMsg("AttackDamage: "+GetUnitName(GetEventDamageSource())+" -> "+GetUnitName(GetTriggerUnit()))
   endif

endfunction

//===========================================================================
function InitTrig_Unbezeichneter_Ausl__ser_001 takes nothing returns nothing
   local trigger trig = CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_DAMAGED )
    call TriggerAddAction( trig, function OnDamage)
endfunction
 
Level 19
Joined
Aug 16, 2007
Messages
881
You need to confirm that the live version does produce unique frames at 144Hz. It could be producing 60 frames per second and duplicating them to be at 144Hz. Maybe something like OBS could be used to record at 144Hz (if resources allow) to check for differences between frames.
I've attached a 10s video of recorded 144 fps footage of the live version of the game.

I went frame by frame in VLC, but I'm not sure how to properly make the decision if it's unique frames or not. The models appears to run and update at a lower fps, but cursor and "patrol-command-point"-model appears to be updated every frame of 144 frames?
 

Attachments

  • wc3_live_144fps_recording.rar
    5.9 MB · Views: 147
Level 19
Joined
Aug 16, 2007
Messages
881
I've also done some experimenting with the new abilityfield natives; trying to change the ability hotkey at runtime. Unfortunately it appears to be impossible.

It's easy enough to change other fields, such as Cast Range, etc. I've not found any issues with these natives so far.

You can call any "Set" integer/string/real/boolean native for any fieldID, it will not crash the game and simply not work if the fieldID is of another type.

I've not done any testing with the "LevelArray" natives, but I'd guess these are for "Buffs" and "Targets Allowed" fieldIDs, with multiple selections.

JASS:
function ChangeAbilityFieldTest_Actions takes nothing returns nothing

    /*
    native BlzSetAbilityBooleanLevelField              takes ability whichAbility, abilitybooleanlevelfield whichField, integer level, boolean value returns boolean
    native BlzSetAbilityIntegerLevelField              takes ability whichAbility, abilityintegerlevelfield whichField, integer level, integer value returns boolean
    native BlzSetAbilityRealLevelField                 takes ability whichAbility, abilityreallevelfield whichField, integer level, real value returns boolean
    native BlzSetAbilityStringLevelField               takes ability whichAbility, abilitystringlevelfield whichField, integer level, string value returns boolean
    */

    local unit u = gg_unit_Hpal_0000

    local integer abilID = 'Amls' // Aerial Shackles
    //local integer fieldID = 'ahky' // Ability Hotkey FieldID in Object Editor (doesn't appear to work)
    local integer fieldID = 'aran' // Ability Cast Range FieldID in Object Editor

    local integer integerValue = 1231
    local string stringValue = "D"
    local real realValue = 9999.0

    call DisplayTimedTextToForce( GetPlayersAll(), 30, "fieldID: " + I2S(fieldID)) // 'ahky' returns 1634233209

    call BlzSetAbilityIntegerLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityIntegerLevelField(fieldID), 1, integerValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "Int Field: " + I2S(BlzGetAbilityIntegerLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityIntegerLevelField(fieldID), 0) ))

    call BlzSetAbilityStringLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityStringLevelField(fieldID), 1, stringValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "String Field: " + BlzGetAbilityStringLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityStringLevelField(fieldID), 0) )

    call BlzSetAbilityRealLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityRealLevelField(fieldID), 1, realValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "Real Field: " + R2S(BlzGetAbilityRealLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityRealLevelField(fieldID), 0) ))

    set u = null
endfunction

//===========================================================================
function InitTrig_ChangeAbilityFieldTest takes nothing returns nothing
    local trigger t = CreateTrigger( )
    call TriggerRegisterPlayerChatEvent( t, Player(0), "t", true )
    call TriggerAddAction( t, function ChangeAbilityFieldTest_Actions )
endfunction

Maybe it's already mentioned, but there's a bug (I'd asume atleast) with all "Get" natives, such as
native BlzGetAbilityIntegerLevelField takes ability whichAbility, abilityintegerlevelfield whichField, integer level returns integer
where the "integer level" argument must be 1 lower than the targeted level (i.e. 0 = 1 and 1 = 2, etc). The "Set" natives doesn't have this issue and works differently (i.e. level 1 = 1 and 2 = 2, etc).
 
Last edited:

Ardenaso

HD Model Reviewer
Level 33
Joined
Jun 22, 2013
Messages
1,811
You do not really meet what I would think are the minimum requirements. Integrated GPU on a very low end CPU with only 2GB of memory. Adding more memory, eg to 4 GB, would likely fix the crashes to some extent.

But patch the latest patch works perfectly fine though, so I assume that it won't be different anymore here. But I guess I'll just find out how to get more memory to my laptop.
 
Level 5
Joined
May 10, 2018
Messages
129
In most maps no unit uses attacktype spell as attack and attacks allways have damage type normal. Therefore with the restriction to not use attacktype spell for attacks one should be able to detect damage from attacks by something like that:

JASS:
function OnDamage takes nothing returns nothing
   //not attacktype spell and damage Normal.
   if BlzGetEventAttackType  () != ATTACK_TYPE_NORMAL and BlzGetEventDamageType() == DAMAGE_TYPE_NORMAL then
//Debug Print msg
       call BJDebugMsg("AttackDamage: "+GetUnitName(GetEventDamageSource())+" -> "+GetUnitName(GetTriggerUnit()))
   endif

endfunction

//===========================================================================
function InitTrig_Unbezeichneter_Ausl__ser_001 takes nothing returns nothing
   local trigger trig = CreateTrigger()
       call TriggerRegisterAnyUnitEventBJ( trig, EVENT_PLAYER_UNIT_DAMAGED )
    call TriggerAddAction( trig, function OnDamage)
endfunction
Most Maps must exclude DotA, one of the most famous maps on war3.
JASS:
function V08 takes unit Z77,unit X77,integer V58,real P08 returns nothing
if V58==AA4 then
return
endif
if V58==AB4 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_FIRE,WEAPON_TYPE_WHOKNOWS)
elseif V58==AC4 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
elseif V58==A34 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)
elseif V58==A64 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_PIERCE,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
elseif V58==AL4 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
elseif V58==A14 then
call SetUnitState(X77,UNIT_STATE_LIFE,RMaxBJ(GetUnitState(X77,UNIT_STATE_LIFE)-P08,1))
if GetUnitState(X77,UNIT_STATE_LIFE)<2 then
call UnitRemoveBuffs(X77,true,true)
call UnitRemoveAbility(X77,'Aetl')
call UnitDamageTarget(CreateUnit(GetOwningPlayer(Z77),'e00E',0,0,0),X77,100000000.,true,false,ATTACK_TYPE_MELEE,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
endif
elseif V58==A04 then
if GetUnitAbilityLevel(X77,'Aetl')>0 or GetUnitAbilityLevel(X77,'B01N')>0 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
endif
elseif V58==AA94 then
call UnitDamageTarget(Z77,X77,P08,true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
endif
endfunction
 
Level 12
Joined
Nov 3, 2013
Messages
989
In most maps no unit uses attacktype spell as attack and attacks allways have damage type normal. Therefore with the restriction to not use attacktype spell for attacks one should be able to detect damage from attacks by something like that:
And what about ranged attacks? Unless there's no projectile simply using a DDS won't work.

Also, iirc DDS don't register missed attacks.


Anyway, this along with some other listed features which I've been eagerly waiting for and expected from 1.31 still haven't been added... But the things listed on Producer Update: Natives List are meant to be added at some point, right?

It's fine so long as it gets added soon™.

JASS:
    constant unitevent EVENT_UNIT_DAMAGE_RELEASE         
       //This triggers when a unit's attack is released, aka when a melee unit hits its target or a ranged unit launches a missile.
 
Invalid magic number in map header.

The war3map.w3i format changed. I wrote a converter but it only works one way. You shouldn't be uploading PTR maps to epicwar anyway.

For those of you who want to play with Lua this is what I use.

JNGP Lua Edition - Combining JASS/vJass/Lua

It allows you to combine JASS and Lua. You can also code in external editors wile having the World Editor open. Hopefully Blizzard implements something similar natively. All we to would need to use Lua from code editors is the ability to include other Lua files from within the map's MPQ.

luavscode-gif.321802

I'll be releasing my VS Code setup soon.
 

Attachments

  • luavscode.gif
    luavscode.gif
    1.1 MB · Views: 1,186
Last edited:
Level 5
Joined
May 10, 2018
Messages
129
I've also done some experimenting with the new abilityfield natives; trying to change the ability hotkey at runtime. Unfortunately it appears to be impossible.

It's easy enough to change other fields, such as Cast Range, etc. I've not found any issues with these natives so far.

You can call any "Set" integer/string/real/boolean native for any fieldID, it will not crash the game and simply not work if the fieldID is of another type.

I've not done any testing with the "LevelArray" natives, but I'd guess these are for "Buffs" and "Targets Allowed" fieldIDs, with multiple selections.

JASS:
function ChangeAbilityFieldTest_Actions takes nothing returns nothing

    /*
    native BlzSetAbilityBooleanLevelField              takes ability whichAbility, abilitybooleanlevelfield whichField, integer level, boolean value returns boolean
    native BlzSetAbilityIntegerLevelField              takes ability whichAbility, abilityintegerlevelfield whichField, integer level, integer value returns boolean
    native BlzSetAbilityRealLevelField                 takes ability whichAbility, abilityreallevelfield whichField, integer level, real value returns boolean
    native BlzSetAbilityStringLevelField               takes ability whichAbility, abilitystringlevelfield whichField, integer level, string value returns boolean
    */

    local unit u = gg_unit_Hpal_0000

    local integer abilID = 'Amls' // Aerial Shackles
    //local integer fieldID = 'ahky' // Ability Hotkey FieldID in Object Editor (doesn't appear to work)
    local integer fieldID = 'aran' // Ability Cast Range FieldID in Object Editor

    local integer integerValue = 1231
    local string stringValue = "D"
    local real realValue = 9999.0

    call DisplayTimedTextToForce( GetPlayersAll(), 30, "fieldID: " + I2S(fieldID)) // 'ahky' returns 1634233209

    call BlzSetAbilityIntegerLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityIntegerLevelField(fieldID), 1, integerValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "Int Field: " + I2S(BlzGetAbilityIntegerLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityIntegerLevelField(fieldID), 0) ))

    call BlzSetAbilityStringLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityStringLevelField(fieldID), 1, stringValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "String Field: " + BlzGetAbilityStringLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityStringLevelField(fieldID), 0) )

    call BlzSetAbilityRealLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityRealLevelField(fieldID), 1, realValue)
    call DisplayTimedTextToForce( GetPlayersAll(), 30, "Real Field: " + R2S(BlzGetAbilityRealLevelField( BlzGetUnitAbility(u, abilID), ConvertAbilityRealLevelField(fieldID), 0) ))

    set u = null
endfunction

//===========================================================================
function InitTrig_ChangeAbilityFieldTest takes nothing returns nothing
    local trigger t = CreateTrigger( )
    call TriggerRegisterPlayerChatEvent( t, Player(0), "t", true )
    call TriggerAddAction( t, function ChangeAbilityFieldTest_Actions )
endfunction

Maybe it's already mentioned, but there's a bug (I'd asume atleast) with all "Get" natives, such as
native BlzGetAbilityIntegerLevelField takes ability whichAbility, abilityintegerlevelfield whichField, integer level returns integer
where the "integer level" argument must be 1 lower than the targeted level (i.e. 0 = 1 and 1 = 2, etc). The "Set" natives doesn't have this issue and works differently (i.e. level 1 = 1 and 2 = 2, etc).
Blizzard please fix this ASAP, in case this bug would become a feature in the next version for campatibility!
 
And what about ranged attacks? Unless there's no projectile simply using a DDS won't work.
ranged attacks use the same damage type, I don't see a problem for simple ranged attacks. Problem could be splash/multitarget/bouncing ranged attacks, cause that way one can not differ between main target and additional targets, without additional effort.

Also, iirc DDS don't register missed attacks.
I also don't see any good/simple way to detect missed attacks with damage events, currently.


When you deal the damage with code, you have the power to prevent your own code-damage seen as attack by adding with low additional effort. But none of the built in spells/actions will be miss interpreted, cause the don't inflict dat attacktype damagetype combo, only attacks do.


The GUI getters of unit weapons use the wrong field options.
 
Last edited:
Level 9
Joined
Feb 24, 2018
Messages
342
Holy @#$%!!!
Integrated text colorizer!

Also Ritual Dagger ability can apparently can be modified into AoE heal centered on target, either instant or periodic, and it doesn't necessarily has to kill the target! Very useful.

Funny thing is that ability of new Orb of Fire is called "Shadow Meld (item) and its fields are named after Shadow Meld fields, except they have values of OfF ability and it has projectile and orb sfx. I wonder if I tick fields that have nothing to do with Orb of Fire, like "Permanent Cloak"...
 
Level 12
Joined
Nov 3, 2013
Messages
989
ranged attacks use the same damage type, I don't see a problem for simple ranged attacks. Problem could be splash/multitarget/bouncing ranged attacks, cause that way one can not differ between main target and additional targets, without additional effort.
Well the thing is that a DDS registers when you deal damage, not when you fire whatever projectile you're shooting.

i.e. with a dds you can detect when a projectile hits, but not when it's shot.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
Invalid magic number in map header.
Please do not distribute 1.31 PTR maps since they might not be compatible with 1.31 release. For now it is only for testing. Also report that issue to EpicWar.
1. Cannot convert
ability
to
integer
And what should this conversion do? Or are you asking for a native to convert from an ability to its Ability Type ID?
Some kind of nonsense from my map was completely erased base of import, when it was opened in the editor and after editing I tried to save my map, but I wrote that it was impossible to save, I paid attention to the way C \ which I opened was completely removed without my permission by the editor, it was only possible to save the version that was opened in the editor to the desktop, however, it was saved without import, it is partially missing. NEGATIVE .

Pay attention in the old version, everything is fine, but the new one is ruined by imports and not only.

communication is broken if you open it, then my hero for some reason shoots buildings.

And buildings that were neutral became enemy units. All he did was open the map in the new version of the editor and re-save. And the original map from where it opened the editor for some reason deleted it and erased it from the C drive where it lay. why does the editor take action without my approval?
Your "good" map is corrupt. When I try opening it in WorldEdit it tries to request 180GB of memory. Only enterprise level hardware (AMD ThreadRipper, Intel Xenon) can have that much memory and nothing one can make in Warcraft III should ever need that much memory anyway.

If you "protected" your map, please post the unprotected version to confirm that it corrupts on map save with the 1.31 PTR editor. If you are uncomfortable handling it to the public, consider sending it to Kam (Will is on holiday ATM) along with the steps needed to reliably to recreate the corruption.
Will LUA perform better? As I recall, you said JASS2 was converted to some crappy bytecode. Hopefully, the same does not happen with LUA?
All such languages work via bytecode. Even Java, a serious programming language, does.

Inherently performance should be similar since both use runtime resolution of types and such. However Lua might be faster due to it being a lot more mature and maintained than JASS2.

Technically Lua can be a lot faster if a JIT compiling virtual machine is used. However Will has confirmed that they are using the standard Lua implementation (not JIT compiler) due to requiring the use of other libraries to serialize the Lua state for save/load game support. They might look into JIT Lua support if needs dictate it, but currently they do not.

That said some tasks Lua will perform a lot better than JASS due to how the language works and what the language supports inherently. For example passing functions around dynamically is trivial for Lua but with JASS2 needed some very complex hacky code such as using triggers or passing around function name strings. There is also no limit to table size and Lua tables likely perform better with large mapping counts compared with hashtables. Functionally there is no reason to use hashtable in Lua since Lua natively offers better functionality. Lua also has built in bitwise operators which will almost certainly be faster than the newly added JASS2 natives to achieve the same results.

Where Lua will be slower is due to its garbage collector. JASS did not really have a serious one since most JASS related data, other than handles, was static and declared at map initialization. Lua on the other hand can incure significant overhead if one abuses creating lots of tables which will eventually be garbage collected. However one can fine tune the garbage collector and through careful programming one can also reduce the amount of garbage produced if the collector performance does become an issue.

Lua has fantastic error reporting. If a native function call fails it will throw an error which one can catch and print. This alone makes it a lot better than JASS2 to work with since what used to take 30 minutes of trial and error to diagnose could be discovered the instance it is encountered. For people using Lua I strongly recommend taking advantage of this error reporting when developing code as it could save you a lot of time without much overhead. You can even log such errors in production code if you want!
Bytecode is needed, it's like virtual machine code, so the only code the JASS- or Lua VM (virtual machine) can read. So maybe it's not necessarily faster, but depends how the VM is built.
It is not JIT compiling. It is more mature so possibly more optimized.
I went frame by frame in VLC, but I'm not sure how to properly make the decision if it's unique frames or not. The models appears to run and update at a lower fps, but cursor and "patrol-command-point"-model appears to be updated every frame of 144 frames?
Use the lower frame rate then. The unit models are the most important thing since they represent the action and unless they are smooth at 144Hz having something else appear smooth is not useful as it will appear inconsistent.

In any case I guess we could add high refresh rate support to the list of desired features. However this may or many not be possible depending on how the game is designed as perhaps it is not possible interpolate animations between frames like how StarCraft II works to achieve smooth high refresh rate animation.
But patch the latest patch works perfectly fine though, so I assume that it won't be different anymore here. But I guess I'll just find out how to get more memory to my laptop.
The x86-64 build will use more memory due to larger pointer sizes (64bit vs 32bit). Additionally like all other current Blizzard games they might drop support for D3D9 and x86 in the future.
 
Level 2
Joined
Feb 27, 2015
Messages
8
I was trying to use this function in our shiny new Lua script.
Lua:
print(BlzGetAbilityTooltip('AHfs', 1))
It gave no output and crashed the rest of the calling function.
I found these lines in the common.j file. The AbilityId function always gives 0, whatever the input.
vJASS:
// Not currently working correctly...
constant native AbilityId                   takes string  abilityIdString   returns integer
constant native AbilityId2String            takes integer abilityId         returns string

So I decided to do it myself. I thought this would work, but it just gives me "Tooltip missing!"
Lua:
function GetAbilityID (code)
    local length = #code
    if length == 4 then
        local id = 0
        for i = 1, length do
            id = id + (256 ^ (length - i)) * code:byte(i)
        end
        return id | 0
    else
        return 0, 'Error: ' .. code .. ' is not an ability!'
    end
end
print(BlzGetAbilityTooltip(GetAbilityID('AHfs'), 1))

After some debugging, I found the issue. In the standalone Lua interpreter, the function call gives the expected value 1095263859. But in game, it gives 1095263744.
Lua:
print(GetAbilityID('AHfs'))
I suspect the error is related to the floating point numbers. It is. The following version works correctly.
Lua:
function GetAbilityID (code)
    local length = #code
    if length == 4 then
        local id = 0
        for i = 1, length do
            -- Must convert floats to integers, or there will be severe rounding errors
            id = id + (256 ^ (length - i) | 0) * code:byte(i)
        end
        return id
    else
        return 0, 'Error: ' .. code .. ' is not an ability!'
    end
end
My conclusion:
  1. Automatic conversion from ability ID string to integer does not work in Lua scripts
  2. There are some subtle bugs in the new Lua VM related to floating point numbers
  3. Integer and Real types are not indistinguishable even in Lua scripts
 
Last edited:

Ardenaso

HD Model Reviewer
Level 33
Joined
Jun 22, 2013
Messages
1,811
The x86-64 build will use more memory due to larger pointer sizes (64bit vs 32bit). Additionally like all other current Blizzard games they might drop support for D3D9 and x86 in the future.

Kinda going off-topic here, but would you rather recommend saving for a new laptop instead of buying a new memory card then?
 

~El

Level 17
Joined
Jun 13, 2016
Messages
556
  1. Automatic conversion from ability ID string to integer does not work in Lua scripts
  2. There are some subtle bugs in the new Lua VM related to floating point numbers
  3. Integer and Real types are not indistinguishable even in Lua scripts

1. It doesn't work in JASS either. JASS simply treats any single-quote enclosed "string" as an integer, and does the conversion for you. 'xxxx' in JASS is not a string, it's an integer.
2. This might be related to the fact that the standalone Lua runner is compiled in x64 mode, while WC3's Lua may be x86, which would limit numbers (integers and floats) to 32 bits.
3. This isn't entirely true. Lua has a single "number" type which can be both integer and float, but it switches internal representations depending on what you do with the number. For example, bitshift operators always convert the arguments to integers, and produce integers.

You're encouraged to take use of Lua's inbuilt bitwise operators. With those, the String2Id function becomes trivial:

Lua:
function String2Int(input)
    local bytes = {string.byte(input, 1, 4)}

    return (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4]
end
 
Level 2
Joined
Feb 27, 2015
Messages
8
1. It doesn't work in JASS either. JASS simply treats any single-quote enclosed "string" as an integer, and does the conversion for you. 'xxxx' in JASS is not a string, it's an integer.
2. This might be related to the fact that the standalone Lua runner is compiled in x64 mode, while WC3's Lua may be x86, which would limit numbers (integers and floats) to 32 bits.
3. This isn't entirely true. Lua has a single "number" type which can be both integer and float, but it switches internal representations depending on what you do with the number. For example, bitshift operators always convert the arguments to integers, and produce integers.

You're encouraged to take use of Lua's inbuilt bitwise operators. With those, the String2Id function becomes trivial:

Lua:
function String2Int(input)
    local bytes = {string.byte(input, 1, 4)}

    return (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | bytes[4]
end
  1. I know nothing about JASS, so thanks for explaining this.
  2. I'm using the x64 version World Editor and Warcraft III. I also tried this trick from StackOverflow, and #string.pack("T",0)*8 gives 64, so Warcraft's Lua should also be x64. That said, only the devs can be certain about this. Still, I think this issue is worth investigating.
  3. I understand how Lua 5.3 handles the new integer representation. I'm trying to say that when using Jass native function, this difference matters. For example, BlzGetAbilityTooltip(1095263859, 1) works but BlzGetAbilityTooltip(1095263859.0, 1) crashed. There seems to be no automatic conversion here.
  4. Thanks for giving an alternative version. I'm a Python programmer who rarely uses bitwise operators, and I just start to learn Lua specifically for Warcraft III. Your help is much appreciated.
EDIT: Now I'm certain this problem is very likely caused by a 32-bit float.
This gives 1095263744.000000 1095263872 (WRONG)
C:
float t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
printf("%f %d", t, (int)(t+115));
And this gives 1095263744.000000 1095263859 (CORRECT)
C:
double t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
printf("%f %d", t, (int)(t+115));
 
Last edited:

~El

Level 17
Joined
Jun 13, 2016
Messages
556
  1. I understand how Lua 5.3 handles the new integer representation. I'm trying to say that when using Jass native function, this difference matters. For example, BlzGetAbilityTooltip(1095263859, 1) works but BlzGetAbilityTooltip(1095263859.0, 1) crashed. There seems to be no automatic conversion here.

That's likely to be expected for a while, now. Blizzard announced Lua support as beta, and it's quite obvious they haven't really adapted anything beyond the bare minimum for Lua.
Being able to accept both integers and reals (or strings, even) in some of the natives would require special code in the C++ side to handle the different types. Right now, it seems, they just assert that the received argument is of the right type (as declared in common.j) and that's about it.

I think in the future we might expect more Lua-specific QOL improvements, but for now, there's a lot of rough edges.

Personally, I think that's fine. For the most part, these things we can deal with.
 
Level 3
Joined
Feb 24, 2018
Messages
39
Yes. Without it, I can't even get the name/tip of an ability.
  1. I know nothing about JASS, so thanks for explaining this.
  2. I'm using the x64 version World Editor and Warcraft III. I also tried this trick from StackOverflow, and #string.pack("T",0)*8 gives 64, so Warcraft's Lua should also be x64. That said, only the devs can be certain about this. Still, I think this issue is worth investigating.
  3. I understand how Lua 5.3 handles the new integer representation. I'm trying to say that when using Jass native function, this difference matters. For example, BlzGetAbilityTooltip(1095263859, 1) works but BlzGetAbilityTooltip(1095263859.0, 1) crashed. There seems to be no automatic conversion here.
  4. Thanks for giving an alternative version. I'm a Python programmer who rarely uses bitwise operators, and I just start to learn Lua specifically for Warcraft III. Your help is much appreciated.
EDIT: Now I'm certain this problem is very likely caused by a 32-bit float.
This gives 1095263744.000000 1095263872 (WRONG)
C:
float t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
printf("%f %d", t, (int)(t+115));
And this gives 1095263744.000000 1095263859 (CORRECT)
C:
double t = pow(256, 3) * 65 + pow(256, 2) * 72 + 256 * 102;
printf("%f %d", t, (int)(t+115));
('>I4'):unpack 'AHfs'
 
Level 3
Joined
May 2, 2017
Messages
5
I've tested new ui functions and this is what i've got so far
I'm definitely doing something wrong, but maybe this map would help someone
Does someone also test it?
 

Attachments

  • ui-test.jpg
    ui-test.jpg
    47.3 KB · Views: 538
  • ui-test.w3m
    18.1 KB · Views: 110

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
Kinda going off-topic here, but would you rather recommend saving for a new laptop instead of buying a new memory card then?
Memory card? Are you referring to a DIMM?

I would need to know the full specs of your current system to give any sort of recommendation.
EDIT: Now I'm certain this problem is very likely caused by a 32-bit float.
This gives 1095263744.000000 1095263872 (WRONG)
And this gives 1095263744.000000 1095263859 (CORRECT)
Warcraft III does not use hardware floats. All floats are software emulated. This is required to keep in sync between computers.
('>I4'):unpack 'AHfs'
Um what? You might want to add some context to why you posted that.
 
Level 3
Joined
Feb 24, 2018
Messages
39
Memory card? Are you referring to a DIMM?

I would need to know the full specs of your current system to give any sort of recommendation.

Warcraft III does not use hardware floats. All floats are software emulated. This is required to keep in sync between computers.

Um what? You might want to add some context to why you posted that.
print ( BlzGetAbilityTooltip (('>I4'):unpack 'AHfs') , 1 ))
Don't thank me. lol
 
Last edited:
Status
Not open for further replies.
Top