Game Development Community

What's Happening With File I/O in TGB 1.5?

by Garrett Brown · in Torque Game Builder · 07/24/2007 (1:20 pm) · 19 replies

Hello,

I'm using TGB 1.5.1 on Windows XP

I'm having some problems with file i/o. The problem seems to be related to
isWriteAbleFileName()
always returning false.

I'm using FileObjects as follows:

%file = new FileObject();
%file.openForWrite("./test.txt");
%file.writeLine("foo");
%file.close();

Looking through the forums, it seems I'm not alone in having issues tied to file i/o. I found a work-around here:

www.garagegames.com/mg/forums/result.thread.php?qt=64729

but after I recompile with these changes, I can no longer load levels. Not to mention, even with that fix, the only place I can seem save to is c:\Documents and settings\user\Application Data...etc.

I'm actually wondering if this is by design, maybe to work on Vista or something. Really, I'm in the dark about the whole thing. All I know is that, out the box, I can't get files to save. I also receive the following messages in my console that maybe related:

XML::beginWrite - Failed to write to filecommon/commonConfig.xml.
saveGameConfigurationData - Failed to write to file: common/commonConfig.xml

It seems like, by default, I can't save anything. How many developers are having this problem with TGB 1.5 or above? Or any developers not having these problems? Should I be using the .save function that I've seen around? Any information on the subject would be great.

*Edit: I know I just said I can't save anything, but yes, I am able to save GUI's, Particle Effects, and Levels. I simply mean that I can't save things that aren't already set up for me through some tool.

About the author

I work at n-Space, located in Orlando, FL as a designer. When I'm not there, I work on side projects, generally using TGB. Side projects I've finished are Oddictive, Klockotock, and AstroDriller3020


#1
07/24/2007 (1:34 pm)
Try using the full path? I had a similar issue that was resolved by using the full path...
#2
07/24/2007 (5:18 pm)
I just tried the full path, and yes, it did work. Is there a way that you can get the full path of the user by chance? Because my full path is something like "C:/Documents and Settings/dssa/Desktop/project MAGE/Code/TGB/POC/game/data/test.txt" and this would not work on someone else's PC.

I tried the function called

expandFileName("./test.txt");
(found it here tdn.garagegames.com/wiki/TorqueScript_Console_Functions_7#expandFilename.28_file...)

and all it returned was "game/gameScripts/test.txt"

which will not pass the isWriteAbleFileName() checks.

Thanks for the help so far!
#3
07/24/2007 (5:29 pm)
I tried that function as well. I've been trying to save objects so that I can save the state of a scene.

I think the issue is with file writing permission, I think some of it might have been deactivated and then never turned back on? I'm not sure, will look into the specifics, but this is a known issue that--if it hasn't been taken care of in the 1.5.1 update--will be dealt with soon.
#4
07/24/2007 (7:41 pm)
Melissa is definitely correct, this is an issue with file writing permissions. If you look at the fix that I posted on the topic that you linked to, you should be able to alter/add those lines to create more writable paths.
#5
07/25/2007 (7:52 am)
Thanks very much for the feedback.
@Melissa - I'm running 1.5.1 and running into the same issues. The changelog mentioned something about a file function that always returned "" being fixed, but as I said, still running into the same problems.

@Luke - I've tried the exact fix posted and it was able to save in the "getUserDataDirectory" folder, but:
1.) I'd rather not save there, I'd rather be able to save anywhere I want
2.) After I recompile with those changes, I could no longer load levels. I received an error stating:
"Invalid File - level.t2d" or something very similar. Would you have any more insight into why that happens?
And do you know where I could find/research on the issue? When you say alter those lines, it sounds like there are more types of paths I can add, I'm just not sure where to look for those function calls. Do you just have to dig through the source to find them? Any file I should start in?

I really appreciate the help so far, thanks again.
#6
07/25/2007 (11:28 am)
Well, I came up with a solution. You guys can give me input on this, tell me what you think:

I searched through the code base for "GetUserDataDirectory", "MakeFullPath", "expandFileName"...just for research. I wanted to find a console function equal to MakeFullPath. I couldn't find it, so I just went ahead and made it. It looks as follows, in consolefunctions.cc:

ConsoleFunction(makeFullPath, const char *, 2, 3, "(string path, [string currentWorkingDir])")
{
   char *buf = Con::getReturnBuffer(512);
   Platform::makeFullPathName(argv[1], buf, 512, argc > 2 ? argv[2] : NULL);
   return buf;
}
And in script:
%fileName = makeFullPath("./test.txt");

And it works. The only thing is, I know that GG made the changes to file writing permissions for a reason. I don't feel I'm bypassing them this way, but I would still like to know why they were changed. Anyways, does anybody foresee this change messing me up down the road?
#7
07/25/2007 (1:59 pm)
I'm glad that it finally working. It would make sense that the permissions were changed due to the new, separate directory structure in 1.5. I don't know much more other than that.
#8
07/29/2007 (4:04 am)
Yes, it's finally working - for TGB pro owners!!!!!!!
I'm running TGB indie version and I found fileIO object completely useless in ver. 1.5.
openForWrite/openforRead always returns false, even if I use full paths.
What's the point of changing file write/read permissions in 1.5? What's wrong if someone wants to save/open text file in any directory.

So what's the solution for us - TGB indie owners ??
Do I have to stop developing my project in 1.5 and go back to 1.1.3 just to be able to save score table and ini settings to proper directory ???
#9
07/29/2007 (6:00 pm)
The proper directory is the user directory.

