i wonder is there any simple way to save an object property to text file and read it, I’ve tried to understand these python scripts posted in saving score posts in the forum but i failed to understand it, so i need it as simple as possible because i don’t know any thing about python and scripting
and thank you very much
Here’s a simple script. I’ve commented it as much as possible to explain what’s going on and hopefully is simple enough to follow (4 lines to save, 4 lines to load). Here’s the save script:
#create a file object f = open('save.txt', 'w') #convert the property you want to save to a string #change 'someProperty' to the name of the property you want to save toSave = str(own['someProperty']) #write the string to the file f.write(toSave) #close the file f.close()
First of all we create a file object (called f in the above example) using the open() command. Open takes the file name to be opened (if the file doesn’t exist Python will create it) and specify the open mode as ‘w’ for write so we can write data to it. Because the file will only accept strings as data we convert the property we want to save to a string in the next line using str() and assign the string to another variable. We then write that variable to the file using the file objects .write() method. Then, finally close the file to free up the memory.
#create file object, and set open mode f = open('save.txt', 'r') #read a line and save it's value toLoad = f.readline() #convert the variable type and assign the loaded variable to a propery own['someProperty'] = int(toLoad) #close the file f.close()
Here, when opening the file we use the ‘r’ flag to tell python we only want to read from the file, not write to it. The next line uses the .readline() method to read the first line of the file (calling readline() again will read subsequent lines) and saves the returned line in a variable. Because readline() returns a string in the next line when we load the variable back into a property we have to convert it back to an integer using int(). Then close the file again.
If the data your loading needs to be a string then there’s no need to change the type. Also if the data is a floating point instead of an integer then you can use float() instead of int() to convert it to the right type.
Then it’s just a case of hooking this up to logic bricks and triggering the save and load at appropriate points.
I hope all this made sense and helps! Any troubles just let us know.
thank you very much, i think it’s simple enough, I’m going to try it and i will come back
i really appreciate your help
No worries Glad I could help!
If you get stuck at any point or if there’s any part you don’t understand let us know and we’ll try an help you.
Since I posted a similar question, here I come. So if on read I can access a specific line, can I on write do the same, let’s say overwrite a line? Can I for example (of course I can but how?) have different properties from different objects and write a line per object, then maybe save the line number somewhere(in an object’s property) to access it later! Sorry, this is the first set of questions, eventually, I may come to ask about the most complex thing that can be done with it. Apologies to mgmislam for ‘intruding’ in your thread!
Simplest way ever: put everything into a dict. Save the dict. Now worry about line, characters positions etc. You save a dict, you load a dict.
Hi Mr battery,
I’m sorry but I’ve this error:
NameError: name ‘own’ is not defined
@torakunsama(torakunsama) no worries you are welcome
(Monster) thanks for reply
@ mgmislam: Oh ok, thanks! Monster Sensei, the question is not about a better way of doing it is just knowing how to do this. Alternatively, one can use the ‘proper’ way. Since some of us are still learning python(at my level, I could just go to the site and learn the intermediate to advanced site, if I had time), and it’s applications in the BGE. So the small scripts (examples) are vital for this process. Thank you for understanding!
Monsters right, using Python’s built in file objects isn’t the easiest way to deal with saves, and is not suited for saving anything complex. But I think the best method depends on what you’re saving. For example, in Pistolero - the game I’m currently scripting - the only thing that needs to be saved is the highest score. Dumping the globalDict would be overkill, just easier to save the one value I’m interested in an a text file.
@torakunsama: editing a particular line is a bit more tricky. And has Monster pointed out keeping track of which byte you’re operating on in the file is hard. Luckily file objects are iterable. So basically we can loop through the file, load each line into a list then using the list it’s much easier to keep track of the line you want to edit, finally dump the list back into a file overwriting the old data. Say, for example, you have a text file with a list of scores (all integers), with each value on a separate line:
f = open('test.txt', 'r+') savedData =  for line in f:#loop through the file and add each line to the list saveData.append(int(line)) #we can then use list indices to select a line and edit it savedData = 100 #return the cursor to the beginning f.seek(0) for line in saveData:#loop through the list and write the elements to the file f.write(str(line) + ' ') f.close()
Some important things to note: Firstly the file is opened in read/write mode (‘r+’) because we need to both read form it and write to it. This script will not work in any other mode. When looping through the file each line is converted to an interger so the data stored in the file can be used (file objects always return strings, which isn’t useful when dealing with scores!). The ‘cursor’ that reads through the file needs to returned to the beginning of the file before writing otherwise when we dump the list contents it will just be added to the bottom of the file. Resulting in 2 copies of the score list in the same file. Finally when saving the data it needs to be converted back to a string again (the .write() method only accepts strings) and a newline character (’
') needs to be added at the end of the string so that each score will appear on it’s own line. Hopefully all that made sense! Any questions just ask.
@mgmislam: own is the name of the controller’s owner that the scripts attached to. You’re getting an error because own is not defined in the script. If you’ve used a different name for the owner change own to that. If not you need to define it, it’s normally done at the top of a script. In Blender 2.49b it’s done like this:
cont = GameLogic.getCurrentController() own = cont.owner
If you’re using Blender 2.5x then it’s like this:
cont = bge.logic.getCurrentController() own = cont.owner
Hope this helps!
it works perfectly,