robn

Pioneer: Savefile upgrades - a modest proposal

Jan 10th, 2015
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.36 KB | None | 0 0
  1. From: Robert Norris
  2. Subject: Savefile upgrades - a modest proposal
  3. Date: Wednesday, December 19, 2012 10:32 PM
  4.  
  5. We've known we have to tackle savefile upgrades (backward-compatibility)
  6. for a while. For some reason I found myself thinking about it again
  7. today, and got motivated enough to write some code on the way home.
  8.  
  9. Right now I'm concentrating more on the on-disk format rather than the
  10. data within it. John B had some really good thoughts about how we might
  11. change the data we store in a previous post[1], and I think we
  12. absolutely have to do some of that, but right now I'm just thinking
  13. about a format that can cope with changes in stored data assuming
  14. everything else (positions, terrain, etc) doesn't change.
  15.  
  16. Now we certainly could make what we have upgradeable. Its "just" a small
  17. matter of reading the old format, putting the data into a new format and
  18. plugging any gaps with sane defaults. The trouble with the current
  19. format is that its only structure is tied to the order its written and
  20. read in. If you're off by even one byte, everything explodes. This is a
  21. healthy source of bugs for anything that touches it, including
  22. conversion code.
  23.  
  24. The format is also not particularly easy to extend. This makes life
  25. difficult when you want to store arbitrary structured data in it, like
  26. anything from Lua. As we put more and more functionality out to Lua,
  27. this is going to become more of a problem. Really, the needs of the core
  28. are minimal in comparison.
  29.  
  30. So, some rough requirements/desirables:
  31.  
  32. - Order not significant.
  33. - Can sanely store Lua data types.
  34. - Can store floating-point numbers without loss.
  35. - Works cross-platform.
  36.  
  37. Here's my plan, based on some playing I'm doing on
  38. robn/savefile-experiment.
  39.  
  40. - JSON. The disk format is fairly unimportant, but JSON is nice to work
  41. with, familiar to many, human readable, has close to a 1:1 mapping to
  42. Lua, and is basically a hashtable (dictionary) format, so can handle
  43. unordered, nested data. I'm not particularly wedded to JSON but I'm
  44. already planning to bring in a JSON lib[2] for the RPC stuff I'm
  45. doing, so we might as well use it over yet another format. In
  46. particular the serialisation/deserialisation of Lua data is
  47. incredibly easy.
  48.  
  49. - The native JSON number type is defined as arbitrary-precision.
  50. jsoncpp uses up to 16 fractional digits (the C format "%#.16g") but
  51. its still a base-10 format, so subject to loss. But, I think we can
  52. work around this by encoding doubles using the C99 %a format, for
  53. hexadecimal notation. To mark this in the file for the parser, we'll
  54. store a double (or float) as [ "d", "0x9.e0652141ef0dbf6p-3" ]
  55. (that's 1.23456789). Its still relatively human-readable (maybe
  56. human-decipherable is a better term).
  57.  
  58. - The only really cross-platform concerns are float construction and
  59. endianness. Endianness is not a problem for JSON (not that we work
  60. anywhere that isn't Intel anyway), and as far as I can tell from a
  61. light skim of the relevant bits of the glibc code, %a should convert
  62. back and forth anywhere.
  63.  
  64. That's the format itself. The way I want to handle upgrades is to store
  65. a numeric version in a metadata section, and then in the code, we
  66. provide a number of conversion methods. Each one converts from version N
  67. to version N+1. If we stick to our tradition that we do one version bump
  68. per month, then each individual method should be fairly small, and we
  69. can gradually remove older ones quite simply.
  70.  
  71. To do an upgrade of an older savefile, we just progressively run the
  72. data through the necessary methods until we get it up to the latest
  73. version.
  74.  
  75. So I think that will do for now. Like I said, initially this is only
  76. about the data format, so no interface changes (at least on the Lua
  77. side). I think the ability to load out-of-order will help with a lot of
  78. stuff in the future, but that's for after this is done. Something I
  79. think will be easy will be to not call the Lua loaders until the core
  80. game state is established, so there won't be a need to do the
  81. onGameStart post-load stuff that we do now. That's a big win right
  82. there.
  83.  
  84. I'll be hacking on this over the next little while, in amongst all the
  85. other junk I'm working on, so you'll see this in PR before long. But I'm
  86. interested to hear any thoughts you have and especially anything I've
  87. missed.
  88.  
  89. Cheers,
  90. Rob.
Advertisement
Add Comment
Please, Sign In to add comment