# Development Summary - 2026-02-01

## Session Overview
Major changes: Rebirth death notification customization with localization, ConfigurationManager reversion across all mods, CultOfQoL logging refactor, and TraitControl reeducation feature.

---

## Rebirth - Custom Death Notification with Localization

### Feature
Replaced vanilla "died of old age" death subtitle with custom localized "succumbed to unknown forces..." message in 11 languages.

### Problem
Rebirth showed generic "died of old age" message during death animation, breaking immersion. Two notification messages appear during rebirth:
1. Death subtitle (during death animation) - showed vanilla "died of old age"
2. Post-rebirth notification (line 134) - already customizable

### Solution

**Harmony Postfix on FollowerInfo.GetDeathText():**
- Intercepts death text generation before subtitle is shown
- Checks if follower is undergoing rebirth using HashSet tracking
- Returns custom localized message instead of vanilla text

**Tracking System:**
- `HashSet<int>` tracks follower IDs currently undergoing rebirth
- `MarkFollowerForRebirth(id)` called at start of DieRoutine
- `UnmarkFollowerRebirth(id)` called inside GetDeathText patch after message is applied

**Timing Fix:**
Initial implementation unmarked follower immediately after `Die()` call, but `GetDeathText()` is called asynchronously during death coroutine. Fixed by moving unmark operation into the GetDeathText patch itself.

**Localization:**
Created message dictionary for 11 languages with rich text formatting:
```csharp
private static readonly Dictionary<string, string> RebirthDeathMessages = new()
{
    { "English", "<color=#FFD201>{0}</color> succumbed to unknown forces..." },
    { "French", "<color=#FFD201>{0}</color> a succombé à des forces inconnues..." },
    { "German", "<color=#FFD201>{0}</color> erlag unbekannten Mächten..." },
    // ... 8 more languages
};
```

### Files Modified
- `Rebirth/Patches.cs` - Added HashSet, mark/unmark methods, GetDeathText postfix with localization
- `Rebirth/RebirthCommand.cs` - Modified DieRoutine to mark follower before death, added logging
- `Rebirth/GlobalUsings.cs` - Added `global using I2.Loc;`
- `Thunderstore/rebirth/CHANGELOG.md` - Added feature entry, removed superseded graveyard line

### Result
- Death subtitle shows custom localized message in all supported languages
- Follower name appears in gold color (rich text preserved)
- Graveyard still correctly shows "died of old age" (not "murdered")

---

## ConfigurationManager Reversion (All Mods)

### Task
Reverted all mods from ConfigurationManagerEnhanced back to original BepInEx ConfigurationManager version 18.4.1 (hard dependency).

### Plugin.cs Files Updated (5 mods)

**Changed from:**
```csharp
[BepInDependency("com.p1xel8ted.configurationmanagerenhanced", "1.0")]
```

**Changed to:**
```csharp
[BepInDependency("com.bepis.bepinex.configurationmanager", "18.4.1")]
```

**Files:**
- CultOfQoL/Plugin.cs (line 10)
- Rebirth/Plugin.cs (line 8)
- SkipOfTheLamb/Plugin.cs (line 3)
- TraitControl/Plugin.cs (line 7)
- Namify/Plugin.cs (line 6)

### Thunderstore Manifests Updated (3 mods)

Removed `"p1xel8ted-ConfigurationManagerEnhanced-1.0.0"` dependency from:
- Thunderstore/cult/manifest.json
- Thunderstore/traitcontrol/manifest.json
- Thunderstore/namify/manifest.json

**Note:** Rebirth and SkipOfTheLamb manifests didn't have CME dependency, no changes needed.

### Project Files Updated

**TraitControl/TraitControl.csproj:**
Removed direct assembly reference:
```xml
<Reference Include="ConfigurationManagerEnhanced">
    <HintPath>..\libs\ConfigurationManagerEnhanced.dll</HintPath>
</Reference>
```

### Build Status
All mods build successfully:
- 0 Warnings
- 0 Errors

---

