Add WOTD language rotation, fancy word detection, arena improvements, and death consolidation

- Rotate WOTD between Portuguese, French, and English daily with cognate filtering
- Replace LLM-based fancy word detection with DreamDict frequency data (batch API + cache)
- Track fancy word usage per user and add Wordsmith archetype
- Restore full arena combat flavor text and add player miss actions
- Consolidate death logic into Kill() method with 2-hour lockout
- Fix arena death XP grant missing level-up check
- Fix LLM wotd_used classification by injecting actual WOTD into prompt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-03-31 18:47:49 -07:00
parent 306b4c2ae8
commit 3d6bc1a066
9 changed files with 350 additions and 139 deletions

View File

@@ -68,6 +68,9 @@ const (
thAdvDiverseMaxShare = 40
thGearheadMinMasterwork = 3
// Communication (vocabulary)
thWordsmithMinFancyWords = 10
// Social
thPatronMinRepGiven = 5
thPatronRatioMultiplier = 2
@@ -86,6 +89,7 @@ var archetypeFlavors = map[string]string{
"Enthusiast": "Genuinely excited about things. All the things. Possibly all at once.",
"Chatterbox": "Has thoughts. Many thoughts. Shares them all. You wouldn't have it any other way.",
"Linkmaster": "The community's unofficial curator. Their tab count is not your business.",
"Wordsmith": "Uses words most people have to look up. The thesaurus fears them.",
// Temporal
"Night Owl": "Awake when they probably shouldn't be. Thriving despite all evidence.",
@@ -226,6 +230,7 @@ type userData struct {
totalEmojis int
nightMsgs int
morningMsgs int
fancyWords int
// sentiment_stats
sentPositive int
@@ -273,10 +278,12 @@ func loadUserData(d *sql.DB, userID string) userData {
// user_stats
d.QueryRow(`SELECT total_messages, total_words, total_links, total_images,
total_questions, total_exclamations, total_emojis, night_messages, morning_messages
total_questions, total_exclamations, total_emojis, night_messages, morning_messages,
COALESCE(fancy_words, 0)
FROM user_stats WHERE user_id = ?`, userID).Scan(
&u.totalMsgs, &u.totalWords, &u.totalLinks, &u.totalImages,
&u.totalQuestions, &u.totalExcl, &u.totalEmojis, &u.nightMsgs, &u.morningMsgs)
&u.totalQuestions, &u.totalExcl, &u.totalEmojis, &u.nightMsgs, &u.morningMsgs,
&u.fancyWords)
// sentiment_stats
d.QueryRow(`SELECT COALESCE(positive,0), COALESCE(negative,0), COALESCE(neutral,0)
@@ -438,6 +445,13 @@ func evaluateArchetypes(u userData, pct communityPercentiles) []archetypeResult
})
}
if u.fancyWords >= thWordsmithMinFancyWords {
results = append(results, archetypeResult{
Name: "Wordsmith", Category: "Communication",
SignalScore: clampSignal(float64(u.fancyWords) / float64(thWordsmithMinFancyWords*3)),
})
}
// ── Temporal ──
if u.totalMsgs >= thNightOwlMinMsgs {