Hello again, I just want to know if there's a SDK or just some docs planned to help about creating mods and hacks ? |
If it's any help, I have extracted (semi-automatically) DTDs for the level XML files (level, scene and resource scripts); I haven't really done anything with them yet, but these may be useful to people who want to edit their own levels.
(See attachment)
I also figured out the profile data file, which I'll share if anyone has a legitimate use for it. Last modified Tue, 10/28/2008 - 14:32 by Soultaker |
I've watched them (thanks for these by the way) In fact, if I find the motivation, I may try to create a level editor. I put a may since I haven't found the motivation yet :) |
I received a request for this, so I am adding (my interpretation of) the format of the pers2.dat file. Additions and corrections are welcome.
[pre] The pers2.dat file is encrypted in the same way as the data files, except the plaintext is padded with zero bytes. The character encoding used is unknown; most likely it is the native character set of the operating system.
At the highest level, it contains a sequence of strings, terminated by the sequence ",0." (without quotes). Each string is encoded with a decimal integer signifying its length, followed by a comma, followed by the string contents. For example, "foo" would be encoded as "3,foo" (quotes for clarity only).
The strings in the data file describe a dictionary, with alternating keys and values. Keys in use are:
- "countrycode": values are two-letter ISO 3166-1 country codes, or EU for the European Union, or XX for unknown. - "fullscreen": indicates whether the game runs in full-screen or in windowed mode; value is either "true" or "false" - "mrpp": most recent player profile; value is a decimal integer between 1 and 3. - "profile_0"/"profile_1"/"profile_2": the three player profile slots.
Obviously, the player profile strings are the most interesting. These strings consist of a number of fields, seperated by comma's. The first four fields are: - player name - player flags (see below) - total play time (in seconds) - number of levels played/completed
The player flags field is an integer that combines several bits: 1: online play is enabled 2: World of Goo Corporation has been unlocked 4: World of Goo Corporation has been destroyed 8: the whistle has been found 16: the Terms & Conditions have been accepted (this unlocks Deliverance)
So a player that has finished the first two chapters, for example, would have flags set to 2|8 = 10 or 1|2|8 = 11 (here '|' indicates bitwise-or).
Then follows, for each level: - level id (same as the directory name in res/levels/) - greatest number of balls collected - least number of moves used - least time taken (in seconds)
Usually, the number of level descriptions is equal to fourth field (total number of levels played), but sometimes there is more level data. I haven't looked into exactly why this is; maybe these are levels that have been played but not yet completed.
Then, the World of Goo Coporation data follows, which is a string prefixed by an underscore character (_) which is how it can be distinguished from more level data.
It may be empty if WoGC has not been unlocked yet. Otherwise, it contains first the location of balls, and then the configuration of strands (connections between balls). All data is seperated by colon characters (:).
Each ball description consists of six fields; for example: b:Drained:-61.88:211.98:-0.96:1.75 The fields are: - "b" (fixed) - "Drained" (fixed) - x-coordinate as a decimal number - y-coordinate as a decimal number - unknown decimal number - unknown decimal number The unknown numbers may be horizontal/vertical walking speed or something like that.
Each strand description consists of seven fields; for example: s:Drained:288,20,9.000,140.0,0 The fields are: - "s" (fixed) - "Drained" (fixed) - first endpoint (zero-based index of a ball in the list above) - second endpoint (same as above) - "9.0" (fixed): may be connection strength - decimal number: usually close to 140, may be length of strand but this can also be derived from its endpoints. - "0" or "1": indicates whether or not a ball was absorbed to create this strand, which is released if the strand is destroyed.
Next, the online player key follows, which is prefixed by an underscore; the player key is 32 characters long and consists of lower-case hexadecimal digits. If the player has never connected to the internet, the key is empty.
Since this key is used to authenticate players online, it should be kept private. I propose to take an MD5 hash code of the string and use that instead, so players can be identified without compromising their scoreboard standing. For example: "d41d8cd98f00b204e9800998ecf8427e" would be transformed to "74be16979710d4c4e7c6647856088456". If you do not want players to be globally identifiable, use an HMAC instead.
The final field is a decimal integer, representing the number of newly collected goo balls since the player last visited World of Goo Corporation. This number is displayed on the main screen. [/pre] |
I've setup a project on sourceforge to help organizing knowledge about the file structure a little while ago: See http://sourceforge.net/projects/wogedit
I'm currently focusing on trying to visualize level data correctly (level.bin is mostly done, I'm now focusing on scene.bin).
Feel free to contribute to the wiki of the project: http://apps.sourceforge.net/mediawiki/wogedit/index.php?title=Main_Page
|
Thanks Soultaker, this was very useful.
Jonas sent me his profile which fails to parse according to this algorithm (http://pastebin.com/f54eba97a). Here's my analysis.
[quote author=Soultaker link=topic=643.msg4700#msg4700 date=1225388207] [pre]Obviously, the player profile strings are the most interesting. These strings consist of a number of fields, seperated by comma's. The first four fields are: [snip]
Then follows, for each level: - level id (same as the directory name in res/levels/) - greatest number of balls collected - least number of moves used - least time taken (in seconds)
Then, the World of Goo Coporation data follows, which is a string prefixed by an underscore character (_) which is how it can be distinguished from more level data. [/pre]
I have found that:
- for most profiles, after the levels, a level named "0" indicates the end of levels, with no balls/moves/time data. After that is the tower, beginning with _.
[pre]...HangLow,22,6,170,[=12pt]0[/],_b:Drained:-488.46:11.32:-1.08:0.00:...[/pre]
- for some players, this 0 doesn't exist. Instead is a 1 followed by a level name, followed by the tower. I'm not sure what the 1 indicates (perhaps the number of fields following), nor what the level name means. I do know that the level doesn't appear anywhere else in the list so maybe it's the level they're currently attempting.
[pre]...ObservatoryObservationStation,0,12,96,[=12pt]1,HTInnovationCommittee[/],_b:Drained:-551.97:811.85:-0.87:-0.44:...[/pre]
I think for now I will code it so that if it receives an integer when expecting a level name, it skips over that many fields to reach the tower. Normally 0 but in this case 1, and possibly may have other values.
-davidc |
Sorry for resurrecting this ancient thread, but I figured this information belonged with the rest of the file format information above:
The mysterious list of level names is the list of levels that have been skipped. Makes sense to keep them separate, since you can't have completion stats for them.
Edit: Also, in the tower data:
Quote: Each ball description consists of six fields; for example: b:Drained:-61.88:211.98:-0.96:1.75 The fields are: - "b" (fixed) - "Drained" (fixed) - x-coordinate as a decimal number - y-coordinate as a decimal number - unknown decimal number - unknown decimal number
Observations and experiments confirm that the last two numbers are x-velocity and y-velocity of that goo ball.
Edit: I figured out the 6th field in the strand data.
Quote: Each strand description consists of seven fields; for example: s:Drained:288,20,9.000,140.0,0 The fields are: - "s" (fixed) - "Drained" (fixed) - first endpoint (zero-based index of a ball in the list above) - second endpoint (same as above) - "9.0" (fixed): may be connection strength - decimal number: usually close to 140, may be length of strand but this can also be derived from its endpoints. - "0" or "1": indicates whether or not a ball was absorbed to create this strand, which is released if the strand is destroyed.
The 6th field is the "desired" length of the strand. That is, if the strand is that length, it will exert no force on its endpoints. I'm guessing the previous field is the spring constant, but I can't confirm because WoG overwrites it to 9.0 on loading. (It also changes the ball and strand types back to "Drained", for the curious.) The desired length is truncated to the range [100.0, 140.0]. This explains the behavior of how sometimes links will grow or shrink after you've placed a gooball. Intriguingly, a strand that has a gooball "inside" it can have a larger desired length, up to 200.0. Last modified Tue, 03/31/2009 - 04:55 by D0SBoots |
[quote author=D0SBoots link=topic=643.msg11125#msg11125 date=1238282680] The mysterious list of level names is the list of levels that have been skipped. Makes sense to keep them separate, since you can't have completion stats for them.
Nice find. Was I correct in assuming that the number that precedes them is the counter of skipped levels then?
-davidc |
[quote author=davidc link=topic=643.msg11128#msg11128 date=1238285026]Nice find. Was I correct in assuming that the number that precedes them is the counter of skipped levels then?
Yes, sorry I didn't make that clear. I was a wimp, so in my file it goes, "...,3,UpperShaft,ThirdWheel,HTInnovationCommittee,_b:Dra..."
I'm fiddling with the numbers in WoGC, because I'm really interested to know the role of the rest of those fields. I'll edit more stuff in to my first post to keep things compact. |