diff --git a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js
index 8abc729be4349dec7c9bb870f77c1d4b189e96b7..03e7e994ae7ae7336ad93bd7ea6e6c69a9cc1ce7 100644
--- a/xtrn/DDAreaChoosers/DDMsgAreaChooser.js
+++ b/xtrn/DDAreaChoosers/DDMsgAreaChooser.js
@@ -40,6 +40,9 @@
  * 2022-08-19 Eric Oulashin   Version 1.30
  *                            Set the control key pass-thru so that some hotkeys (such as Ctrl-P for PageUp) only
  *                            get caught by this script.
+ * 2022-11-04 Eric Oulashin   Version 1.31
+ *                            Made use of the 'posts' property in msg_area.sub[sub-code] (or msg_area.grp_list.sub_list)
+ *                            for the number of posts without votes
 */
 
 // TODO: In the area list, the 10,000ths digit (for # posts) is in a different color)
@@ -136,11 +139,6 @@ else if (typeof(argv[0]) == "string")
 	gChooseMsgGrpOnStartup = (argv[0].toLowerCase() == "true");
 
 
-// When using the number of messages in a sub-board, whether or not to count the
-// number of readable messages (which can be slow).  If false, will just look at the number
-// of all messages in the sub-board.
-var gUseNumReadableMessagesForMsgCount = false;
-
 // 2nd command-line argument: Determine whether or not to execute the message listing
 // code (true/false)
 var executeThisScript = true;
@@ -1070,17 +1068,7 @@ function DDMsgAreaChooser_CreateLightbarSubBoardMenu(pLevel, pGrpIdx, pSubIdx)
 						{
 							// There is no sub-subboard list, so this is just a regular sub-board.
 							// Get the number of readable messages in the sub-board.
-							// TODO: This can take a long time
-							if (gUseNumReadableMessagesForMsgCount)
-							{
-								numItems = numReadableMsgs(msgBase, this.areaChooser.group_list[this.grpIdx].sub_list[pSubIdx].code);
-							}
-							// Fast but could be inaccurate due to counting deleted messages,
-							// vote responses, etc..
-							else
-							{
-								numItems = msgBase.total_msgs;
-							}
+							numItems = numReadableMsgs(msgBase, this.areaChooser.group_list[this.grpIdx].sub_list[pSubIdx].code);
 						}
 						msgBase.close();
 					}
@@ -1634,10 +1622,7 @@ function DDMsgAreaChooser_ListSubBoardsInMsgGroup_Traditional(pGrpIndex, pSubIdx
 						subBoardInfo.description = msg_area.grp_list[grpIndex].sub_list[subIdx].description;
 					}
 
-					if (gUseNumReadableMessagesForMsgCount)
-						subBoardInfo.numPosts = numReadableMsgs(msgBase, msg_area.grp_list[grpIndex].sub_list[subIdx].code);
-					else
-						subBoardInfo.numPosts = msgBase.total_msgs;
+					subBoardInfo.numPosts = numReadableMsgs(msgBase, msg_area.grp_list[grpIndex].sub_list[subIdx].code);
 
 					// Get the date & time when the last message was imported.
 					if (this.showDatesInSubBoardList && (subBoardInfo.numPosts > 0))
@@ -1931,11 +1916,7 @@ function DDMsgAreaChooser_GetSubBoardInfo(pGrpIdx, pSubIdx, pSubSubIdx)
 		retObj.subCode = msg_area.grp_list[pGrpIdx].sub_list[pSubIdx].code;
 
 		// Get the number of messages in the sub-board
-		var numMsgs = 0;
-		if (gUseNumReadableMessagesForMsgCount)
-			numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIdx].sub_list[pSubIdx].code);
-		else
-			numMsgs = getNumMsgsInSubBoard(msg_area.grp_list[pGrpIdx].sub_list[pSubIdx].code);
+		var numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIdx].sub_list[pSubIdx].code);
 		if (numMsgs > 0)
 		{
 			retObj.numItems = numMsgs;
@@ -2018,11 +1999,7 @@ function DDMsgAreaChooser_GetMsgSubBrdLine(pGrpIndex, pSubIndex, pHighlight)
 	var msgBase = new MsgBase(msg_area.grp_list[pGrpIndex].sub_list[pSubIndex].code);
 	if (msgBase.open())
 	{
-		var numMsgs = 0;
-		if (gUseNumReadableMessagesForMsgCount)
-			numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIndex].sub_list[pSubIndex].code);
-		else
-			numMsgs = msgBase.total_msgs;
+		var numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIndex].sub_list[pSubIndex].code);
 		var newestDate = {}; // For storing the date of the newest post
 		// Get the date & time when the last message was imported.
 		var msgHeader = getLatestMsgHdr(msg_area.grp_list[pGrpIndex].sub_list[pSubIndex].code);
@@ -2601,11 +2578,7 @@ function getGreatestNumMsgs(pGrpIndex)
 		if (msgBase == null) continue;
 		if (msgBase.open())
 		{
-			var numMsgs = 0;
-			if (gUseNumReadableMessagesForMsgCount)
-				numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIndex].sub_list[subIndex].code);
-			else
-				numMsgs = msgBase.total_msgs;
+			var numMsgs = numReadableMsgs(msgBase, msg_area.grp_list[pGrpIndex].sub_list[subIndex].code);
 			if (numMsgs > greatestNumMsgs)
 				greatestNumMsgs = numMsgs;
 			msgBase.close();
@@ -2943,6 +2916,20 @@ function isReadableMsgHdr(pMsgHdr, pSubBoardCode)
 // Return value: The number of readable messages in the sub-board
 function numReadableMsgs(pMsgbase, pSubBoardCode)
 {
+	// The posts property in msg_area.sub[sub_code] and msg_area.grp_list.sub_list is the number
+	// of posts excluding vote posts
+	if (typeof(msg_area.sub[pSubBoardCode].posts) === "number")
+		return msg_area.sub[pSubBoardCode].posts;
+	else if ((pMsgbase !== null) && pMsgbase.is_open)
+	{
+		// Just return the total number of messages..  This isn't accurate, but it's fast.
+		return pMsgbase.total_msgs;
+	}
+	else
+		return 0;
+
+	// Older code, used before Synchronet 3.18c when the 'posts' property was added - This is slow:
+	/*
 	if ((pMsgbase === null) || !pMsgbase.is_open)
 		return 0;
 
@@ -2971,6 +2958,7 @@ function numReadableMsgs(pMsgbase, pSubBoardCode)
 		}
 	}
 	return numMsgs;
+	*/
 }
 
 // Returns whether a given name matches the logged-in user's handle, alias, or
@@ -3303,10 +3291,7 @@ function getLatestMsgTime(pSubCode)
 	var msgBase = new MsgBase(pSubCode);
 	if (msgBase.open())
 	{
-		if (gUseNumReadableMessagesForMsgCount)
-			numMsgs = numReadableMsgs(msgBase, pSubCode);
-		else
-			numMsgs = msgBase.total_msgs;
+		numMsgs = numReadableMsgs(msgBase, pSubCode);
 		msgBase.close();
 	}
 	delete msgBase; // Free some memory?
diff --git a/xtrn/DDAreaChoosers/readme.txt b/xtrn/DDAreaChoosers/readme.txt
index f9c59346c52a1341b2b8a2fd2dd4fcf56523182d..96252de30f60371639fb1d0164a012e842174238 100644
--- a/xtrn/DDAreaChoosers/readme.txt
+++ b/xtrn/DDAreaChoosers/readme.txt
@@ -1,6 +1,6 @@
                      Digital Distortion Area Choosers
-                               Version 1.30
-                        Release date: 2022-08-19
+                            Version 1.31/1.30
+                        Release date: 2022-11-04
 
                                   by
 
diff --git a/xtrn/DDAreaChoosers/revision_history.txt b/xtrn/DDAreaChoosers/revision_history.txt
index ed97678feb7de703a4b2c0164f91ba0c3926db91..2d8e3f17c19c4a2cc7a92faaa8b54c47ddc339fe 100644
--- a/xtrn/DDAreaChoosers/revision_history.txt
+++ b/xtrn/DDAreaChoosers/revision_history.txt
@@ -5,6 +5,11 @@ Revision History (change log)
 =============================
 Version  Date         Description
 -------  ----         -----------
+1.31     2022-11-04   Message area chooser only: Made use of the 'posts'
+                      property in msg_area.sub[sub-code] (or
+                      msg_area.grp_list.sub_list) for the number of posts
+                      without votes, if that property exists (it was added
+                      in Synchronet 3.18c)
 1.30     2022-08-19   Made use of the control key passthru setting so that
                       certain hotkeys (such as Ctrl-P, for Pageup) are only
                       caught by the scripts and not passed thru to the BBS.