## CultOfQoL - Logging Method Rename

### Change
User renamed `L()` method to `WriteLog()` in Plugin.cs line 796 for better clarity.

### Method Signature
```csharp
public static void WriteLog(string message, LogType type = LogType.Info)
{
    switch (type)
    {
        case LogType.Error:
            Log.LogError(message);
            break;
        case LogType.Info:
            if (ConfigCache.GetCachedValue(ConfigCache.Keys.EnableLogging, () => EnableLogging.Value))
            {
                Log.LogInfo(message);
            }
            break;
        case LogType.Warning:
            Log.LogWarning(message);
            break;
    }
}
```

### Updates Made
Replaced **58 occurrences** of `L(` with `WriteLog(` across **10 files**:

| File | Occurrences |
|------|-------------|
| Plugin.cs | 3 |
| FollowerPatches.cs | 24 |
| FastCollectingPatches.cs | 1 |
| InteractionPatches.cs | 4 |
| PickUps.cs | 2 |
| RitualEnrichmentNerf.cs | 4 |
| Rituals.cs | 7 |
| SoundPatches.cs | 1 |
| StructurePatches.cs | 11 |
| TwitchItems.cs | 1 |

### Exception Logging Fix

**Runtime Exception (1 instance):**
Fixed `FastCollectingPatches.cs:213` to use `LogType.Error`:
```csharp
Plugin.WriteLog($"[MassCollectOfferingShrines] Error collecting from shrine: {ex.Message}", Plugin.LogType.Error);
```

**Transpiler Exceptions (16 instances):**
Left as `Plugin.Log.LogWarning()` - appropriate for graceful IL patching fallbacks that return original code.

### Build Status
- Successful
- 0 Warnings
- 0 Errors

---

## TraitControl - Trait Reroll via Reeducation

### Feature
Added new "Trait Reroll via Reeducation" feature that allows players to re-roll follower traits using the Re-educate command.

### Problem
Vanilla reeducation is only available for dissenters and only removes the dissenter trait. Players had no way to re-randomize traits on normal followers without using Re-indoctrination (which only works at the altar and changes appearance/name).

### Solution

**New Configuration Option:**
Added `TraitRerollOnReeducation` toggle in section 01 (Trait Replacement):
- When enabled, adds the Re-educate command to normal followers
- Using it re-rolls their traits using configured min/max and weights
- Respects all TraitControl settings (weights, trait replacement, unique traits, etc.)

**Implementation:**

**1. Command Addition (FollowerCommandGroups patch):**
```csharp
[HarmonyPostfix]
[HarmonyPatch(typeof(FollowerCommandGroups), nameof(FollowerCommandGroups.NormalCommands))]
private static void FollowerCommandGroups_NormalCommands_AddReeducate(ref List<CommandItem> __result)
{
    if (!Plugin.TraitRerollOnReeducation.Value) return;
    __result.Add(FollowerCommandItems.Reeducate());
}
```

**2. Coroutine Wrapping (ReeducateRoutine patch):**
```csharp
[HarmonyPostfix]
[HarmonyPatch(typeof(interaction_FollowerInteraction), nameof(interaction_FollowerInteraction.ReeducateRoutine))]
private static void ReeducateRoutine_Postfix(ref IEnumerator __result, interaction_FollowerInteraction __instance)
{
    if (!Plugin.TraitRerollOnReeducation.Value) return;
    if (__instance.follower.Brain.Info.CursedState == Thought.Dissenter) return;

    __result = WrapReeducateRoutine(__result, __instance.follower.Brain);
}
```

**3. Trait Reroll Logic:**
- Runs original reeducation routine to completion
- Clamps Reeducation stat to 0 (fixes vanilla underflow bug)
- Generates new traits using `RandomisedTraits()` (already patched by TraitControl)
- Applies trait replacement if enabled (removes negative traits)
- Logs all steps for debugging

