This guide has been written to help advanced Warcraft III map developers understand the changes that we’ve made to the JASS functionality. Please note that these changes apply to only a small set of custom map developers, and most Warcraft 3 custom maps remain unaffected. For those developers whose maps are affected by the changes we’ve made, please review the steps below to understand how to bring your map into compliance with our new implementation.
Note: JASS-enabled maps that are not brought into compliance with the may not work correctly or at all after we release the next Warcraft III patch.
Details on our new implementation:
This patch includes 97 new native JASS functions and one new JASS handle type designed to assist map makers. These enhancements are part of a new hashtable storage system which is very similar in structure to the GameCache.
While the original GameCache JASS functions only allowed units and JASS primitives to be stored (Integer, Real, Boolean, and String), hashtables can store most JASS handle types. However unlike the GameCache which uses strings for keys, the hashtable uses integers. Additionally, storing and retrieving data in hashtables are much faster and safer than storing data in the GameCache.
The new functions GetHandleId and StringHash are to assist in turning either a handle or a string into an integer. This indirectly allows handles and strings to be used as hashtable keys.
StringHash takes a string and returns an integer much like S2I, however StringHash can be used on any string.
GetHandleId takes a handle and returns an integer. GetHandleId works exactly like H2I functions that were written with the return bug. In order to reduce the number of JASS naming conflicts with existing maps, we named the function GetHandleId. We ask map makers to not create a GetHandleId alias function with the name H2I, as we will add a native H2I function to JASS in the future.
Hashtable variables can be declared using the type name ‘hashtable’. As mentioned before, hashtables work very similar to gamecache objects. To create a new hashtable call InitHashtable. For example local hashtable ht = InitHashtable() will create a new hashtable object and assign it to ht.
All handle types share the same key namespace. For instance, if you call SavePlayerHandle followed by SaveUnitHandle, with the same keys, then the unit handle will overwrite the player handle. Even though the handle functions share the same key space, The SaveXHandle and LoadXHandle functions are type safe. For instance, calling SavePlayerHandle followed by local unit u = LoadUnitHandle will result with u initialized to null.
All handle objects saved or removed from a hashtable are automatically reference-counted (with the exception of TextTag, Lightning, Image, Ubersplat, and FogState). This allows handle objects to be saved in the hashtable without risk of the object’s being prematurely memory freed. The reference counts are updated when an object is either added to, flushed, or overwritten in a hashtable.