-
Notifications
You must be signed in to change notification settings - Fork 192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Save Files Format #329
Comments
Just to make sure I understand your intention. Do you want to load the original Diablo 1 save file format? I definitely think that Freeablo should use a standardized format for save/load. And then add support for converting old save files to this format (convert of legacy save files). The legacy save format is quite simple, once the Once the Further information about items on ground, missiles in the air, monsters on the map, etc is kept in the The Note: not all fields are known, so the offsets of known fields are specified and their size in bytes.
Rather than inventing a new format, lets use something established. How about bson, a binary version of JSON. |
I've already implemented saving, and am actively working on it at the moment. As for loading old saves, sure, but our implementation of stats isn't ready for that yet. |
Wtote a tool that may be used for decoding the Diablo 1 save files. This could be used to create a legacy import feature for Freeablo. |
@wheybags You already write a hard coded binary file which is hard coded. I talked about developing the serialization process. We should actually implement the player stats, etc in lua or python. That way we have a sandbox for modding set up too. We could dynamically handle sending data in bunches using lua or python whereas the hard coded version will get messy. |
@mewmew yes I meant standardized format. Other people may want to load in the file by themselves and exit it as a tool or something. |
Now a $ sv -json hero
{
"DAction": -1,
"Param1": 0,
"Param2": 0,
"DLvl": 0,
"X": 75,
"Y": 68,
"TargetX": 75,
"TargetY": 68,
"Name": "a",
"PlayerClass": "Warrior",
"StrBase": 30,
"MagBase": 10,
"DexBase": 20,
"VitBase": 25,
"CLvl": 1,
"Points": 0,
"Exp": 0,
"GoldTotal": 100,
"HPBaseCur": 4480,
"HPBaseMax": 4480,
"MPBaseCur": 640,
"MPBaseMax": 640,
"SpellLvlFromSpellID": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
],
"KnownSpells": [
0, 0
],
"BodyItems": [
{
"Seed": 1217677573,
"CF": 0,
"ItemID": "Short Sword",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 20,
"DurabilityMax": 20,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 0,
"OnlyUsedByEar": 0
},
{
"Seed": 441146358,
"CF": 0,
"ItemID": "Buckler",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 10,
"DurabilityMax": 10,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 0,
"OnlyUsedByEar": 0
}
],
"InvItems": [
{
"Seed": 1306853907,
"CF": 0,
"ItemID": "Club",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 20,
"DurabilityMax": 20,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 0,
"OnlyUsedByEar": 0
},
{
"Seed": 808692058,
"CF": 0,
"ItemID": "Gold",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 0,
"DurabilityMax": 0,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 100,
"OnlyUsedByEar": 0
}
],
"InvNumFromInvGrid": [
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
],
"NInvItems": 2,
"BeltItems": [
{
"Seed": 1262929936,
"CF": 0,
"ItemID": "Potion of Healing",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 0,
"DurabilityMax": 0,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 0,
"OnlyUsedByEar": 0
},
{
"Seed": 1942205617,
"CF": 0,
"ItemID": "Potion of Healing",
"IdentifiedAndItemQuality": 0,
"DurabilityCur": 0,
"DurabilityMax": 0,
"ChargesMin": 0,
"ChargesMax": 0,
"GoldPrice": 0,
"OnlyUsedByEar": 0
}
],
"OnBattlenet": 0,
"HasManashild": 0,
"Difficulty": 0
} |
Great job! |
On the off-chance that someone in this years old thread happens to come back, I had a couple of questions about mewmew's comment.
Either way, thanks for what is already described as this was a hellish rabbit-hole to go down into. |
Let's start work on the file format that diablo 1 uses so that we at least have the file head and the immediate character body able to be loaded in. This is more of a self assign thing, but I think this would be a great addition to carry on more of the building up of stats and menus and intro to leveling up.
Possible duplicate of #24 (which is really just a discussion)
So it appears that we should create a 'freeablo proprietary file format'. Which I am a guru of creating such file formats to load beautifully and efficiently (look at libpng api holds lunch). It was also stated that we should have the basic, immediate stats like the dungeon levels, player type, name, stats, and ground items. This should be easy to serialize. I noticed
components/serial
which is cool and noticed how it plays intoFAWord::ActorStats
however, this way of loading and saving doesn't support a lot of features, but gives sanity that things aren't mixed up - especially because hardcodedness that we need to circumvent for modders. Perhaps more work on serial will yield good results.I would highly recommend to use binary format - we don't need to depend on XML or JSON or parse plain text and just use magic bytes for the immediate stats, all strings should come last as they are variable. Or, or, just use a struct with definite sizes (which leads to endianess issues, circumvented easily by forced-endianess exporting) Perhaps a procedural file format is the best for this like BMP has 'chunks'. Ideas?
The text was updated successfully, but these errors were encountered: