# How Clubs (Character Classes) Modify Player Abilities in PHPDTS: clubslct.func.php Explained

> Discover how PHPDTS clubs modify player abilities with permanent stat bonuses and unique skills via clubslctfuncphp Explained Optimize your character build now

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

---

**In the PHPDTS game engine, clubs modify player abilities by applying permanent stat bonuses to weapon proficiencies and character attributes, then granting club-specific skills through the `updateskill()` function defined in [`include/game/clubslct.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/clubslct.func.php).**

The `amarillonmc/phpdts` repository implements a character class system where "clubs" serve as the primary mechanism for differentiating player capabilities. When a player selects a club, the system triggers a three-stage process involving deterministic generation, validation, and ability modification that permanently alters combat statistics and unlocks unique skills.

## Understanding the Club System Architecture

### What Are Clubs in PHPDTS?

Clubs represent **character classes** that provide two types of modifications: **permanent stat bonuses** to weapon proficiencies (`$wp`, `$wk`, `$wc`, `$wg`, `$wd`, `$wf`) and base attributes (HP, attack, defense), plus **club-specific skills** that enable unique gameplay mechanics. Each club is identified by a numeric ID ranging from 0 to 19, with specific IDs mapping to distinct combat archetypes like melee fighters (ID 1), ranged specialists (ID 3), or hybrid classes (ID 12).

### The Three-Stage Modification Process

The club ability system operates through three distinct functions in [`include/game/clubslct.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/clubslct.func.php):

1. **`getclub()`** – Generates three candidate club IDs using deterministic pseudo-random calculations
2. **`selectclub($id)`** – Validates the player's choice against allowed lists and triggers ability application
3. **`updateskill()`** – Applies stat bonuses and grants club-specific skills

## Stage 1: Club Determination with getclub()

The `getclub()` function generates three potential clubs for the player to choose from during character entry. It utilizes a deterministic hash function `calc()` that combines game instance parameters to produce consistent, reproducible results based on the specific game session.

```php
$c1 = calc(12347,10007,$curgid,$curuid,$curpid,$starttime,$validtime);
$c1 %= 6; 
if ($c1 == 0) $c1 = 9;  // Maps to club ID 9 (超能称号)

$c2 = calc(10009,7789+$delt,...);  // Generates range 1-5
$c3 = calc(11131,6397,...);        // Lookup in $clubid array

```

The function ensures the three generated IDs are sorted so `$c1 ≤ $c2 ≤ $c3`, presenting players with three distinct class options determined by their entry timing and game parameters.

## Stage 2: Club Selection with selectclub()

Once the player chooses from the three generated options, `selectclub($id)` validates the selection against two allowed lists before applying modifications. This security layer prevents players from selecting restricted or unauthorized clubs.

```php
$t1_list = valid_getclublist_t1($udata);   // Random clubs: 6,10,11,12,13,19
$t2_list = valid_getclublist_t2($udata);   // Fixed clubs: 0,1-5,7-9

if (in_array($id,$t1_list) || in_array($id,$t2_list)) {
    $club = $id;
    updateskill();   // Immediately apply stat bonuses and skills
    return 0;
}

```

Upon successful validation, the function stores the club ID in the global `$club` variable and immediately invokes `updateskill()` to modify player abilities.

## Stage 3: Ability Modification with updateskill()

The `updateskill(&$data = NULL)` function in [`include/game/clubslct.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/clubslct.func.php) performs the actual ability modifications through two distinct mechanisms: direct stat bonuses and skill grants.

### Permanent Stat Bonuses

The function applies immediate, permanent increases to weapon proficiencies and character attributes using a series of conditional checks against the global `$club` variable:

```php
if ($club == 1 || $club == 13) { $wp += 50; }  // 击系: +50 殴熟
if ($club == 2)               { $wk += 50; }  // 斩系: +50 斩熟
if ($club == 3)               { $wc += 50; }  // 射系: +50 射熟
if ($club == 4)               { $wg += 50; }  // 投系: +50 投熟
if ($club == 5)               { $wd += 50; }  // 爆系: +50 爆熟
if ($club == 9)               { $wf += 40; }  // 超能: +40 灵熟
if ($club == 11)              { $money += 680; } // 富豪: +680 money
if ($club == 12) {
    $wp += 25; $wk += 25; $wc += 25; $wg += 25; $wd += 25; $wf += 25;
    $mhp += 250; $hp += 250; $att += 300; $def += 300;
}  // 全能: +25 all weapons, +250 HP, +300 att/def

```

These modifications directly alter the player's combat variables: `$wp` (punch proficiency), `$wk` (slash), `$wc` (shoot), `$wg` (throw), `$wd` (explosive), `$wf` (spirit), plus base stats like `$att` (attack), `$def` (defense), and `$hp`/`$mhp` (current/max health).

### Club-Specific Skills

After applying stat bonuses, the function grants club-specific abilities defined in the `$club_skillslist` array:

```php
if (!empty($club_skillslist[$club])) {
    foreach ($club_skillslist[$club] as $sk) {
        if (get_skilltags($sk,'player') && $type) continue; // NPCs skip player-only skills
        getclubskill($sk,$clbpara);
    }
}

```

The `$club_skillslist` configuration resides in [`gamedata/club21cfg.php`](https://github.com/amarillonmc/phpdts/blob/main/gamedata/club21cfg.php), mapping each club ID to an array of skill IDs. The `getclubskill()` function (defined in [`include/game/revclubskills.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/revclubskills.func.php)) activates these abilities with the appropriate parameters.

