> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rpg-leveling.zuxaw.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Database Sync

> External database synchronization - sync player level, XP, and stats to MySQL, MariaDB, PostgreSQL, or H2.

# Database Sync

Sync player data (level, XP, stat allocations) to an external database for analytics, web dashboards, or external tools.

<Info>
  **One-way sync only.** Data flows **from the game to the database**. Hytale storage is the source of truth. Changes made directly in the database **do not** affect players in-game. This may evolve in future versions.
</Info>

## How It Works

1. **Hytale storage** - Player data (level, XP, stats) is stored by Hytale in JSON files under `universe/players/`. This is always the authoritative source.
2. **Database mirror** - When enabled, the plugin copies this data to an external database table whenever it changes.
3. **When sync runs:**
   * **On startup** - All players from disk are synced to the DB (table is created if it does not exist).
   * **On change** - Whenever a player levels up, gains XP, allocates stats, or has stats reset, their data is synced asynchronously.

## Configuration File

`DatabaseConfig.json` is in `mods/Zuxaw_RPGLeveling/` (next to other config files).

### All Parameters

| Parameter       | Type    | Default          | Description                                                                               |
| --------------- | ------- | ---------------- | ----------------------------------------------------------------------------------------- |
| **Version**     | string  | (plugin version) | Auto-written by the plugin. Used for config compatibility.                                |
| **Enabled**     | boolean | `false`          | When `true`, database sync is active. When `false`, no DB connection is made.             |
| **JdbcUrl**     | string  | H2 file URL      | Full JDBC connection URL. See [Connection URLs](#connection-urls) below.                  |
| **Username**    | string  | `""`             | Database username. Empty for H2 file mode.                                                |
| **Password**    | string  | `""`             | Database password.                                                                        |
| **MaxPoolSize** | integer | `10`             | HikariCP connection pool size (1–…). Higher values allow more concurrent sync operations. |

### Example Configuration

**MariaDB / MySQL:**

```json theme={null}
{
  "Version": "0.2.0",
  "Enabled": true,
  "JdbcUrl": "jdbc:mariadb://localhost:3306/rpgleveling",
  "Username": "rpguser",
  "Password": "rpgpass",
  "MaxPoolSize": 10
}
```

**PostgreSQL:**

```json theme={null}
{
  "Version": "0.2.0",
  "Enabled": true,
  "JdbcUrl": "jdbc:postgresql://localhost:5432/rpgleveling",
  "Username": "rpguser",
  "Password": "rpgpass",
  "MaxPoolSize": 10
}
```

**H2 (no external DB):**

```json theme={null}
{
  "Version": "0.2.0",
  "Enabled": true,
  "JdbcUrl": "jdbc:h2:file:./mods/Zuxaw_RPGLeveling/data/sync;MODE=MySQL",
  "Username": "",
  "Password": "",
  "MaxPoolSize": 5
}
```

## Connection URLs

| Database       | JDBC URL format                          |
| -------------- | ---------------------------------------- |
| **MariaDB**    | `jdbc:mariadb://host:port/database`      |
| **MySQL**      | `jdbc:mysql://host:port/database`        |
| **PostgreSQL** | `jdbc:postgresql://host:port/database`   |
| **H2 (file)**  | `jdbc:h2:file:./path/to/file;MODE=MySQL` |

* Replace `host`, `port`, and `database` with your values.
* H2 file mode stores data locally; no external server is needed. Username and Password are usually empty.
* All table names use the `RPGLeveling_` prefix for consistency with the plugin.

## Table Schema

The plugin creates `RPGLeveling_players` automatically when it connects (if it does not exist).

| Column                  | Type        | Description                                                   |
| ----------------------- | ----------- | ------------------------------------------------------------- |
| `uuid`                  | VARCHAR(36) | Player UUID (primary key)                                     |
| `username`              | VARCHAR(64) | Display name                                                  |
| `level`                 | INT         | Current level                                                 |
| `experience`            | DOUBLE      | Current XP                                                    |
| `available_stat_points` | INT         | Unallocated stat points                                       |
| `allocated_stats`       | TEXT        | JSON map of stat allocations, e.g. `{"Damage":5,"Defense":3}` |
| `last_updated`          | BIGINT      | Last sync timestamp (milliseconds since epoch)                |

## Example Queries

Get data for one player (by UUID or username):

```sql theme={null}
SELECT * FROM RPGLeveling_players WHERE uuid = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
```

```sql theme={null}
SELECT uuid, username, level, experience, available_stat_points, allocated_stats
FROM RPGLeveling_players WHERE username = 'PlayerName';
```

## Important Notes

* **Sync is one-way.** Edits in the database (e.g. via SQL) are **not** applied to players in-game.
* **Hytale storage wins.** If there is any conflict, the in-game data is authoritative.
* **Performance** - Sync runs asynchronously; it does not block gameplay.
* **Failure handling** - If the DB is unreachable, sync fails quietly and is logged. The game continues normally.
