Page 1 of 1

[solved] adding new files

Posted: Fri Nov 13, 2020 5:32 pm
by The King
So here's the deal, I wanted to make it so that at certain sections in my game, it would add a text file into the game folder. This is the code I have written for this process:

"Loading..."
$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\"filename.txt", "w")
$ f.write("This is a test file")
$ f.close()
"There should now be a file loaded."

The problem is, that when I get to this part in the dialogue, I guess this error message:

I'm sorry, but an uncaught exception occurred.

While running game code:
File "game/script.rpy", line 448, in script
$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\"filename.txt", "w")
File "game/script.rpy", line 448, in <module>
$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\"filename.txt", "w")
IOError: [Errno 22] Invalid argument: 'C:\\Users\\King\\Downloads\renpy-7.4.0-sdk\\CodenameX\\game"filename.txt'

-- Full Traceback ------------------------------------------------------------

Full traceback:
File "game/script.rpy", line 448, in script
$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\"filename.txt", "w")
File "renpy/ast.py", line 908, in execute
renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
File "renpy/python.py", line 2104, in py_exec_bytecode
exec(bytecode, globals, locals)
File "game/script.rpy", line 448, in <module>
$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\"filename.txt", "w")
IOError: [Errno 22] Invalid argument: 'C:\\Users\\King\\Downloads\renpy-7.4.0-sdk\\CodenameX\\game"filename.txt'

I don't exactly know what it means, or how to fix it. Can somebody please help me out? Thank you :)

Re: adding new files

Posted: Fri Nov 13, 2020 6:38 pm
by _ticlock_
Hi, The King,

Try removing " from path name before filename.txt:

Code: Select all

$ f = open("C:\Users\King\Downloads\renpy-7.4.0-sdk\CodenameX\game\filename.txt", "w")

Re: adding new files

Posted: Fri Nov 13, 2020 7:14 pm
by The King
Right, so I made the change you suggested I make, but I got the exact same error message as before. I tried to change the file name to test.txt, but no difference in the error. Same thing when I added a folder called test in the game folder to put the file in. What else could I try?

Re: adding new files

Posted: Fri Nov 13, 2020 8:26 pm
by drKlauz
Type \\ instead of single \. \ is escape character in python. Or better use / instead of \\.
Also avoid using hardcoded paths, use config.gamedir and/or config.savedir.

Re: adding new files

Posted: Fri Nov 13, 2020 9:52 pm
by The King
Okay, so here's my new line of code:

$ f = open(config.gamedir = game "test.txt", "w")

I changed nothing else before or after this, but now I just get an error that says this is invalid syntax, and it points to the comma. What do I do now?

Re: adding new files

Posted: Fri Nov 13, 2020 10:35 pm
by _ticlock_
According to this link https://www.renpy.org/wiki/renpy/doc/co ... _from_file you need to use renpy.loader.transfn function:
Check this out as well viewtopic.php?t=42614
I am not sure if it is proper way to do it, but I would try using test.txt:

Code: Select all

$ f = open(renpy.loader.transfn("test.txt"), "w")
Just checked it and it worked.

Re: adding new files

Posted: Sat Nov 14, 2020 12:36 am
by The King
Okay, so I did that, and it did work. That will be useful for me down the road. However, and perhaps I should have been clearer in the beginning, my apologies, but I was kinda looking for a way to create a brand new file from scratch within the game, not modify an existing file. When I tried this, it didn't work until I created the test.txt file manually. Is there a way to create a brand new text file from within the game? If so, how do I do that?

Re: adding new files

Posted: Sat Nov 14, 2020 1:27 am
by Vladya
  • renpy.loader.transfn returns the path to file only if it is in one of the config.searchpath directories.
  • To create a new file, attach the required path in Ren'Py format to the variable config.gamedir. Like this:

    Code: Select all

    init python:
    
        #  Module for correct work with paths,
        #  taking into account the features of different operating systems.
        from os import path
    
        full_path = path.abspath(path.join(config.gamedir, "need_file.txt"))
    
    
  • To close files correctly, in case of errors, I recommend using "with" context manager:

    Code: Select all

    init python:
    
        from os import path
    
        full_path = path.abspath(path.join(config.gamedir, "need_file.txt"))
        with open(full_path, "wb") as _file_object:
            _file_object.write(b"Hello, world!")
    
    
  • In addition to the above, I also recommend that you first save the data to a temporary file and rename it as a destination file. With this logic, even if an error occurs, the final file will not be corrupted:

    Code: Select all

    init python:
    
        import io
        import os
        from os import path
    
        def _save_text_data_to_file(data, filename):
            
            if not isinstance(data, basestring):
                raise TypeError("'data' should be a string.")
            if isinstance(data, unicode):
                data = data.encode("utf_8")
    
            filename = path.abspath(path.join(config.gamedir, filename))
            _dirname = path.dirname(filename)
            if not path.isdir(_dirname):
                os.makedirs(_dirname)
    
            temp_fn = "{0}.tmp".format(filename)
            with io.BytesIO(data) as _read_file:
                with open(temp_fn, "wb") as _write_file:
                    while True:
                        chunk = _read_file.read((2 ** 20))  # 1mB
                        if not chunk:
                            break
                        _write_file.write(chunk)
    
            if path.isfile(filename):
                os.remove(filename)
            os.rename(temp_fn, filename)
    
    label start:
        $ _save_text_data_to_file("Hello, world!", "helloWorld1.txt")
        "..."
        $ _save_text_data_to_file("Some text.", "folder1/folder2/helloWorld2.txt")
        "..."
        return
    
    

Re: adding new files

Posted: Sat Nov 14, 2020 9:41 pm
by The King
Okay, everything seems to be a good working order now. Thank you for your help :)