**Dissenter Filtering:**
Dissenters are excluded from trait reroll because:
1. They already have reeducation in vanilla
2. Vanilla reeducation for dissenters has different behavior (removes dissenter trait)
3. Avoiding double-processing and conflicts with vanilla logic

**Bug Fix:**
Discovered and fixed vanilla bug where Reeducation stat can go negative after reeducation cost is applied. Added clamp to 0 before trait reroll.

### Files Modified
- `TraitControl/Configs.cs` - Added `TraitRerollOnReeducation` property declaration
- `TraitControl/GlobalUsings.cs` - Added `global using Lamb.UI.FollowerInteractionWheel;`
- `TraitControl/Plugin.cs` - Added config binding (line 138-140)
- `TraitControl/Patches/TraitWeights.cs` - Added 76 lines of reeducation implementation (lines 708-780)
- `TraitControl/Patches/NoNegativeTraits.cs` - Lambda simplification (line 40)

### Result
- Players can now re-roll follower traits without re-indoctrination
- Trait reroll respects all TraitControl configuration (min/max, weights, replacements)
- Re-educate command seamlessly integrates with vanilla UI/workflow
- Fixed vanilla Reeducation stat underflow bug

---

## Changelog Updates

### Rebirth CHANGELOG.md (version 1.1.2)

**Added:**
```markdown
* Changed death notification during rebirth to show "succumbed to unknown forces..." (localized for all supported languages).
```

**Removed:**
```markdown
* Switched to ConfigurationManagerEnhanced dependency.
```

**Reasoning:**
- CME line removed because we reverted back to original ConfigurationManager
- Previous "graveyard" line about "died of old age" was removed as contradictory/superseded by the custom message

---

## Documentation & Guidelines

### Changelog Best Practices (from user feedback)

**Development fixes vs user-facing features:**
- Don't list bugs fixed during development of a new feature before release
- If a feature is being added for the first time, only describe the final working feature
- Users never experienced the broken version, so don't mention the fix
- Example: Don't say "Added feature X" and "Fixed bug in feature X" in same release - just say "Added feature X" with correct specs

**Technical details belong elsewhere:**
- Implementation notes, bug root causes, and fix details go in commit messages and summary-*.md files
- Changelogs describe the final user experience, not the development journey
- Focus on what users experience, not how it was implemented

**Always include dates:**
- Every version entry must have date in DD/MM/YYYY format
- Even if multiple versions released same day

---

## Files Modified Summary

### New Files
None

### Modified Files
**Rebirth (4 files):**
- Patches.cs
- RebirthCommand.cs
- GlobalUsings.cs
- Thunderstore/rebirth/CHANGELOG.md

**All Mods - ConfigurationManager Reversion (8 files):**
- CultOfQoL/Plugin.cs
- Rebirth/Plugin.cs
- SkipOfTheLamb/Plugin.cs
- TraitControl/Plugin.cs
- TraitControl/TraitControl.csproj
- Namify/Plugin.cs
- Thunderstore/cult/manifest.json
- Thunderstore/traitcontrol/manifest.json
- Thunderstore/namify/manifest.json

**CultOfQoL - Logging Refactor (10 files):**
- Plugin.cs
- Patches/Followers/FollowerPatches.cs
- Patches/Systems/FastCollectingPatches.cs
- Patches/Gameplay/InteractionPatches.cs
- Patches/Gameplay/PickUps.cs
- Patches/Gameplay/RitualEnrichmentNerf.cs
- Patches/Gameplay/Rituals.cs
- Patches/Systems/SoundPatches.cs
- Patches/Structures/StructurePatches.cs
- Patches/Gameplay/TwitchItems.cs

**TraitControl - Reeducation Feature (5 files):**
- Configs.cs
- GlobalUsings.cs
- Plugin.cs
- Patches/TraitWeights.cs
- Patches/NoNegativeTraits.cs

---

## Build Status

All projects build successfully:
```
Build succeeded.
    0 Warning(s)
    0 Error(s)
```

## Next Steps
- Commit changes
- Test Rebirth custom death message in-game
- Test ConfigurationManager integration in all mods
