Add character creation flow with description prompt

This commit is contained in:
Jared Miller 2026-02-14 16:45:06 -05:00
parent 0f3ae87f33
commit 1c22530be7
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C
2 changed files with 132 additions and 0 deletions

36
src/mudlib/creation.py Normal file
View file

@ -0,0 +1,36 @@
"""Character creation flow for new players."""
async def character_creation(
name: str,
read_func,
write_func,
) -> dict:
"""Run character creation prompts for a new player.
Args:
name: Player name
read_func: Async function to read a line of input (returns str or None)
write_func: Async function to write output
Returns:
Dict with creation data: {"description": str}
"""
await write_func("\r\n--- Character Creation ---\r\n\r\n")
await write_func(
"Describe yourself in a short sentence or two.\r\n"
"(This is what others see when they look at you.)\r\n\r\n"
)
await write_func("Description: ")
desc_input = await read_func()
description = ""
if desc_input is not None:
description = desc_input.strip()
if description:
await write_func(f'\r\nYou will be known as: "{description}"\r\n')
else:
await write_func("\r\nNo description set. You can change it later.\r\n")
return {"description": description}

96
tests/test_creation.py Normal file
View file

@ -0,0 +1,96 @@
"""Tests for character creation flow."""
from collections import deque
import pytest
from mudlib.creation import character_creation
async def make_io(inputs):
"""Create mock read/write functions."""
input_queue = deque(inputs)
output = []
async def read_func():
if input_queue:
return input_queue.popleft()
return None
async def write_func(msg):
output.append(msg)
return read_func, write_func, output
@pytest.mark.asyncio
async def test_character_creation_with_description():
"""Test providing a description returns it."""
read_func, write_func, output = await make_io(
["A wandering swordsman with a mysterious past."]
)
result = await character_creation("TestPlayer", read_func, write_func)
assert result["description"] == "A wandering swordsman with a mysterious past."
assert any("Character Creation" in msg for msg in output)
assert any("Description:" in msg for msg in output)
assert any("A wandering swordsman with a mysterious past." in msg for msg in output)
@pytest.mark.asyncio
async def test_character_creation_empty_input():
"""Test empty input returns empty string."""
read_func, write_func, output = await make_io([""])
result = await character_creation("TestPlayer", read_func, write_func)
assert result["description"] == ""
assert any("No description set" in msg for msg in output)
@pytest.mark.asyncio
async def test_character_creation_none_input():
"""Test None input (disconnect) returns empty string."""
read_func, write_func, output = await make_io([None])
result = await character_creation("TestPlayer", read_func, write_func)
assert result["description"] == ""
assert any("No description set" in msg for msg in output)
@pytest.mark.asyncio
async def test_character_creation_prompts():
"""Test the output includes the prompts."""
read_func, write_func, output = await make_io(["Test description"])
await character_creation("TestPlayer", read_func, write_func)
output_text = "".join(output)
assert "Character Creation" in output_text
assert "Describe yourself" in output_text
assert "This is what others see when they look at you" in output_text
assert "Description:" in output_text
@pytest.mark.asyncio
async def test_character_creation_confirmation():
"""Test the confirmation message includes the description."""
read_func, write_func, output = await make_io(["A fierce warrior"])
await character_creation("TestPlayer", read_func, write_func)
output_text = "".join(output)
assert "You will be known as:" in output_text
assert "A fierce warrior" in output_text
@pytest.mark.asyncio
async def test_character_creation_strips_whitespace():
"""Test that leading/trailing whitespace is stripped."""
read_func, write_func, output = await make_io([" A nimble thief "])
result = await character_creation("TestPlayer", read_func, write_func)
assert result["description"] == "A nimble thief"