|
Post by zenzou on Feb 13, 2011 3:51:23 GMT -5
A quick update: after spending half a day trying alternately to pin down exactly which parts are screwing up my attempts to get a successful build and scouring Google for leads based on the handful of error messages I was able to hunt up, I've gotten precisely nowhere. I guess I'm too late, but what I did to get it to work was to find/use the pre-compiled girls from Feb bugged 2, and compile the files in asistants/people as well as OW. I haven't really gotten around to retesting which girls weren't playing nice. I'd get to it, I feel we might as well wait till Doc stabilizes his changes to the girls' classes and functions.
|
|
|
Post by compuscribe on Feb 14, 2011 3:32:13 GMT -5
I'm feeling incredibly stupid, now. I'd already tried all the stuff you suggested, and more. In the end, it turns out I was missing an update for CS4. It hasn't been updated in a while, so I was convinced I already had the latest version ... and at one point, I did. I just forgot that I did a clean sweep of my hard drive a couple months back. I thought I'd updated Flash when I reinstalled it, but evidently something came up and distracted me. Since all of my other projects worked fine, I didn't notice anything. I kept telling myself I was already up to date and looking for other problems, and what should've been the first thing I checked, ended up being the last. Not my proudest moment.
Long story short: I have been able to build a working version of the game, finally. (At least it seems to be working. The game's complicated enough that it'll take a while to be certain, but there's nothing obviously broken, anymore.)
Now, I can actually start testing some of my ideas.
On a side note, since I'm evidently not the only one using CS4, could I ask someone who does have CS5 to take the Asuka, Nanoha, Rena, Sakura, and Yoruichi FLAs and save them as CS4 files, instead? If the idea is to make the project accessible and open to the community, the fact that anyone with CS4 can't even open the files does kind of hurt that, a bit. (At least I'm assuming they were saved in CS5. That'd be consistent with the "Unexpected file format" error I get whenever I try to open them.)
Yes, you don't need the FLAs to build the game, but suppose someone wishes to expand the girls, at some point in the future ... perhaps to take advantage of new features that have been added to the game. Being able to get in there and putter around could be useful, and it'd be more useful if it's accessible to the greatest number of people possible. (If nothing else, it seems weird to have CS4 and CS5 files in the same project.)
Anyway, having completed my victory lap, I'm off to bed for some well-deserved rest.
|
|
|
Post by docclox on Feb 14, 2011 4:37:26 GMT -5
On a side note, since I'm evidently not the only one using CS4, could I ask someone who does have CS5 to take the Asuka, Nanoha, Rena, Sakura, and Yoruichi FLAs and save them as CS4 files, instead? If the idea is to make the project accessible and open to the community, the fact that anyone with CS4 can't even open the files does kind of hurt that, a bit. (At least I'm assuming they were saved in CS5. That'd be consistent with the "Unexpected file format" error I get whenever I try to open them.) I'll take a look when I get a chance. CS5 is a bit hostile to working in CS4 - always saves in CS5 by default. You need to "Save As", choose CS4 from the drop down list, say "yes I really do want to overwrite the file I'm saving" and then dismiss a nag screen where it tells you how you're going to lose Nifty Stuff by saving in an outdated format. Bloody Adobe. I'm not surprised people accidentally save in CS5 from time to time.
|
|
|
Post by compuscribe on Feb 16, 2011 1:52:29 GMT -5
I'm no stranger to the hassles of trying to get Flash to keep a file in an earlier format, but that's part of the reason why I made the request here, rather than on, say, the Game Girl Creation board. Those are the files most likely to be saved in the wrong format, but they're also being created by people who probably shouldn't be required to jump through the extra hoops of making sure everything is CS4-compatible.
Anyway, I'm sorry Daisy, but it looks like saves are still broken. My own experience shows the game still saving at times when it shouldn't (I think I've got a handle on that), and some of my own tests, combined with one of the comments on the blog seem to indicate there might be some logic errors in there, as well. (While debugging my changes, I was getting some errors about trying to access the properties of a null value in areas of the code I hadn't even touched. This resulted in the game freezing behavior the poster described ... which also seems to support the idea that it isn't unique to anything I did.)
Unfortunately, I'm hesitant to go too much deeper into the save/load logic, just yet, since zenzou has a point about waiting until Doc's classes are in a more presentable state. At that point, we'll probably end up having to rewrite a good chunk of that code, anyway, if only to take advantage of the improved readability, and it doesn't makes sense to do it twice.
Now that I can test my code, I do have a couple other things, in a similar vein, that I've been toying with, in the meantime, like saving the game options and saving the settings used the last time you created a character, like SlaveMaker does. (Both of those would be separate files completely independent of the game saving/loading code.) While comparatively simple, since they only require storing a handful of values, each, they don't have the obvious hooks into the existing framework that the game saves/loads do, and I'm trying to avoid changing the existing code any more than I absolutely have to, if only to make the new code easier to incorporate, without messing up any of the stuff other people are working on. So,I'm taking some time to think about how I want to approach it.
Basically, while it makes sense for me to wait until the girl classes are ready for deployment before going too much deeper into the save/load functions, there's no need to hurry, on my account.
[edit] Also, I wanted to apologize for derailing this thread as much as I have. I'll try restrict my comments to actual code-related issues, from here on out ... at least until I have something ready for scrutiny.
|
|
|
Post by daisy_strike on Feb 16, 2011 2:00:36 GMT -5
Now that I can test my code, I do have a couple other things, in a similar vein, that I've been toying with, in the meantime, like saving the game options and saving the settings used the last time you created a character, like SlaveMaker does. (Both of those would be separate files completely independent of the game saving/loading code.) While comparatively simple, since they only require storing a handful of values, each, they don't have the obvious hooks into the existing framework that the game saves/loads do, and I'm trying to avoid changing the existing code any more than I absolutely have to, if only to make the new code easier to incorporate, without messing up any of the stuff other people are working on. So,I'm taking some time to think about how I want to approach it. Once doc gets his great code done we should be able to set options outside the game by changing xml. Daisy
|
|
|
Post by compuscribe on Feb 16, 2011 2:50:48 GMT -5
Oh, yeah! He is moving a lot of data and options to external files, isn't he?
Even so, writing the save for that should be a pretty simple addition, so I might do it anyway, just to have something in place until Doc can get around to it. (I mean, by my count, there are only 3 options, at the moment: Work Safe, Skip Jobs, and Lolis Available, and Skip Jobs doesn't even work, right now.) Besides Doc's got a lot on his plate, and I think the classes are probably a bigger issue, at the moment, since a lot of future development hinges on them. It might take a while for him to get around to moving everything to XML. (And if the save/load option functions are in place, it'll give him a place to stick some of that code when he does find the time for it.) I'll have to think about it.
Either way, the part about saving character creation info could still be useful, and that was the one I'm most interested in getting up and running, anyway. I'm getting tired of entering the same names and selecting the same background, goal, and assistant each time I want to test something new. (And I do want to use the same ones, so I know any changes in the program's performance aren't due do those choices, rather than the code I just tweaked.) Being able to just click "Next," because it remembered all of the settings would be a big help.
|
|
|
Post by docclox on Feb 16, 2011 3:15:53 GMT -5
A preferences xml would be easy enough - if we can figure out how to not keep overwriting it with each new release. anyway.
|
|
|
Post by docclox on Feb 16, 2011 9:10:12 GMT -5
Good plan on the numbers to ints - I've been doing that as I find them, but haven't been at all systematic about it.
Yeah - SharedObject.close seems to be for remote connections, where the object is on a server somewhere. I think the best we can do is clobber all instances and let it be garbage collected.
The alternative is to deep-copy the game data into the shobj, but that's a lot of work. That said, a quick google throws up [urlhttp://www.kirupa.com/forum/showpost.php?p=1897368&postcount=77]this[/url], which could be an easy fix: clone the data, copy it to the shared obj, and it then doesn't matter if the game data changes, because the shared object has a copy.
That said, we stand to copy a lot of bitmap data if we do that. Probably a lot of copies of bitmap data, since multiple references to the same data will result in multiple clones, all the same size as the original.
Something to think about, anyway.
@daisy: not sure if I should report this as a bug: should primes use the piercing values in the girl .as files? Or have things moved on from that, in which case I can remove the values from the object.
|
|
|
Post by daisy_strike on Feb 16, 2011 16:47:49 GMT -5
Yes primes should use the piercing of the arch in the girl file.
Daisy
|
|
|
Post by compuscribe on Mar 2, 2011 1:33:02 GMT -5
Sorry for taking so long, but real life has been kicking my butt, lately. (Last week, in particular, was shot to hell.) Anyway, I've managed to update the charactercreation.as to include the functionality to save the settings for the last character created, and load those as the default, the next time you start a new game. (Only took a couple hours to nail that down, once I finally found the time.) The file with the changes I made can be found, here:
In other news, in an effort to make some further progress on the real saves, I tried checking out a more recent version. Daisy's branch is missing all of the sub-folders (and with everything in flux, I'm not entirely sure which versions to replace them with), and trying to build from the trunk gives me the following error: "1046: Type was not found or was not a compile-time constant: Girl." on the following lines:
function pushNewGirlNow(GT:Girl) function find_archetype(func:Function):Girl (lines 799 & 835, respectively).
Is there something missing or am I doing something wrong? Which file contains the implementation of the Girl class, anyway? (There are a lot of files, and searching for girl and/or class doesn't narrow it down a whole lot. And the obvious suspects, like girls.as, don't seem to be the ones I'm looking for.)
(Edited to remove outdated link.)
|
|
|
Post by docclox on Mar 2, 2011 8:32:04 GMT -5
OK I'll take a look tonight. and trying to build from the trunk gives me the following error: Update and try it again. I messed up on the merge and some files didn't get added that were needed. Daisy's compiled and run the current trunk (rev 51) so that should build fine. Any problems, let me know
|
|
|
Post by compuscribe on Mar 2, 2011 19:20:33 GMT -5
When did that update go up, 'cause I know I tried that recently. (In other words, yeah, it builds, now. I haven't messed around with it enough to know how well it's working, but it's running, which is a definite improvement. I will say that it's much better at telling you exactly what files you're missing, now.) Anyway, after posting that, I realized that I'd intended to go back and throw in some error checking with the flush method (I'd used a quick & dirty approach until I could get the save/load data juggling sorted out), and I forgot. Since I didn't, it currently requires you to have already given the game permission to use the disk space (flush() fails on "pending"), so depending on your settings, it might not work on the first attempt. It's an imperfect solution, but it works. I'm working to pound out the problems, as we speak. I thought I had it sorted out, but the things that should be working don't seem to be, so it's taking a little longer than I thought.[edit] It was a scope issue. (It's funny how Flash seems to pick and choose when the rules of scope actually apply.) I had to make myData a global variable. It's a sub-optimal solution, but it should work, for now. It might not even be worth making a class to handle this. There isn't a whole lot that was changed (I basically replaced the flush call with a more robust series of checks, and added an event handler to deal with pending flushes), but for simplicity's sake, an updated file can be found, here:
PS - feel free to change "myData" to "playerData" or "characterData" or anything that seems more appropriate. I should've done that, myself. (A global search & replace should be fine.)
(Edited to remove outdated link.)
|
|
|
Post by docclox on Mar 3, 2011 2:13:58 GMT -5
When did that update go up, 'cause I know I tried that recently. (In other words, yeah, it builds, now. I haven't messed around with it enough to know how well it's working, but it's running, which is a definite improvement. I will say that it's much better at telling you exactly what files you're missing, now.) The commit went through at around midday yesterday, GMT. You were probably typing the message around the time I started sending. Anyway, after posting that, I realized that I'd intended to go back and throw in some error checking with the flush method (I'd used a quick & dirty approach until I could get the save/load data juggling sorted out), and I forgot. Since I didn't, it currently requires you to have already given the game permission to use the disk space (flush() fails on "pending"), so depending on your settings, it might not work on the first attempt. It's an imperfect solution, but it works. I'm working to pound out the problems, as we speak. I thought I had it sorted out, but the things that should be working don't seem to be, so it's taking a little longer than I thought.[edit] It was a scope issue. (It's funny how Flash seems to pick and choose when the rules of scope actually apply.) I had to make myData a global variable. It's a sub-optimal solution, but it should work, for now. It might not even be worth making a class to handle this. There isn't a whole lot that was changed (I basically replaced the flush call with a more robust series of checks, and added an event handler to deal with pending flushes), but for simplicity's sake, an updated file can be found, here: www.mediafire.com/?ygsokachqqp5lxaPS - feel free to change "myData" to "playerData" or "characterData" or anything that seems more appropriate. I should've done that, myself. (A global search & replace should be fine.) Thanks for that. I'm out and about today, so I might not get to sync it in until tomorrow.I'll keep you posted.
|
|
|
Post by compuscribe on Mar 3, 2011 20:33:17 GMT -5
Sorry for the repeated updates. If you've already started trying to sync it, you've probably already tracked down the problems, but if not, here's a version built to work with the trunk (at least as of revision 51):
I'm currently working out of 2 different directories, one with an old revision from Daisy's branch and and fairly recent revision from the trunk. I'm just waiting for the trunk to stabilize a bit more before I jump over. Unfortunately, I forgot to take into consideration the fact that the files were updated since revision of the branch I was using (most notably, the addition of the Player class), so I forgot to try it in the trunk, once I got that working.
Hopefully, this will be the last revision. Sorry for any problems the repeated updates may have caused. Just trying to save you the trouble of having to fix my mistakes.
[edit] More in line with the original purpose of this topic, now that the classes are starting to take shape, I've been looking at the main saving/loading issues again, and I realize that there is a certain level of crossover with the character creation saving. Rather than simply copying the same functions over again, it would make sense to form a package of some sort, after all. My question is what are people's thoughts on the best way to tackle that?
After puzzling it over for a while, I'm not at all sure that there is a perfect solution. A proper class would have problems accommodating the multiple types of data allowed by a shared object. (Besides, I don't feel like writing 8 different methods just to handle the storing and retrieving of ints, numbers, Booleans, and Strings, and I'm sure no one else would want to maintain them. I suppose you could just store everything as a String, then cast it to the proper type upon retrieval, but I'm not sure that's much better.) A static class would allow easy access to the commonly used functions, but it'd run into problems related to passing the SharedObject to required functions (most notably, the event handler).
As a compromise, I've come up with the following proposal, but like I said, it's an imperfect solution, so I was curious what others thought. (Feel free to skim. It's a concept, not tested code, so I doubt it's perfect. The important parts, as far as this discussion are concerned, are the methods and their intended purposes, as well as the public SharedObject property.)
package{ public class LocalSharedObject{ public localData:SharedObject = null; //SharedObject for this instance private fileName = ""; //file name for this SharedObject //default constructor public function LocalSharedObject(){ } /* constructor * parameter: file - contains the name to be used for the created SharedObject */ public function LocalSharedObject(file:String){ localData = SharedObject.getLocal(file); } //Writes the data stored in the SharedObject to the file location specified by the fileName property public function Write(){ localData.data.fileExists = new Boolean(true); //file is being written, so indicate that it exists
//flush data to disk var flushStatus:String = null; try { flushStatus = localData.flush(); } catch (error:Error) { trace("Error! Could not write SharedObject to disk!"); localData=null; //clean up SharedObject } if (flushStatus != null) { switch (flushStatus) { case SharedObjectFlushStatus.PENDING: trace("Requesting permission to save object..."); localData.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus); break; case SharedObjectFlushStatus.FLUSHED: trace("Value flushed to disk."); localData=null; //data saved, so kill SharedObject break; } } } //any common load functionality? public function Load(){ } // checks if file exists (if it has been written to at least once) // Returns true if the file exists on the user's computer; false if not public function FileExists():Boolean{ localData=SharedObject.getLocal(filename); var exists:Boolean=localData.data.fileExists; //check if file exists and store value for later use localData=null; //value retrieved, so kill SharedObject return exists; } //event handler for dealing with the "pending" status on a flush attempt private function onFlushStatus(event:NetStatusEvent):void { trace("User closed permission dialog..."); switch (event.info.code) { case "SharedObject.Flush.Success": trace("User granted permission. Value saved."); break; case "SharedObject.Flush.Failed": trace("User denied permission. Value not saved."); break; } // having been triggered, it's the event listener is no longer needed localData.removeEventListener(NetStatusEvent.NET_STATUS, onFlushStatus); localData=null; //whether successful or not, data handling is finished, so kill SharedObject } } }
This would allow you to type something like 'LocalSharedObject myData = new LocalSharedObject()' or even 'LocalSharedObject myData = new LocalSharedObject("fileName")' and instantly have access to all of the flush checking when it's time to write to the disk, by simply typing 'myData.Write()'; (It would even take care of adding the value used to check if the file exists, automatically.) That's good. You won't have to keep copying and pasting it into every file that needs to handling flushing a SharedObject.
The downside is that, in order to store or retrieve data, you'd need to type something like "myData.localData.data.fileExists" rather than simply "myData.data.fileExists" ... and that adds an extra layer of complexity (not mention more room for errors to creep in) in a very commonly used area, and I'm not at all sure if the ease of the reusable code would balance out the added hurdles, here.
What do people think? Is it a net gain? Is it more trouble than it's worth? Is there a better solution I'm just not seeing? I'm open to suggestions.
[Edit 2] Now that I think about it, perhaps I should just take the obvious approach and simply make the new class an extension of SharedObject, directly. That would still allow for adding new functionality, while sidestepping most of the problems of linking back to the other stuff. It's late, so I'll look into that tomorrow, though.
[Edit the 3rd] Or I could just test it, now (because once I get an idea in my head, it's hard to just walk away), and discover that "getLocal" is a static method of SharedObject, meaning it isn't inherited; implicit coersion fails; and with the implementation of SharedObject being a big, black box, I have no idea how I would go about defining an explicit coersion. I don't even have a useful constructor (at least not as far as I can tell) to give me a starting point.
(edited to remove outdated link)
|
|
|
Post by docclox on Mar 4, 2011 14:56:57 GMT -5
Sorry for the repeated updates. If you've already started trying to sync it, you've probably already tracked down the problems, but if not, here's a version built to work with the trunk (at least as of revision 51): www.mediafire.com/?25kw9oqdmfplvkjI'll look at that now. Been away the last couple of days, so not much done at my end. More in line with the original purpose of this topic, now that the classes are starting to take shape, I've been looking at the main saving/loading issues again, and I realize that there is a certain level of crossover with the character creation saving. Rather than simply copying the same functions over again, it would make sense to form a package of some sort, after all. My question is what are people's thoughts on the best way to tackle that? Not sure. I keep meaning to see if I can access static properties by subscripting the object instance (or maybe the class isntance). If we can, we can probably write a look to clone Player, girls and assistants into anonymous objects and save them in the shared object. We could reload the same way, and since most of the game data is in player, that should do it. After puzzling it over for a while, I'm not at all sure that there is a perfect solution. A proper class would have problems accommodating the multiple types of data allowed by a shared object. (Besides, I don't feel like writing 8 different methods just to handle the storing and retrieving of ints, numbers, Booleans, and Strings, and I'm sure no one else would want to maintain them. I suppose you could just store everything as a String, then cast it to the proper type upon retrieval, but I'm not sure that's much better.) A static class would allow easy access to the commonly used functions, but it'd run into problems related to passing the SharedObject to required functions (most notably, the event handler). I seem to recall seeing a function in the standard adobe libs that would clone an object into a byte array. That could serve as a universal conversion for saving. Possibly loading too if it works both ways. There has to be a good serialization/deserialization solution somewhere for AS3 As a compromise, I've come up with the following proposal, but like I said, it's an imperfect solution, so I was curious what others thought. (Feel free to skim. It's a concept, not tested code, so I doubt it's perfect. The important parts, as far as this discussion are concerned, are the methods and their intended purposes, as well as the public SharedObject property.) Hmm... probably put an IOError listener on that flush method if it'll take one. If it's async, it probably will. What do people think? Is it a net gain? Is it more trouble than it's worth? Is there a better solution I'm just not seeing? I'm open to suggestions. Can I think about it a bit more? That's a lot to take in at once, and it's been a long week Or I could just test it, now (because once I get an idea in my head, it's hard to just walk away), and discover that "getLocal" is a static method of SharedObject, meaning it isn't inherited; implicit coersion fails; and with the implementation of SharedObject being a big, black box, I have no idea how I would go about defining an explicit coersion. I don't even have a useful constructor (at least not as far as I can tell) to give me a starting point. mmm.... let me get back to you. I think I have an idea, but I want to stew on it a while
|
|