diff --git a/lib/GameConstants.h b/lib/GameConstants.h
index 2c11cb431..11ec82534 100644
--- a/lib/GameConstants.h
+++ b/lib/GameConstants.h
@@ -1223,6 +1223,7 @@ class SpellID
 public:
 	enum ESpellID
 	{
+		SPELLBOOK_PRESET = -3,
 		PRESET = -2,
 		NONE = -1,
 		SUMMON_BOAT=0, SCUTTLE_BOAT=1, VISIONS=2, VIEW_EARTH=3, DISGUISE=4, VIEW_AIR=5,
diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp
index 8fb292b50..dfbe598b3 100644
--- a/lib/mapObjects/CGHeroInstance.cpp
+++ b/lib/mapObjects/CGHeroInstance.cpp
@@ -287,16 +287,23 @@ void CGHeroInstance::initHero(CRandomGenerator & rand)
 	if (ID == Obj::HERO)
 		appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
 
-	if(!vstd::contains(spells, SpellID::PRESET)) //hero starts with a spell
+	if(!vstd::contains(spells, SpellID::PRESET))
 	{
+		// hero starts with default spells
 		for(const auto & spellID : type->spells)
 			spells.insert(spellID);
 	}
 	else //remove placeholder
 		spells -= SpellID::PRESET;
 
-	if(!getArt(ArtifactPosition::MACH4) && !getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook) //no catapult means we haven't read pre-existent set -> use default rules for spellbook
-		putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK));
+	if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET))
+	{
+		// hero starts with default spellbook presence status
+		if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
+			putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createNewArtifactInstance(ArtifactID::SPELLBOOK));
+	}
+	else
+		spells -= SpellID::SPELLBOOK_PRESET;
 
 	if(!getArt(ArtifactPosition::MACH4))
 		putArtifact(ArtifactPosition::MACH4, ArtifactUtils::createNewArtifactInstance(ArtifactID::CATAPULT)); //everyone has a catapult
diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp
index 553763eb4..665e38339 100644
--- a/lib/mapping/MapFormatH3M.cpp
+++ b/lib/mapping/MapFormatH3M.cpp
@@ -878,6 +878,9 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
 	if(!hasArtSet)
 		return;
 
+	// Workaround - if hero has customized artifacts game should not attempt to add spellbook based on hero type
+	hero->spells.insert(SpellID::SPELLBOOK_PRESET);
+
 	if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
 	{
 		logGlobal->warn("Hero %s at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getNameTranslated(), hero->pos.toString());