-
-
Notifications
You must be signed in to change notification settings - Fork 0
Database
Everything persistent lives in one database: spawners, their stored loot, and (with the internal economy) player balances.
DATABASE:
TYPE: SQLITE # SQLITE | MYSQL | MARIADB| Backend | Good for |
|---|---|
| SQLite (default) | Any single server. No setup, no external process, a single file. |
| MySQL / MariaDB | Sharing data across servers, or an existing central database. |
Changing this requires a full restart. The connection is opened once at start-up.
The JDBC drivers are declared as libraries in plugin.yml and downloaded by the server on
first start, which keeps the plugin jar small. The first start therefore needs internet access;
after that the drivers are cached by the server.
DATABASE:
TYPE: SQLITE
SQLITE:
FILE: spawners.dbThe file is created inside plugins/UltimateVirtualSpawner/. Nothing else to do.
DATABASE:
TYPE: MYSQL
MYSQL:
HOST: localhost
PORT: 3306
DATABASE: ultimatevirtualspawner
USERNAME: uvs
PASSWORD: 'your-password'
USE_SSL: falseCreate the database and user first — the plugin creates tables, not databases:
CREATE DATABASE ultimatevirtualspawner CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'uvs'@'%' IDENTIFIED BY 'your-password';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER ON ultimatevirtualspawner.* TO 'uvs'@'%';
FLUSH PRIVILEGES;The connection string sets useUnicode=true, characterEncoding=UTF-8, autoReconnect=true and
allowPublicKeyRetrieval=true. Set USE_SSL: true for a remote database over an untrusted
network.
MARIADB is accepted as a synonym for MYSQL and uses the same driver.
The plugin refuses to enable:
The database is unavailable, so no spawner data could be read.
Refusing to start: running now would treat every managed spawner
as an ordinary vanilla spawner. Fix the database error logged
above and restart - the stored spawner data itself is untouched.
This is deliberate, and it is the safe behaviour. Starting without data would mean every managed spawner in the world looks unmanaged — players could break them as vanilla spawners, losing their stacks and stored loot permanently. Refusing to start loses nothing.
Fix the connection error logged just above that block and restart.
One row per managed spawner block.
| Column | Type | |
|---|---|---|
id |
auto-increment | Primary key |
world |
varchar(96) | |
x, y, z
|
integer | |
owner_uuid |
varchar(36) | |
owner_name |
varchar(32) | Name snapshot at placement time |
mob_type |
varchar(64) | Type key from spawners.yml
|
stack_amount |
bigint | |
access_mode |
varchar(24) |
OWNER_ONLY / OWNER_AND_TEAM / PUBLIC
|
last_processed_at |
bigint | Epoch millis; drives the catch-up maths |
created_at, updated_at
|
bigint | Epoch millis |
disabled_loot_keys |
text | Filtered-off loot keys |
stored_xp |
double |
Unique on (world, x, y, z) — one managed spawner per block, enforced by the database.
One row per material stored in a spawner.
| Column | Type |
|---|---|
spawner_id |
bigint |
loot_key |
varchar(64) |
material |
varchar(96) |
amount |
bigint |
Primary key (spawner_id, loot_key).
Only used by the internal economy.
| Column | Type |
|---|---|
player_uuid |
varchar(36), primary key |
player_name |
varchar(32) |
balance |
double |
updated_at |
bigint |
Writes go through a dedicated daemon thread, so disk latency or a distant MySQL server never stalls a game tick. Balance writes are additionally serialised per player.
On shutdown, pending work is flushed before the connection closes. Always stop the server
properly (/stop) rather than killing the process — a hard kill can lose the last few seconds
of generation.
Back up the database with the world, on the same schedule. Spawner data is only meaningful alongside the world that contains the blocks.
SQLite — stop the server, then copy the file:
cp plugins/UltimateVirtualSpawner/spawners.db backups/spawners-$(date +%F).dbCopying a live SQLite file can capture a half-written transaction. Stop the server, or use
sqlite3 spawners.db ".backup 'backup.db'" which is safe while running.
MySQL
mysqldump -u uvs -p ultimatevirtualspawner > uvs-$(date +%F).sqlThere is no built-in migration command. Move the three tables manually:
- Stop the server.
- Export from SQLite:
sqlite3 plugins/UltimateVirtualSpawner/spawners.db .dump > dump.sql - Adjust the dump for MySQL — the main edits are
AUTOINCREMENTtoAUTO_INCREMENT, and dropping the SQLite-specific pragma and transaction lines. - Create the MySQL database and let the plugin start once against it, so the tables are created
with the right types. Then import only the
INSERTstatements. - Set
DATABASE.TYPE: MYSQLwith your credentials, and restart. - Verify with
/spawner version— the managed spawner count should match what it was before.
Keep the old spawners.db until you have confirmed the move.
If the world is rolled back but the database is not — or vice versa — the plugin reconciles what it can:
-
Block exists, no database row: the block still carries its own persistent data (type, stack,
owner, access mode), so the plugin recreates the row and logs
Restored a stray … spawner … from its block data; its stored loot could not be recovered.Stack and ownership come back; stored loot does not, because it only ever lived in the database. -
Database row, no block: the row stays but generates nothing, since generation checks that
the block is still a spawner. Clean it up by placing a spawner there and using
/spawner remove, or by deleting the row directly.
Backing up the world and the database together avoids both cases.
Useful queries when investigating:
-- biggest spawners
SELECT owner_name, mob_type, stack_amount, world, x, y, z
FROM uvs_spawners ORDER BY stack_amount DESC LIMIT 20;
-- spawners per player
SELECT owner_name, COUNT(*) AS blocks, SUM(stack_amount) AS spawners
FROM uvs_spawners GROUP BY owner_name ORDER BY spawners DESC;
-- most stored loot
SELECT s.owner_name, l.material, l.amount
FROM uvs_spawner_loot l JOIN uvs_spawners s ON s.id = l.spawner_id
ORDER BY l.amount DESC LIMIT 20;
-- richest players
SELECT player_name, balance FROM uvs_balances ORDER BY balance DESC LIMIT 20;Edit rows only while the server is stopped. The plugin holds spawner state in memory and writes it back, so live edits will be overwritten.
-
config.yml — the
DATABASEreference -
Economy — what lives in
uvs_balances - Troubleshooting
Repository · Releases · Issues · Discord · MIT License
Getting started
Reference
Configuration
Features
Operations
Development