HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Save/Load Shortening Problem

03-28-2005, 07:29 PM#1
Das Jank
Alright if anyone is up for making a save/load code for me then send me a pm and ill give you massive credit in my map. Now with that out of the way I am going to figure this stuff out with maybe some help from you all.

Im making a map which is going to require a save/load code. I have read the tutorials and stuff and know the basics of creating a save/load code but im not quite sure how to shorten it without losing vital information. As of now I am saving:

Players name, first 3 letters + length(max of 15) = 5 digits
Gold, max of 999,999 = 6 Digits
Experience, max or 9,999,999 = 7 Digits
Stats, max of 999 each, 3 of them = 9 Digits
Items, 6 inventory slots, 2 digits per item = 12 digits
Spells, 4 Spells, 2 digits per spell, 1 digit for level = 12 digits
Grand Total = 51 Digits

Wow that would be a giant code and a pain in the ass to save... 51 letter/numbers. The first thing I though of was to square root the experience, which would knock off a few digits but in loading your character you would lose a bit of exp from the rounding off of numbers.So anyways I was wondering if anyone could give me some tips on how to shorten the code.
03-28-2005, 08:07 PM#2
Guest
I bet you can find a way to store the spells/items/abilities with only 1 digit using the 255 ASCII
Integer conversion of the square root of gold and experience can save a nice number of digits also.
For player length, you can use lengths 3-9 + 0 for lengths 10+
Can't find anymore ideas...
03-28-2005, 11:17 PM#3
Das Jank
Quote:
Originally Posted by BadFurDay
I bet you can find a way to store the spells/items/abilities with only 1 digit using the 255 ASCII
Integer conversion of the square root of gold and experience can save a nice number of digits also.
For player length, you can use lengths 3-9 + 0 for lengths 10+
Can't find anymore ideas...

Ive never heard of 255 ASCII but ill have to check that out, I already thought about using square root but too much is lost from the numbers rounding off. Like lets say the character has 2,009,900 which is somewhere around where it takes to creat lv200 on a hero... square root it and you get 1417. Now square it, and you get 2007889. Thats a net loss of 2011 exp. My map is going to cap at lv200 so when you would load you would be put back to lv199, not to mention im going to make it nearly impossible to reach lv200 so any loss of exp from level 100+ would be a great loss of time.
03-29-2005, 06:45 AM#4
Guest
You could try converting the numbers from decimal into a base-16 (0-F hexadecimal), base-36 (0-Z), or base-62 (0-z, lowercase + uppercase). That would shorten the code length a LOT...
One more thing too...
In my opinion you really dont need to save the abilities (unless, you dont learn the abilities normally through the 'Hero Ability Menu'). You can just learn the abilities when you load your character because when you set the character's level it gives it hero points as well.
Plus, most RPG maps just save your level.
03-29-2005, 02:17 PM#5
Das Jank
Quote:
Originally Posted by Raichu
You could try converting the numbers from decimal into a base-16 (0-F hexadecimal), base-36 (0-Z), or base-62 (0-z, lowercase + uppercase). That would shorten the code length a LOT...
One more thing too...
In my opinion you really dont need to save the abilities (unless, you dont learn the abilities normally through the 'Hero Ability Menu'). You can just learn the abilities when you load your character because when you set the character's level it gives it hero points as well.
Plus, most RPG maps just save your level.

Im a little confused, what exatcly is a base-16, base-36, and base-62? Im not really sure how those work. Sorry im a real noob when it comes to this stuff.
03-29-2005, 03:00 PM#6
PitzerMike
Decimal numbers is base-10, hexadecimal is base-16 and so on ...
The number tells how many different digits your "alphabet" has
03-29-2005, 03:02 PM#7
Guest
base 10 = numerical
0123456789

base 16 = hexadecimal
ABCDEF0123456

base 32 = alphabetical
ABCDEFGHIJKLMNOPQRSTUVWXYZ

base 64 = case sensitive alphabetical
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

base 74 = basic ASCII
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

base 255 = ASCII
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + all symbols (◊æÚêÃ?ĐÃ?îœÂ etc...)
03-29-2005, 03:26 PM#8
Das Jank
How exactly would I implement one of those into my code to make it smaller? Would it be like A=10, B=12......a=40, b=41 sorta like that?
03-29-2005, 05:48 PM#9
Guest
Exactly ^_^

E.G. you could code a double edged sword by calling it "a", or a fire orb with "7", a staff of lightning with "A", a healing potion with "≈"... etc...
03-29-2005, 07:50 PM#10
iNfraNe
I recommend using 0-1a-zA-Z , no other symbols, cuz that must be a pain in the ass loading it... Also on this code, color the cases or leave out uppercase i and lowercase l cuz they look the same in wc3. But thats np if u color them.
03-29-2005, 10:55 PM#11
Guest
Code:
function DecimalStr takes string base36String returns integer
    local integer i = 0
    loop
        if (SubStringBJ("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", i + 1, i + 1) == base36String) then
            return i
        endif
        set i = i + 1
    endloop
    return 0
endfunction

function Base362Decimal takes string base36String returns integer
    local integer array multiplyResults
    local integer numResults = 0
    local integer result = 0
    local integer i = StringLength(base36String)
    loop
        exitwhen numResults == (StringLength(base36String))
        set multiplyResults[numResults] = DecimalStr(SubStringBJ(base36String, i, i))

        set multiplyResults[numResults] = multiplyResults[numResults] * R2I(Pow(36, I2R(numResults)))

        set numResults = numResults + 1
        set i = i - 1

    endloop

    loop
        exitwhen numResults == 0
        set numResults = numResults - 1
        set result = result + multiplyResults[numResults]
    endloop
    return result
endfunction

function Base36Num takes integer decimalNum returns string
    return SubStringBJ("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", decimalNum + 1, decimalNum + 1)
endfunction

function Decimal2Base36 takes integer decimalNum returns string
    local string array divideRemainders
    local integer numRemainders = 0
    local string result = ""

    loop
        exitwhen decimalNum == 0
        set numRemainders = numRemainders + 1
        set divideRemainders[numRemainders] = Base36Num(ModuloInteger(decimalNum, 36))
        set decimalNum = decimalNum / 36
    endloop

    loop
        exitwhen numRemainders == 0
        set result = result + divideRemainders[numRemainders]
        set numRemainders = numRemainders - 1
    endloop
    return result
endfunction
That is JASS script that can be used to convert numbers from decimal to base 36 and back... its what i currently use in my save system. Hope it helps.
EDIT:
Changed the stuff
03-30-2005, 08:01 AM#12
iNfraNe
please.... dont use so much if then else... try this:

str="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"

dec2base36=substr(str, int, int) and the other way around do a loop.
03-30-2005, 10:18 PM#13
Vexorian
One thing is that while using case specific symbols would reduce the code length , it screws everything, you should only use capitals, some times it is hard to tell if an I is a l
03-31-2005, 02:26 AM#14
Guest
Color code will help...
In fact, most RPGs that have case-sensitive codes DO color code the generated save string