Tour of the server code
ishtaria-server is one Rust binary (axum, SQLx, PostgreSQL). Every gameplay area is a module
with its own routes() that src/main.rs merges into the router, a SQL migration for its tables
and, where the content is data, a file in etc/.
How a request is handled
A typical action (POST /players/me/...) always does the same things in the same order:
players::player_id(&state, &players::token_hash(&headers)?)turns the bearer token into a character id (expired, revoked, dead and banned sessions are refused with 401).The request body is parsed into a struct with
#[serde(deny_unknown_fields)]and validated.A transaction starts and
survival::lock_alivelocks the character’s row. If the character is dead the handler returnsError::Obituary.The handler checks position, reach, cooldown and ownership, changes tables and commits, or returns an
Error::Status(code, "fixed message")that rolls everything back.The reply is usually
players::profile(&state, player_id)so that the client’s HUD and inventory are always in step.
Modules
File |
Responsibility |
|---|---|
|
configuration, router, start-up, world import |
|
accounts, login, sessions, profile, equipment |
|
health, stamina, water, food, |
|
walking, running, jumping, collision, |
|
local relief and spawning, imported height maps, the sun |
|
harvesting trees and rocks, crafting ( |
|
wear of tools, weapons and armour; experience and levels |
|
hunting animals, drops, milking ( |
|
armour, blocking and the bites of dangerous animals ( |
|
mana, scrolls, spells ( |
|
things put into the world, crops, stations, fishing ( |
|
merchants ( |
|
drop and pick up ground piles, NPC scooping, wayfarer errands and merchant stock |
|
nearby players, say and whisper, friends, the |
|
portals and links, signing and peers, real-money land leases |
|
hall of fame; achievements ( |
|
generated towns and props; datadisks, dialogue, quests, NPCs, settlements, wayfarers |
Data files (etc/)
Rules that a designer may change without writing Rust are JSON or YAML compiled into the binary
(include_str!) and parsed once at first use; a unit test in the owning module checks that the
file is consistent, and configured_items_exist checks that every item it names is in the
catalogue. To add one, see Cookbook: adding things to the game.
File |
Content |
|---|---|
|
crafting recipes: inputs, outputs, tool or station, experience |
|
what trees and rocks give; the generated object catalogue |
|
animals: hits, drops, respawn, weapon strength; where fauna lives |
|
armour defence and slots, dangerous animals |
|
things to place, crops, fishing |
|
merchants and their goods; dialogues of generated traders, shipwrights and wayfarers |
|
mana and spells |
|
portal materials |
Tests
src/tests.rs holds the shared helpers (initialize_spawn_world, create_session,
player_request, response_json) and src/tests/*.rs one file per gameplay area. A test that
needs PostgreSQL is #[sqlx::test] and #[ignore]; take AUTH_TESTS so that tests which
register players do not interleave. Look at src/tests/trade.rs for a test with two players and at
src/tests/farming.rs for one that needs a different world.