## Removing Club Effects with lostclub()

When players change clubs or lose their class status, the `lostclub()` function ensures clean removal of previous abilities to prevent stacking:

```php
function lostclub() {
    global $club, $clbpara, $club_skillslist;
    if (!empty($club_skillslist[$club])) {
        foreach ($club_skillslist[$club] as $sk) {
            lostclubskill($sk,$clbpara);  // Remove each club skill
        }
    }
    $club = 0;  // Reset to no club
}

```

This function iterates through the current club's skill list and calls `lostclubskill()` (from [`include/game/revclubskills.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/revclubskills.func.php)) to deactivate each ability before resetting the `$club` variable to 0.

## Key Files in the Club System

The club modification system spans several files in the `amarillonmc/phpdts` repository:

- **[`include/game/clubslct.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/clubslct.func.php)** – Contains `getclub()`, `selectclub()`, `updateskill()`, and `lostclub()` for core club logic
- **[`include/game/revclubskills.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/revclubskills.func.php)** – Implements `getclubskill()` and `lostclubskill()` for skill management
- **[`gamedata/club21cfg.php`](https://github.com/amarillonmc/phpdts/blob/main/gamedata/club21cfg.php)** – Defines `$club_skillslist` mapping club IDs to skill arrays
- **[`include/game/item.weapon.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/item.weapon.php)** – Uses weapon proficiency variables (`$wp`, `$wk`, etc.) modified by clubs

## Summary

- Clubs modify player abilities through **`updateskill()`** in [`include/game/clubslct.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/clubslct.func.php) by applying permanent stat bonuses and granting club-specific skills
- **Stat bonuses** directly increase weapon proficiencies (`$wp`, `$wk`, `$wc`, `$wg`, `$wd`, `$wf`), base attack/defense, and HP based on the club ID
- **Club-specific skills** are defined in `$club_skillslist` (from [`gamedata/club21cfg.php`](https://github.com/amarillonmc/phpdts/blob/main/gamedata/club21cfg.php)) and granted via `getclubskill()` from [`include/game/revclubskills.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/game/revclubskills.func.php)
- **`getclub()`** generates three candidate clubs using deterministic pseudo-random calculations based on game instance parameters
- **`selectclub()`** validates the player's choice against allowed lists before triggering ability modifications
- **`lostclub()`** removes all club-specific skills when changing classes, preventing bonus stacking

## Frequently Asked Questions

### How does PHPDTS determine which three clubs to offer a player?

The `getclub()` function uses a deterministic pseudo-random hash function called `calc()` that combines game instance parameters including `$curgid`, `$curuid`, `$curpid`, `$starttime`, and `$validtime`. This generates three distinct club IDs that are sorted and presented as `$c1`, `$c2`, and `$c3`, ensuring consistent options for the same game session while maintaining variety across different instances.

### What prevents players from selecting restricted or unauthorized clubs?

The `selectclub($id)` function implements a validation layer that checks the requested club ID against two allowed lists: `valid_getclublist_t1()` for random clubs (IDs 6, 10, 11, 12, 13, 19) and `valid_getclublist_t2()` for fixed clubs (IDs 0, 1-5, 7-9). Only if the ID exists in either list does the function set `$club` and call `updateskill()`, preventing exploitation of restricted classes.

### Can NPCs receive the same club-specific skills as players?

While NPCs can receive club stat bonuses, the `updateskill()` function filters club-specific skills based on the `$type` variable. When processing skills from `$club_skillslist[$club]`, it checks `get_skilltags($sk,'player')` and skips the skill if it is player-only and the target is an NPC. This ensures certain powerful abilities remain exclusive to human players while NPCs still benefit from base stat modifications.

### How does the game handle club changes without stacking bonuses?

The `lostclub()` function ensures clean transitions between classes by iterating through the current club's skill list in `$club_skillslist[$club]` and calling `lostclubskill()` for each active skill. This removes all club-specific abilities before resetting `$club` to 0. When the player selects a new club, `updateskill()` applies fresh bonuses to a clean slate, preventing the accumulation of stats or skills from multiple classes.