Document project architecture and asset provenance
This commit is contained in:
parent
930acdb1a6
commit
866cc0fc06
10 changed files with 705 additions and 0 deletions
72
docs/ARCHITECTURE.md
Normal file
72
docs/ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# 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.
|
||||
|
||||
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).
|
||||
|
||||
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).
|
||||
109
docs/ASSET-PROVENANCE.md
Normal file
109
docs/ASSET-PROVENANCE.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Asset provenance
|
||||
|
||||
This document records where runtime assets came from and what must be verified
|
||||
before redistribution. A Git commit proves when bytes entered this repository;
|
||||
it does not by itself prove authorship or licensing.
|
||||
|
||||
## Intake policy
|
||||
|
||||
For every new external or supplied asset, record:
|
||||
|
||||
- creator or supplying party;
|
||||
- original source location or delivery channel;
|
||||
- source filename and repository destination;
|
||||
- source and destination SHA-256 when copied without modification;
|
||||
- license or explicit permission;
|
||||
- any permitted transformations;
|
||||
- the importing commit or release.
|
||||
|
||||
Runtime resources must use `res://` paths. Workstation Sync folders are intake
|
||||
locations only and must never appear in scenes or resources.
|
||||
|
||||
## Current inventory
|
||||
|
||||
| Asset family | Repository location | Recorded provenance |
|
||||
| --- | --- | --- |
|
||||
| Fish art and portraits | `fish/species/`, `art/exported/fish/` | 2D artwork by contributor Rheannon Eisworth. |
|
||||
| Item icons | `items/icons/` | 2D artwork by contributor Rheannon Eisworth. |
|
||||
| Inventory notepad | `art/ui/ui_notepad.png` | 2D artwork by contributor Rheannon Eisworth; integrated without a runtime external path. |
|
||||
| Environment textures | `art/exported/environment/textures/` | 2D artwork by contributor Rheannon Eisworth. |
|
||||
| UI patterns | `art/patterns/` | 2D artwork by contributor Rheannon Eisworth. |
|
||||
| Character and world models | `art/exported/` | Original 3D models by the project owner. Any embedded 2D artwork is by Rheannon Eisworth. |
|
||||
| Tuffy font | `ui/fonts/Tuffy_Bold.otf` | Public-domain dedication in `ui/fonts/Tuffy-LICENSE.txt`. |
|
||||
| Seattle Avenue font | `ui/fonts/seattle_avenue.otf` | License and attribution not present; resolve before public distribution. |
|
||||
| Title music | `audio/music/title/as_in_four_wolves.ogg` | Original music composed and owned by the project owner. |
|
||||
| Fishing fight loop | `audio/sfx/fishing/fighting.wav` | Edited from “Spinning reel.wav” by Freesound user tosha73, sound 509902, CC0. |
|
||||
| Manual-reeling loop | `audio/sfx/fishing/reeling.wav` | Edited from the same CC0 “Spinning reel.wav” source. |
|
||||
| Saltwater wave ambience | `audio/ambience/waves.wav` | “Gentle Ocean Waves Loop” by Freesound user kkenny101, sound 852826, CC0. |
|
||||
| Bobber water impact | `audio/sfx/fishing/bobber.wav` | “Quick Water Droplet” by Freesound user qubodup, sound 792931, CC0. |
|
||||
|
||||
### Fishing fight loop source record
|
||||
|
||||
- Source page: https://freesound.org/s/509902/
|
||||
- Creator: tosha73
|
||||
- Source title: `Spinning reel.wav`
|
||||
- License: Creative Commons Zero (CC0)
|
||||
- Downloaded source filename: `509902__tosha73__spinning-reel.wav`
|
||||
- Downloaded source SHA-256:
|
||||
`9741afdb1ec9c73f5e039f0e5ac174998cb0a1f737b626531e63919d4d232fad`
|
||||
- Audacity working project: `fighting.aup3`
|
||||
- Audacity project SHA-256:
|
||||
`9928f077ecf48d01416f8d05700707e1b07d0f731846db80e27116f5b82dbbf5`
|
||||
- Runtime edit source/destination SHA-256:
|
||||
`b6f3f2f94bfaf9254ac04dd96b1fd28c15e1011a1db44bb3e70eeaa95de3c212`
|
||||
- Runtime format: 48 kHz, 16-bit, stereo PCM WAV; 2.593479 seconds;
|
||||
configured as a forward loop by the fishing presentation.
|
||||
- Manual-reeling Audacity project: `reeling.aup3`
|
||||
- Manual-reeling Audacity project SHA-256:
|
||||
`20ad52f6bdd16ae6561f06f8355fe309e95023e815053fd5dfbd5a5ce3c1f9f9`
|
||||
- Manual-reeling runtime source/destination SHA-256:
|
||||
`e403d5b7c8af1da4b28599cc0f51de3eda70d9e9296db27852fe7dc95617a29d`
|
||||
- Manual-reeling runtime format: 48 kHz, 16-bit, stereo PCM WAV;
|
||||
2.388083 seconds; configured as a forward loop.
|
||||
- The downloaded source and Audacity projects remain in the project owner's
|
||||
source-work archive; only the finished runtime edits ship in the game.
|
||||
|
||||
### Saltwater wave ambience source record
|
||||
|
||||
- Source page: https://freesound.org/s/852826/
|
||||
- Creator: kkenny101
|
||||
- Source title: `Gentle Ocean Waves Loop`
|
||||
- License: Creative Commons Zero (CC0)
|
||||
- Downloaded source filename:
|
||||
`852826__kkenny101__gentle-ocean-waves-loop.wav`
|
||||
- Downloaded source and runtime source/destination SHA-256:
|
||||
`f93e9890583f072ac52cf197b8b5942397d3d5e889fbdb9112a0776142f50229`
|
||||
- Runtime format: 48 kHz, 24-bit, mono PCM WAV; 21.769917 seconds;
|
||||
configured as a forward loop.
|
||||
- The downloaded source remains in the project owner's source-work archive;
|
||||
only the finished runtime loop ships in the game.
|
||||
|
||||
### Bobber water-impact source record
|
||||
|
||||
- Source page: https://freesound.org/s/792931/
|
||||
- Creator: qubodup
|
||||
- Source title: `Quick Water Droplet`
|
||||
- License: Creative Commons Zero (CC0)
|
||||
- Downloaded source filename: `792931__qubodup__quick-water-droplet.wav`
|
||||
- Downloaded source and runtime source/destination SHA-256:
|
||||
`aef0d16384efed4a7b071c4d80c21597617f882f4e0c1d5295ac194d315eafb7`
|
||||
- Runtime format: 48 kHz, 16-bit, mono PCM WAV; 0.197146 seconds; one-shot.
|
||||
- The downloaded source remains in the project owner's source-work archive;
|
||||
only the finished runtime sound ships in the game.
|
||||
|
||||
## Generated resources
|
||||
|
||||
Godot `.import` sidecars and deterministic shoreline `.tres` meshes are derived
|
||||
repository resources, not original artwork. `.godot/imported/`, editor caches,
|
||||
captures, exports, and temporary test data are not tracked.
|
||||
|
||||
## Release gate
|
||||
|
||||
Before a public binary or source release:
|
||||
|
||||
1. Resolve the Seattle Avenue font license and attribution gap above.
|
||||
2. Record the public owner/studio credit and the contributor's redistribution
|
||||
permission in the chosen project license or release records.
|
||||
3. Confirm the project-wide source/content license selected by the owner.
|
||||
4. Search exported resources for external filesystem paths.
|
||||
5. Preserve required third-party notices with the package.
|
||||
41
docs/BALANCE.md
Normal file
41
docs/BALANCE.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Balance and content notes
|
||||
|
||||
Balance is authored data and should change deliberately. This document records
|
||||
the policy; exact current values remain authoritative in `.tres` resources and
|
||||
typed scripts.
|
||||
|
||||
## Fish
|
||||
|
||||
- Stable fish IDs and catalog numbers must not be changed for display cleanup.
|
||||
- Species availability may constrain water type, time, weather, bait, and other
|
||||
authored context.
|
||||
- Location pools control selection weight; the global catalog remains
|
||||
comprehensive.
|
||||
- Freshwater/saltwater habitat is validated by the host in addition to pool
|
||||
membership.
|
||||
- Value, rarity, quality, and weight ranges should be reviewed together because
|
||||
they affect economy and catch difficulty.
|
||||
|
||||
## Economy and progression
|
||||
|
||||
- Sales and purchases are host-authoritative and must mutate inventory and
|
||||
wallet exactly once.
|
||||
- Reserved assets are rejected atomically; mixed valid/reserved batches must
|
||||
not partially succeed.
|
||||
- Item effects, shop prices, cooler capacity, fishing upgrades, jobs, and
|
||||
experience are separate balance axes. Avoid changing several in an unrelated
|
||||
presentation pass.
|
||||
|
||||
## Recording a balance change
|
||||
|
||||
Include in the change description:
|
||||
|
||||
1. affected stable IDs and resource paths;
|
||||
2. old and new values;
|
||||
3. intended player-facing outcome;
|
||||
4. interactions with quality, availability, and economy;
|
||||
5. deterministic validation performed;
|
||||
6. whether existing saves remain semantically valid.
|
||||
|
||||
Do not bump the save schema or network protocol simply because an authored
|
||||
number changed. Bump a format only when its serialized contract changes.
|
||||
63
docs/TESTING.md
Normal file
63
docs/TESTING.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Testing
|
||||
|
||||
NETfishing validations are Godot `SceneTree` scripts. They use assertions and
|
||||
exit nonzero on failure. Run them with isolated user data so development checks
|
||||
cannot touch real saves, identity, trust, relationships, or settings.
|
||||
|
||||
## Consolidated runner
|
||||
|
||||
```sh
|
||||
scripts/run_validations.sh quick
|
||||
scripts/run_validations.sh full
|
||||
scripts/run_validations.sh host
|
||||
scripts/run_validations.sh network
|
||||
scripts/run_validations.sh all
|
||||
scripts/run_validations.sh --list
|
||||
```
|
||||
|
||||
- `quick` runs deterministic content and domain validations.
|
||||
- `full` adds socket-free scene/runtime checks suitable for headless execution.
|
||||
- `host` runs single-process authoritative-host checks that bind a local UDP
|
||||
port.
|
||||
- `network` runs the loopback host/client validations in pairs.
|
||||
- `all` runs `full`, `host`, and then `network`.
|
||||
|
||||
Set `GODOT_BIN` to select another executable. Set `TEST_TIMEOUT_SECONDS` to
|
||||
change the per-process timeout. The runner creates one temporary XDG root per
|
||||
process and removes it on exit.
|
||||
|
||||
## One focused test
|
||||
|
||||
```sh
|
||||
test_root="$(mktemp -d)"
|
||||
XDG_DATA_HOME="$test_root/data" \
|
||||
XDG_CONFIG_HOME="$test_root/config" \
|
||||
godot --headless --path . --script tests/fish_catalog_content_validation.gd
|
||||
rm -rf -- "$test_root"
|
||||
```
|
||||
|
||||
Do not set `NETFISHING_DATA_DIR` to an arbitrary empty folder: that variable is
|
||||
an explicit portable-data override and must point at a valid NETfishing data
|
||||
root. Isolating XDG paths is sufficient for the validation scripts.
|
||||
|
||||
## Graphical checks
|
||||
|
||||
Headless tests cannot prove visual alignment, actual mouse routing, shader
|
||||
appearance, controller feel, or window-resize behavior. Presentation changes
|
||||
need a real graphical startup with isolated XDG roots and inspection at the
|
||||
canonical 1280×720 layout plus relevant low/high and ultrawide resolutions.
|
||||
|
||||
## Network checks
|
||||
|
||||
Host and paired tests bind loopback UDP ports defined in their scripts. Ensure
|
||||
no old Godot validation process is holding those ports and that the execution
|
||||
environment permits local sockets. The runner starts paired hosts before their
|
||||
clients and requires both processes to exit successfully. Network tests do not
|
||||
contact external servers.
|
||||
|
||||
## Release checks
|
||||
|
||||
A release audit additionally includes clean Git/tag verification, editor import,
|
||||
export-template checks, platform exports, executable smoke tests, archive
|
||||
inspection, and SHA-256 verification. Those checks are intentionally not hidden
|
||||
inside the development runner.
|
||||
27
docs/decisions/0001-host-authority.md
Normal file
27
docs/decisions/0001-host-authority.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# ADR 0001: Host-authoritative shared state
|
||||
|
||||
Status: accepted
|
||||
|
||||
## Context
|
||||
|
||||
NETfishing supports private hosts, open hosts, and joined clients. Catches,
|
||||
currency, owned items, jobs, mail, drawings, profiles, and moderation affect
|
||||
state that cannot safely trust a client's local presentation.
|
||||
|
||||
## Decision
|
||||
|
||||
The host validates requests against registered peers and host-owned context,
|
||||
then performs the authoritative mutation. Clients receive results and replicated
|
||||
presentation state. Client evidence is bounded and reconstructed where
|
||||
possible; it is not treated as authority.
|
||||
|
||||
Private single-player uses the same host path. Presentation-only state does not
|
||||
add RPCs or persistence.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Shared behavior is consistent across private, open-host, and joined-client
|
||||
modes.
|
||||
- Tests must cover local-host and paired host/client paths.
|
||||
- Stable protocol payloads and rejection cleanup require explicit handling.
|
||||
- UI activation cannot be used as proof that a server-side mutation succeeded.
|
||||
27
docs/decisions/0002-authored-data-and-stable-ids.md
Normal file
27
docs/decisions/0002-authored-data-and-stable-ids.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# ADR 0002: Authored resources and stable identifiers
|
||||
|
||||
Status: accepted
|
||||
|
||||
## Context
|
||||
|
||||
Fish, items, pools, availability, shop stock, and other game content evolve
|
||||
independently from saved catches and network messages. Display labels and scene
|
||||
node names are expected to change during development.
|
||||
|
||||
## Decision
|
||||
|
||||
Repository-owned resources are the authoritative authored data. Persistent and
|
||||
networked records refer to stable IDs. Display names, filenames, node names,
|
||||
coordinates, and pool names are not compatibility identifiers.
|
||||
|
||||
Cross-domain concepts such as water type use one typed definition rather than
|
||||
duplicated strings. Comprehensive catalogs remain separate from location-
|
||||
specific selection pools.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Renaming visible UI does not require save migration.
|
||||
- Removing or changing a stable ID requires an explicit compatibility plan.
|
||||
- Content validation checks uniqueness, catalog completeness, pool membership,
|
||||
and typed habitat compatibility.
|
||||
- New authored assets need provenance records as well as resource references.
|
||||
Loading…
Add table
Add a link
Reference in a new issue