88 lines
4.2 KiB
Markdown
88 lines
4.2 KiB
Markdown
# Architecture
|
|
|
|
## Composition
|
|
|
|
`main/main.tscn` is the application composition root. It owns long-lived
|
|
services, the active world, player container, save/settings managers, and the
|
|
pixelated UI viewport. Services are scene-owned rather than global autoloads,
|
|
which makes their dependencies visible in the main scene and allows focused
|
|
tests to instantiate the same composition.
|
|
|
|
The main script coordinates title, session, world, and UI lifecycle. Domain
|
|
logic remains in typed resources and services rather than being stored solely
|
|
in controls.
|
|
|
|
## Domain boundaries
|
|
|
|
- `fish/` defines species, availability, catches, pools, quality, and selection.
|
|
- `fishing/` owns cast/chase state and resolves authoritative fishing surfaces.
|
|
- `inventory/`, `items/`, `economy/`, `progression/`, and `jobs/` own persistent
|
|
player-facing game state.
|
|
- `world/` owns authored map composition and presentation. Water type is a
|
|
shared typed definition used by water bodies, fish habitat, fishing
|
|
validation, Logbook classification, and saltwater shoreline presentation.
|
|
- `ui/` observes and invokes domain services. It does not define stable item or
|
|
fish identity.
|
|
|
|
Resource files (`.tres`) are authored data. Stable IDs, not display names or
|
|
node names, connect persistent and networked state to that data.
|
|
|
|
## Networking
|
|
|
|
`NetworkSession` owns ENet session lifecycle and peer registration. Dedicated
|
|
network services validate and replicate bounded domains such as fishing,
|
|
sales, shops, item use, profiles, jobs, mail, chat, drawings, time, and weather.
|
|
|
|
`DiscoveryClient` is an optional directory layer beside `NetworkSession`. An
|
|
open host may publish a short-lived room lease, and the shared Join Game page
|
|
may browse compatible leases before handing the selected address back to the
|
|
existing direct ENet connection flow. The directory does not carry gameplay
|
|
traffic or become a gameplay authority. Its base URL comes from
|
|
`network/discovery/base_url`, with `NETFISHING_DISCOVERY_URL` available as a
|
|
development/deployment override.
|
|
|
|
The host is authoritative. Clients submit requests or evidence; the host
|
|
derives trusted context from registered peers, authoritative regions, and
|
|
server-owned state before mutating inventory, wallet, progression, or shared
|
|
world state. See [`decisions/0001-host-authority.md`](decisions/0001-host-authority.md).
|
|
|
|
Moderation follows the same boundary. Player hosts may grant session-scoped
|
|
operator status to an authenticated identity. Dedicated servers derive
|
|
operators from their configured fingerprint allowlist. Operator status is
|
|
replicated for presentation, but kick, ban, unban, and artwork-reset requests
|
|
are always reauthorized against the authenticated sender by the host. Only a
|
|
player host can grant or revoke operators; operators cannot moderate the host
|
|
or another operator.
|
|
|
|
Protocol compatibility is defined in `network/network_protocol.gd`. A visible
|
|
release version is not a reason to change the protocol number.
|
|
|
|
## Persistence
|
|
|
|
`PlayerDataRoot` selects and validates a portable data root. Stores receive
|
|
paths from that owner rather than inventing unrelated locations. Progression is
|
|
written by `PlayerSaveManager`; device settings and social/identity stores have
|
|
separate formats and lifecycles.
|
|
|
|
Save migrations are sequential and explicit. Existing catches and ownership
|
|
are keyed by stable IDs so authored metadata can evolve without rewriting
|
|
historical records. Current source constants—not documentation—are
|
|
authoritative for format versions.
|
|
|
|
## Presentation
|
|
|
|
Gameplay is rendered in 3D with the GL Compatibility renderer. The main UI is
|
|
presented through a uniformly scaled SubViewport. Shared UI components and
|
|
palette resources prevent page-specific geometry and style drift.
|
|
|
|
World presentation systems (time/weather visuals, procedural sky and water,
|
|
shoreline ribbons, player blob shadows) do not own gameplay collision or
|
|
network authority. Generated shoreline meshes are deterministic presentation
|
|
resources baked from explicitly configured static terrain.
|
|
|
|
## Validation
|
|
|
|
Tests are executable Godot `SceneTree` scripts. Some are pure content/domain
|
|
checks, some instantiate the main scene, and multiplayer checks run paired host
|
|
and client processes on loopback. The repository runner provides isolation and
|
|
consistent entry points; see [`TESTING.md`](TESTING.md).
|