Index: code/mission/missioncampaign.cpp
===================================================================
--- code/mission/missioncampaign.cpp	(revision 9221)
+++ code/mission/missioncampaign.cpp	(working copy)
@@ -63,6 +63,7 @@
 int	Num_campaigns;
 int Campaign_file_missing;
 int Campaign_names_inited = 0;
+SCP_vector<SCP_string> Ignored_campaigns;
 
 char Default_campaign_file_name[MAX_FILENAME_LEN - 4]  = { 0 };
 
@@ -106,6 +107,8 @@
 #define CAMPAIGN_STATS_FILE_COMPATIBLE_VERSION	1
 #define CAMPAIGN_STATS_FILE_ID						0xabbadaad
 
+bool campaign_is_ignored(char *filename, bool add_extension = false);
+
 /**
  * Returns a string (which is malloced in this routine) of the name of the given freespace campaign file.  
  * In the type field, we return if the campaign is a single player or multiplayer campaign.  
@@ -258,9 +261,14 @@
 {
 	char name[NAME_LENGTH];
 	char *desc = NULL;
-	int type, max_players;
+	int i, type, max_players;
 
 	if ( mission_campaign_get_info( filename, name, &type, &max_players, &desc) ) {
+		// don't add ignored campaigns
+		if (campaign_is_ignored(filename)) {
+			return 0;
+		}
+
 		if ( !MC_multiplayer && (type == CAMPAIGN_TYPE_SINGLE) ) {
 			Campaign_names[Num_campaigns] = vm_strdup(name);
 
@@ -429,6 +437,11 @@
 
 	filename = cf_add_ext(filename, FS_CAMPAIGN_FILE_EXT);
 
+	if (campaign_is_ignored(filename)) {
+		Campaign_file_missing = 1;
+		return CAMPAIGN_ERROR_IGNORED;
+	}
+
 	// open localization
 	lcl_ext_open();	
 
@@ -2338,6 +2351,28 @@
 		Int3();
 }
 
+bool campaign_is_ignored(char *filename, bool add_extension)
+{
+	bool current_campaign_ignored = false;
+	int i;
+	char campaign_name[NAME_LENGTH] = {""};
+
+	strcpy_s(campaign_name, filename);
+
+	if (add_extension) {
+		strcat_s(campaign_name, FS_CAMPAIGN_FILE_EXT);
+	}
+
+	for (i = 0; i < (int)Ignored_campaigns.size(); i++) {
+		if (!stricmp (campaign_name, Ignored_campaigns[i].c_str())) {
+			current_campaign_ignored = true;
+			break;
+		}
+	}
+	
+	return current_campaign_ignored;
+}
+
 // returns 0: loaded, !0: error
 int mission_load_up_campaign( player *pl )
 {
@@ -2345,27 +2380,32 @@
 		pl = Player;
 
 	if ( strlen(pl->current_campaign) ) {
-		return mission_campaign_load(pl->current_campaign, pl);
-	} else {
-		int rc = mission_campaign_load(Default_campaign_file_name, pl);
+		if (!campaign_is_ignored(pl->current_campaign, true)) {
+			return mission_campaign_load(pl->current_campaign, pl);
+		}
+		else {
+			Campaign_file_missing = 1;
+		}
+	}
 
-		// if the builtin campaign is missing/corrupt then try and fall back on whatever is available
-		if (rc) {
-			// no descriptions, and no sorting since we want the actual first entry found
-			mission_campaign_build_list(false, false);
+	int rc = mission_campaign_load(Default_campaign_file_name, pl);
 
-			if ( (Campaign_file_names[0] != NULL) && strlen(Campaign_file_names[0]) )
-				rc = mission_campaign_load(Campaign_file_names[0], pl);
+	// if the builtin campaign is missing/corrupt then try and fall back on whatever is available
+	if (rc) {
+		// no descriptions, and no sorting since we want the actual first entry found
+		mission_campaign_build_list(false, false);
 
-			mission_campaign_free_list();
-		}
-		
-		if (!rc) {
-			pl->main_hall = Campaign.missions[0].main_hall;
-			strcpy_s(pl->current_campaign, Campaign.filename);
-		}
-		return rc;
+		if ( (Campaign_file_names[0] != NULL) && strlen(Campaign_file_names[0]) )
+			rc = mission_campaign_load(Campaign_file_names[0], pl);
+
+		mission_campaign_free_list();
 	}
+	
+	if (!rc) {
+		pl->main_hall = Campaign.missions[0].main_hall;
+		strcpy_s(pl->current_campaign, Campaign.filename);
+	}
+	return rc;
 }
 
 /**
Index: code/mission/missioncampaign.h
===================================================================
--- code/mission/missioncampaign.h	(revision 9221)
+++ code/mission/missioncampaign.h	(working copy)
@@ -24,6 +24,7 @@
 #define CAMPAIGN_ERROR_CORRUPT			-1
 #define CAMPAIGN_ERROR_SEXP_EXHAUSTED	-2
 #define CAMPAIGN_ERROR_MISSING			-3
+#define CAMPAIGN_ERROR_IGNORED			-4
 
 // types of campaigns -- these defines match the string literals listed below which
 // are found in the campaign files.  I don't think that we need campaigns for furball
@@ -143,6 +144,7 @@
 extern char *Campaign_descs[MAX_CAMPAIGNS];
 extern int	Num_campaigns;
 extern int	Campaign_names_inited;
+extern SCP_vector<SCP_string> Ignored_campaigns;
 
 extern char Default_campaign_file_name[MAX_FILENAME_LEN - 4];
 
Index: code/mod_table/mod_table.cpp
===================================================================
--- code/mod_table/mod_table.cpp	(revision 9221)
+++ code/mod_table/mod_table.cpp	(working copy)
@@ -72,6 +72,14 @@
 		strcpy_s(Default_campaign_file_name, temp);
 	}
 
+	if (optional_string("#Ignored Campaign File Names")) {
+		SCP_string campaign_name; 
+		while (optional_string("$Campaign File Name:")) {
+			stuff_string(campaign_name, F_NAME); 
+			Ignored_campaigns.push_back(campaign_name); 
+		}
+	}
+
 	optional_string("#HUD SETTINGS");
 
 	// how long should the game wait before displaying a directive?
