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

[General] Limitations of objects ids

Status
Not open for further replies.
Level 13
Joined
Mar 6, 2008
Messages
852
Hiho,
for a project which I wanted to release this weekend, I am generating over 10,000 objects via compiletime functions.
The first version of the object id generator I am currently using only differentiated via prefix between normal units and hero units,
because hero ids must have a capital letter as first char (e.g. hero = 'W001' / normal unit = 'w001').

Besides the first char thing, I encountered different problems:
  • a comma(,) and a quotation mark(") can't be used for objects that are used by another one like adding abilities to units or trainable units.
  • While the first char is crucial to decide between unit and hero, the other three chars don't distinguish between capital letter and lower case.

Please let me know if you know more limitations of object ids.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
When i dabbled around it quite some time ago i came to the conclusion that nearly everything is allowed but '\0' and '\''. ',' being forbidden is new to me but i guess it could make sense. Also note that these are bytes so values up to '\255' are also allowed.

Ofcourse most of this is rather impossible in normal WE so i directly modified the corrensponding files in the mpq. I can't quite remember what objects i tested. I think units and maybe abilities. Maybe different objects have different limitations?
 
Level 13
Joined
Mar 6, 2008
Messages
852
',' being forbidden is new to me but i guess it could make sense.

It's not forbidden, the objects are still generated correctly, but if the object is an ability and you add this ability to an unit, it won't work.
Because abilities are saved as a string and so you have to follow the rules of a string. A comma breaks the abiltiy id in this case and a quotation mark simply ends the string.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
If you only use digits or letters, you can make a rough 45k different unit types with the same first character.
So 45k human heroes,
45k human units, (repeat for all races)
45k items,
45k abilities, (i think 45k for hero and 45k for items/units)
45k destructibles,
45k upgrades,
and maybe more.

For an object's instance... there is the maximum of the same 45k or almost 1,68 million instances possible... only counting limitations of the handle ids (ids)

I don't know what characters are able to be used and what ones are not but you can stick to the original ones without problems, thats for sure.
 
Level 13
Joined
Mar 6, 2008
Messages
852
Did not someone claim there would be an 8k object limit anyway?
I hope that is not the case, because I wanted to push it a little bit further ^^

Also I have to add that abilities which have a minus (-) in its id don't work.
At the moment, it seems that I have solved all issues with object ids.

But now the Widgetizer can't load my w3a file anymore and removes all custom abilities :/
It seems like I have to look for another way to optimize my files unless it would be okay to wait 3-4 minutes in the loading screen :D
 
Level 13
Joined
Mar 6, 2008
Messages
852
Where did you get that idea? They work fine for me.

I could observe it multiple times and I only could solve this issue by making an exception for minus.
Maybe it is different in the way we use the abilities.
I add about 96 abilities to an unit and and disable them for the player at the beginning of the game. Whenever I want to make them useable for this unit I just enable them and the abilities with a minus in its id won't appear for me.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
It might have something to do with which letter the minus is.

If those abilities didn't work, then it would quickly be apparent in my bonusmod.
JASS:
//! external ObjectMerger w3a AItg AD-0 anam "AD" Iatt 1 -1 |
//! external ObjectMerger w3a AItg AD-1 anam "AD" Iatt 1 -2 |
//! external ObjectMerger w3a AItg AD-2 anam "AD" Iatt 1 -4 |
//! external ObjectMerger w3a AItg AD-3 anam "AD" Iatt 1 -8 |
//! external ObjectMerger w3a AItg AD-4 anam "AD" Iatt 1 -16 |
//! external ObjectMerger w3a AItg AD-5 anam "AD" Iatt 1 -32 |
//! external ObjectMerger w3a AItg AD-6 anam "AD" Iatt 1 -64 |
//! external ObjectMerger w3a AItg AD-7 anam "AD" Iatt 1 -128 |
//! external ObjectMerger w3a AItg AD-8 anam "AD" Iatt 1 -256 |
//! external ObjectMerger w3a AItg AD-9 anam "AD" Iatt 1 -512 |
//! external ObjectMerger w3a AItg AD+A anam "AD" Iatt 1 1024 |

//! external ObjectMerger w3a AIsx AS-0 anam "AS" Isx1 1 -0.01 |
//! external ObjectMerger w3a AIsx AS-1 anam "AS" Isx1 1 -0.02 |
//! external ObjectMerger w3a AIsx AS-2 anam "AS" Isx1 1 -0.04 |
//! external ObjectMerger w3a AIsx AS-3 anam "AS" Isx1 1 -0.08 |
//! external ObjectMerger w3a AIsx AS-4 anam "AS" Isx1 1 -0.16 |
//! external ObjectMerger w3a AIsx AS-5 anam "AS" Isx1 1 -0.32 |
//! external ObjectMerger w3a AIsx AS-6 anam "AS" Isx1 1 -0.64 |
//! external ObjectMerger w3a AIsx AS-7 anam "AS" Isx1 1 -1.28 |
//! external ObjectMerger w3a AIsx AS+8 anam "AS" Isx1 1 2.56 |

//! external ObjectMerger w3a AId1 AR-0 anam "AR" Idef 1 -1 |
//! external ObjectMerger w3a AId1 AR-1 anam "AR" Idef 1 -2 |
//! external ObjectMerger w3a AId1 AR-2 anam "AR" Idef 1 -4 |
//! external ObjectMerger w3a AId1 AR-3 anam "AR" Idef 1 -8 |
//! external ObjectMerger w3a AId1 AR-4 anam "AR" Idef 1 -16 |
//! external ObjectMerger w3a AId1 AR-5 anam "AR" Idef 1 -32 |
//! external ObjectMerger w3a AId1 AR-6 anam "AR" Idef 1 -64 |
//! external ObjectMerger w3a AId1 AR-7 anam "AR" Idef 1 -128 |
//! external ObjectMerger w3a AId1 AR-8 anam "AR" Idef 1 -256 |
//! external ObjectMerger w3a AId1 AR-9 anam "AR" Idef 1 -512 |
//! external ObjectMerger w3a AId1 AR+A anam "AR" Idef 1 1024 |

//! external ObjectMerger w3a AIi1 IN-0 anam "INT" Iint 1 -1 |
//! external ObjectMerger w3a AIi1 IN-1 anam "INT" Iint 1 -2 |
//! external ObjectMerger w3a AIi1 IN-2 anam "INT" Iint 1 -4 |
//! external ObjectMerger w3a AIi1 IN-3 anam "INT" Iint 1 -8 |
//! external ObjectMerger w3a AIi1 IN-4 anam "INT" Iint 1 -16 |
//! external ObjectMerger w3a AIi1 IN-5 anam "INT" Iint 1 -32 |
//! external ObjectMerger w3a AIi1 IN-6 anam "INT" Iint 1 -64 |
//! external ObjectMerger w3a AIi1 IN-7 anam "INT" Iint 1 -128 |
//! external ObjectMerger w3a AIi1 IN-8 anam "INT" Iint 1 -256 |
//! external ObjectMerger w3a AIi1 IN-9 anam "INT" Iint 1 -512 |
//! external ObjectMerger w3a AIi1 IN+A anam "INT" Iint 1 1024 |

//! external ObjectMerger w3a AIa1 AG-0 anam "AGI" Iagi 1 -1 |
//! external ObjectMerger w3a AIa1 AG-1 anam "AGI" Iagi 1 -2 |
//! external ObjectMerger w3a AIa1 AG-2 anam "AGI" Iagi 1 -4 |
//! external ObjectMerger w3a AIa1 AG-3 anam "AGI" Iagi 1 -8 |
//! external ObjectMerger w3a AIa1 AG-4 anam "AGI" Iagi 1 -16 |
//! external ObjectMerger w3a AIa1 AG-5 anam "AGI" Iagi 1 -32 |
//! external ObjectMerger w3a AIa1 AG-6 anam "AGI" Iagi 1 -64 |
//! external ObjectMerger w3a AIa1 AG-7 anam "AGI" Iagi 1 -128 |
//! external ObjectMerger w3a AIa1 AG-8 anam "AGI" Iagi 1 -256 |
//! external ObjectMerger w3a AIa1 AG-9 anam "AGI" Iagi 1 -512 |
//! external ObjectMerger w3a AIa1 AG+A anam "AGI" Iagi 1 1024 |

//! external ObjectMerger w3a AIs1 ST-0 anam "AGI" Istr 1 -1 |
//! external ObjectMerger w3a AIs1 ST-1 anam "AGI" Istr 1 -2 |
//! external ObjectMerger w3a AIs1 ST-2 anam "AGI" Istr 1 -4 |
//! external ObjectMerger w3a AIs1 ST-3 anam "AGI" Istr 1 -8 |
//! external ObjectMerger w3a AIs1 ST-4 anam "AGI" Istr 1 -16 |
//! external ObjectMerger w3a AIs1 ST-5 anam "AGI" Istr 1 -32 |
//! external ObjectMerger w3a AIs1 ST-6 anam "AGI" Istr 1 -64 |
//! external ObjectMerger w3a AIs1 ST-7 anam "AGI" Istr 1 -128 |
//! external ObjectMerger w3a AIs1 ST-8 anam "AGI" Istr 1 -256 |
//! external ObjectMerger w3a AIs1 ST-9 anam "AGI" Istr 1 -512 |
//! external ObjectMerger w3a AIs1 ST+A anam "AGI" Istr 1 1024 |

//! external ObjectMerger w3a AIlz LP-0 anam "LIFE" Ilif 1 -1 |
//! external ObjectMerger w3a AIlz LP-1 anam "LIFE" Ilif 1 -2 |
//! external ObjectMerger w3a AIlz LP-2 anam "LIFE" Ilif 1 -4 |
//! external ObjectMerger w3a AIlz LP-3 anam "LIFE" Ilif 1 -8 |
//! external ObjectMerger w3a AIlz LP-4 anam "LIFE" Ilif 1 -16 |
//! external ObjectMerger w3a AIlz LP-5 anam "LIFE" Ilif 1 -32 |
//! external ObjectMerger w3a AIlz LP-6 anam "LIFE" Ilif 1 -64 |
//! external ObjectMerger w3a AIlz LP-7 anam "LIFE" Ilif 1 -128 |
//! external ObjectMerger w3a AIlz LP-8 anam "LIFE" Ilif 1 -256 |
//! external ObjectMerger w3a AIlz LP-9 anam "LIFE" Ilif 1 -512 |
//! external ObjectMerger w3a AIlz LP-A anam "LIFE" Ilif 1 -1024 |
//! external ObjectMerger w3a AIlz LP-B anam "LIFE" Ilif 1 -2048 |
//! external ObjectMerger w3a AIlz LP-C anam "LIFE" Ilif 1 -4096 |
//! external ObjectMerger w3a AIlz LP-D anam "LIFE" Ilif 1 -8192 |
//! external ObjectMerger w3a AIlz LP+E anam "LIFE" Ilif 1 16384 |

//! external ObjectMerger w3a AImz MP-0 anam "MANA" Iman 1 -1 |
//! external ObjectMerger w3a AImz MP-1 anam "MANA" Iman 1 -2 |
//! external ObjectMerger w3a AImz MP-2 anam "MANA" Iman 1 -4 |
//! external ObjectMerger w3a AImz MP-3 anam "MANA" Iman 1 -8 |
//! external ObjectMerger w3a AImz MP-4 anam "MANA" Iman 1 -16 |
//! external ObjectMerger w3a AImz MP-5 anam "MANA" Iman 1 -32 |
//! external ObjectMerger w3a AImz MP-6 anam "MANA" Iman 1 -64 |
//! external ObjectMerger w3a AImz MP-7 anam "MANA" Iman 1 -128 |
//! external ObjectMerger w3a AImz MP-8 anam "MANA" Iman 1 -256 |
//! external ObjectMerger w3a AImz MP-9 anam "MANA" Iman 1 -512 |
//! external ObjectMerger w3a AImz MP-A anam "MANA" Iman 1 -1024 |
//! external ObjectMerger w3a AImz MP-B anam "MANA" Iman 1 -2048 |
//! external ObjectMerger w3a AImz MP-C anam "MANA" Iman 1 -4096 |
//! external ObjectMerger w3a AImz MP-D anam "MANA" Iman 1 -8192 |
//! external ObjectMerger w3a AImz MP+E anam "MANA" Iman 1 16384 |

//! external ObjectMerger w3a Arel LR-0 anam "LIFEREG" Ihpr 1 -1 |
//! external ObjectMerger w3a Arel LR-1 anam "LIFEREG" Ihpr 1 -2 |
//! external ObjectMerger w3a Arel LR-2 anam "LIFEREG" Ihpr 1 -4 |
//! external ObjectMerger w3a Arel LR-3 anam "LIFEREG" Ihpr 1 -8 |
//! external ObjectMerger w3a Arel LR-4 anam "LIFEREG" Ihpr 1 -16 |
//! external ObjectMerger w3a Arel LR-5 anam "LIFEREG" Ihpr 1 -32 |
//! external ObjectMerger w3a Arel LR-6 anam "LIFEREG" Ihpr 1 -64 |
//! external ObjectMerger w3a Arel LR-7 anam "LIFEREG" Ihpr 1 -128 |
//! external ObjectMerger w3a Arel LR-8 anam "LIFEREG" Ihpr 1 -256 |
//! external ObjectMerger w3a Arel LR-9 anam "LIFEREG" Ihpr 1 -512 |
//! external ObjectMerger w3a Arel LR+A anam "LIFEREG" Ihpr 1 1024 |

Btw, why do you add 96 abilities to a unit when they're not all needed yet?
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
It's not forbidden, the objects are still generated correctly, but if the object is an ability and you add this ability to an unit, it won't work.
Because abilities are saved as a string and so you have to follow the rules of a string. A comma breaks the abiltiy id in this case and a quotation mark simply ends the string.
Incorrect? Strings are null terminated so only the null character 0x00 will not be allowed. JASS references to abilities using string form will have problems with a lot of control codes because they could cause the parser to do all kinds of strange things. However this limit can be avoided by using the integer for of ability ids since that has no formatting restrictions (although is parsed slower?). If you are referring to the object editor then I guess so (it could break the parsing of the underlying file).

The problem here sounds like the 10,000 objects. The map will probably take several hours to load. Loading is not very efficient and from rough reverse engineering it looked like some very bad data structures are used which degrade quickly. I would advise optimizing the object number to something reasonable like 1-2 thousand odd.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
integers are in fact not parsed slower than rawcodes, at least it didnt change the max op limit in a loop
That is because the oplimit is based on JASS operations for determinism? As such any form of constant literal should have the same op-limit cost.

The argument of which was faster was one started long ago with people like Vexorian. The tests they performed involved loading several thousand of such constants and comparing the load times. I remember the conclusion being that there was a difference but so small it was not worth the effort to change them.
 
Level 13
Joined
Mar 6, 2008
Messages
852
It might have something to do with which letter the minus is.
[...]
Btw, why do you add 96 abilities to a unit when they're not all needed yet?

It's the last letter, yes.
I knew that the seconds question would come :D
It does not belong in this thread but it has something to do with morphing,

Incorrect? Strings are null terminated so only the null character 0x00 will not be allowed. JASS references to abilities using string form will have problems with a lot of control codes because they could cause the parser to do all kinds of strange things. However this limit can be avoided by using the integer for of ability ids since that has no formatting restrictions (although is parsed slower?). If you are referring to the object editor then I guess so (it could break the parsing of the underlying file).
What?
The problem here sounds like the 10,000 objects. The map will probably take several hours to load. Loading is not very efficient and from rough reverse engineering it looked like some very bad data structures are used which degrade quickly. I would advise optimizing the object number to something reasonable like 1-2 thousand odd.
3-4 minutes load time, optimized a few seconds.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
3-4 minutes load time, optimized a few seconds.
Quite impressive.

In any case there has not been a recorded limit to object type definitions. That said it does not mean there is not a non-sensible one at some arbitrary number, just no one has ever declared enough object types to ever hit one and make a post about it.

As long as you do not declare any object type names which will corrupt the underlying files or the trigger script (if using literals) then there is no problem calling an object anything you like. As a test I made an object '@@@@' and the game handled it perfectly. The only issues I ran into was with control characters as they started to mess up the editor if literals were used.
 
Level 13
Joined
Mar 6, 2008
Messages
852
There are a few things I have to clarify, because I mistakenly based some of my states on a version that only has 3,000 objects.
In fact I haven't playtested the 10,000 objects version yet because of the loading time.

The 3-4 minutes loadtime belongs to the 3,000 objects version.

I went with the 10,000 version because it was the last thing I did but I am currently using 3,000 version again simply because of the
issues which occurred and seemingly coming from the ids.

The issues I am referring to are based on generating abilities and units. Units get their set of abilities in the process of being generated.
I don't add abilities to units ingame, because of the reason I am too lazy to write about right now and it doesn't fit the topic of this thread.
Units and abilities are getting their id from an id generator.

(although is parsed slower?).
I don't know what you mean by that.
You can't simply say "incorrect", because I am basing my statements on things I could observe and tested multiple times under different circumstances.
If you are referring to the object editor then I guess so (it could break the parsing of the underlying file).
Yes, that is what this thread is about.

I have no problem with '@@@@' as well.
The problems I experienced were stated in the previous posts.
- '\'
- a comma(,) and a quotation mark(")
- no difference in capital letter and lower case for the last digits
- a minus (-) as the last digit

Because I planned to add more features to the map which will require a lot of additional objects,
I want to know if there are more points I would have to consider.
There are a lot of objects I can reduce simply by making a custom spell but I only do that if it is necessary.
I hope the 8,000 object limit is not true. I'll have to test that soon, but I won't be able to do that before christmas.
 
Status
Not open for further replies.
Top