# Features of the Save System in the Undertale Changer Template

> Explore the Undertale Changer Template's robust save system featuring JSON serialization, automatic persistence, sequential slot management, and an in-game UI for seamless game saving.

- Repository: [Archived AIk/undertale-changer-template](https://github.com/arch-aik/undertale-changer-template)
- Tags: how-to-guide
- Published: 2026-02-25

---

**TLDR:** The Undertale Changer Template provides a complete slot-based save system with JSON serialization, automatic fact-table persistence, sequential slot management, and an integrated in-game UI with pause functionality.

The Undertale Changer Template ships with a production-ready save architecture designed for Unity-based Undertale-style games. According to the source code in `arch-aik/undertale-changer-template`, the system handles player data persistence, narrative state tracking, and user preferences through a centralized JSON-based workflow. Understanding these features allows developers to customize save behaviors without rebuilding core infrastructure.

## JSON-Based Player Data Persistence

At the core of the Undertale Changer Template save system is the `SaveController.SaveData` method in [`Assets/Scripts/UCT/Core/SaveController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Core/SaveController.cs). This method serializes the `PlayerControl` ScriptableObject to JSON using Newtonsoft.Json and writes it to `Application.dataPath/Data/*.json`.

The implementation automatically creates the `Data` folder if missing and generates files following the `Data{n}.json` naming convention. This ensures that player progress, inventory, and positional data persist between sessions using human-readable JSON files rather than binary formats.

## Automatic Fact-Table Serialization

Beyond player stats, the system preserves narrative state through `FactTable` assets. The `SaveFactTablesToJson` method scans the `Resources/Tables` directory and serializes all table assets to a companion file named `<saveName>Table.json`.

This feature stores the path-to-fact mapping alongside player data, ensuring that story flags, dialogue states, and progression markers synchronize with the specific save slot. When loading, `LoadFactTablesFromJson` reconstructs these tables to restore the exact narrative context.

## Sequential Slot Management and Auto-Renaming

The template enforces clean slot organization through the `SortAndRenameData` method. When players delete saves or create new ones, the system automatically reorders files to eliminate gaps, ensuring sequential naming from [`Data0.json`](https://github.com/arch-aik/undertale-changer-template/blob/main/Data0.json) upward.

This `SortAndRenameData` implementation (lines 92-134) handles both player data files and their corresponding table companions simultaneously. The `GetDataNumber` method provides a quick count of existing slots by scanning for `Data*.json` patterns, enabling dynamic UI generation for save/load screens.

## Loading, Deletion, and Data Recovery

Loading operations deserialize JSON back into fresh `PlayerControl` instances via `SaveController.LoadData`. This method reads the specified slot file, populates a new ScriptableObject, caches it for performance, and triggers fact-table restoration.

For deletion, `DeleteData` removes the specified slot file and its cached entry before invoking the renaming pass to close sequence gaps. This ensures that the slot inventory remains compact and predictable after save removal operations.

## In-Game Save UI and Pause Integration

The `SaveBoxController` class in [`Assets/Scripts/UCT/Overworld/SaveBoxController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Overworld/SaveBoxController.cs) provides the visual interface and input handling layer. When activated via `OpenSaveBox`, the system pauses the game by disabling player movement and setting a global pause flag through `SetGamePaused`.

Input handling supports left/right arrow keys to toggle between *Confirm* and *Cancel* options, while **Z** confirms selections and **X** cancels. The `HandleSelectionInput`, `HandleConfirmationInput`, and `HandleCancellationInput` methods manage these interactions, providing immediate visual feedback through the UI elements.

## PlayerPrefs Integration for Settings

The save system extends beyond game state to include user preferences. The `SaveService.SavePlayerPreferences` method persists language settings, resolution, last used slot, SFX, and V-Sync configurations to `PlayerPrefs`. This ensures that display and audio preferences persist independently of individual save slots, maintaining consistency across playthroughs.

## How to Use the Save System

Developers interact with the Undertale Changer Template save system through straightforward API calls that wrap the underlying complexity.

### Saving the Game

To trigger a complete save operation including player data, scene information, and preferences:

```csharp
// Centralized save call that handles all persistence layers
SaveService.SaveGame();

```

This method, located in [`SaveBoxController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/SaveBoxController.cs), coordinates `SaveController.SaveData`, scene metadata capture, and preference persistence in a single atomic operation.

### Loading a Specific Slot

To load existing save data programmatically:

```csharp
// Load slot 2 (corresponds to Data2.json)
PlayerControl loadedPlayer = SaveController.LoadData("Data2");
if (loadedPlayer != null)
{
    // Apply loaded data to current game state
}

```

The `LoadData` method returns a populated `PlayerControl` instance ready for injection into the active game scene.

### Deleting Save Data

To remove a specific slot and maintain sequential ordering:

```csharp
// Delete slot 3 and auto-rename remaining files
SaveController.DeleteData("Data3");

```

This operation removes both the player data file and its associated fact-table companion before triggering the automatic renaming pass.

### Querying Available Slots

To determine how many save slots exist for UI generation:

```csharp
int slotCount = SaveController.GetDataNumber();
// Returns 4 if Data0.json through Data3.json exist

```

This scan-based approach allows dynamic save menu construction that reflects the current `Data` folder contents.

## Summary

- The Undertale Changer Template provides **JSON-based serialization** for `PlayerControl` data via `SaveController.SaveData` in [`Assets/Scripts/UCT/Core/SaveController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Core/SaveController.cs).
- **Fact-table persistence** automatically synchronizes narrative state files alongside player saves using companion JSON files.
- **Auto-renaming logic** maintains sequential slot ordering without gaps through `SortAndRenameData`, called automatically during save and delete operations.
- The **in-game UI layer** in [`SaveBoxController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/SaveBoxController.cs) handles input routing, game pausing, and visual feedback with dedicated methods for confirmation and cancellation.
- **Player preferences** persist separately via `PlayerPrefs` through the `SaveService` integration, storing settings like language and resolution independently of game saves.

## Frequently Asked Questions

### How does the Undertale Changer Template handle save file organization?

The template maintains sequential slot naming ([`Data0.json`](https://github.com/arch-aik/undertale-changer-template/blob/main/Data0.json), [`Data1.json`](https://github.com/arch-aik/undertale-changer-template/blob/main/Data1.json), etc.) through the `SortAndRenameData` method. When saves are deleted, the system automatically renames remaining files to eliminate gaps, ensuring that `GetDataNumber` always returns a continuous count. Player data and fact-table companions are renamed in tandem to maintain data integrity.

### What data is included when saving in the Undertale Changer Template?

Each save captures the complete `PlayerControl` object (position, inventory, stats) as JSON, plus all `FactTable` assets from `Resources/Tables`. Additionally, `SaveService.SavePlayerPreferences` stores language, resolution, audio, and V-Sync settings to `PlayerPrefs`. Scene metadata including current level and player position is also recorded.

### Can I modify the save UI behavior in the Undertale Changer Template?

Yes. The `SaveBoxController` class in [`Assets/Scripts/UCT/Overworld/SaveBoxController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Overworld/SaveBoxController.cs) exposes methods like `OpenSaveBox`, `SetGamePaused`, and `UpdateAfterSaveUI` for customization. Input handling logic resides in `HandleSelectionInput` and related methods, allowing developers to remap keys or change the confirmation flow. The UI prefab elements (`saveHeart`, `saveText`) can be configured via the `BackpackBehaviour` prefab reference.

### Where are save files stored in the Undertale Changer Template?

Save files are written to `Application.dataPath/Data/` as individual JSON files following the `Data{n}.json` pattern, with companion files `Data{n}Table.json` for fact tables. This places saves in the application's data directory, which varies by platform but ensures accessibility for debugging and backup purposes.