# Functional Difference Between $tablepre and $gtablepre Database Prefixes in PHPDTS

> Understand $tablepre vs $gtablepre database prefixes in PHPDTS. Discover how they enable concurrent game instances with isolated gameplay and global user data for amarillonmc/phpdts.

- Repository: [Nemo Ma/phpdts](https://github.com/amarillonmc/phpdts)
- Tags: deep-dive
- Published: 2026-02-24

---

**$tablepre isolates per-room gameplay tables while $gtablepre identifies global tables shared across all rooms, enabling the amarillonmc/phpdts system to run concurrent game instances while maintaining centralized user accounts and rankings.**

The amarillonmc/phpdts codebase uses two distinct database prefix variables to separate transient room data from persistent global data. Understanding the functional difference between `$tablepre` and `$gtablepre` is essential for writing correct SQL queries, configuring multi-room deployments, and maintaining data integrity across isolated game sessions.

## What Are $tablepre and $gtablepre?

### $tablepre (Room-Specific Isolation)

`$tablepre` is the variable that prefixes tables containing data specific to a single game room. According to the source code in [`config.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/config.inc.php) at line 58, the base prefix is defined as `$tablepre = 'acbra3_';`, though this value is often customized during installation.

This variable prefixes gameplay tables that must remain isolated between concurrent rooms, including:

- **players** – Character state and inventory for current room
- **mapitem** – Items dropped on the current map
- **chat** – Room-specific chat messages
- **gambling** – Betting data for the current instance
- **shopitem** – Shop inventory for the current room

In [`install.php`](https://github.com/amarillonmc/phpdts/blob/main/install.php) at line 243, the system dynamically adjusts `$tablepre` by concatenating it with the room identifier: `$tablepre = $tablepre.'s'.$groomid.'_';`. This creates unique namespaces like `acbra3_s2_` for room 2, ensuring that multiple simultaneous battles do not interfere with each other.

### $gtablepre (Global Shared Data)

`$gtablepre` is the variable that prefixes tables shared across all game rooms. Initialized in [`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php) at line 45 as `$gtablepre = $master_tablepre;`, this variable references tables that require global consistency, such as:

- **users** – Player accounts and credentials
- **game** – Global game configuration and state
- **winners** – Hall of fame and victory records
- **messages** – Cross-room mail and notifications

When no master database is configured, the system falls back to `$gtablepre = $tablepre;`, allowing single-instance deployments to function without separate database connections.

## Source Code Implementation

### Configuration Logic

The prefix separation begins in [`config.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/config.inc.php), where administrators set the base `$tablepre` value. The global prefix resolution occurs immediately afterward in [`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php) at line 45, where the code checks for master database configuration:

```php
// From include/common.inc.php line 45
$gtablepre = $master_tablepre;
// If no master DB configured, falls back to:
// $gtablepre = $tablepre;

```

This conditional assignment enables master-slave database architectures, where room-specific tables reside on local database instances while global user data lives on a central master server.

### Dynamic Prefix Construction

When creating or entering a specific room, [`install.php`](https://github.com/amarillonmc/phpdts/blob/main/install.php) modifies `$tablepre` to include the room ID. This runtime modification ensures that queries automatically target the correct isolated table set without requiring manual table name construction in every query.

## Query Examples in Practice

### Room-Specific Player Lookup

To fetch a player character within the current room context, the code uses `$tablepre` as shown in [`include/state.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/state.func.php) at line 73:

```php
// Uses $tablepre → room-specific players table
$result = $db->query(
    "SELECT * FROM {$tablepre}players WHERE name='$cuser' AND type=0"
);

```

This query targets only the players table for the specific room instance, preventing cross-room data leakage.

### Global User Account Update

When updating persistent account information visible across all rooms, the system uses `$gtablepre` as demonstrated in [`include/state.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/state.func.php) at line 941:

```php
// Uses $gtablepre → shared users table
$db->query(
    "UPDATE {$gtablepre}users SET lastgame='$gamenum' WHERE username='$name'"
);

```

This ensures that user metadata remains synchronized regardless of which room the player currently occupies.

### Room Map Item Creation

Inserting items into the current room's map uses the room-specific prefix, as seen in [`include/system.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/system.func.php) at line 258:

```php
$db->query(
    "INSERT INTO {$tablepre}mapitem (itm,itmk,itme,itms,itmsk,pls) 
     VALUES ('$itm','$itmk','$itme','$itms','$itmsk',$pls)"
);

```

### Global Ranking Query

Fetching the server-wide ranking list requires the global prefix, shown in [`rank.php`](https://github.com/amarillonmc/phpdts/blob/main/rank.php) at line 44:

```php
$result = $db->query(
    "SELECT * FROM {$gtablepre}users 
     WHERE validgames>0 ORDER BY credits DESC, credits2 DESC LIMIT $ranklimit"
);

```

## Architectural Rationale

The dual-prefix system serves three critical architectural functions:

- **Room Isolation** – By appending room IDs to `$tablepre`, each game instance operates in a separate table namespace. This allows multiple concurrent battles with identical table schemas without data collision.
- **Global Consistency** – Player accounts, rankings, and cross-room messaging rely on `$gtablepre` to ensure that authentication and persistent progress remain unified across the entire server.
- **Master-Slave Support** – The ability to set `$gtablepre` to `$master_tablepre` while keeping `$tablepre` local enables horizontal scaling, where room data distributes across multiple database servers while user data centralizes on a master node.

## Summary

- **`$tablepre`** prefixes tables containing transient room data (players, items, chat) and dynamically includes the room ID to isolate concurrent game instances.
- **`$gtablepre`** prefixes persistent global tables (users, winners, messages) shared across all rooms, falling back to `$tablepre` when no master database exists.
- **Configuration** occurs in [`config.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/config.inc.php) (line 58) and [`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php) (line 45), enabling both single-server and distributed master-slave architectures.
- **Query selection** depends on data scope: use `$tablepre` for room-state operations and `$gtablepre` for account and cross-room operations.

## Frequently Asked Questions

### Can $tablepre and $gtablepre point to physically different databases?

Yes. When configured for master-slave operation in [`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php), `$gtablepre` uses `$master_tablepre` while `$tablepre` remains local. This allows the global users table to reside on a central authentication database while room-specific tables distribute across game server nodes.

### What happens to existing room data if I change the base $tablepre?

Changing `$tablepre` in [`config.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/config.inc.php) affects only new room creation and queries. Existing rooms with dynamically constructed prefixes (like `acbra3_s2_`) retain their original table names. Administrators must manually migrate or drop old room tables when modifying base prefixes to avoid orphaned data.

### Which tables must use $gtablepre instead of $tablepre?

Always use `$gtablepre` for the **users**, **winners**, **messages**, and **game** tables. These contain account credentials, cross-room statistics, mail systems, and global configuration that must persist across room resets. Using `$tablepre` for these tables would fragment user accounts and break authentication when players switch rooms.

### How does the system handle $gtablepre when no master database is configured?

When `$master_tablepre` is undefined or empty, [`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php) falls back to `$gtablepre = $tablepre;`. In this configuration, both prefixes reference the same tables, effectively running in single-database mode where global and room data coexist in the same namespace without functional separation.