Write /read from a .txt file(or database)

Hello, it’s me again! In my project I need to save and retrieve info from an external file. Unfortunately, ll the examples I saw of write to file were mixed with other stuff, so at my level, I could not retrieve the useful piece of code. Can you help me with a simple write, append, delete, and whatnot in a txt file? For example: Player gets to a zone(planet) and add an object (trap) the gets out that zone. As he leaves the zone to another, all objects in that zone disappear. Fortunately all added objects have their info in a txt file, with the name,parent(planet),local position, orientation, and property name+value. Now, on return to this zone, the object must be respawned on the same spot it was added. If the trap is destroyed, it’s info should be delete from the file. If the property changes it’s value, it should be updated. A better way to do this would be to use a database like sqlite3, but since I am SQL illiterate, I can’t add tables and do queries, etc. So for now txt files should do! Thank you very much!

i would save the relevant information to a globalDictionary and save this with the Game-Actuator, this is easier than do it by hand…

example:

player1 = {"name: “thename”, “planet”: “theplanet”, “position”: “theposition”, etc}

Thank you sevi, but I don’t know if the info will stay next time I play the game (since it’s a persistent game) or if other players can access the objects. Globaldict should be great for local values such as ally NPC info and the such. I need a more permanent way to save and access data. It’s not data related to the player BTW. I think someone was already able to use a database with the BGE. This is what I got so far from Raiderium: to write, read, append: r= open(filename, ‘w’) r2= open(filename, ‘r’) r3= open(filename, ‘a’) I’m not sure if is just ‘open’ or ‘openfile’. I’d like to have some help even if is just for knowledge sake! Thank you!

the file looks like filename.bgeconfig. This file is persistent.
All you have to do, is a script that checks, if a valid file is on the harddisk wich can be loaded to build your scene, if not, create a file. next time you start the game, it will load the information needet.
I cant imagine, what kind of data you’ll need, that can not be stored in the globalDictionary. Instances of classes and KX_GameObjects cant be stored anyway, i guess. So go the easy way or go the hard way…

This is a script i used for a commercial project, but only to see what actually is stored in the bgeconfig file:


import GameLogic as G
import os
import os.path
import shutil
# import ast
import time
sce = G.getCurrentScene()
ob = sce.objects
cont  =G.getCurrentController()

def getTime():
    localTime     = time.localtime()
    Tag         = time.ctime()[0:4]
    year         = localTime[0]
    month         = localTime[1]
    day         = localTime[2]
    std         = localTime[3]
    min         = localTime[4]
    sek         = localTime[5]
    
    date         = day,month,year
    return date
def writeContentInfo(cont):
    Projekt_Verzeichnis = G.expandPath("//")
    date = getTime()
    
    sep         = os.path.sep
    path         = Projekt_Verzeichnis + "LogFiles" + sep
    file         = path + "LogFile" + str(date) + ".txt"
    infofile     = path + "InfoFile" + str(date) + ".txt"
    
    print("writing Logfile")
    own = ob['OBGame']
    # open
    Log = open(infofile, "w")
    
    # write 
    Log.write("Raster")
    Log.write('
')
    Log.write('
')
    Log.write(str(G.globalDict['Allezahlen']))
    Log.write('
')
    Log.write('
')
    Log.write("G.globalDict['Superzahlen']")
    Log.write('
')
    Log.write(str(G.globalDict['Superzahlen']))
    Log.write('
')
    Log.write('
')
    Log.write("G.globalDict['Profizahlen']")
    Log.write('
')
    Log.write(str(G.globalDict['Profizahlen']))
    Log.write('
')
    Log.write('
')
    Log.write("G.globalDict['Kleinzahlen']")
    Log.write('
')
    Log.write(str(G.globalDict['Kleinzahlen']))
    Log.write('
')
    Log.write('
')
    Log.write("G.globalDict['Trostzahlen']")
    Log.write('
')
    Log.write(str(G.globalDict['Trostzahlen']))
    Log.write('
')
    Log.write('
')
    Log.write("G.globalDict['passedWinnumbers']")
    Log.write('
')
    Log.write(str(G.globalDict['passedWinnumbers']))
    Log.write('
')
    Log.write('
')
    Log.write('Ausgeloeste Zahlen:')
    Log.write('
')
    Log.write("G.globalDict['playedWins']")
    Log.write('
')
    Log.write(str(G.globalDict['playedWins']))
    Log.write('
')
    
    for i in range(len(G.globalDict['playedWins'])):
        Log.write(str(G.globalDict['playedWins'][i]))
        Log.write('
')
    
    Log.write('
')
    Log.write('
')
    
    
    for i in (own.getPropertyNames()):
        Log.write(i)
        Log.write('
')
        Log.write(str(own[i]))
        Log.write('
')
        # print (i)
        # print (own[i])
    # close the file
    Log.close()
def writeContent(cont):
    Projekt_Verzeichnis = G.expandPath("//")
    date = getTime()
    
    sep         = os.path.sep
    path         = Projekt_Verzeichnis + "LogFiles" + sep
    file         = path + "LogFile" + str(date) + ".txt"
    infofile     = path + "InfoFile" + str(date) + ".txt"
    own = ob['OBGame']
    # open
    Log = open(file, "w")
    # write
    PropList = []
    for i in (own.getPropertyNames()):
        PropList.append([i,own[i]])

    Log.write(str(PropList))
    Log.close()
def deleteOldNumbers(cont):
    own = ob['OBGame']
    G.globalDict['Superzahlen'] = G.globalDict['Superzahlen'][own['Superpreise']]
    G.globalDict['Profizahlen'] = G.globalDict['Profizahlen'][own['Profipreise']]
    G.globalDict['Kleinzahlen'] = G.globalDict['Kleinzahlen'][own['Kleinpreise']]
    G.globalDict['Trostzahlen'] = G.globalDict['Trostzahlen'][own['Trostpreise']]
def readContent(cont):
    print ("readContent(cont)")
    Projekt_Verzeichnis = G.expandPath("//")
    date = getTime()
    
    sep         = os.path.sep
    path         = Projekt_Verzeichnis + "LogFiles" + sep
    file         = path + "LogFile" + str(date) + ".txt"
    infofile     = path + "InfoFile" + str(date) + ".txt"
    
    own = ob['OBGame']
    Log = open(file, "r")
    PropList = Log.readlines()
    L = eval(PropList[0])

    own['Games'] = int(L[0][1])
    own['Kleinpreise']     = int(L[1][1])
    own['Profipreise']     = int(L[2][1])
    own['Superpreise']     = int(L[3][1])
    own['Trostpreise']     = int(L[4][1])
    own['init']         = int(L[6][1])
    own['percent']         = float(L[7][1])
    own['wins']         = int(L[8][1])
    deleteOldNumbers(cont)

    Log.close()    
def createLogFile(cont):
    Projekt_Verzeichnis = G.expandPath("//")
    date = getTime()
    
    sep         = os.path.sep
    path         = Projekt_Verzeichnis + "LogFiles" + sep
    file         = path + "LogFile" + str(date) + ".txt"
    infofile     = path + "InfoFile" + str(date) + ".txt"
    
                                    
    if not os.path.exists(file):
        writeContent(cont)
        writeContentInfo(cont)
            
    else:
        writeContent(cont)
        writeContentInfo(cont)
            
    if cont.sensors['O'].positive:    
        readContent(cont)
def main(cont):            
    if cont.sensors['L'].positive:
        # print (dir(cont.sensors['L'].positive))
        createLogFile(cont)
    if cont.sensors['O'].positive:
        createLogFile(cont)
        

The function you’re thinking of is open().

To open a file (create it if it doesn’t exist, and open it for writing if it does), is:


file = open('filename.txt', 'w')
# OR, to open it for appending
file = open('filename.txt', 'a')

I wouldn’t really recommend adding things to the file line by line, unless you need them to stick around between scene changes. Otherwise, you can just write at the end of the game. If you do write to the file, you can use:


file.write('This is a string')
# OR
file.write(str(planet.worldPosition))

And once you’re done,


file.close()

Note that there is also pickling, which allows you to write whole Python objects to files and restore them, though I don’t know how well they work in the BGE (since you can’t overwrite any of the hard-coded objects).

Here’s the documentation of Python using File Objects - it’s for Python 2 instead of Python 3 because for whatever reason, Python 3 doesn’t use File Objects anymore, but a whole different way of looking at these objects (but they still perform the same, I think).