expandpath() ?? can python reach out to an external directory on users comp? I have a scores text file (game scores kept here) that gets created on completion of game level.

I am installing users downloads of my game into C:\Program Files\ folder, but programs folder is not writable.

My Python logic (below) in my game levels creates a text file in the existing installation folder, where my other game blend files are stored.

But when I test the download, no scores saved, because the file installs into Windows C:\Program Files\ folder (which is of course fine, it's the right place for a game, but I lament).

So I want to get the script below to not just create a scores.txt file in the existing folder, but to create it in documents (not My Documents/).

My installer will add a blank folder in documents whose name is known, lets call it blurb\, then Python does exactly what it did before, but create the folder (and of course fetch/get/load) in documents\blurb\scores.txt.

This I assume is where it all happens:

scores = _loadScoresFromFile("scores.txt")

from bge import logic
import pickle

def _saveScoresToFile(list_scores, string_filepath):

    file = open(string_filepath, "wb")
    pickle.dump(list_scores, file)
    file.close()

def _loadScoresFromFile(string_filepath):

    try:
        file = open(string_filepath, "rb")
    except IOError:
        print("Failed to load scores from {}".format(string_filepath))
        return []

    return pickle.load(file)

scores = _loadScoresFromFile("scores.txt")

def display():

    scene = logic.getCurrentScene()
    writer = scene.objects["Writer"]

    name = logic.globalDict["name"]
    score = logic.globalDict["score"]
    score2 = logic.globalDict["score2"]

    tup_entry = (name, score, score2)
    scores.append(tup_entry)
    scores.sort(key=lambda entry: entry [1])

    new_entry_idx = scores.index(tup_entry)

    for entry, i in zip(scores, range(len(scores))):
        new_writer = scene.addObject("Writer_new", writer)
        new_writer["Text"] = "{:d} - {:s} - {:2}:{:2}".format(i + 1, entry[0], entry[1], entry[2])

        new_writer.worldPosition.y -= 0.105 * i
        new_writer.localScale = writer.localScale

        if i == new_entry_idx:
            new_writer.state = 1

    _saveScoresToFile(scores, "scores.txt")

def setName():

    scene = logic.getCurrentScene()
    name = scene.objects ["Name"]

    logic.globalDict["name"] = name["Text"].strip()

def setScore():

    cont = logic.getCurrentController()
    score = cont.owner

    logic.globalDict["score"] = score["Text"]

def setScore2():

    cont = logic.getCurrentController()
    score = cont.owner

    logic.globalDict["score2"] = score["Text"]
Python is able to access the entire file system, except paths that require elevated rights (such as C:\Program files\ and C:\Windows\). It can also access them if you run your it as administrator, but you would usually not want that.

If you want to get the user directory path, use:

from os.path import expanduser
home = expanduser("~")


It also works on Windows. Example result: 'C:\\Users\\CoDEmanX'

Note that the Documents folder is not necessarily called like that, if you really want the actual path, you'll need to do this:

import ctypes.wintypes
CSIDL_PERSONAL= 5       # My Documents
SHGFP_TYPE_CURRENT= 0   # Want current, not default value

buf= ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
ctypes.windll.shell32.SHGetFolderPathW(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, buf)

print(buf.value)


For me it prints D:\Dokumente, because I set it up this way on my system.