Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1145,6 +1145,40 @@
 		"warnings",
 	};
 }
+std::string module_impl::get_message_instruments() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
+		std::string instname = m_sndFile->GetInstrumentName( i );
+		if ( !instname.empty() ) {
+			valid = true;
+		}
+		tmp += instname;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
+std::string module_impl::get_message_samples() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
+		std::string samplename = m_sndFile->GetSampleName( i );
+		if ( !samplename.empty() ) {
+			valid = true;
+		}
+		tmp += samplename;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
 std::string module_impl::get_metadata( const std::string & key ) const {
 	if ( key == std::string("type") ) {
 		return mpt::ToCharset(mpt::Charset::UTF8, m_sndFile->m_modFormat.type );
@@ -1172,35 +1206,55 @@
 	} else if ( key == std::string("message") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
 		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
-				std::string instname = m_sndFile->GetInstrumentName( i );
-				if ( !instname.empty() ) {
-					valid = true;
-				}
-				tmp += instname;
-				tmp += "\n";
+			switch ( m_sndFile->m_modFormat.messageHeuristic ) {
+				case ModMessageHeuristicOrder::Instruments:
+					retval = get_message_instruments();
+					break;
+				case ModMessageHeuristicOrder::Samples:
+					retval = get_message_samples();
+					break;
+				case ModMessageHeuristicOrder::InstrumentsSamples:
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					break;
+				case ModMessageHeuristicOrder::SamplesInstruments:
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					break;
+				case ModMessageHeuristicOrder::BothInstrumentsSamples:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+					}
+					break;
+				case ModMessageHeuristicOrder::BothSamplesInstruments:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+					}
+					break;
 			}
-			if ( valid ) {
-				retval = tmp;
-			}
 		}
-		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
-				std::string samplename = m_sndFile->GetSampleName( i );
-				if ( !samplename.empty() ) {
-					valid = true;
-				}
-				tmp += samplename;
-				tmp += "\n";
-			}
-			if ( valid ) {
-				retval = tmp;
-			}
-		}
 		return mod_string_to_utf8( retval );
 	} else if ( key == std::string("message_raw") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -146,6 +146,8 @@
 	std::size_t read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved );
+	std::string get_message_instruments() const;
+	std::string get_message_samples() const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int command ) const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
 	static double could_open_probability( const OpenMPT::FileReader & file, double effort, std::unique_ptr<log_interface> log );
Index: soundlib/Load_it.cpp
===================================================================
--- soundlib/Load_it.cpp	(revision 12440)
+++ soundlib/Load_it.cpp	(working copy)
@@ -1257,6 +1257,7 @@
 	m_modFormat.type = (GetType() == MOD_TYPE_MPT) ? U_("mptm") : U_("it");
 	m_modFormat.madeWithTracker = std::move(madeWithTracker);
 	m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+	m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
 
 	return true;
 }
Index: soundlib/Load_itp.cpp
===================================================================
--- soundlib/Load_itp.cpp	(revision 12440)
+++ soundlib/Load_itp.cpp	(working copy)
@@ -399,6 +399,7 @@
 	m_modFormat.type = U_("itp");
 	m_modFormat.madeWithTracker = U_("OpenMPT ") + mpt::ufmt::val(m_dwLastSavedWithVersion);
 	m_modFormat.charset = mpt::Charset::Windows1252;
+	m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
 
 	return true;
 #endif // MPT_EXTERNAL_SAMPLES
Index: soundlib/Load_mo3.cpp
===================================================================
--- soundlib/Load_mo3.cpp	(revision 12440)
+++ soundlib/Load_mo3.cpp	(working copy)
@@ -831,11 +831,13 @@
 
 	mpt::ustring originalFormatType;
 	mpt::ustring originalFormatName;
+	ModMessageHeuristicOrder messageHeuristic = ModMessageHeuristicOrder::Default;
 	if(fileHeader.flags & MO3FileHeader::isIT)
 	{
 		SetType(MOD_TYPE_IT);
 		originalFormatType = U_("it");
 		originalFormatName = U_("Impulse Tracker");
+		messageHeuristic = ModMessageHeuristicOrder::Samples;
 	} else if(fileHeader.flags & MO3FileHeader::isS3M)
 	{
 		SetType(MOD_TYPE_S3M);
@@ -856,6 +858,7 @@
 		SetType(MOD_TYPE_XM);
 		originalFormatType = U_("xm");
 		originalFormatName = U_("FastTracker 2");
+		messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	}
 
 	if(fileHeader.flags & MO3FileHeader::linearSlides)
@@ -1948,6 +1951,7 @@
 		m_modFormat.charset = mpt::Charset::ISO8859_1;
 	else
 		m_modFormat.charset = mpt::Charset::CP437;
+	m_modFormat.messageHeuristic = messageHeuristic;
 
 	if(unsupportedSamples)
 	{
Index: soundlib/Load_xm.cpp
===================================================================
--- soundlib/Load_xm.cpp	(revision 12440)
+++ soundlib/Load_xm.cpp	(working copy)
@@ -1032,6 +1032,7 @@
 		m_modFormat.originalType = U_("xm");
 		m_modFormat.madeWithTracker = std::move(madeWithTracker);
 		m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	} else
 	{
 		m_modFormat.formatName = mpt::format(U_("FastTracker 2 v%1.%2"))(fileHeader.version >> 8, mpt::ufmt::hex0<2>(fileHeader.version & 0xFF));
@@ -1038,6 +1039,7 @@
 		m_modFormat.type = U_("xm");
 		m_modFormat.madeWithTracker = std::move(madeWithTracker);
 		m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	}
 
 	return true;
Index: soundlib/Sndfile.cpp
===================================================================
--- soundlib/Sndfile.cpp	(revision 12440)
+++ soundlib/Sndfile.cpp	(working copy)
@@ -1576,6 +1576,21 @@
 	Patterns.OnModTypeChanged(oldType);
 
 	m_modFormat.type = mpt::ToUnicode(mpt::Charset::UTF8, GetModSpecifications().fileExtension);
+	switch(newType)
+	{
+	case MOD_TYPE_MPT:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_IT:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_XM:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
+		break;
+	default:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Default;
+		break;
+	}
 }
 
 #endif // MODPLUG_TRACKER
Index: soundlib/Sndfile.h
===================================================================
--- soundlib/Sndfile.h	(revision 12440)
+++ soundlib/Sndfile.h	(working copy)
@@ -247,6 +247,17 @@
 };
 
 
+enum class ModMessageHeuristicOrder
+{
+	Instruments,
+	Samples,
+	InstrumentsSamples,
+	SamplesInstruments,
+	BothInstrumentsSamples,
+	BothSamplesInstruments,
+	Default = InstrumentsSamples,
+};
+
 struct ModFormatDetails
 {
 	mpt::ustring formatName;         // "FastTracker 2"
@@ -255,6 +266,7 @@
 	mpt::ustring originalFormatName; // "FastTracker 2" in the case of converted formats like MO3 or GDM
 	mpt::ustring originalType;       // "xm" in the case of converted formats like MO3 or GDM
 	mpt::Charset charset = mpt::Charset::UTF8;
+	ModMessageHeuristicOrder messageHeuristic = ModMessageHeuristicOrder::Default;
 };
 
 
