Player Killing (PK) with open-source tools
Implementing a Player Killing (PK) system requires balancing technical enforcement with gameplay fairness. This guide focuses on the architecture of PK flags, level-restricted engagement, and state-driven anti-griefing measures for a production MUD environment.

Define PK Status and Persistent Flags
Add a bitmask or boolean to the player structure to track PK participation. This must be saved to the player file (pfile) to prevent players from toggling status to avoid consequences.
#define PLR_PK (1 << 10)
void do_pk_toggle(CHAR_DATA *ch, char *argument) {
if (IS_SET(ch->act, PLR_PK)) {
send_to_char("You are already a PKer.\n\r", ch);
return;
}
SET_BIT(ch->act, PLR_PK);
save_char_obj(ch);
send_to_char("You are now flagged for PK.\n\r", ch);
}⚠ Common Pitfalls
- •Allowing players to toggle PK status while in combat
- •Failing to save the flag, allowing a logout/login to reset status
Implement Level-Range Engagement Logic
To prevent 'newbie-slaying,' modify the combat initiation function to check the level difference between the attacker and the target. A common standard is +/- 5 to 10 levels.
bool can_attack(CHAR_DATA *ch, CHAR_DATA *victim) {
if (!IS_SET(ch->act, PLR_PK) || !IS_SET(victim->act, PLR_PK)) return FALSE;
if (abs(ch->level - victim->level) > 10) {
send_to_char("Level difference is too great.\n\r", ch);
return FALSE;
}
return TRUE;
}⚠ Common Pitfalls
- •Hard-coding level limits which may need tuning as the player base scales
- •Ignoring group/party combat where a high-level player might 'tank' for a low-level PKer
Enforce Room-Based PK Restrictions
Integrate room flags into the attack check. Define ROOM_SAFE for towns/newbie areas and ROOM_BATTLEFIELD for areas where level-range checks are ignored.
if (IS_SET(ch->in_room->room_flags, ROOM_SAFE)) {
send_to_char("A mystical force prevents your violence here.\n\r", ch);
return FALSE;
}
if (IS_SET(ch->in_room->room_flags, ROOM_CHAOTIC)) {
return TRUE; // Ignore level checks in chaotic zones
}⚠ Common Pitfalls
- •Players 'border hopping' between safe and PK rooms to avoid death (ping-ponging)
- •Forgetting to flag critical quest rooms as safe
Develop the Combat Timer (Anti-Quit)
Apply a 'combat pulse' or timer to players. While active, the player cannot logout, use 'recall' spells, or enter ROOM_SAFE areas. This ensures players must survive the encounter or flee.
void update_combat_timer(CHAR_DATA *ch) {
ch->pcdata->pk_timer = 120; // 2 minutes of real time
}
// In do_quit command
if (ch->pcdata->pk_timer > 0) {
send_to_char("You are too agitated to quit!\n\r", ch);
return;
}⚠ Common Pitfalls
- •Timers being too short, allowing players to quit during a chase
- •Not refreshing the timer when a player is hit, only when they attack
Handle PK Death and Corpse Mechanics
Modify the death function to differentiate between Mob-Death and PK-Death. Implement specific loot rules, such as allowing the killer to take a limited number of items or a percentage of gold.
void handle_pk_death(CHAR_DATA *victim, CHAR_DATA *killer) {
OBJ_DATA *corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE), 0);
corpse->owner = str_dup(victim->name);
corpse->killer = str_dup(killer->name);
// Logic to move inventory to corpse
log_printf("PK: %s killed by %s at room %d", victim->name, killer->name, victim->in_room->vnum);
}⚠ Common Pitfalls
- •Item duplication bugs during inventory transfer
- •Allowing killers to loot 'No-Drop' or quest-essential items
Implement PK Logging and Auditing
Automate the logging of every PK kill to a dedicated file or database. Include timestamps, levels, and room VNUMs. This is essential for resolving griefing disputes and balancing classes.
⚠ Common Pitfalls
- •Incomplete logs that don't show who initiated the fight
- •Log files growing excessively large without rotation
What you built
A robust PK system is defined by its edge-case handling—specifically combat timers and room transitions. Once the core engagement logic is stable, focus on community-facing features like PK ladders or bounty systems to incentivize healthy competition.