How do I save to appdata with this?

I am in a Game Jam that ends on January 3rd and there were a lot of bugs in the save system but it is finally working and now all I have to do is save to the right place but I don’t know how.

from bge import logic
path    = logic.expandPath("//")

def save():
    cont = logic.getCurrentController()
    own = cont.owner 
    # 'info' is what will be saved to the file.
    # Example:
    # info = str(*What you want to save*)
    
    info = str(own['prop'])
        
    file = open(path+str(own)+".txt", 'w')    
    file.write(str(info))
    
    
def load():
    cont = logic.getCurrentController()
    own = cont.owner
    
    file = open(path+str(own)+'.txt','r')
    line = file.readline().replace('\n','').split(',')
    own['prop'] = int(line[0])
    own['prop0'] = float(line[1])

How can I save in the famous appdata?

what is appdate, folder or file ??

appdata is a folder

just add it to you path.

path = logic.expandPath("//appdata")

this is how i handle storage, you are welcome to pick from it.
datastore.py (4.3 KB)


import os, sys
import sqlite3
import shelve

__all__ = ["Datastore", "Datastore_sqlite", "DictStore"]


class Datastore:
    def __init__(self, **kw):
        self.folder = ""
        self.path = ""

        for arg in kw:
            if arg in vars(self):
                self[arg] = kw[arg]

        if self.path:
            self.path = os.path.join(self.path, self.folder)
        else:
            self.path = os.path.join(os.getcwd(), self.folder)

        os.makedirs(self.path, exist_ok=True)

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        setattr(self, key, value)

    def scandir(self, path=None):
        tmp = []

        if path:
            path = self.path

        if sys.version_info[0] == 3 and sys.version_info[1] > 5:
            with os.scandir(path) as it:
                for entry in it:
                    if entry.is_file():
                        tmp.append(entry.name)
        else:  # fallback
            for entry in os.scandir(path):
                if entry.is_file():
                    tmp.append(entry.name)

        return tmp

    def save(self, data="", filename=None, flag='w'):

        if filename:
            filename = os.path.join(self.path, filename)
            with open(filename, flag) as file:
                file.write(data)
                return True

        return False

    def load(self, filename=None, flag='r'):
        if filename:
            filename = os.path.join(self.path, filename)

            if os.path.isfile(filename):
                with open(filename, flag) as file:
                    data = file.read()
                    return data

        return False


class Datastore_sqlite:

    def __init__(self, **kw):
        self.folder = ""
        self.path = ""
        self.filename = "datastore.db"

        for arg in kw:
            if arg in vars(self):
                self[arg] = kw[arg]

        if self.path:
            self.path = os.path.join(self.path, self.folder)
        else:
            self.path = os.path.join(os.getcwd(), self.folder)

        os.makedirs(self.path, exist_ok=True)

        self.dbfile = os.path.join(self.path, self.filename)

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        setattr(self, key, value)

    def execute(self, sql, tableattr=None):
        with sqlite3.connect(self.dbfile) as conn:
            c = conn.cursor()
            c.execute("PRAGMA foreign_keys = ON")
            if tableattr:
                c.execute(sql, tableattr)
            else:
                c.execute(sql)


class DictStore:

    @staticmethod
    def save(data, key='qs', dbname='quicksave'):
        if data:
            with shelve.open(dbname) as sdb:
                sdb[key] = json.dumps(data)
        else:
            print("Error, No data submitted")

    @staticmethod
    def load(key='qs', dbname='quicksave'):
        with shelve.open(dbname) as sdb:
            if key not in sdb:
                return {}
            else:
                return json.loads(sdb[key])

can you send a .blend?

here is an blend, it uses a simpler version

level-store.blend (757.6 KB)

I didn’t understand how it works

@Cotaks
You had helped me before. so can you help me now?

i have tried to make is simpler.

storage.blend (479.9 KB)

what about appdata?

the reason i did not include in the blend is do to i don’t have a directory named appdata (you get and error if you try to access i non existent directory), so if you need just add it to your path.

the answer to that is in this tread

1 Like

I found this module that does exactly what you want in a cross platform way.

Also you can use Python standard library’s pathlib, which allows easier path manipulation and can avoid a lot of string processing code. For creating and deleting trees of files, try shutil.

from pathlib import Path

# Get the current blend file directory
path = Path(expandPath("//")).resolve()

# Get a string representation of the Path object, if needed
pathstr = path.as_posix()

# Get the current user directory (for example, "C:/Users/Joel")
userdir = path.home()

# The operator "/" can be used to add a new element to the path
appdir = userdir / "MyApp" # Results in "C:/Users/Joel/MyApp"

# Creates the appdir directory if not exists
if not appdir.exists():
    appdir.mkdir()
1 Like


that way?

I think I did something wrong

I already found the problem, thank you for your help :slightly_smiling_face:

os.environ['APPDATA']

On Windows, that’ll get you a String path that looks something like:
C:\Users\(username)\AppData\Roaming