|
Post by daisy_strike on Jan 3, 2011 20:41:16 GMT -5
For all you programmers out there I need help fixing saving and loading everything I do just seems to make it worse. So I am asking for help, any help is great but fixes are better.
Please check the open source files it is savingloading.as
Daisy
|
|
|
Post by zenzou on Jan 3, 2011 21:39:57 GMT -5
Where can we find what you currently have? Might be easier if we nitpick your code, instead of thinking one up ourselves. Also saves time incase what we come up with is the same or similar to yours.
|
|
|
Post by daisy_strike on Jan 3, 2011 21:44:56 GMT -5
|
|
|
Post by zenzou on Jan 3, 2011 22:15:50 GMT -5
SWEET! *makes edits to Sakura for personal use...*
|
|
|
Post by docclox on Jan 3, 2011 22:27:10 GMT -5
Is the google code repository still maintained? I'd find it a lot easier to just update from svn than to keep downloading the entire codebase
|
|
|
Post by daisy_strike on Jan 3, 2011 22:35:20 GMT -5
I never got the svn to work well enough to keep it up. Damn thing just irritated the hell out of me spent hours on it and it still never updated properly in my mind...
Daisy
|
|
|
Post by docclox on Jan 4, 2011 6:17:05 GMT -5
Pity. It would have made keeping changes in sync much easier. I'll take a look at the saving problem today, see if I can spot anything. [edit] OK, not had as much time today as I'd planned, but I've taken a look. I think part of the the problem is that the shared object connection isn't being closed. So you have the data object containing references to in-game data structs, and as they are changed the data object is changing, which explains why the save appears to be continuous once saved, and why a crash can result in a corrput save file. You've clearly tried to mitigate this by declaring new arrays to hold the saved data, but the problem is the same as for the girl arrays - it's a shallow copy and the array contents are all references to the live values. Closing the connection (and optionally flushing it first) should solve that problem since with the connection closed, the updates cease. Better yet, (if I read the documentation right) the shared object should auto-update the save file if the connection re-opens. So you'd only need to set up the SO once, and then just re-open, flush and close for subsequent saves. But I haven't tried any of this yet, so this could all be wrong. I'll have a bit play... [edit] OK, close() is just for remote objects, and the auto-update feature is for local copies of remote SOs. OK, that seems to work for the simple cases. I'll need to do some more tests though. [edit] I don't suppose anyone feels like summarising the currently open load/save bugs for me? Also, does anyone look at the new "load" icon and think "save", and vice versa? My first thought was that the icons were the wrong way around, but maybe it's just me... [edit] Daisy, try this: www.mediafire.com/?dggnk7xrjw7pwqfAll I've done is make the SharedObject instance local to the load and save functions, and make sure the save instance flushed before returning to the game. I also had to add a save_file_exists() func so that otherworld.as didn't need to directly access the global shared object (which now no longer exists). There are a few tweaks we could probably do using an array of key strings to copy data into the save file. Might take a lot of the pain out of keeping save and load code synchronised. [edit] Also, try this: www.mediafire.com/?s32xh771fcosk5fSame thing, but saves the player data by assigning the object rather than setting individual fields (redundantly since you already assigned the object). Not a major change, but should save some hear tearing when the player object changes.
|
|
|
Post by daisy_strike on Jan 4, 2011 19:01:39 GMT -5
Okay that makes sense actually. I really think your on the right track. And that sure beats my next idea.
Going to have to play with it a bit to see if it actually fixes it. I'm hoping.
Daisy
|
|
|
Post by compuscribe on Jan 4, 2011 20:00:53 GMT -5
At the very least that should definitely take care of your biggest problems. According to Adobe's manual for AS3, "In order for a shared object to be saved to the user’s hard drive, you must explicitly call the SharedObject.flush() method," and you weren't flushing the shared object when you were done with it.
I can't say that I could improve on Docclox's code too much (certainly not without putting a whole lot more time into it), but I'd have probably tweaked it just a tiny bit, by replacing
myLocalData.flush(); storyHopper.push("Game Saved"); with something like this:
if(myLocalData.flush()) { storyHopper.push("Game Saved"); } else { storyHopper.push("***SAVE FAILED***"); }
Since flush will return a boolean true or false depending on whether the save file could successfully be written or not, this way the user gets at least a little feedback if the save couldn't be written, for any reason, rather than simply assuming success. (If you want to get really fussy, technically flush could also return a string value of "pending" if the user is allowing files to be written to his hard drive but hasn't allocated enough space for the process to actually finish. You could check for that, if you want to be really thorough, but the above should probably be sufficient. At least it provides some error checking.)
EDIT: I should probably point out, just for the sake of honesty, that I'm much more familiar with AS1 than AS3, but pretty sure the above code should still work.
|
|
|
Post by zenzou on Jan 4, 2011 21:33:00 GMT -5
My skills in programing aren't that great and I'm not very familiar with Actionscript coding, nor have I really had time to look at your code very carefully. Using what I know from autoit scripting, and using adobe's dictionary as reference: www.adobe.com/support/flash/action_scripts/actionscript_dictionary/I feel like a lot of repetitive code could be shortened/simplified if you used more functions. www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary373.htmlAlso using switch might shorten/simplify your if...elseif...else statements. www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary703.htmlIf I'm right, if (AssistantArray[i].asArch == "Neko") { var result = new MiniNeko(); addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result; } else if (AssistantArray[i].asArch == "Angel") { var result = new MiniAngel(); addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result; } else if (AssistantArray[i].asArch == "Lamia") { var result = new MiniLamia(); addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result; } else if (AssistantArray[i].asArch == "Fairy") { var result = new MiniFairy(); addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result; }
could be shortened to switch ((AssistantArray[i].asArch) { Case "Neko" InsertFunctionName(MiniNeko) Case "Angel" InsertFunctionName(MiniAngel) Case "Lamia" InsertFunctionName(MiniLamia) Case "Fairy" InsertFunctionName(MiniFairy) }
function InsertFunctionName(mini) { var result = new mini; addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result; }
NOTE: This code is only being supposed and HAS NOT been tested.
|
|
|
Post by daisy_strike on Jan 4, 2011 22:27:47 GMT -5
compuscribethank you for the flush command that was a missing piece. zenzouThe assistant code is sort of in a holding pattern here... it works but is not a final version as it needs to be changed later on to allow for adding more assistants WITH OUT adding more code to the core game. (Just like girls). Its just something I haven't gotten to yet. Daisy
|
|
|
Post by zenzou on Jan 5, 2011 1:15:18 GMT -5
I gotcha. The changes I presented were more for demonstration than anything else.
|
|
|
Post by docclox on Jan 5, 2011 4:09:31 GMT -5
compuscribethank you for the flush command that was a missing piece. I did have the flush command in there, but compuscribe is exactly right in checking the return code. Strictly speaking, the get_local() call needs a try {} block around it, as well For the assistant problem, try this: package daisy_strikes.otherworld { public class AssistantFactory { static var lookup:Object = null; public function AssistantFactory(assist_list:Object) { if(lookup) { return; } lookup = new Object(); /* * add the standard assistants in by default */ lookup["Neko"] = MiniNeko; // add Class object, not an instance! lookup["Angel"] = MiniAngel; // add Class object, not an instance! lookup["Lamia"] = MiniLamia; // add Class object, not an instance! lookup["Fairy"] = MiniFairy; // add Class object, not an instance! /* * we can load additional assistants from the parameter object */ for (var key in assist_list) { add(key, assist_list[key]); } }
/* * you could load assisstants from a swf file (or several) * and use this method to add them to the list */ public function add(ast_name:String, ast_class:Class) { lookup[ast_name] = ast_class; }
/* * use this to create an assistance instance from her name * returns null if no such assistant */ public function create(name:String):Object { classdef:Class = lookup[string]; if(classdef == null) { return null; } return new classdef(); }
public function list_assistants():Array { l:Array = new Array() for (var key in lookup) { l.push(key); } return l; } }
Then you can write something like this (excuse pseudocode): af:AssistantFactory = new AssistantFactory() // ...
var asst:Object = af.create(assistant_name); if(asst == null) { error("no such assisstant: " + assistant_name); continue; } addChild(result); result.visible = false; AssistantArray[whatAs].asPic = result;
That should let you add assistants to the list on-the-fly, but still instantiate them from their name. [Edit] Same code, sans syntax errors, and with the load function modified to use the assistant factory. Seems to work just fine. [edit] I'm an idiot. Same code after the changes to savingloading.as have been saved. Still seems to work, however. www.mediafire.com/?53d3wyl8jwrbrzj
|
|