diff --git a/src/lang/english.txt b/src/lang/english.txt
index 8f29dc5269..d4cf1e22e0 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1661,12 +1661,17 @@ STR_CONFIG_SETTING_ZOOM_MIN                                     :Maximum zoom in
 STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT                            :The maximum zoom-in level for viewports. Note that enabling higher zoom-in levels increases memory requirements
 STR_CONFIG_SETTING_ZOOM_MAX                                     :Maximum zoom out level: {STRING2}
 STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT                            :The maximum zoom-out level for viewports. Higher zoom-out levels might cause lag when used
+STR_CONFIG_SETTING_SPRITE_ZOOM_MIN                              :Highest resolution sprites to use: {STRING2}
+STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT                     :Limit the maximum resolution to use for sprites. Limiting sprite resolution will avoid using high resolution graphics even when available. This can help keep the game appearance unified when using a mix of GRF files with and without high resolution graphics.
 STR_CONFIG_SETTING_ZOOM_LVL_MIN                                 :4x
 STR_CONFIG_SETTING_ZOOM_LVL_IN_2X                               :2x
 STR_CONFIG_SETTING_ZOOM_LVL_NORMAL                              :Normal
 STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X                              :2x
 STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X                              :4x
 STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X                              :8x
+STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN                          :4x
+STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X                        :2x
+STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL                       :1x
 STR_CONFIG_SETTING_TOWN_GROWTH                                  :Town growth speed: {STRING2}
 STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT                         :Speed of town growth
 STR_CONFIG_SETTING_TOWN_GROWTH_NONE                             :None
diff --git a/src/settings.cpp b/src/settings.cpp
index a69162708b..f1db6b4d48 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -1127,6 +1127,13 @@ static bool ZoomMinMaxChanged(int32 p1)
 	return true;
 }
 
+static bool SpriteZoomMinChanged(int32 p1) {
+	GfxClearSpriteCache();
+	/* Force all sprites to redraw at the new chosen zoom level */
+	MarkWholeScreenDirty();
+	return true;
+}
+
 /**
  * Update any possible saveload window and delete any newgrf dialogue as
  * its widget parts might change. Reinit all windows as it allows access to the
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 914ef933fa..d81c4d071f 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -1495,6 +1495,7 @@ static SettingsContainer &GetSettingsTree()
 		{
 			graphics->Add(new SettingEntry("gui.zoom_min"));
 			graphics->Add(new SettingEntry("gui.zoom_max"));
+			graphics->Add(new SettingEntry("gui.sprite_zoom_min"));
 			graphics->Add(new SettingEntry("gui.smallmap_land_colour"));
 			graphics->Add(new SettingEntry("gui.graph_line_thickness"));
 		}
diff --git a/src/settings_type.h b/src/settings_type.h
index 433e8d5355..4137049607 100644
--- a/src/settings_type.h
+++ b/src/settings_type.h
@@ -117,6 +117,7 @@ struct GUISettings {
 	uint8  window_soft_limit;                ///< soft limit of maximum number of non-stickied non-vital windows (0 = no limit)
 	ZoomLevel zoom_min;                      ///< minimum zoom out level
 	ZoomLevel zoom_max;                      ///< maximum zoom out level
+	ZoomLevel sprite_zoom_min;               ///< maximum zoom level at which higher-resolution alternative sprites will be used (if available) instead of scaling a lower resolution sprite
 	byte   autosave;                         ///< how often should we do autosaves?
 	bool   threaded_saves;                   ///< should we do threaded saves?
 	bool   keep_all_autosave;                ///< name the autosave in a different way
diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp
index f3c3ed8ac7..30ea094443 100644
--- a/src/spriteloader/grf.cpp
+++ b/src/spriteloader/grf.cpp
@@ -11,6 +11,7 @@
 #include "../gfx_func.h"
 #include "../fileio_func.h"
 #include "../debug.h"
+#include "../settings_type.h"
 #include "../strings_func.h"
 #include "table/strings.h"
 #include "../error.h"
@@ -265,7 +266,16 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_po
 		byte colour = type & SCC_MASK;
 		byte zoom = FioReadByte();
 
-		if (colour != 0 && (load_32bpp ? colour != SCC_PAL : colour == SCC_PAL) && (sprite_type != ST_MAPGEN ? zoom < lengthof(zoom_lvl_map) : zoom == 0)) {
+		bool is_wanted_colour_depth = (colour != 0 && (load_32bpp ? colour != SCC_PAL : colour == SCC_PAL));
+		bool is_wanted_zoom_lvl;
+
+		if (sprite_type != ST_MAPGEN) {
+			is_wanted_zoom_lvl = (zoom < lengthof(zoom_lvl_map) && zoom_lvl_map[zoom] >= _settings_client.gui.sprite_zoom_min);
+		} else {
+			is_wanted_zoom_lvl = (zoom == 0);
+		}
+
+		if (is_wanted_colour_depth && is_wanted_zoom_lvl) {
 			ZoomLevel zoom_lvl = (sprite_type != ST_MAPGEN) ? zoom_lvl_map[zoom] : ZOOM_LVL_NORMAL;
 
 			if (HasBit(loaded_sprites, zoom_lvl)) {
diff --git a/src/table/settings.ini b/src/table/settings.ini
index b48ac6cd6a..6e19e3ade1 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -39,6 +39,7 @@ static bool RedrawTownAuthority(int32 p1);
 static bool InvalidateCompanyInfrastructureWindow(int32 p1);
 static bool InvalidateCompanyWindow(int32 p1);
 static bool ZoomMinMaxChanged(int32 p1);
+static bool SpriteZoomMinChanged(int32 p1);
 static bool MaxVehiclesChanged(int32 p1);
 static bool InvalidateShipPathCache(int32 p1);
 
@@ -2830,6 +2831,19 @@ strval   = STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X
 proc     = ZoomMinMaxChanged
 startup  = true
 
+[SDTC_VAR]
+var      = gui.sprite_zoom_min
+type     = SLE_UINT8
+flags    = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
+guiflags = SGF_MULTISTRING
+def      = ZOOM_LVL_MIN
+min      = ZOOM_LVL_MIN
+max      = ZOOM_LVL_OUT_4X
+str      = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN
+strhelp  = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT
+strval   = STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN
+proc     = SpriteZoomMinChanged
+
 [SDTC_BOOL]
 var      = gui.population_in_label
 flags    = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC