I wrote a program to scan through every character's speech files and sort out mentions of other characters. It was originally intended to show the relationships between characters. It looks for certain keywords related to characters (usually nicknames) as well as character-specific items.
This is the python script used to generate it:
import re import html address = r"C:\Program Files (x86)\Steam\SteamApps\common\Don't Starve Together Beta\data\scripts" + "\\" speeches = [ "wathgrithr", "waxwell", "webber", "wendy", "wickerbottom", "willow", "wilson", "wolfgang", "woodie", "wx78" ] specifics = { "wathgrithr": [ "wathgrithr", "wathgrithrhat", "spear_wathgrithr" ], "waxwell": [ "waxwell", "waxwelljournal", "chesspiece_formal", "statuemaxwell", "maxwell", "maxwellhead", "shadowdigger" ], "webber": [ "webber", "webberskull" ], "wendy": [ "wendy", "abigail", "abigailheart", "abigail_flower" ], "wickerbottom": [ "wickerbottom", "book_birds", "book_tentacles", "book_gardening", "book_sleep", "book_brimstone" ], "willow": [ "willow", "lighter", "bernie_active", "bernie_inactive" ], "wilson": [ "wilson", "chesspiece_pawn" ], "wolfgang": [ "wolfgang", ], "woodie": [ "woodie", "lucy" ], "wx78": [ "wx78", "trinket_11" #lying robot ], "wes": [ "wes", "balloon", "balloons_empty" ], "charlie": [ "rose", "chesspiece_muse", "multiplayer_portal", "statue_marble", "stagehand", "announce_charlie", "announce_charlie_attack", "shadowheart" ], "misc": [ "trinket_10", "player", "maxwelllight", "maxwelllock", "maxwellthrone" ], "family": [ ] } aliases = { "wathgrithr": [ "wigfrid" ], "waxwell": [ "maxwell", "magician", "frail human" ], "webber": [ "webber", "spider child", "monster child" ], "wendy": [ "wendy", "abigail", "abby" ], "wickerbottom": [ "librarian", "wicker", "brainlady" ], "willow": [ "willow" ], "wilson": [ "wilson" ], "wolfgang": [ "wolfgang", "strongman" ], "woodie": [ "woodie", "lucy", "lumberjack", "beaver", "beard will not like such pictures" #for a special case w/ wolfgang ], "wx78": [ "wx" ], "wes": [ "\\bwes\\b" ], "charlie": [ "rose", "charlie" ], "misc": [ ], "family": [ "mother", "father", "\\bparent\\b", "grandparent", "\\buncle\\b", "\\baunt\\b", "cousin", "nephew", "\\bniece", "dad\\b", "mom\\b", "ancestor", "sibling", "sister", "brother", "\\bson\\b", "grandson", "daughter\\b" ] } def mastermaker(): dump = open("master.txt", "a") master = {} for k in speeches: master[k] = {} for k in sorted(master): for s in sorted(specifics): master[k][s] = [] for char in sorted(master): print(char) speech = open(address + "speech_" + char + ".lua", "r").read() for described in master[char]: for alias in specifics[described]: match = re.search( r"\s+" + alias + r" =.*,.*", speech, re.I) if match == None: #for bracket stuff match = re.search( r"\s+" + alias + r" =[^}]*},", speech, re.I|re.M) if match: master[char][described].append(match.group()) for alias in aliases[described]: match = re.findall( r"^\s+.*\".*" + alias + r".*\",.*$", speech, re.I|re.M) for quote in match: if not quote in master[char][described]: master[char][described].append(quote) if char == described: #for inspectself match = re.search( r"\s+" + "inspectself" + r" =.*,.*", speech, re.I|re.M) if match: if not match.group() in master[char]["charlie"]: master[char][described].append(match.group()) if char == "waxwell": #charle comments match = re.findall( r"^\s+.*--.*\.\.\..*$", speech, re.I|re.M) #they end in ellipses for quote in match: if not quote in master[char]["charlie"]: master[char]["charlie"].append(quote) return master def masterhandler(first,second): for i in m[first][second]: print(i) mh = masterhandler def htmltablemaker(): dump = open("table.html", "a") dump.write("""<style> td .hideifintable {display:none;} table { overflow: hidden; } td, th { padding: 5px; position: relative; outline: 0; } body:not(.nohover) tbody tr:hover { background-color: #ffa; } td:hover::after, thead th:not(:empty):hover::after, td:focus::after, thead th:not(:empty):focus::after { content: ''; height: 10000px; left: 0; position: absolute; top: -5000px; width: 100%; z-index: -1; } td:hover::after, th:hover::after { background-color: #ffa; } td:focus::after, th:focus::after { background-color: lightblue; } </style>""") dump.write("<table border=\"1\">\n") dump.write("<tr>\n") dump.write("<td/>") for described in sorted(m["wilson"]): dump.write("<td>"+described+"</td>") dump.write("</tr>") for speaker in sorted(m): dump.write("<tr>") dump.write("<td>"+speaker+"</td>\n") for described in sorted(m[speaker]): dump.write("<td id=\""+speaker+described+"\" class=\""+speaker+" "+described+"\" onmouseover=\"document.getElementById('changer').innerHTML = document.getElementById('"+speaker+described+"').innerHTML;\"><div class=\"hideifintable\" ") #good luck dump.write("<ul>") for i in m[speaker][described]: dump.write("<li>"+html.escape(i)+"</li>") dump.write("</ul>") dump.write("</div></td>\n") dump.write("</tr>") dump.write("</table><div id=\"changer\">mouse over cells to display quotes. the speaker is on the left, the subject is on the top.</div>") dump.close() m = mastermaker() htmltablemaker()
It's kind of messy, but you can see the keywords that it looks for. "aliases" is for detecting words in the quote, and "specifics" is for character-related prefabs.
I think that the table works pretty well, but I am open to suggestions on how I could improve it. I probably forgot a few keywords or items, or maybe there is another category I can add. It uses javascript for readability, so just hover over the table and the corresponding data should appear in the space below it. Or, if you're on mobile, you should be able to tap.