A while back I finished Snapshot 12. It turned out to be one of the longest snapshots I've worked on, coming out at about 8 months. Most of the changes were behind the scenes stuff, so to most users nothing has changed since the beginning of the year.
Under the hood, I've made quite a lot of changes. The biggest of which is splitting the codebase into a client and a server thread. Currently the server thread takes care of creating the initial terrain, and nothing more. However, over the next few snapshots I'll gradually move more of the client's processing into the server, with the eventually goal of supporting multiplayer.
One of the biggest issues I encountered during that time was serialisation of gamestate. Somewhere around 2 years ago I made an error in judgement which made serialisation impossible without an extensive rewrite. I didn't notice at the time because I hadn't written any of the serialisation code yet.
In retrospect I should have implemented the save and load functions early on. This would have forced me to consider game state serialisation immediately.
So, lessons to be learned here:
1) As soon as you start creating game objects, write the code that serialises and deserialises them.
2) Maintain your serialising code. If you modify the game objects, modify the serialisers. Don't rely on coming back to it at a later date. You will forget.
3) Write unit tests to verify your serialisation/deserialisation process works correctly and then maintain them.