1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  4. Dismiss Notice
  5. The Highway to Hell has been laid open. Come along and participate in the 5th Special Effect Contest.
    Dismiss Notice
  6. 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.

Is it possible to have large numbers?

Discussion in 'World Editor Help Zone' started by mr po, Jun 20, 2018.

  1. mr po

    mr po

    Joined:
    Dec 8, 2016
    Messages:
    127
    Resources:
    1
    Maps:
    1
    Resources:
    1
    It seems Warcraft 3 large numbers are limited around billions, how do i do mathematics in numbers larger than that, like trillions?
     
  2. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,287
    Resources:
    0
    Resources:
    0
    You should not use this large numbers. Integers can represent 2^32 different numbers, which should be enough for pretty much any map.

    If you really need large numbers, you can use multiple integers and interpret them as one number. You will have to write custom functions to perform arithmetic operations on them.
    The resulting big number cannot be used for any native function.
    You will have to write custom functions that work with larger numbers.
     
  3. Kaijyuu

    Kaijyuu

    Joined:
    Jun 2, 2004
    Messages:
    848
    Resources:
    0
    Resources:
    0
    There are, of course, the floating point numbers (reals), though they come with all the standard limitations.
     
  4. nedio95

    nedio95

    Joined:
    Mar 24, 2011
    Messages:
    1,055
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Isn't it 2^31-1 ? The 32nd bit being reserved for positive/negative.
    Edit//Ah, I see what you mean now, you are correct. I got confused by the wording.

    Still, same limitation.

    regards
    -Ned
     
  5. mr po

    mr po

    Joined:
    Dec 8, 2016
    Messages:
    127
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Basically that's nearly no difference from writing a new calculator, but cant i really circumvent that limited integer number and use innate warcraft 3 calculator?
     
  6. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,716
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    They use two's compliments for negative numbers. This means that although it is technically a sign bit, it does not out right represent positive/negative but instead represents {-(2 ^ 31)}.
    Not true. Although floating points still have the same limitation on number of possible representable number states, the numeric range covered by floating points is completely different. For a standard IEEE 32 bit float the range is...

    {(2 − (2 ^ −23)) × 2 ^ 127}

    Which is considerably larger than both 32bit and even 64bit integers. This is achieved by sacrificing numeric accuracy, floats represent numbers accurately to only a small number of significant figures.
     
  7. nedio95

    nedio95

    Joined:
    Mar 24, 2011
    Messages:
    1,055
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Interesting.
    For some bizarre reason, I was left with the impression that Real in war3 did not use floating point.

    regards
    -Ned
     
  8. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,716
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Probably confused with StarCraft II. In StarCraft II the real type is fixed point with a maximum value of ~500,000.
     
  9. Wark

    Wark

    Joined:
    Oct 12, 2016
    Messages:
    738
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Why do you need an integer in the trillions?
     
  10. Kaijyuu

    Kaijyuu

    Joined:
    Jun 2, 2004
    Messages:
    848
    Resources:
    0
    Resources:
    0
    One thing I came across recently was my custom experience curve. After 100 levels or so the total experience was in the trillions. I fixed it for my purposes by inferring total experience from level + xp to next level, instead of keeping explicit track of the total.

    The answer to "why would you need x" is always that someone, somewhere has a plausible use case.
     
  11. Wark

    Wark

    Joined:
    Oct 12, 2016
    Messages:
    738
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Yea, I'm aware of it.
    I'm just asking "why" since I am very good at finding alternatives with the same goal, especially concerning formulas or limitations.
     
  12. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,716
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Mostly it is just because they like silly numbers...
    Or you could use a Xenoblade style system where the experience earned is based on the difference between monster level and character level. This removes the need to inflate the numbers so heavily as levels progress as players will not be able to farm low level monsters and gain levels.
     
  13. mr po

    mr po

    Joined:
    Dec 8, 2016
    Messages:
    127
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Thank you guys for tips and help. Consider the problem solved, i have made triggers to extend the numbers.

    Because i am developing a business type map, i think it is silly to say "maximum profit you can earn is only 2 billion. Sorry. Game over."
     
  14. EdgeOfChaos

    EdgeOfChaos

    Joined:
    Jan 8, 2014
    Messages:
    639
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    Some of the 'incremental' rpgs like golden gods rpg use extremely high numbers. Be warned that there is no good way to save these numbers, if your map uses a save system. I have tried every save system on THW and other sites, and none of them actually work for all cases (some even start generating faulty codes before the numbers hit 1 million). I guess save systems are very hard to make

    I wrote a BigFloat library a while ago to do this, maybe it is useful (or not)

    Code (vJASS):

    * Representation of a very large number (greater than MAXINT)
    * This is achieved by putting the numbers into scientific notation, making them
    * easier to represent
    * For a standard real, any values above 2.14b or so will become negative.
    * This is intended to solve this problem and make very large
    * numbers possible to work with.
    * Does not handle negative numbers. Behavior with negatives is undefined
    */
    struct BigFloat

    //Stores the number part of the scientific number
    private real number
    //Stores the exponential part - i.e. 10^25
    private integer exponent

    /**
    * Default no-args constructor for a large number
    */

    public static method create takes real n, integer e returns thistype
    local thistype new = thistype.allocate()
    call new.change(n,e)
    return new
    endmethod


    public method empty takes nothing returns nothing
    set this.number = 0.
    set this.exponent = 0
    endmethod

    /**
    * Gets the number value of this BigFloat
    */

    public method getNum takes nothing returns real
    return this.number
    endmethod

    /**
    * Gets the exponent of this BigFloat
    */

    public method getExp takes nothing returns integer
    return this.exponent
    endmethod

    /**
    * Detects whether this big number is empty or not
    * Defined as empty if it is 0 * 10^0
    */

    public method isEmpty takes nothing returns boolean
    return (this.getNum() <= 1 and this.getExp()==0)
    endmethod

    /**
    * Takes as much of this BigFloat as possible and return it as a real
    * This will be either 2147483646 or all remaining
    */

    public method take takes nothing returns real
    local real toRemove = 2147483646
    if(isEmpty()==false)then
    if((this.exponent < 9) or (this.exponent==9 and this.getNum <= 2.147483646))then
    set toRemove = this.number * Pow(10,this.exponent)
    set this.exponent = 0
    set this.number = 0
    return toRemove
    endif
    set toRemove = toRemove / Pow(10,this.exponent)
    set this.number = this.number - toRemove
    if(this.number <= 0)then
    set this.number = 10 - this.number
    set this.exponent = this.exponent-1
    endif
    endif
    return I2R(R2I(toRemove))
    endmethod

    private method change takes real n, integer e returns nothing
    set this.number = n
    set this.exponent = e
    call this.compress()
    endmethod

    private method compress takes nothing returns nothing
    loop
    exitwhen this.getNum() < 10.
    set this.number = this.number / 10
    set this.exponent = this.exponent + 1
    endloop

    if(this.getNum() <= 0) then
    set this.number = 0
    set this.exponent = 0
    elseif(this.getNum() < 1) then
    loop
    exitwhen this.getNum() >= 1.
    set this.number = this.number * 10
    set this.exponent = this.exponent - 1
    endloop
    endif
    endmethod

    /**
    * Returns the scientific notation
    * of the big number.
    */

    public method toString takes nothing returns string
    return R2S(number) + " * 10^" + I2S(exponent)
    endmethod

    /**
    * Destroys this big number.
    */

    public method destroy takes nothing returns nothing
    call this.deallocate()
    endmethod

    /**
    * Creates a new BigFloat from the specified real num
    * Num must be less than MAXINT.
    */

    public static method convert takes real num returns thistype
    local real numFinal = num
    local integer expFinal = 0
    return thistype.create(numFinal,expFinal)
    endmethod

    /**
    * Changes the specified scientific notation string
    * into a BigFloat
    * Strings MUST be in the format:
    * 5 * 10^15 for example
    */

    public static method fromScientific takes string num returns thistype
    local real numberSection = 0.
    local integer exponentSection = 0
    local integer pointer = 0
    local integer breakCheck = 0
    local string temp = ""

    loop
    exitwhen ((breakCheck > 200) or (SubString(num,pointer-1,pointer)==" "))
    set temp = SubString(num,0,pointer)
    set pointer = pointer + 1
    set breakCheck = breakCheck + 1
    endloop

    set numberSection = S2R(temp)

    loop
    exitwhen ((breakCheck > 200) or (SubString(num,pointer-1,pointer)=="^"))
    set pointer = pointer + 1
    set breakCheck = breakCheck + 1
    endloop

    set temp = SubString(num,pointer,200)
    set exponentSection = S2I(temp)

    return thistype.create(numberSection,exponentSection)
    endmethod

    /**
    * Multiplies this with another big number
    * If destroy is set to true, the second BigFloat will be destroyed after the t
    */

    public method multiply takes BigFloat by, boolean destroy returns nothing
    local real numFinal = by.getNum() * this.getNum()
    local integer expFinal = by.getExp() + this.getExp()

    if(destroy)then
    call by.destroy()
    endif
    call this.change(numFinal,expFinal)
    endmethod

    /**
    * Divides this with another big number
    * If destroy is set to true, the second BigFloat will be destroyed after the t
    */

    public method divide takes BigFloat by, boolean destroy returns nothing
    local real numFinal = this.getNum() / by.getNum()
    local integer expFinal = this.getExp() - by.getExp()
    if(destroy)then
    call by.destroy()
    endif
    call this.change(numFinal,expFinal)
    endmethod

    /**
    * Adds another big number
    * If destroy is set to true, the second BigFloat will be destroyed after the t
    */

    public method add takes BigFloat by, boolean destroy returns nothing
    local real numFinal = 0.
    local integer expFinal = 0
    local integer diff = this.getExp() - by.getExp()
    if(diff==0)then
    set numFinal = this.getNum() + by.getNum()
    set expFinal = this.getExp()
    elseif(diff>0)then
    set numFinal = this.getNum() + (by.getNum() / (Pow(10,diff)))
    set expFinal = this.getExp()
    else
    set diff = -diff
    set numFinal = by.getNum() + (this.getNum() / (Pow(10,diff)))
    set expFinal = by.getExp()
    endif

    if(destroy)then
    call by.destroy()
    endif
    call this.change(numFinal,expFinal)
    endmethod

    /**
    * Subtracts another big number
    * If destroy is set to true, the second BigFloat will be destroyed after the t
    */

    public method subtract takes BigFloat by, boolean destroy returns nothing
    local real numFinal = 0.
    local integer expFinal = 0
    local integer diff = this.getExp() - by.getExp()
    if(diff==0)then
    set numFinal = this.getNum() - by.getNum()
    set expFinal = this.getExp()
    elseif(diff>0)then
    set numFinal = this.getNum() - (by.getNum() / (Pow(10,diff)))
    set expFinal = this.getExp()
    else
    call change(0,0)
    endif

    if(destroy)then
    call by.destroy()
    endif
    call this.change(numFinal,expFinal)
    endmethod

    public method percentOf takes BigFloat small, boolean destroy returns real
    local real percent = 0.
    call small.divide(this,false)
    set percent = small.take() * 100
    if(destroy)then
    call small.destroy()
    endif
    return percent
    endmethod

    public method displayAt takes real x, real y returns nothing
    local texttag txt = CreateTextTag()
    call SetTextTagText(txt,toString(),TextTagSize2Height(10))
    call SetTextTagPos(txt,x,y,0)
    call SetTextTagPermanent(txt,false)
    call SetTextTagVelocity(txt,0,TextTagSpeed2Velocity(40))
    call SetTextTagLifespan(txt,1.5)
    set txt = null
    endmethod


    /**
    * Copies the old BigFloat to a new one
    */

    public static method copy takes thistype old returns thistype
    return thistype.create(old.getNum(),old.getExp())
    endmethod
    endstruct
    /**


    iirc just create a BigFloat either from scientific notation or from another real (obviously limited by size), then you can multiply/add to it, etc, to go over the limit
     
    Last edited: Jun 24, 2018
  15. nedio95

    nedio95

    Joined:
    Mar 24, 2011
    Messages:
    1,055
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Usually it is game design.

    I started playing World of Warships (it's a multiplayer Naval battles with semi-simulator/arcade mechanics game, usually PvP 15v15) a few years ago and when I saw the HP and damage it made little sense to me. (Ships HP ranges around 10000 to 90000 and DPM ranges 100000 to 400000) Those numbers are pretty unhandy for precise fast-paced in-match calculations.
    The Dev of World of Warships has another game World of Tanks (multiplayer Tank battles game with semi-simulator/arcade mechanics, usually PvP 15v15) where the numbers are much more handy ( in the ranges around 100-3000 for HP and DPM 800 - 5000) Which again are a bit confusing as usually in PvP shooting games you'd have something like 100 or more round and handy numbers.

    But when you put it in context, it all makes sense.
    You are not in control of a single person. You have a mighty tank made of steel!
    You are in a bloody battleship. Bismark, Yamato, Tirpitz, Misouri ! You are in control of a 70 000 ton beast with 2000 crew members and shells bigger than you! Those are the only appropriate numbers in the case!

    Also, do you know what gamers like ? Big numbers. Do you know what gamers like enve more ? Seeing big numbers become bigger :)

    Of course, there are a bajillion games where there is absolutely no reason for use of those numbers, like why the hell should my Lvl 1 character deal 1531564645 damage with basic attack and 56465464 with that skill and 15486486464 with that other skill... like, wtf?
    I can agree on high/max lvl having pumped up numbers, but there is absolutely no reason to have exclusively big numbers. Use them wisely :)

    regards
    -Ned
     
  16. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,716
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    These numbers are sensible. One could even argue they are scaled such that the tanks could fight the battleships in a realistic way, not that it is possible.

    Not sensible numbers would be ship health like 900,000,000,000,000,000,000,000,000,000,000,000,000,000 which is like what I have seen some WC3 RPGs have for unit health and damage.
    Actually gamers do not like big numbers as it makes mental maths impossible. It even makes balance more error prone as it becomes increasingly more easy for a developer to leave a 0 off of a number by mistake when there are 10-40 of them.
     
  17. nedio95

    nedio95

    Joined:
    Mar 24, 2011
    Messages:
    1,055
    Resources:
    1
    Spells:
    1
    Resources:
    1
    True that those numbers are a lot more sensible than 5646489 bazzilions.
    Well, it is still a pretty unhandy number for the average player. Most of the time it is not a 0s there, more like 65850 hp and 345698 DPM for ships and 1450 HP and 1878 DPM for tanks.
    Still, as long as it is used within a good game design reason, large numbers are ok.
    Have in mind that an average person would not have to deal with large numbers on a daily basis.

    PS: We all love those war3 maps where you start with a black field for health and some numbers for hero stats that were created by rolling your head on the num pad... usually I quit immediately...

    Big numbers getting bigger is usually the result of your character/resources/stats getting better.
    Take WoW for example, or most MMORPGs, usually early game you'd be comparing single to quad digits while end game you are usually comparing millions and more. But the more sensible ones would give you a number like 1,500,000 instead of 6,851,313.

    regards
    -Ned
     
  18. Wark

    Wark

    Joined:
    Oct 12, 2016
    Messages:
    738
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Back on topic,
    In terms of just using formulas in triggers, I'd recommend using something along the lines of scientific notation to bypass the integer or real limits (powers of 10).

    For display, are you planning to use a multiboard for player stats?
    I imagine you could have a multiboard indicate your net worth is in the billions or trillions, while the gold display or something shows you how many millions/thousands you've got.
    Alternatively, are you using the lumber resource for anything?
    It'd be easy to make a formula to indicate large numbers on the screen between gold and lumber. You can even change those icons and info text in the interface.
     
  19. mr po

    mr po

    Joined:
    Dec 8, 2016
    Messages:
    127
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Definitely multiboard will be used to display your net worth or current portfolio, but for the resources display, lumber will be part of the game. So dont think i can use the gold display to show billion dollar cash flow, what i can do is implement compulsory savings plan whenever the gold display exceeds 6 digit.
     
  20. Daffa

    Daffa

    Joined:
    Jan 30, 2013
    Messages:
    7,746
    Resources:
    28
    Packs:
    1
    Maps:
    8
    Spells:
    17
    Tutorials:
    2
    Resources:
    28
    If you take the recent patch, that'll be 7 digits.