mud_server.services.character_provisioning ========================================== .. py:module:: mud_server.services.character_provisioning .. autoapi-nested-parse:: Shared character provisioning service used by admin and player APIs. Why this module exists: The codebase previously duplicated character creation logic across route handlers. This service centralizes deterministic name generation, DB create retries, and optional entity-state seeding so every caller follows one canonical behavior. Attributes ---------- .. autoapisummary:: mud_server.services.character_provisioning.logger Classes ------- .. autoapisummary:: mud_server.services.character_provisioning.CharacterProvisioningResult Functions --------- .. autoapisummary:: mud_server.services.character_provisioning.generate_provisioning_seed mud_server.services.character_provisioning.fetch_generated_full_name mud_server.services.character_provisioning.fetch_entity_state_for_seed mud_server.services.character_provisioning.get_world_slot_capacity mud_server.services.character_provisioning.provision_generated_character_for_user Module Contents --------------- .. py:data:: logger .. py:class:: CharacterProvisioningResult Result payload for generated-character provisioning. .. attribute:: success True when provisioning completed and DB rows were persisted. .. attribute:: reason Stable reason key for caller-level error mapping. .. attribute:: message Human-readable status message. .. attribute:: character_id Created character id when successful. .. attribute:: character_name Created character name when successful. .. attribute:: world_id Target world id for the created character. .. attribute:: seed Deterministic provisioning seed used for name/entity generation. .. attribute:: entity_state Raw entity payload when fetched successfully. .. attribute:: entity_state_error Non-fatal warning when entity seeding fails. .. py:attribute:: success :type: bool .. py:attribute:: reason :type: str .. py:attribute:: message :type: str .. py:attribute:: character_id :type: int | None :value: None .. py:attribute:: character_name :type: str | None :value: None .. py:attribute:: world_id :type: str | None :value: None .. py:attribute:: seed :type: int | None :value: None .. py:attribute:: entity_state :type: dict[str, Any] | None :value: None .. py:attribute:: entity_state_error :type: str | None :value: None .. py:function:: generate_provisioning_seed() Generate a replayable, non-zero seed for provisioning flows. We intentionally use ``secrets.randbelow`` rather than module-global RNG state to avoid coupling name/entity generation to gameplay randomness. .. py:function:: fetch_generated_full_name(seed) Generate a deterministic ``first last`` character name for provisioning. The same base seed is used for both lookups with an offset for the surname so retry attempts remain deterministic across deployments. .. py:function:: fetch_entity_state_for_seed(seed, *, world_id = None) Fetch an optional entity-state payload for a provisioning seed. Entity-state integration is non-fatal: character creation continues even if the upstream call fails. .. py:function:: get_world_slot_capacity(user_id, world_id) Return ``(current_count, slot_limit)`` for account ownership in one world. .. py:function:: provision_generated_character_for_user(*, user_id, world_id, max_attempts = 8) Create a generated-name character with optional entity-state axis seeding. The flow is intentionally deterministic per retry sequence: 1. Resolve slot capacity early and fail fast if world budget is full. 2. Generate ``first last`` names from deterministic seeds. 3. Retry on unique-name collisions. 4. Apply optional entity-state deltas as a non-fatal post-step.