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)

def _loadScoresFromFile(string_filepath):

        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.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"]
  • $\begingroup$ Do you mean the path C:\Users\USERNAME\Documents? AFAIK this one shows as My Documents in the OS (and localized on system of other languages) despite its real folder name, which is always English. And do you want to know how to use Python's expandpath() or what is it actually about? $\endgroup$ – CodeManX Jun 2 '14 at 9:25
  • $\begingroup$ yes, c:\user\USERNAME\documents $\endgroup$ – jareel Jun 2 '14 at 10:07
  • $\begingroup$ I know :// means to use the existing directory...Im trying to figure out if blender/python can reach out beyond its own directory to edit the scores file in c:\user\USERNAME\documents of the users computer. Im sure this is all quite clear. $\endgroup$ – jareel Jun 2 '14 at 10:11
  • $\begingroup$ ok...im using an installer to install my game, the installer instals in c:/programs forlder, this is non writable. The pythin code above is in my blender level file, which works fine when i use it in a user folder. but installed in program files, obviously it cannot be written to. I need the code to reach out to documents or even appdata where a folder is kept that can contain the scores text when its created and then be written on, so my game has persistent memory for scores! $\endgroup$ – jareel Jun 2 '14 at 10:20

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)


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

| improve this answer | |
  • $\begingroup$ huh? so how do i change the code above to simply access a folder (outside of program files) to create a text file with the users scores in my game. My installer will create the blank file....anyway...Ima go buy a gun to shoot myself $\endgroup$ – jareel Jun 2 '14 at 11:40
  • $\begingroup$ scores = _loadScoresFromFile("scores.txt") I want to use expandpath so i can tell blender to choose a folder outside the program files folder $\endgroup$ – jareel Jun 2 '14 at 11:46
  • $\begingroup$ I don't see anything Blender-related here, you just determine any writable path, preferably in the user dir (I discourage to use a fixed path, as nothing is guaranteed, like C:\ being the system drive). Check the official Python docs, StackOverflow or whatever for general IO questions. $\endgroup$ – CodeManX Jun 2 '14 at 11:59
  • $\begingroup$ Sorry, yesterday was a bit frustrated with this problem, I added this to my code $\endgroup$ – jareel Jun 2 '14 at 23:02
  • $\begingroup$ from os.path import expanduser home = expanduser("~") then this scores = _loadScoresFromFile("/home/scores.txt") but its ignoring the variable home as the designated place, i also tried home +scores.txt with no difference $\endgroup$ – jareel Jun 2 '14 at 23:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.