# How the PHPDTS Bot Daemon Process Interacts with Game Logic

> Discover how the PHPDTS bot daemon interacts with game logic by polling game state files and executing AI actions via shared core libraries. Learn more about bot_enable.sh.

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

---

**The PHPDTS bot daemon operates as a persistent PHP CLI process that continuously polls shared game state files, executing AI actions through the same core libraries ([`common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/common.inc.php), [`game.func.php`](https://github.com/amarillonmc/phpdts/blob/main/game.func.php)) used by the web frontend.**

The `amarillonmc/phpdts` repository implements a real-time browser game where AI players require background processing to simulate human opponents. Understanding how this bot daemon process interacts with game logic reveals a tightly coupled architecture where the background service functions as a headless PHP client that directly reads and writes the same state files and data structures utilized by the web interface.

## Entry Point and Daemon Boot Sequence

### The bot_enable.sh Wrapper

The daemon lifecycle begins in **[`bot/bot_enable.sh`](https://github.com/amarillonmc/phpdts/blob/main/bot/bot_enable.sh)**, a minimal Bash wrapper responsible for setting the correct working directory and launching the PHP service. This script ensures the daemon runs from the project root, allowing relative path resolution for all subsequent includes.

```bash

# bot/bot_enable.sh

cd ..                 # move to the game's root directory

php bot/revbotservice.php   # start the daemon

```

When executed, this script backgrounds the PHP process and returns control to the shell, enabling the daemon to persist independently of the terminal session.

### Core Environment Initialization

Upon launch, **[`bot/revbotservice.php`](https://github.com/amarillonmc/phpdts/blob/main/bot/revbotservice.php)** bootstraps the exact same environment as the web frontend by requiring the core initialization files. This shared bootstrap ensures the daemon accesses identical global variables (`$gamestate`, `$gamevars`, `$db`) and configuration constants.

```php
require_once $gameRoot.'include/common.inc.php';
require_once GAME_ROOT.'./include/game.func.php';
require_once GAME_ROOT.'./bot/revbot.func.php';

```

By loading **[`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php)** and **[`include/game.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game.func.php)**, the daemon gains access to critical state management functions including `load_gameinfo()`, `save_gameinfo()`, and `save_combatinfo()`, ensuring perfect synchronization with the game's state machine.

## State Synchronization and Lock Mechanisms

### Loading Shared Game State

The daemon enters a perpetual loop that begins by refreshing its view of the game world. Each iteration calls **`load_gameinfo()`** to reload `$gamestate`, `$gamevars`, and current player data from disk. This polling mechanism guarantees the daemon always operates on the latest game state, preventing desynchronization with web-based player actions.

```php
load_gameinfo();

```

### Process Locking for Thread Safety

To prevent race conditions during bot initialization, the daemon implements a file-based locking system in the **`bot/lock/`** directory. Before performing any initialization steps, it creates a process-specific lock file, ensuring only one daemon instance handles bot spawning at any given time.

```php
// Creates lock file in bot/lock/1.lock
$lock_file = fopen('bot/lock/'.$process_id.'.lock', 'w');

```

When the game stops or restarts, the daemon detects the state change and jumps back to the preparation stage (`goto bot_prepare_flag`), recreating its lock file to re-establish safe synchronization with the game's own locking mechanisms.

## Bot Lifecycle Management

### Initialization Protocol

The daemon continuously monitors the `$gamestate` variable, waiting for the game to enter an active state (`$gamestate > 10`). When active, it checks `$gamevars['botplayer']` to determine if pending bot slots require filling.

```php
if($gamestate > 10 && $gamevars['botplayer'] > 0) {
    $id = bot_player_valid(1);
    $gamevars['botid'][] = $id;
    $gamevars['botplayer']--;
    save_gameinfo();
}

```

The function **`bot_player_valid(1)`**, defined in **[`bot/revbot.func.php`](https://github.com/amarillonmc/phpdts/blob/main/bot/revbot.func.php)**, selects and validates an available player ID. The daemon then registers this ID in `$gamevars['botid']` and decrements the pending counter, immediately persisting changes via `save_gameinfo()`.

### Action Execution and Respawn Logic

Once initialized, the daemon triggers bot behavior through **`bot_acts($id)`**, which processes AI decisions for the specified player. After each action, the daemon evaluates the bot's survival status via the `$flag` return value.

If a bot dies (`$flag == 0`), the daemon applies the configurable **`$bot_respawn_chance`** to determine if the player should queue for reincarnation:

```php
if ($flag == 0) {
    $roll = mt_rand(1,100);
    if($bot_respawn_chance > 0 && $roll <= $bot_respawn_chance) {
        $gamevars['botplayer'] = ($gamevars['botplayer'] ?? 0) + 1;
        echo "BOT：{$id} 已死亡；已加入重生队列。roll={$roll}, chance={$bot_respawn_chance}\n";
    }
    save_gameinfo();
    save_combatinfo();
}

```

This respawn mechanism ensures continuous AI population while respecting probability-based configuration. The daemon persists both general game state and combat information before continuing to the next iteration or exiting.

## Key Interaction Points Between Daemon and Game Logic

The tight coupling between the background process and game engine manifests through several critical integration points:

- **[`include/common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/include/common.inc.php)**: Provides the foundational `$db` connection and global variables (`$now`, `$gamestate`) required for all game operations.
- **[`include/game.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game.func.php)**: Supplies state persistence functions (`load_gameinfo()`, `save_gameinfo()`) that synchronize daemon actions with the web frontend.
- **[`bot/revbot.func.php`](https://github.com/amarillonmc/phpdts/blob/main/bot/revbot.func.php)**: Contains AI-specific logic including `bot_player_valid()` for ID selection and `bot_acts()` for behavior execution.
- **`$gamevars` array**: Acts as the shared memory structure tracking active bot IDs (`$gamevars['botid']`) and pending initialization counts (`$gamevars['botplayer']`).
- **`bot/lock/` directory**: Implements mutual exclusion that coordinates daemon initialization with the game's internal state transitions.

## Summary

- The **bot daemon** is launched via [`bot/bot_enable.sh`](https://github.com/amarillonmc/phpdts/blob/main/bot/bot_enable.sh), which executes [`bot/revbotservice.php`](https://github.com/amarillonmc/phpdts/blob/main/bot/revbotservice.php) as a background PHP CLI process.
- It initializes using the same core files as the web frontend ([`common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/common.inc.php), [`game.func.php`](https://github.com/amarillonmc/phpdts/blob/main/game.func.php)), ensuring access to identical game state and functions.
- **File-based locks** in `bot/lock/` prevent race conditions during bot initialization when multiple processes might compete for resources.
- The daemon **polls game state** continuously via `load_gameinfo()`, executing bot actions only when `$gamestate > 10` indicates an active game.
- **Bot respawn logic** uses `$bot_respawn_chance` to probabilistically requeue deceased AI players, maintaining consistent opponent populations.
- All state modifications are persisted immediately through `save_gameinfo()` and `save_combatinfo()`, keeping the daemon's changes visible to the web interface in real-time.

## Frequently Asked Questions

### How does bot_enable.sh start the daemon process?

The [`bot_enable.sh`](https://github.com/amarillonmc/phpdts/blob/main/bot_enable.sh) script performs two essential actions: it changes the working directory to the project root (`cd ..`) and then invokes the PHP interpreter to run [`bot/revbotservice.php`](https://github.com/amarillonmc/phpdts/blob/main/bot/revbotservice.php). This ensures all relative includes resolve correctly and the daemon starts with the proper environment context. The script is typically executed with `&` to background the process, allowing it to run independently of the user's terminal session.

### What prevents multiple daemon instances from corrupting game state?

The daemon implements a **process-lock file mechanism** within the `bot/lock/` directory. Before initializing bots, it creates a unique lock file (e.g., `1.lock`) that signals other potential instances to wait. Additionally, the daemon checks `$gamestate` to ensure it only acts during appropriate game phases, and it uses atomic file operations through `save_gameinfo()` to persist changes, minimizing collision risks with the web frontend.

### How does the daemon know when to spawn or respawn bots?

The daemon monitors two key variables loaded via `load_gameinfo()`: `$gamestate` and `$gamevars['botplayer']`. When `$gamestate > 10` (indicating an active game) and `$gamevars['botplayer']` contains a positive value, the daemon calls `bot_player_valid(1)` to claim a player ID and decrement the counter. For respawns, after a bot dies (`$flag == 0`), it performs a random roll against `$bot_respawn_chance`; if successful, it increments `$gamevars['botplayer']`, effectively requeuing the slot for immediate reinitialization.

### Why does the daemon use the same PHP includes as the web frontend?

By requiring [`common.inc.php`](https://github.com/amarillonmc/phpdts/blob/main/common.inc.php) and [`game.func.php`](https://github.com/amarillonmc/phpdts/blob/main/game.func.php), the daemon ensures it operates on the **exact same data structures and business logic** as the browser-based interface. This architectural choice eliminates API translation layers and allows the bot system to directly manipulate `$gamevars`, `$gamestate`, and database connections (`$db`) using proven, battle-tested functions like `save_gameinfo()`, guaranteeing consistency between AI actions and player actions.