diff --git a/client/audio.c b/client/audio.c
index 2bd6840..aff0256 100644
--- a/client/audio.c
+++ b/client/audio.c
@@ -217,7 +217,7 @@ void audio_real_init(const char *const spec_name,
     tagfile = NULL;
     return;
   }
-  if (!(tagfile = secfile_load(filename, TRUE))) {
+  if (!(tagfile = secfile_load(filename, TRUE, TRUE))) {
     log_fatal(_("Could not load sound spec-file '%s':\n%s"), filename,
               secfile_error());
     exit(EXIT_FAILURE);
diff --git a/client/gui-gtk-2.0/pages.c b/client/gui-gtk-2.0/pages.c
index f1f78d3..fb0ac04 100644
--- a/client/gui-gtk-2.0/pages.c
+++ b/client/gui-gtk-2.0/pages.c
@@ -2564,7 +2564,8 @@ static void update_scenario_page(void)
 
     gtk_list_store_append(scenario_store, &it);
 
-    if ((sf = secfile_load_section(pfile->fullname, "scenario", TRUE))) {
+    if ((sf = secfile_load_section(pfile->fullname, "scenario",
+                                   TRUE, FALSE))) {
       const char *sname, *sdescription;
 
       sname = secfile_lookup_str_default(sf, NULL, "scenario.name");
diff --git a/client/gui-sdl/themespec.c b/client/gui-sdl/themespec.c
index e03c9f0..2e7e0da 100644
--- a/client/gui-sdl/themespec.c
+++ b/client/gui-sdl/themespec.c
@@ -480,7 +480,7 @@ static void ensure_big_sprite(struct specfile *sf)
   /* Otherwise load it.  The big sprite will sometimes be freed and will have
    * to be reloaded, but most of the time it's just loaded once, the small
    * sprites are extracted, and then it's freed. */
-  if (!(file = secfile_load(sf->file_name, TRUE))) {
+  if (!(file = secfile_load(sf->file_name, TRUE, TRUE))) {
     log_fatal(_("Could not open '%s':\n%s"), sf->file_name, secfile_error());
     exit(EXIT_FAILURE);
   }
@@ -514,7 +514,7 @@ static void scan_specfile(struct theme *t, struct specfile *sf,
   struct section_list *sections;
   int i;
 
-  if (!(file = secfile_load(sf->file_name, TRUE))) {
+  if (!(file = secfile_load(sf->file_name, TRUE, TRUE))) {
     log_fatal(_("Could not open '%s':\n%s"), sf->file_name, secfile_error());
     exit(EXIT_FAILURE);
   }
@@ -716,7 +716,7 @@ struct theme *theme_read_toplevel(const char *theme_name)
   }
   log_verbose("themespec file is \"%s\".", fname);
 
-  if (!(file = secfile_load(fname, TRUE))) {
+  if (!(file = secfile_load(fname, TRUE, TRUE))) {
     log_error("Could not open '%s':\n%s", fname, secfile_error());
     FC_FREE(fname);
     theme_free(t);
diff --git a/client/helpdata.c b/client/helpdata.c
index 48fdca2..6cd7b32 100644
--- a/client/helpdata.c
+++ b/client/helpdata.c
@@ -738,7 +738,7 @@ void boot_help_texts(struct player *pplayer)
     return;
   }
   /* after following call filename may be clobbered; use sf->filename instead */
-  if (!(sf = secfile_load(filename, FALSE))) {
+  if (!(sf = secfile_load(filename, FALSE, FALSE))) {
     /* this is now unlikely to happen */
     log_error("failed reading help-texts from '%s':\n%s", filename,
               secfile_error());
diff --git a/client/options.c b/client/options.c
index 85e7127..234fbc4 100644
--- a/client/options.c
+++ b/client/options.c
@@ -4158,6 +4158,9 @@ static void save_cma_presets(struct section_file *file)
 /* The first version the new option name appeared (2.2). */
 #define FIRST_MAJOR_NEW_OPTION_FILE_NAME 2
 #define FIRST_MINOR_NEW_OPTION_FILE_NAME 2
+/* The first version the new boolean values appeared (2.3). */
+#define FIRST_MAJOR_NEW_BOOLEAN 2
+#define FIRST_MINOR_NEW_BOOLEAN 3
 /****************************************************************
   Returns pointer to static memory containing name of the current
   option file.  Usually used for saving.
@@ -4192,19 +4195,21 @@ static const char *get_current_option_file_name(void)
   return name_buffer;
 }
 
-/****************************************************************
-  Check the last option file we saved.  Usually used to load.
-  Ie, based on FREECIV_OPT env var, and home dir. (or a
-  OPTION_FILE_NAME define defined in config.h)
-  Or NULL if not found.
-*****************************************************************/
-static const char *get_last_option_file_name(void)
+/****************************************************************************
+  Check the last option file we saved. Usually used to load. Ie, based on
+  FREECIV_OPT env var, and home dir. (or a OPTION_FILE_NAME define defined
+  in config.h), or NULL if not found.
+
+  Set in allow_old_boolean if we should look for old boolean values (saved
+  as 0 and 1), so if the rc file version is older than 2.3.0.
+****************************************************************************/
+static const char *get_last_option_file_name(bool *allow_old_boolean)
 {
   static char name_buffer[256];
   const char *name;
 
+  *allow_old_boolean = FALSE;
   name = getenv("FREECIV_OPT");
-
   if (name) {
     sz_strlcpy(name_buffer, name);
   } else {
@@ -4235,6 +4240,11 @@ static const char *get_last_option_file_name(void)
                        get_current_option_file_name() + strlen(name) + 1,
                        name_buffer + strlen(name) + 1);
           }
+          if (FIRST_MAJOR_NEW_BOOLEAN > major
+              || (FIRST_MAJOR_NEW_BOOLEAN == major
+                  && FIRST_MINOR_NEW_BOOLEAN > minor)) {
+            *allow_old_boolean = TRUE;
+          }
           return name_buffer;
         }
       }
@@ -4248,6 +4258,7 @@ static const char *get_last_option_file_name(void)
                    "loading from '%s' instead."),
                  get_current_option_file_name() + strlen(name) + 1,
                  OLD_OPTION_FILE_NAME);
+      *allow_old_boolean = TRUE;
       return name_buffer;
     } else {
       return NULL;
@@ -4261,6 +4272,8 @@ static const char *get_last_option_file_name(void)
 #undef NEW_OPTION_FILE_NAME
 #undef FIRST_MAJOR_NEW_OPTION_FILE_NAME
 #undef FIRST_MINOR_NEW_OPTION_FILE_NAME
+#undef FIRST_MAJOR_NEW_BOOLEAN
+#undef FIRST_MINOR_NEW_BOOLEAN
 
 
 /****************************************************************************
@@ -4615,18 +4628,19 @@ void options_dialogs_set(void)
 void options_load(void)
 {
   struct section_file *sf;
+  bool allow_old_boolean;
   int i, num;
   const char *name;
   const char * const prefix = "client";
 
-  name = get_last_option_file_name();
+  name = get_last_option_file_name(&allow_old_boolean);
   if (!name) {
     log_normal(_("Didn't find the option file."));
     options_fully_initialized = TRUE;
     create_default_cma_presets();
     return;
   }
-  if (!(sf = secfile_load(name, TRUE))) {
+  if (!(sf = secfile_load(name, TRUE, allow_old_boolean))) {
     log_debug("Error loading option file '%s':\n%s", name, secfile_error());
     /* try to create the rc file */
     sf = secfile_new(TRUE);
diff --git a/client/servers.c b/client/servers.c
index d3460eb..7e524bf 100644
--- a/client/servers.c
+++ b/client/servers.c
@@ -112,7 +112,7 @@ static struct server_list *parse_metaserver_data(fz_FILE *f)
   int nservers, i, j;
 
   /* This call closes f. */
-  if (!(file = secfile_from_stream(f, TRUE))) {
+  if (!(file = secfile_from_stream(f, TRUE, TRUE))) {
     return NULL;
   }
 
diff --git a/client/tilespec.c b/client/tilespec.c
index 7ae1db1..ee75236 100644
--- a/client/tilespec.c
+++ b/client/tilespec.c
@@ -1124,7 +1124,7 @@ static void ensure_big_sprite(struct specfile *sf)
   /* Otherwise load it.  The big sprite will sometimes be freed and will have
    * to be reloaded, but most of the time it's just loaded once, the small
    * sprites are extracted, and then it's freed. */
-  if (!(file = secfile_load(sf->file_name, TRUE))) {
+  if (!(file = secfile_load(sf->file_name, TRUE, TRUE))) {
     log_fatal(_("Could not open '%s':\n%s"), sf->file_name, secfile_error());
     exit(EXIT_FAILURE);
   }
@@ -1158,7 +1158,7 @@ static void scan_specfile(struct tileset *t, struct specfile *sf,
   struct section_list *sections;
   int i;
 
-  if (!(file = secfile_load(sf->file_name, TRUE))) {
+  if (!(file = secfile_load(sf->file_name, TRUE, TRUE))) {
     log_fatal(_("Could not open '%s':\n%s"), sf->file_name, secfile_error());
     exit(EXIT_FAILURE);
   }
@@ -1379,7 +1379,7 @@ struct tileset *tileset_read_toplevel(const char *tileset_name, bool verbose)
   }
   log_verbose("tilespec file is \"%s\".", fname);
 
-  if (!(file = secfile_load(fname, TRUE))) {
+  if (!(file = secfile_load(fname, TRUE, TRUE))) {
     log_error("Could not open '%s':\n%s", fname, secfile_error());
     free(fname);
     return NULL;
diff --git a/modinst/download.c b/modinst/download.c
index 5ef0db1..d5717ad 100644
--- a/modinst/download.c
+++ b/modinst/download.c
@@ -273,7 +273,7 @@ const char *download_modpack(const char *URL,
     return _("Failed to download modpack control file from given URL");
   }
 
-  control = secfile_load(local_name, FALSE);
+  control = secfile_load(local_name, FALSE, FALSE);
 
   if (control == NULL) {
     return _("Cannot parse modpack control file");
diff --git a/server/auth.c b/server/auth.c
index c945321..2066bd4 100644
--- a/server/auth.c
+++ b/server/auth.c
@@ -284,7 +284,7 @@ static bool load_auth_config(const char *filename)
 
   fc_assert_ret_val(NULL != filename, FALSE);
 
-  if (!(secfile = secfile_load(filename, FALSE))) {
+  if (!(secfile = secfile_load(filename, FALSE, FALSE))) {
     log_error(_("Cannot load auth config file '%s':\n%s"), filename,
               secfile_error());
     return FALSE;
diff --git a/server/gamehand.c b/server/gamehand.c
index e992fee..081c6cf 100644
--- a/server/gamehand.c
+++ b/server/gamehand.c
@@ -544,7 +544,7 @@ void handle_single_want_hack_req(struct connection *pc,
   bool you_have_hack = FALSE;
 
   if (!with_ggz) {
-    if ((secfile = secfile_load(get_challenge_fullname(pc), FALSE))) {
+    if ((secfile = secfile_load(get_challenge_fullname(pc), FALSE, FALSE))) {
       token = secfile_lookup_str(secfile, "challenge.token");
       you_have_hack = (token && strcmp(token, packet->token) == 0);
       secfile_destroy(secfile);
diff --git a/server/ruleset.c b/server/ruleset.c
index 16c0031..8cb419a 100644
--- a/server/ruleset.c
+++ b/server/ruleset.c
@@ -220,7 +220,7 @@ static struct section_file *openload_ruleset_file(const char *whichset)
 
   sz_strlcpy(sfilename, dfilename);
 
-  if (!(secfile = secfile_load(sfilename, FALSE))) {
+  if (!(secfile = secfile_load(sfilename, FALSE, TRUE))) {
     ruleset_error(LOG_FATAL, "Could not load ruleset '%s':\n%s",
                   sfilename, secfile_error());
   }
diff --git a/server/stdinhand.c b/server/stdinhand.c
index e3ac230..9d93de2 100644
--- a/server/stdinhand.c
+++ b/server/stdinhand.c
@@ -3467,7 +3467,7 @@ bool load_command(struct connection *caller, const char *filename, bool check)
 
   /* attempt to parse the file */
 
-  if (!(file = secfile_load(arg, FALSE))) {
+  if (!(file = secfile_load(arg, FALSE, TRUE))) {
     cmd_reply(CMD_LOAD, caller, C_FAIL, _("Could not load savefile: %s"),
               arg);
     log_debug("Error loading savefile '%s':\n%s", arg, secfile_error());
diff --git a/utility/registry.c b/utility/registry.c
index d6af1d9..e5b08f0 100644
--- a/utility/registry.c
+++ b/utility/registry.c
@@ -216,7 +216,8 @@ static inline void entry_use(struct entry *pentry);
 
 static void entry_to_file(const struct entry *pentry, fz_FILE *fs);
 static void entry_from_token(struct section *psection, const char *name,
-                             const char *tok, struct inputfile *file);
+                             const char *tok, struct inputfile *file,
+                             bool allow_old_boolean);
 
 static char error_buffer[MAX_LEN_ERRORBUF] = "\0";
 
@@ -451,7 +452,8 @@ static bool secfile_hash_delete(struct section_file *secfile,
 static struct section_file *secfile_from_input_file(struct inputfile *inf,
                                                     const char *filename,
                                                     const char *section,
-                                                    bool allow_duplicates)
+                                                    bool allow_duplicates,
+                                                    bool allow_old_boolean)
 {
   struct section_file *secfile;
   struct section *psection = NULL;
@@ -572,7 +574,8 @@ static struct section_file *secfile_from_input_file(struct inputfile *inf,
                    table_lineno, astr_str(&columns.p[num_columns - 1]),
                    (int) (i - num_columns + 1));
         }
-        entry_from_token(psection, astr_str(&entry_name), tok, inf);
+        entry_from_token(psection, astr_str(&entry_name), tok, inf,
+                         allow_old_boolean);
       } while (inf_token(inf, INF_TOK_COMMA));
 
       if (!inf_token(inf, INF_TOK_EOL)) {
@@ -651,10 +654,12 @@ static struct section_file *secfile_from_input_file(struct inputfile *inf,
         goto END;
       }
       if (i == 0) {
-        entry_from_token(psection, astr_str(&base_name), tok, inf);
+        entry_from_token(psection, astr_str(&base_name), tok, inf,
+                         allow_old_boolean);
       } else {
         astr_set(&entry_name, "%s,%d", astr_str(&base_name), i);
-        entry_from_token(psection, astr_str(&entry_name), tok, inf);
+        entry_from_token(psection, astr_str(&entry_name), tok, inf,
+                         allow_old_boolean);
       }
     } while (inf_token(inf, INF_TOK_COMMA));
     if (!inf_token(inf, INF_TOK_EOL)) {
@@ -709,9 +714,11 @@ END:
   Create a section file from a file.  Returns NULL on error.
 **************************************************************************/
 struct section_file *secfile_load(const char *filename,
-                                  bool allow_duplicates)
+                                  bool allow_duplicates,
+                                  bool allow_old_boolean)
 {
-  return secfile_load_section(filename, NULL, allow_duplicates);
+  return secfile_load_section(filename, NULL, allow_duplicates,
+                              allow_old_boolean);
 }
 
 /**************************************************************************
@@ -720,23 +727,27 @@ struct section_file *secfile_load(const char *filename,
 **************************************************************************/
 struct section_file *secfile_load_section(const char *filename,
                                           const char *section,
-                                          bool allow_duplicates)
+                                          bool allow_duplicates,
+                                          bool allow_old_boolean)
 {
   char real_filename[1024];
 
   interpret_tilde(real_filename, sizeof(real_filename), filename);
   return secfile_from_input_file(inf_from_file(real_filename, datafilename),
-                                 filename, section, allow_duplicates);
+                                 filename, section, allow_duplicates,
+                                 allow_old_boolean);
 }
 
 /**************************************************************************
   Create a section file from a stream.  Returns NULL on error.
 **************************************************************************/
 struct section_file *secfile_from_stream(fz_FILE *stream,
-                                         bool allow_duplicates)
+                                         bool allow_duplicates,
+                                         bool allow_old_boolean)
 {
   return secfile_from_input_file(inf_from_stream(stream, datafilename),
-                                 NULL, NULL, allow_duplicates);
+                                 NULL, NULL, allow_duplicates,
+                                 allow_old_boolean);
 }
 
 /**************************************************************************
@@ -2950,6 +2961,7 @@ struct entry {
     /* ENTRY_INT */
     struct {
       int value;
+      bool may_be_old_boolean;
     } integer;
     /* ENTRY_STR */
     struct {
@@ -3004,22 +3016,37 @@ static struct entry *entry_new(struct section *psection, const char *name)
   return pentry;
 }
 
-/**************************************************************************
+/****************************************************************************
   Returns a new entry of type ENTRY_INT.
-**************************************************************************/
-struct entry *section_entry_int_new(struct section *psection,
-                                    const char *name, int value)
+****************************************************************************/
+static struct entry *section_entry_int_new_full(struct section *psection,
+                                                const char *name, int value,
+                                                bool allow_old_boolean)
 {
   struct entry *pentry = entry_new(psection, name);
 
   if (NULL != pentry) {
     pentry->type = ENTRY_INT;
     pentry->integer.value = value;
+    /* Before 2.3.0, the boolean where saved as integers,
+     * keeping compatibility with old files. */
+    pentry->integer.may_be_old_boolean = (allow_old_boolean
+                                          && (0 == value || 1 == value));
   }
 
   return pentry;
 }
 
+/****************************************************************************
+  Returns a new entry of type ENTRY_INT.
+****************************************************************************/
+struct entry *section_entry_int_new(struct section *psection,
+                                    const char *name, int value)
+{
+  /* New computed boolean values are always real booleans. */
+  return section_entry_int_new_full(psection, name, value, FALSE);
+}
+
 /**************************************************************************
   Returns a new entry of type ENTRY_BOOL.
 **************************************************************************/
@@ -3228,13 +3255,16 @@ bool entry_bool_get(const struct entry *pentry, bool *value)
 {
   SECFILE_RETURN_VAL_IF_FAIL(NULL, NULL, NULL != pentry, FALSE);
 
-  if (ENTRY_INT == pentry->type
-      && (pentry->integer.value == 0
-          || pentry->integer.value == 1)) {
+  if (ENTRY_INT == pentry->type && pentry->integer.may_be_old_boolean) {
     *value = (0 != pentry->integer.value);
     return TRUE;
   }
 
+  if (ENTRY_BOOL != pentry->type) {
+    log_error("in %s: %s.%s",
+              secfile_name(pentry->psection->secfile),
+              section_name(pentry->psection), entry_name(pentry));
+  }
   SECFILE_RETURN_VAL_IF_FAIL(pentry->psection->secfile, pentry->psection,
                              ENTRY_BOOL == pentry->type, FALSE);
 
@@ -3368,7 +3398,8 @@ static void entry_to_file(const struct entry *pentry, fz_FILE *fs)
   Creates a new entry from the token.
 **************************************************************************/
 static void entry_from_token(struct section *psection, const char *name,
-                             const char *tok, struct inputfile *inf)
+                             const char *tok, struct inputfile *inf,
+                             bool allow_old_boolean)
 {
   if ('$' == tok[0] || '"' == tok[0]) {
     char buf[strlen(tok) + 1];
@@ -3384,7 +3415,8 @@ static void entry_from_token(struct section *psection, const char *name,
     int value;
 
     if (1 == sscanf(tok, "%d", &value)) {
-      (void) section_entry_int_new(psection, name, value);
+      (void) section_entry_int_new_full(psection, name, value,
+                                        allow_old_boolean);
       DEBUG_ENTRIES("entry %s %d", name, value);
       return;
     }
diff --git a/utility/registry.h b/utility/registry.h
index 79b2f7d..3cac4a0 100644
--- a/utility/registry.h
+++ b/utility/registry.h
@@ -57,12 +57,15 @@ const char *secfile_error(void);
 /* Main functions. */
 struct section_file *secfile_new(bool allow_duplicates);
 struct section_file *secfile_load(const char *filename,
-                                  bool allow_duplicates);
+                                  bool allow_duplicates,
+                                  bool allow_old_boolean);
 struct section_file *secfile_load_section(const char *filename,
                                           const char *section,
-                                          bool allow_duplicates);
+                                          bool allow_duplicates,
+                                          bool allow_old_boolean);
 struct section_file *secfile_from_stream(fz_FILE *stream,
-                                         bool allow_duplicates);
+                                         bool allow_duplicates,
+                                         bool allow_old_boolean);
 void secfile_destroy(struct section_file *secfile);
 
 bool secfile_save(const struct section_file *secfile, const char *filename,
