8.1 KiB
8.1 KiB
Pre-Commit Test Checklist
Run through these checks before every commit to ensure consistent feature coverage.
Build
cargo buildsucceeds with no errorscargo build --bin mudtoolsucceeds
Server Startup
- Server starts:
RUST_LOG=info ./target/debug/mudserver - World loads all rooms, NPCs, objects, races, classes (check log output)
- Database opens (or creates) successfully
- Tick engine starts and logs tick rate
Character Creation
- New player SSH → gets chargen flow (race + class selection)
- Chargen accepts both number and name input
- After chargen, player appears in spawn room with correct stats
- Player saved to DB after creation
Player Persistence
- Reconnecting player skips chargen, sees "Welcome back!"
- Room, stats, inventory, equipment all restored from DB
- Status effects persist across logout/login (stored in DB)
- Status effects continue ticking while player is offline
- On reconnect, expired effects are gone; active effects resume
- Verify with:
sqlite3 mudserver.db "SELECT * FROM players;"
Movement & Navigation
go north,n,south,s, etc. all work- Invalid direction shows error
- Room view shows: NPCs (colored by attitude), objects, exits, other players
- Cannot move while in combat (combat lockout)
NPC Interaction
examine <npc>shows description, stats, attitude labeltalk <friendly>shows greeting dialoguetalk <hostile>shows snarl message- Dead NPCs don't appear in room view
Combat - Tick-Based
attack <aggressive/hostile npc>enters combat state- Can't attack friendly/neutral NPCs
- Combat rounds resolve automatically on server ticks (not on command)
- Player receives tick-by-tick combat output (damage dealt, damage taken)
- Default combat action is "attack" if no other action queued
defend/defsets defensive stance (reduced incoming damage next tick)- NPC death: awards XP, shifts attitude -10, shifts faction -5
- Player death: respawns at spawn room with full HP, combat cleared
- NPCs respawn after configured time
- Combat lockout: can only attack/defend/flee/look/use/quit during combat
fleequeues escape attempt — may fail based on statsuse <item>in combat queues item use for next tick- Multiple ticks of combat resolve correctly without player input
- Combat ends when NPC dies (player exits combat state)
- Combat ends when player flees successfully
Combat - NPC AI
- Hostile NPCs auto-engage players who enter their room
- Aggressive NPCs do NOT auto-engage (only attackable, not initiating)
- NPC attacks resolve on tick alongside player attacks
- NPCs in combat continue attacking even if player sends no commands
Combat - RNG
- Damage varies between hits (not identical each time)
- Multiple rapid attacks produce different damage values
Items
take <item>picks up takeable objectsdrop <item>places item in roomequip <weapon/armor>works, old gear returns to inventoryuse <consumable>heals and removes item (immediate out of combat)use <consumable>in combat queues for next tickinventoryshows equipped + bag items
Status Effects
- Poison deals damage each tick, shows message to player
- Regeneration heals each tick, shows message to player
- Status effects expire after their duration (in ticks)
statscommand shows active status effects and remaining duration- Multiple status effects can be active simultaneously
- Negative status effects cleared on player death/respawn
- Status effects on offline players resolve by wall-clock time on next login
Passive Regeneration
- Players out of combat slowly regenerate HP over ticks
- Regeneration does not occur while in combat
- HP does not exceed max_hp
Tick Engine
- Tick runs at configured interval (~2 seconds)
- Tick processes: NPC AI → combat rounds → status effects → respawns → regen
- Tick output is delivered to players promptly
- Server remains responsive to immediate commands between ticks
- Multiple players in separate combats are processed independently per tick
Attitude System
- Per-player NPC attitudes stored in DB
examineshows attitude label per-player- Killing NPC shifts attitude (individual -10, faction -5)
- Verify:
sqlite3 mudserver.db "SELECT * FROM npc_attitudes;"
Admin System
- Non-admin can't use
admincommands (gets error) - Set admin via mudtool:
mudtool players set-admin <name> true admin helpshows admin command listadmin promote <player>grants admin (verify in DB)admin demote <player>revokes adminadmin kick <player>disconnects target playeradmin teleport <room_id>warps to room (shows room list on invalid)admin registration offblocks new player creationadmin registration onre-enables itadmin announce <msg>broadcasts to all playersadmin healheals self;admin heal <player>heals targetadmin info <player>shows detailed stats + attitudesadmin setattitude <player> <npc> <value>modifies attitudeadmin listshows all players with online/offline status
Registration Gate
- With registration open (default), new players can create characters
- With registration off, new SSH connections get rejection message
- Existing players can still log in when registration is closed
MUD Tool - CLI
mudtool players listshows all playersmudtool players show <name>shows detailsmudtool players set-admin <name> trueworksmudtool players delete <name>removes player + attitudesmudtool settings listshows settingsmudtool settings set registration_open falseworksmudtool attitudes list <player>shows attitudesmudtool attitudes set <player> <npc> <value>works
MUD Tool - TUI
mudtool tuilaunches interactive interface- Tab/1/2/3 switches between Players, Settings, Attitudes tabs
- Arrow keys navigate rows
- 'a' toggles admin on Players tab
- 'd' prompts delete confirmation on Players tab
- Enter edits value on Settings and Attitudes tabs
- ←→ switches player on Attitudes tab
- 'q' exits TUI
Quick Smoke Test Script
# Start server in background
RUST_LOG=info ./target/debug/mudserver &
SERVER_PID=$!
sleep 2
# Test 1: New player creation + basic commands
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 smoketest@localhost <<'EOF'
1
1
look
stats
go north
talk barkeep
go south
go south
examine thief
attack thief
flee
quit
EOF
# Test 2: Persistence - reconnect
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 smoketest@localhost <<'EOF'
look
stats
quit
EOF
# Test 3: Admin via mudtool
./target/debug/mudtool players list
./target/debug/mudtool players set-admin smoketest true
./target/debug/mudtool players show smoketest
./target/debug/mudtool settings set registration_open false
./target/debug/mudtool settings list
# Test 4: Admin commands in-game
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 smoketest@localhost <<'EOF'
admin help
admin list
admin registration on
admin info smoketest
quit
EOF
# Test 5: Registration gate
./target/debug/mudtool settings set registration_open false
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 newplayer@localhost <<'EOF'
quit
EOF
# Test 6: Tick-based combat (connect and wait for ticks)
./target/debug/mudtool settings set registration_open true
./target/debug/mudtool players delete smoketest
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 smoketest@localhost <<'EOF'
1
1
go south
go south
attack thief
EOF
# Wait for several combat ticks to resolve
sleep 8
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 2222 smoketest@localhost <<'EOF'
stats
quit
EOF
# Verify XP changed (combat happened via ticks)
# Cleanup
./target/debug/mudtool settings set registration_open true
./target/debug/mudtool players delete smoketest
kill $SERVER_PID