Anything else is against Apple OSX and Microsoft Windows XP / Vista application design guides (XP does not enforce it, vista does. In both cases, the path where the files have to be is clear and it is NOT the application directory, just to mention that)

TGB is just following the OS design rules for applications.
#10
07/30/2007 (8:55 am)
TGB is not following the rules correctly.

Currently for my game I am trying to do the simple task of saving a screenshot or exporting a font, both very simple activities in 1.1.1, 1.1.2, and 1.1.3 and in 1.5.2, all I get is "failed to open 'x/y.z' for writing"

I have tried using absolute paths, I have tried using getUserDataDirectory(), getPrefsPath(), etc and the only folder that TGB allows me to write a file is c:\games\MyGame\ and its subdirectories, which is completely counter to what OSX and Vista allow.

I have stepped through the source code of ResManager::isValidWriteFileName and writeablePath = "c:\games\MyGame" which makes absolutely no sense

expandFilename doesn't work at all, I can't use ~ or ^ with it because unless TORQUE_TOOLS is enabled, everything resolves to expandOldFilename

I would like to know if there is any way to write files to other folders without completely ripping out everything TGB 1.5 brought in to make the process more compatible and completely rewriting it ourselves
#11
07/31/2007 (5:24 pm)
To summarize what I've seen so far in 1.5.1:

The old version of ResManager::isValidWriteFileName() didn't allow you to specify full paths. The new version of it *requires* that you send full paths. Since even the common scripts are trying to send it VFS paths, they fail this call and it's no longer able to save fonts, screenshots, or even preferences. The workaround for this right now is either to modify isValidWriteFileName() or to change the common scripts to use full paths. In addition, anything that you're trying to save manually must be a fully qualified path name or it will be considered invalid. Finally as noted in the thread linked in the first post, the application data folder is not by default added to the writeablePath so if that's where your data is going, you also have to manually add that with ResManager::addPath() before you try to save anything.
#12
08/22/2007 (2:52 pm)
Aaah. I was wondering why none of the save game tutorials from TDN were working in TGB 1.5.1 -- this explains it nicely.

Just to clarify, is there a way (that will run on a user's machine, Mac or Windows) to write any kind of file from TorqueScript without recompiling with TGB Pro?

--clint
#13
08/22/2007 (3:12 pm)
As far as I remember, if you try (in 151) to save like: %obj.save("myobj.cs"); will not work. But if you try %obj.save("./myobj.cs"); it will save the file (in current game folder). But I may be mistaken here.
#14
08/22/2007 (3:19 pm)
It is not impossible to write a file from torqueScript to the user's machine without TGB Pro, though it is impossible to get the current install path of the game (which is the only directory, and set of subdirectories you can access)

if your game is on your computer at C:\MyGame, you can explicitly tell TGB to write a file to C:\MyGame\savedata.txt

but it will no longer work if someone takes your game and puts in in C:\MyGame2

If you have TGB Pro, you can run in and make a function called something like GetWritablePath() that returns wherever the game is currently installed.

Hopefully this will be cleared up with the next release
#15
08/22/2007 (5:01 pm)
I just wanted to post in here to let you guys know that we are aware of the issue and are actively seeking to resolve these problems.

The file system in Torque has gone through a number of changes. The first of which was to accommodate the needs of the TGB Tools, which unfortunately broke things in small ways that went unnoticed. The second of which were changes needed to work around OS permissions issues. For instance, Vista requires permissions to write to Program Files. These changes also broke things, and you are all now having to deal with these problems.

It is unfortunate that these issues went unnoticed. And I apologize for the inconvenience.
#16
08/23/2007 (7:35 am)
Okay, I've run into an interesting problem. Using Garrett's fix above, we have managed to make Torque properly output to the prefsPath directory on both Vista and XP (and presumably MacOS, but we don't have a machine to test with). The catch is that the directory doesn't exist until you quit the first time. The general process is this:

You load up our game, create a profile, play for a bit, and quit. None of your progress is saved, though, since C:\documents and settings\application data\game studio\game doesn't exist yet. Then, upon quitting, it creates it. You load it up again, again create a profile, and this time since the directory is there, it saves your progress. And everything after that works just fine.

We're really, really close to finishing up our game, but until we can get saving of player profiles and the like to work properly we're sort of SOL. Does anyone have any ideas on how to force path creation? There doesn't seem to be a script call that can do it, and while we're scanning through the C code now to make it behave properly we'd love any recommendations as to how to go about fixing this.
#17
08/23/2007 (8:02 am)
The path creation is no problem.

Do it as any company does it: Instruct the installer to create the directory and base files instead of trying to do it in client :)
#18
08/23/2007 (8:20 am)
That'd work for one user; but isn't the whole point of prefsPath that each user has their own configuration information and data? I mean, even if we created an application data folder for each user that currently exists during the install, if a new Windows user gets created they'd still run into this bug.

And yes, I guess we could just create a single folder in C:\Documents and Settings\All Users\Application Data. But that sort of defeats the point, I guess?
#19
08/25/2007 (1:24 am)
Quote:As far as I remember, if you try (in 151) to save like: %obj.save("myobj.cs"); will not work. But if you try %obj.save("./myobj.cs"); it will save the file (in current game folder). But I may be mistaken here.
FWIW, I tried this, but it doesn't seem to work (I did this with both SimObjects and t2dSceneObjects).

Robert, thanks a lot for the update on the status of this issue -- it is appreciated. :)

--clint