type data 2 file

Blitz3D Forums/Blitz3D Beginners Area/type data 2 file

PCBGuy(Posted 2005) [#1]
OK so I am crusing along running the game, making things work, bells ring, horns blow, then its time to ask, How the hell do I save all this data for the next time I play ....gulp!
All the peeks and pokes make me soooo confused, so I ask someone to make my writefile101 class a little easier

Example of the data to read out to file and the program code creating it.



All I need is save out the data (it changes as the game progresses) so when the game starts again the data continues from where I left off not starting from scatch (Maybe also an option to choose not to read from the file, but use the initial data in the program, would be nice too)


Sunteam Software(Posted 2005) [#2]
Here are 3 quick funcs to read and write your data. I presume it is just the data contained in the BG type list you want to save and load.

Just supply a filename to writedata and readdata funcs to write and read the data to a file. The cleardata is used by readdata to clear the type list before loading in the saved data. Hope it helps.

Function writedata(filename$)
	Local b.BG,fh
	fh=WriteFile(filename$)
	For b = Each BG
		WriteString fh,b\bgname$
		WriteInt fh,b\bgStrength
		WriteInt fh,b\bgX
		WriteInt fh,b\bgY
	Next
	CloseFile fh
End Function

Function readdata(filename$)
	Local b.BG,fh
	cleardata
	fh=ReadFile(filename$)
	While Not Eof(fh)
		b=New BG
		b\bgname$=ReadString(fh)
		b\bgStrength=ReadInt(fh)
		b\bgX=ReadInt(fh)
		b\bgY=ReadInt(fh)
	Wend
	CloseFile fh
End Function

Function cleardata()
	Local b.BG
	For b = Each BG
		Delete b
	Next
End Function



PCBGuy(Posted 2005) [#3]
Well Sunteam, it looks good but no go! I get a runtime error: "Stream does not exist" at line

WriteString fh,b\bgname$

I checked everything over and over and can't figure it out.


Sunteam Software(Posted 2005) [#4]
have you passed a valid filename to the function? if you could repost the complete code as you've now used it I will take a look for you :)


PCBGuy(Posted 2005) [#5]
You where right! It worked once I figured out how to use the functions. You guys are aces at this stuff .... it never ceases to amaze me how you write this stuff cold with no testing or how its being used!
I am from the old school using BASIC77 on a HP "mini" computer at UofH in 1982 so alot of this is new to me and a real challenge!
One question though. I am spoiled with .txt type ascii files so this .dat output is a little unfriendly. How can I convert .dat to .txt format.
Lastly thanks to you I managed the last hurtle to the strategic/logistic section of my game. This is a great milestone for me and could not have happened with out the kind support from you fellows at Blitz community!


Damien Sturdy(Posted 2005) [#6]
Use Writeline instead of writestring, writeint and writefloat :D
Use Readline instead of Readstring, readint and readfloat.


You should be okay simply changing the commands as the code does all the conversions :D


PCBGuy(Posted 2005) [#7]
Thanks Cygnus. (K)eeping (i)t (s)imple and (s)mart.


fall_x(Posted 2005) [#8]
If you use plain text files for you save games, users will be able to cheat very easily. Also, if you use writeline, everything will be saved as strings, which will result in a bigger save game than needed.
So I recommend using writestring, writeint and writefloat for writing strings, ints and floats so your save file is not too big (which may not be a concern for you), and then encrypting it, and decrypting it when you load it.
I recently wrote a file encryption/decryption - there was one in the code archives already, but I had some problems with it not decrypting some complex files the way they were. You can find my encryption here :

http://blitzbasic.com/codearcs/codearcs.php?code=1264

So feel free to use it if you don't want users to be able to change their amount of lifes or their health in the savegames.

Using it is very simple. You'd probably save all your data to a temp.sav (or similar) file, enrypt it to name.sav, and delete the temp.sav, and when loading you can decrypt it to temp.sav, read that, and delete it.


Rob Farley(Posted 2005) [#9]
Fall,

Regarding filesize. An int saves 4 bytes. So if you want to write out 5,3,4,1,6,2,6,4,1,0,9 for example you're savefile will be 40 bytes.

A short(int) is 2 bytes. Meaning you'd use 20 bytes.
A float is 4 bytes also. 40 bytes again

So if your numbers are between 0 - 255 then using a writeline or writestring is certainly an advantage for filesize. (53416264109 is 10 bytes).

Anyway, I'm kinda being pedantic for the sake of it...

Oh, and regading cheating just covert all you numbers to a weird base, base 36 is always a nice one, so you end up totally unreadable numbers, however, all your characters will be typeable so you can still edit it manually if necessary.


fall_x(Posted 2005) [#10]
Isn't 53416264109 11 bytes (it's 11 digits)? Plus a newline and a carriage return per number (if you don't just append them to eachother, but without a seperator that wouldn't be smart), and you get 33 bytes, or am I wrong?

There is something strange about this as well. In my file encryption, I read in a file byte-by-byte. I then save a short for each byte to another file. But I noticed that both files are always the same size. If shorts use 2 bytes, how is that possible? Shouldn't the filesize double?


Rob Farley(Posted 2005) [#11]
Sorry, 11 bytes. Why would it not be smart not to seperate them? If you know how you wrote the file then you know how to read it.

If you're using writebyte then that's going to use one byte per character.

writebyte 65,66,67 over writeline "ABC" will save 2 bytes for you carrage return, newline. However, neither have seperators.

Oh, and PCBGuy can you please not use 2 instead of To. It's rubbish.
4 n=1 2 4
print n
next



fall_x(Posted 2005) [#12]
Why would it not be smart not to seperate them? If you know how you wrote the file then you know how to read it.

Ok, suppose the numbers are 5,12,100,3,5. Append them and you get 51210035.
Now how do you know the numbers weren't 51,21,0,0 and 35?
So you can only append them if they are either all smaller than ten, or if you store the same amount of digits for each. Suppose you do this for all numbers smaller than 255 as you said earlier, you'd need 3 digits for each, making it 005012100003005 - which is 15 bytes for 5 numbers (3 bytes per number). Or you could use a seperator so it is stored as 5,12,100,3,5 which is 9 bytes fo rthe 5 numbers.

Still don't understand why when I write a short to an output file for each byte of an input file, the size of both input and output files are identical :S


Rob Farley(Posted 2005) [#13]
My suggestion for numbers smaller than 255 would be one character per number ie chr(5) chr(10) chr(50) etc etc etc. This way you're using one byte per number.

There's no advantage over this than over writebyte though.

Anyway, I'm not going to carry on with this pointless discussion.


fall_x(Posted 2005) [#14]
I don't think it's pointless to figuere out the best way to save data. If I offended/irritated you in any way (I don't think so, and I wasn't trying to do so) then I apologize.
Still, could you do me a favour (I asked this question two times already and would like an answer, if you know)? Since you seem to know about this stuff, please check out my encryption routine, and tell me how it is possible that the encrypted file has the same file as the original, since I write a short to the encrypted file for every byte in the original file. If a short is 2 bytes, then the encrypted file size should double, and yet it's always the same.
It's probably a simple answer, but I just don't understand :)


PCBGuy(Posted 2005) [#15]
Thanks again ... all these posts are making me dizzy. I like the sample by fall_x and will likely use it. Using Writeline would still be a good idea for the time you are coding then when the game is finished replace it with a more encryped, smaller size file output system. Thats practicle, dont you think?
Oh I never thought using "2" in the Post title would get any body angry. It must be some programming religion or something, OK I won't use it anymore to keep the peace.