• 🏆 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!

So many Unit Indexers

Status
Not open for further replies.
I see them cropping up all the time and I was wondering if someone could outline a quick difference between all the major Unit Indexers out there. I use Bribe's Unit Event for everything, which uses custom values, but when checking up those other indexers I see mention of hashtables and a certain GetUnitId() native? I imagine GetUnitUserData() would return 0 with some of those indexers then...

Two of the most popular indexers seem to be Nestharus's Unit Indexer and TriggerHappy's UnitDex. I also hear about something called AIDS (lol) and AutoIndex. Can anyone give me a quick rundown of the differences between each system (if you wouldn't mind) and if I should bother switching over to one of them?
 
let's only talk about core functionality.

GUI Unit Indexer (Bribe):
  • GUI friendly.
  • Index from 1-8191.
  • Events for (de-) indexed units.
  • Stores index internaly (in system) into a standard array.
  • Deindex method is not good, and would require extra "Event" system to ensure a good deindex method. But it is gui friendly, as it needs no custom defend ability to detect deindex.
UnitDex (TriggerHappy):
  • (v)JASS-friendly.
  • Index from 1-8191.
  • Events for (de-) indexed units.
  • Stores index internaly (in system) into a standard array.
AIDS (Jesus4Lyf):
  • (v)JASS-friendly.
  • Index from 1-8191.
  • Events for (de)-indexed units.
  • Struct functionality that automaticaly does help to work with custom unit instances. (vJASS only)
  • Stores index internaly (in system) into a standard array.
Autoindex (grim001):
  • (v)JASS-friendly.
  • Index from 1-8190.
  • Events for (de)-indexed units.
  • Struct functionality that automaticaly does help to work with custom unit instances. (vJASS only)
  • (1D) real + integer + struct binding to a unit's index. Variables are globaly provided by the system.
  • Struct to unit association when implementing AutoIndex module. It can help to get a unit's struct instance(s).
    And provides automatic registration/unregistration for struct creation/destruction that have it implemented.
  • Works or with array, or with hashtable. In case you want to use "CustomUnitData" on your own, inside your map, then hashtable can be used and provides the same functionality.
  • Some extra events, that can be used, see AutoEvents - Wc3C.net.
  • Uses 3 hooks. 1 for safety to prevent manual index change ; 2 for providing info about the manual user action to remove unit.
Unit Indexer (Nestharus):
  • ---
I would need to spend too much time again that I could give good critique here, and I honestly don't want that atm. But it has a huge modularity and safety, at least it looks like it when I "quickly scan" it. One should probably read all his "Lab" triggers and tutorials inside the map to get a feeling. (24 tutorial sheets for demo only)
  • So, yes maybe one critique one can say already, is that it's functionality, no matter how far it goes, is probably not very simple to use intuitivly in comparison to others.


I personaly want having the events and jass compatibility. So I like TriggerHappy's very much. It is leight weit, nicely written, and does I think everything I need.
I never tried extra functionality like struct implementations, but it seems if are used to it, that it could save you some time. I did such things always on my own.

if I should bother switching over to one of them?
Bribes indexer is good, if it fits for you. I personaly would not like having an extra event system and I prefer having a good deindex method. But as I use vJASS, it's easy to implement it there, so I just use UnitDex. But UnitDex is of course not GUI friendly by default, etc etc. So I don't know what to use best for you. I hope it helps a bit.
 
Last edited:
I was myself also interested in some differences, and maybe some others, too. So np, you're welcome. ^^

(I have not tested everything), but from code/docu it looks like Bribe's system does not instantly deindex when the unit is removed, but instead, it may happen after an arbitary amount of time. When this runs 32 times then he checks for deindex:

  • -------- --------
  • -------- Check for removed units for every (32) new units created --------
  • -------- --------
  • Set UDexWasted = (UDexWasted + 1)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
    • UDexWasted Equal to 32
  • Then - Actions
    • HERE, THEN COMES DEINDEX
For an instant deindex event, one would require to use a custom ability based on "defend" from human soldier. Bribe doesn't want to have this dependency in GUI I guess.
When a unit leaves the world / is removed, then a "undefend" order is fired always, and so one can provide a good deindex event with it. in vJASS one can create the custom defend ability via script, but in GUI one has to copy it from editor always.

But Bribe suggests in his docu to use his other event system which probably provides a better deindex approach.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I can give a quick rundown on mine if I can remember it all.


1. vJASS Only
2. Index from 1-8191
3. Events for deindexed units.
4. Struct functionality that automaticaly does help to work with custom unit instances. (vJASS only)
5. Stores index internaly (in system) into a standard array.
6. Local deindex events that are specific to a unit. Other Unit Indexers only have global events and require if-statements. This Unit Indexer has events that can be created for specific units.
7. Nested events and code. Chained events and code. Allows for the creation of custom events that can be attached to any Unit Indexer event. From here, these custom events can have new custom events attached to them or code. This allows more control over order of execution, ensuring that everything will always run in the proper order.
8. Support for reverse order events. These are events that run code in reverse order. These are useful for cleanup. I believe the deindex event is by default reverse order. However, a new event can be attached to it that is an in-order event if desired.
- Create For A
- Create For B
- Destroy For B
- Destroy For A
9. The only system that captures all index and deindex events while the map is loading. Index/deindex events may change the state of the game, thus a system that catches them all correctly may result in a different game state from one that does not. How it accomplishes capturing all initial events is that whenever something new is registered to the system while the map is loading, that new thing runs all index/deindex events that have already run to catch it up. Once the map is loaded, this catch up mechanism is disabled.
10. Events in this Unit Indexer run more quickly than native triggers. This is due to the special Trigger library it employs to run its events.



My only other note is that basic Unit Indexer functionality is shown in perhaps the first 1 or 2 very short tutorials (one for index and one for deindex). The advanced features are covered in the remaining ones. It's easy to use and very straightforward if you just want to use the basic API while taking advantage of the good behavior and speed. It is when you want to start getting into all of the craziness of everything else that the other 22ish tutorials come into play.
 
Level 9
Joined
Jul 30, 2012
Messages
156
But hashtables are slooooooooow. At least that's whate everybody says.

It is true that they are slower than arrays, but all those posts complaining about hashtable slowness are probably from 2008~2010. Most of those Benchmark tests are also from before 2011, and computers are now much faster than that time, so using a hashtable these days is not really a bad choice, as it makes things simpler without compromising that much speed.

Btw, I wonder how things would have been if Bytecode execution had been discovered those years. Nestharus would probably be crazy with the possibility to optimize his systems with that :p
 
I mean, I understand that computers are getting better and better all the time, but I use a lot of timers and have been toying with the idea of replacing ranges attacks with a custom missile system in my map, so I try to squeeze out performance wherever I can get it. I still use hahtables, but I avoid them when I can afford to.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Look, I don't know how Warcraft 3's hashtables work, but unless their implementation is extremely horrible, speed shouldn't be a concern.
Many of the dynamically typed languages work with hashtables for basically everything in them (e.g. Python, JavaScript, ...) and they work just fine.
I know people like to spam about O-notations and oh boy what can we do if we have too many buckets and collisions, but that's something whoever built the implementation takes care of, and again, unless for some reason done horribly, is proved to work quite well on MUCH bigger scale than your tiny Jass script.
Without even checking anything, I can instantly assume the Jass calls to the hashtable natives are far more expensive (due to the Jass VM being so unoptimized) than the actual natives.
But take it into perspective, and see if these calls actually matter for speed. Compare them against the code you would have to run without a hashtable. And most importantly, don't do any of these things, because you shouldn't optimize what doesn't need optimization just because it's not 100% efficient, if it runs good enough, then it's good enough.
 
Last edited:
Status
Not open for further replies.
Top