<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39365 >

Daniel Doran wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=39365 >
> I have never experienced any other behavior from Freeciv.  freeciv-1.x 
> versions on Win and Linux exhibited the precise behavior described.
"Never" is an overstatement.  Turns out, the bug was introduced in the
past couple of years....

in savegame.c
at player_load()

   /* Add techs from game and nation, but ignore game.info.tech. */
   /* We used to call give_initial_techs here, but that shouldn't be
    * necessary.  The savegame should already mark those techs as known.
    * give_initial_techs will crash if the nation is unset. */

That change was probably OK, but other changes conspired to cause the
problem here:

in techtools.c
at init_tech()

   if (choose_goal_tech(plr) == A_UNSET) {

Now, I'm not sure this is a good idea.  After all, this is init_tech
(called only when the server is started and when a player is loaded),
so BY DEFINITION the goal should be A_UNSET at this point!

In this case, it's about to get set from the saved game, so there is no
need to assign a random one.  Only the other call (when starting the
server) needs the random tech.

Amazingly enough, this is related to my very first bug 14236 report
back in 2005!

The complete fix is to more carefully analyze how things are initialized
and used, but that's more than I'm willing to do today....


However, the quick fix is to duplicate the rstate at the end of the load,
and that's simple enough:

--- ../savegame.c       Tue Mar 20 22:22:54 2007
+++ server/savegame.c   Thu May 10 13:23:39 2007
@@ -3398,6 +3398,7 @@
    int i, k, id;
    enum server_states tmp_server_state;
+  RANDOM_STATE rstate;
    char *savefile_options;
    const char *string;
    char** improvement_order = NULL;
@@ -3799,7 +3800,6 @@
       2) if it is saved. */
    if (section_file_lookup(file, "random.index_J")
        && secfile_lookup_bool_default(file, TRUE, "game.save_random")) {
-    RANDOM_STATE rstate;
      rstate.j = secfile_lookup_int(file,"random.index_J");
      rstate.k = secfile_lookup_int(file,"random.index_K");
      rstate.x = secfile_lookup_int(file,"random.index_X");
@@ -3822,6 +3822,7 @@
       * be needed later during the load. */
      if (tmp_server_state == RUN_GAME_STATE) {
+      rstate = get_myrand_state();

@@ -4010,6 +4011,12 @@
    players_iterate(pplayer) {
    } players_iterate_end;
+  /* Restore saved game state, just in case various initialization code
+   * inexplicably altered the previously existing state. */
+  if (!game.info.is_new_game) {
+    set_myrand_state(rstate);
+  }


Freeciv-dev mailing list

Reply via email to