Overview
The profile system allows you to create multiple mod configurations and switch between them instantly. Each profile saves which mods are enabled or disabled, making it easy to maintain different setups for various purposes.
How profiles work
Profiles are independent configurations that track:
- Mod enabled/disabled states - Each profile remembers which mods are active
- Profile metadata - Name, description, creation date, and last modified date
- Active profile - One profile is always active at a time
Profiles are stored as JSON files in the profiles/ directory, with each profile having a unique ID (see src/models/profile_manager_model.py:518-539).
Profile data structure
Each profile contains:
{
"id": "unique-uuid",
"name": "My Profile",
"description": "Optional description",
"mods": {
"mod_name_1": {"enabled": true},
"mod_name_2": {"enabled": false}
},
"created_at": "2024-01-15T10:30:00",
"updated_at": "2024-01-20T15:45:00",
"active": true
}
Default profile
BD2 Mod Manager creates a Default profile automatically on first launch. This profile:
- Cannot be deleted
- Serves as the standard profile for managing mods
- Is automatically created if corrupted or missing
The default profile creation is handled in src/models/profile_manager_model.py:396-414:
def _create_default_profile(self) -> None:
"""Loads the default profile or creates it if it doesn't exist or is corrupt."""
default_path = self._profiles_folder / "default.json"
if default_path.exists():
try:
with default_path.open("r", encoding="utf-8") as f:
profile = Profile.from_dict(json.load(f))
# ...
except (json.JSONDecodeError, ValueError) as e:
logger.error(f"Default profile is corrupt: {e}. A new one will be created.")
default_profile = Profile(id="default", _name="Default",
_description="The standard profile for managing mods.")
Creating profiles
Open profile manager
Click the Profiles button or menu option in the mod manager.
Create new profile
Click New Profile or the + button.
Name your profile
Enter a unique name for your profile (e.g., “PvP Setup”, “Story Mode”, “Favorite Characters”).Profile names must be unique. The manager prevents duplicate names.
Add description (optional)
Provide a description to help you remember what this profile is for.
Configure mods
Enable or disable mods as needed. Your selections are automatically saved to the profile.
Profile creation is implemented in src/models/profile_manager_model.py:442-454:
def create_profile(self, name: str, description: Optional[str] = None) -> Profile:
norm_name = name.lower().strip()
if norm_name in self._profiles_by_name:
raise ProfileAlreadyExistsError(f"Profile with name '{name}' already exists.")
profile = Profile(id=str(uuid4()), _name=name, _description=description)
self.save_profile(profile)
self._profiles[profile.id] = profile
self._profiles_by_name[norm_name] = profile
Switching profiles
Switch between profiles to instantly change your mod configuration:
Open profile list
View all available profiles in the profile manager or dropdown.
Select a profile
Click on the profile you want to activate.
Automatic state update
The mod manager immediately updates to show which mods are enabled in the selected profile.
Sync to apply
Click Sync to apply the new mod configuration to the game.
You can switch profiles without syncing to preview which mods would be enabled, then sync when ready.
When switching profiles (see src/models/profile_manager_model.py:501-516):
- The previous active profile is deactivated and saved
- The new profile is marked as active and saved
- A signal is emitted to refresh the mod view
- All mod enabled states are updated from the new profile
This is coordinated in src/models/mod_manager_model.py:138-152:
def _on_profile_switched(self) -> None:
self.refresh_mods_data()
self.currentProfileChanged.emit()
def refresh_mods_data(self) -> None:
profile = self._profile_manager.get_current_profile()
for mod_name, mod_entry in self._mod_entries.items():
if profile:
modinfo = profile.get_mod(mod_name)
if modinfo:
mod_entry.enabled = modinfo.enabled
else:
mod_entry.enabled = False
Editing profiles
Modify profile details at any time:
- Rename profile: Change the profile name (except for Default)
- Update description: Modify or add a description
- Modify mod states: Enable or disable mods in the profile
All changes are automatically saved with an updated timestamp. The updated_at field tracks when the profile was last modified (see src/models/profile_manager_model.py:117-120).
Deleting profiles
Remove profiles you no longer need:
You cannot delete:
- The Default profile
- The currently active profile
Switch to another profile before deleting the one you want to remove.
When you delete a profile:
- The profile JSON file is removed from disk
- The profile is removed from the manager’s cache
- The profile list updates automatically
Deletion validation is in src/models/profile_manager_model.py:456-476:
def delete_profile(self, profile_id: str) -> None:
if profile_id == "default":
raise ValueError("Cannot delete the default profile.")
if self._current_profile and profile_id == self._current_profile.id:
raise ProfileInUseError("Cannot delete the currently active profile.")
profile = self._profiles.get(profile_id)
if not profile:
raise ProfileNotFoundError(f"Profile with ID '{profile_id}' not found.")
Each profile tracks useful metadata:
Timestamps
- created_at: When the profile was created
- updated_at: Last modification time (automatically updated)
Mod counts
- Total mods: Number of mods tracked in the profile
- Enabled mods: Number of currently enabled mods
You can view this information in the profile details view.
Mod counts are calculated dynamically (see src/models/profile_manager_model.py:108-115):
@property
def mod_count(self) -> int:
"""Return the total number of mods in this profile."""
return len(self.mods)
@property
def enabled_mod_count(self) -> int:
"""Return the number of enabled mods in this profile."""
return sum(1 for mod in self.mods.values() if mod.enabled)
Use cases
Profiles are perfect for different scenarios:
Character-focused profiles
Create profiles for your favorite characters:
- “Angelica Mods” - Only Angelica character mods
- “Swimsuit Characters” - Seasonal costume mods
- “Main Team” - Mods for your primary team
Content-specific profiles
- “Story Mode” - Cutscene and dating scene mods for story enjoyment
- “PvP Clean” - Minimal mods for competitive play
- “Screenshot Mode” - Idle animations and special illustrations
Testing profiles
- “Testing New Mods” - Isolated profile for trying new mods before adding to main setup
- “Mod Development” - Profile for testing your own mod creations
Automatic profile updates
Profiles automatically stay in sync with mod operations:
- Mod renamed: All profiles update their references to the new name
- Mod deleted: All profiles remove the mod from their configuration
- Mod added: New mods start as disabled in all profiles
This ensures profile integrity even when mods change (see src/models/mod_manager_model.py:389-392 for rename handling).
Profile storage
Profiles are stored as individual JSON files in the profiles/ directory:
profiles/
├── default.json
├── 550e8400-e29b-41d4-a716-446655440000.json
└── 6ba7b810-9dad-11d1-80b4-00c04fd430c8.json
Each file contains the complete profile data and can be backed up or shared with other users.
You can manually backup your profiles by copying the profiles/ directory to a safe location.