Mirage Engine
Very Simple Binary (Single File) Saving For All - Printable Version

+- Mirage Engine (https://mirage-engine.uk/forums)
+-- Forum: Mirage Source (Nostalgia) (https://mirage-engine.uk/forums/forumdisplay.php?fid=61)
+--- Forum: Archive (2006-2011) (https://mirage-engine.uk/forums/forumdisplay.php?fid=18)
+---- Forum: Resources (https://mirage-engine.uk/forums/forumdisplay.php?fid=49)
+---- Thread: Very Simple Binary (Single File) Saving For All (/showthread.php?tid=754)



Very Simple Binary (Single File) Saving For All - Obsidian - 17-02-2007

Alright, Dave made a great tutorial a while back. Showing everyone how big an optimization Binary really was (atleast when in comparison to the NI system that is currently used). His method was right-on, however, not overly difficult to implement and it worked very well. There was, however, something i struggled a lot with... and that was... everytime you added something new to a UDT (like the NPCRec for example), you had to go back in, and make sure you added in both the get/put line for it, as well as making sure it was cleared out. In this tutorial, the only that you'll be responsible for doing now... is making sure you clear it out correctly.

I will not be holding your hand throughout this tutorial, i really don't think it's necessary if you'll just think (and i know for some of you, that's really asking a lot). I'm going to post one sub, and then what my system looks like, and how it works... so you can make it work for you. I would like to point out however, and it was a problem even in dave's previous sytem... if you have a string, that is NOT a fixed string, you'll start running into problems later on.


Tutorial Difficulty 2/5 - Easy When Read


Here is an example of what your Sub SaveNPC would look like when you completed Dave's Binary Tutorial Correctly:

Code:
Sub SaveNpc(ByVal NpcNum As Long)
Dim FileName As String
Dim nFileNum As Integer
Dim StartByte As Long

    FileName = App.Path & "\data\npcs.bin"
    nFileNum = FreeFile
    
    Open FileName For Binary As #nFileNum
        StartByte = 292 * (NpcNum - 1) + 1

        Put #nFileNum, StartByte, Npc(NpcNum).Name
        Put #nFileNum, , Npc(NpcNum).AttackSay
        Put #nFileNum, , Npc(NpcNum).Sprite
        Put #nFileNum, , Npc(NpcNum).SpawnSecs
        Put #nFileNum, , Npc(NpcNum).Behavior
        Put #nFileNum, , Npc(NpcNum).Range
        Put #nFileNum, , Npc(NpcNum).DropChance
        Put #nFileNum, , Npc(NpcNum).DropItem
        Put #nFileNum, , Npc(NpcNum).DropItemValue
        Put #nFileNum, , Npc(NpcNum).STR
        Put #nFileNum, , Npc(NpcNum).DEF
        Put #nFileNum, , Npc(NpcNum).Speed
        Put #nFileNum, , Npc(NpcNum).MAGI
    Close #nFileNum
  
End Sub

Now, if you weren't sure what i meant earlier with all of the 'put' lines, that should be showing you more than enough. Now, the problem like i mentioned before, was that if you add something new, you'd have to update the StartByte Size, as well as having to add the put/get in the exact same spots on both, to make sure it was read back correctly. Here's an example of my new way of doing the EXACT same thing

Code:
Sub SaveNpc(ByVal NpcNum As Long)
Dim FileName As String
Dim nFileNum As Integer
Dim StartByte As Long

    FileName = App.Path & "\data\npcs.bin"
    nFileNum = FreeFile
    
    StartByte = LenB(Npc(NpcNum)) * (NpcNum - 1) + 1
    
    Open FileName For Binary As #nFileNum
        Put #nFileNum, StartByte, Npc(NpcNum)
    Close #nFileNum
End Sub

So basically, in this version. You get the length in bytes... which is what the LenB() function does... rather than having to go through and say okay the whole NPCRec has 19 Bytes... it does it all for you. Then, you just Put , , where the npc actually belongs, and you place the entire UDT there all at once. See how much more simple that is?

My "challenge" to you now, is to make the LoadNpc function do this same type of thing. It is very simple, and should jump out at everyone here as soon as they spend atleast 5 seconds looking at it. If you try several times with no luck, please feel free to let me know and i'll be able to help you out.

This system works for Everything, although accounts are slightly different. You can check my other tutorial on that, but again, challenge yourself and try and make it work for Items, Maps, Spells, and anything else you may need.


- Ramsey - 17-02-2007

this will come very handy for me


- Obsidian - 17-02-2007

Yeah, thanks for throwing that in, Verr. I was going to go into it a bit, but i really didn't want to confuse people (or myself), trying to help people understand it.


- Spodi - 17-02-2007

I just quickly skimmed this, but I don't see how it would let you change your NPC UDT without having change the file, unless you are loading from a different format, saving as binary, then loading as binary.


- Obsidian - 17-02-2007

You would have to change your file... it doesn't automatically adjust it. You'll either have to make an 'updater' to change to your new binary format... or delete the original binary file and just let it resave.

All this was, was letting people use binary, without have to do a Put/Get line for every declaration in a given UDT. Before you had to use one Get/Put for each line (and make sure they were in the correct order), and then make sure you clear it all out the same way. Now you don't. That's the only real improvement that i made.


- Spodi - 17-02-2007

Ah ok, I guess I just got confused on what you meant by this:

Quote:There was, however, something i struggled a lot with... and that was... everytime you added something new to a UDT (like the NPCRec for example), you had to go back in, and make sure you added in both the get/put line for it, as well as making sure it was cleared out. In this tutorial, the only that you'll be responsible for doing now... is making sure you clear it out correctly.



- William - 17-02-2007

Quote:That's the only real improvement that i made.
Its a very good time decreasing improvement Obsidian.


- lucidar - 19-02-2007

I see two things that are especially 'wrong' and 'bad' about using that method:

i. You do not really learn anything other than how to quickly store/load types unless you've follow Dave's tutorial beforehand AND understood it.
ii. If you add another variable into the type, depending on the procedure you're calling, you can load the wrong values since you havn't saved the binary file before loading (by having every put and get statement written in, you can comment out the get statement for the new variable until you've called a proper put routine -- then uncomment).

I strongly suggest that you stop asking people whom are new to look at your tutorial, as it is very bad practice.

Thought I'd share~ I don't mean to rain on your parade. It's a great time saver .


- lucidar - 20-02-2007

You don't understand where my critism is coming from?

Maybe I came off much to bluntly than I should of, but I don't understand stand how you cannot accept a little critism pointing out a couple of possible flaws by following the tutorial.

Should people be unaware of any future set-backs they may incur after Obsidian refers them to his tutorial?


- Obsidian - 20-02-2007

The only part of your criticism, that actually made sense, was when you said, if they (the programmer for the source) add a new variable to the UDT for say, ItemRec, then data isn't read in correctly anymore. Well wouldn't you know it... unless you go through and write a conversion... that stays true for every tutorial about data saving ever written for this forum. Let's see in Dave's tutorial... you not only had to delete your original Items.*, but you had to add new Get/Put lines, and update the Clear *W/E* Sub... i'm sorry, i understand your argument, but pointing fingers at me for something that has been rather common knowledge for a long time seems extremely pointless in this case. I wrote the tutorial so people who were struggling with Dave's had a much more simplified way of doing the exact same thing.


- lucidar - 21-02-2007

Never knew that posting anything such as conversion method or a theory of one was such a touchy subject. Nor did I know that you'd prefer to not help people understand the concept behind the coding before refering them to an 'easier' solution with the same effect.

My apologies, I'll just leave it alone.