Consolidate project documentation and attribution

Add public-alias credits and a tested in-game credits page, centralize project guidance and asset provenance, import the complete authored fur channel maps, and keep starter-island collision synchronized with imported props.
This commit is contained in:
Alexander Sellite 2026-08-12 22:12:11 -04:00
parent 1940ae13e5
commit db6074ddfa
59 changed files with 1638 additions and 1032 deletions

View file

@ -1,88 +0,0 @@
# 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).

View file

@ -1,161 +0,0 @@
# 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/` | Original 2D artwork by co-owner Rheannon Eisworth. |
| Item icons | `items/icons/` | Original 2D artwork by co-owner Rheannon Eisworth. |
| Inventory notepad | `art/ui/ui_notepad.png` | Original 2D artwork by co-owner Rheannon Eisworth; integrated without a runtime external path. |
| Environment textures | `art/exported/environment/textures/` | Original 2D artwork by co-owner Rheannon Eisworth. |
| UI patterns | `art/patterns/` | Original 2D artwork by co-owner Rheannon Eisworth. |
| Character and world models | `art/exported/` | Original 3D models by co-owner Alexander Sellite. Any embedded original 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` | Public-domain font by JLH Fonts; source record and hash in `ui/fonts/Seattle-Avenue-LICENSE.txt`. |
| Title music | `audio/music/title/as_in_four_wolves.ogg` | Original music composed and owned by co-owner Alexander Sellite. |
| Dusk music | `audio/music/world/craft.mp3` | Original music composed and owned by co-owner Alexander Sellite. |
| 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. |
| Rain ambience | `audio/ambience/rain_loop_ontario.ogg` | Converted from “Rain Loop Ontario” by Freesound user Ayton, sound 212799, CC BY 3.0. |
| Character bark call | `sound/dialogue/calls/bark.wav` | Edited from `Dog_Bark.wav` by Freesound user ivolipa, sound 328729, CC0. |
| Character meow call | `sound/dialogue/calls/meow.wav` | Edited from `Cat meow.m4a` by Freesound user Christyboy100, sound 495694, Attribution 3.0. |
| Animalese placeholder tones | `sound/dialogue/animalese/placeholder/` | Original tones composed and owned by co-owner Alexander Sellite without third-party samples. |
### 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.
### Character-call source records
#### Bark
- Source page: https://freesound.org/s/328729/
- Creator: ivolipa
- Source title: `Dog_Bark.wav`
- License: Creative Commons Zero (CC0)
- Downloaded source filename: `328729__ivolipa__dog_bark.wav`
- Downloaded source SHA-256:
`c3d542dee7bfcc1901428e0c1408c0bd522d778d8e5e1dbca156cab008f3d712`
- Runtime edit source/destination SHA-256:
`5ac2f32f33724a2fc232d725c5c37d4cfe3e93b3c1f19aa4177d2c8e3009ec78`
- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.446780 seconds;
one-shot.
#### Meow
- Source page: https://freesound.org/s/495694/
- Creator: Christyboy100
- Source title: `Cat meow.m4a`
- License: Attribution 3.0
- Downloaded source filename: `495694__christyboy100__cat-meow.m4a`
- Downloaded source SHA-256:
`afa3f6ef7afa2f7fee1e634d5505d2101cbba4421f8d8ff9adf562939c7a18f8`
- Converted working WAV SHA-256:
`a505e6e230e7d9d76b65c46270d97a35a1acc510b43aa5e7343d7b04f424cade`
- Runtime edit source/destination SHA-256:
`cce22ce1fbbc9325126a153aedc4526fde1aacf78780574fb432197dd44eb6b3`
- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.605420 seconds;
one-shot.
- The downloaded sources and working edits remain in the project owner's
source-work archive; only the finished runtime sounds ship in the game.
### Rain ambience source record
- Source page: https://freesound.org/s/212799/
- Creator: Ayton
- Source title: `Rain Loop Ontario`
- License: Creative Commons Attribution 3.0
- Downloaded source filename: `212799__ayton__rain-loop-ontario.aiff`
- Downloaded source SHA-256:
`b491fc036b78a274d9ac7f6acbd014af1b5d24f5cba9bd7e3fdc05c5432ee66f`
- Runtime edit SHA-256:
`b1979609b20fe34ed6f8902f3de65ae787a09abd71429e8aab850e87b74a4fa2`
- Changes: converted from AIFF to Ogg Vorbis and configured as looping
weather ambience.
## 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. Search exported resources for external filesystem paths.
2. Preserve `LICENSE`, `ASSET-LICENSE.md`, `TRADEMARKS.md`, credits, and all
required third-party notices with the package.
3. Publish or offer the exact corresponding GPL source for every distributed
binary release.

321
docs/ATTRIBUTION.md Normal file
View file

@ -0,0 +1,321 @@
# Attribution, licensing, and asset provenance
This is the authoritative project record for ownership, credits, license
boundaries, third-party notices, asset provenance, and redistribution checks.
A Git commit proves when bytes entered the repository; it does not by itself
prove authorship or licensing.
## Ownership and credits
NETfishing is jointly owned, developed, and published by its creators,
publicly credited as Voyager and Endeavour and operating collectively as the
independent team Woofmeow.
- Voyager: co-owner, developer, project director, creator of the game's 3D
art, and composer of the original title/ambient track
`audio/music/title/as_in_four_wolves.ogg`, world track
`audio/music/world/craft.mp3`, and animalese placeholder tones.
- Endeavour: co-owner, developer, and creator of the game's 2D art, including
the original fish, environment, UI, and other artwork.
- chillnfill: contributor of original 3D models for the character bodies and
arms, ears and tails, and multiple world props and decorative assets,
including trees and bridges. The contributor requested to be credited as
`chillnfill`.
- Tekgator: creator of the cooler-capacity and barrier-power shop icons.
Voyager is also the original catalog porter credit in PortMaster metadata.
Third-party creators are credited with their individual records below. Those
credits do not imply endorsement of NETfishing, Woofmeow, or its owners.
## License map
Do not describe the complete repository as covered only by the GPL.
| Material | Governing terms |
| --- | --- |
| Project-owned software code, shaders, code-oriented scene/resource configuration, tests, build tooling, and server software | GPL-3.0-or-later; source-root `LICENSE` and packaged `GPL-3.0-or-later.txt` |
| Project-owned artwork, textures, models, animation, music, audio, narrative content, characters, and other creative assets | Source-root or packaged `ASSET-LICENSE.md` |
| NETfishing and Woofmeow names, logos, icons, and official identity | Source-root or packaged `TRADEMARKS.md` |
| Third-party engines, fonts, sounds, and other external material | Their original terms, recorded below and in adjacent license texts where applicable |
| New outside contributions | Source-root `CONTRIBUTOR-TERMS.md` plus any separately signed agreement |
Generated Godot import metadata and deterministic generated resources follow
the terms of their source material or generating code. Repository location
alone does not relicense third-party material.
The GPL permits study, modification, redistribution, and forks of covered
code. It does not grant rights to NETfishing creative assets or branding. The
NETfishing Asset License separately permits qualifying noncommercial add-on
Mods for official NETfishing software; it does not permit those assets to
accompany code forks, clones, standalone games, unrelated products, or
general-purpose asset packs. A GPL fork must replace NETfishing assets and
reserved branding with independently licensed material and a distinct
identity.
Project-wide code, asset, branding, or contributor-license changes require
written approval from both NETfishing owners under their private joint
ownership agreement.
## Godot Engine notice
NETfishing uses Godot Engine under the MIT License:
> Copyright (c) 2014-present Godot Engine contributors.
> Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the “Software”), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
Godot licensing and bundled third-party-component notices are available at
https://godotengine.org/license/ and
https://github.com/godotengine/godot/blob/master/COPYRIGHT.txt. Godot uses
FreeType for font rendering; portions are copyright The FreeType Project
(https://www.freetype.org) under its applicable license.
## Font notices
- **Tuffy Bold** — Thatcher Ulrich, Karoly Barta, and Michael Evans; dedicated
to the public domain. Runtime file: `ui/fonts/Tuffy_Bold.otf`; original notice:
`ui/fonts/Tuffy-LICENSE.txt`.
- **Seattle Avenue** — JLH Fonts; dedicated to the public domain by the creator.
Runtime file: `ui/fonts/seattle_avenue.otf`; source, hash, and original notice:
`ui/fonts/Seattle-Avenue-LICENSE.txt`.
Public-domain fonts are not governed by the NETfishing Asset License.
## 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.
Maintainers must also obtain affirmative agreement to the source-root
`CONTRIBUTOR-TERMS.md` before accepting an outside contribution and retain
that agreement in a durable pull request, issue, email, or signed document.
Runtime resources must use `res://` paths. Workstation Sync folders are intake
locations only and must never appear in scenes or resources.
## Asset inventory and provenance
| Asset family | Repository location | Recorded provenance |
| --- | --- | --- |
| Fish art and portraits | `fish/species/`, `art/exported/fish/` | Original 2D artwork by co-owner Endeavour. |
| Item icons | `items/icons/` | Original 2D artwork by co-owner Endeavour except where separately credited below. |
| Cooler-capacity shop icon | `items/icons/equipment/64_cooler_plus.png` | Original artwork by Tekgator. Repository SHA-256: `b63705be5b78915753c068170323781a90e22b555b57a5b2ca9466e2726539f7`. |
| Barrier-power shop icon | `items/icons/shop/64_power_plus.png` | Original artwork by Tekgator. Repository SHA-256: `164d34ce152aa6d75de79b69f0be2d9074f7891057de9636678889028ff98ae7`. |
| Inventory notepad | `art/ui/ui_notepad.png` | Original 2D artwork by co-owner Endeavour; integrated without a runtime external path. |
| Environment textures | `art/exported/environment/textures/` | Original 2D artwork by co-owner Endeavour. |
| UI patterns | `art/patterns/` | Original 2D artwork by co-owner Endeavour. |
| Fur customization channel maps | `art/exported/characters/patterns/` | Original 2D channel-map artwork by co-owner Endeavour. Exact file hashes are recorded below. |
| Character base meshes and appendages | `art/source/characters/base/`, `art/exported/characters/base/`, and derived character resources | Original body and arm models and original ear and tail models by chillnfill. Any embedded original 2D artwork is by Endeavour. |
| World and decorative prop models | `art/source/environment/`, `art/exported/environment/`, and derived world resources | Original prop and decorative models by chillnfill, including trees and bridges. Any embedded original 2D artwork is by Endeavour. |
| Tuffy font | `ui/fonts/Tuffy_Bold.otf` | Public-domain dedication in `ui/fonts/Tuffy-LICENSE.txt`. |
| Seattle Avenue font | `ui/fonts/seattle_avenue.otf` | Public-domain font by JLH Fonts; source record and hash in `ui/fonts/Seattle-Avenue-LICENSE.txt`. |
| Title music | `audio/music/title/as_in_four_wolves.ogg` | Original music composed and owned by co-owner Voyager. |
| Dusk music | `audio/music/world/craft.mp3` | Original music composed and owned by co-owner Voyager. |
| 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. |
| Rain ambience | `audio/ambience/rain_loop_ontario.ogg` | Converted from “Rain Loop Ontario” by Freesound user Ayton, sound 212799, CC BY 3.0. |
| Character bark call | `sound/dialogue/calls/bark.wav` | Edited from `Dog_Bark.wav` by Freesound user ivolipa, sound 328729, CC0. |
| Character meow call | `sound/dialogue/calls/meow.wav` | Edited from `Cat meow.m4a` by Freesound user Christyboy100, sound 495694, Attribution 3.0. |
| Animalese placeholder tones | `sound/dialogue/animalese/placeholder/` | Original tones composed and owned by co-owner Voyager without third-party samples. |
Creative Commons Zero information:
https://creativecommons.org/publicdomain/zero/1.0/. Creative Commons
Attribution 3.0 legal text:
https://creativecommons.org/licenses/by/3.0/legalcode.
### chillnfill 3D model contribution record
- Requested credit: `chillnfill`.
- Original contribution families: character bodies and arms; character ears
and tails; and multiple world props and decorative assets, including trees
and bridges.
- Repository mapping: character contributions are incorporated into the
character source/export families identified above. Prop contributions may
be incorporated into combined environment source and export files rather
than retained as one file per originally supplied model.
- Permission record: because these historical contributions predate the
current `CONTRIBUTOR-TERMS.md`, retain the original permission record or a
later written confirmation covering Project use, modification,
distribution, commercial release, and applicable sublicensing.
### Fur customization channel-map record
Original channel-map artwork by Endeavour. Repository paths preserve the
authored `mesh_style.png` filenames.
| Style and mesh | Source filename | Repository file | SHA-256 |
| --- | --- | --- | --- |
| Bengal spots, body and arms | `body_arms_bengal.png` | `art/exported/characters/patterns/bengal/body_arms_bengal.png` | `fa90bd4e74b0b770ce97bf69d069676f5d4bd1f5d649f89e09638a66b61a8470` |
| Bengal spots, main body | `body_main_bengal.png` | `art/exported/characters/patterns/bengal/body_main_bengal.png` | `8662fa198220cfdbe0aa83bdeeef7b855e20124d74f8481467f750d32b67ee8b` |
| Bengal spots, round head | `head_round_bengal.png` | `art/exported/characters/patterns/bengal/head_round_bengal.png` | `7a48c5ac47cfd35ddec1783e6c4defa7807b5ef3f1c6b428157fbc0651e71ef3` |
| Fox, body and arms | `body_arms_fox.png` | `art/exported/characters/patterns/fox/body_arms_fox.png` | `fd2ab31ede371129ca4806480783d57153318a909d6b87c593b6ff82d03d65eb` |
| Fox, main body | `body_main_fox.png` | `art/exported/characters/patterns/fox/body_main_fox.png` | `d2a975cf042728299de4819a023a95e9c1467671a6886f6c6eaf8b44a5a9ca3a` |
| Fox, pointy head | `head_pointy_fox.png` | `art/exported/characters/patterns/fox/head_pointy_fox.png` | `8e74685ef7a9f61b5ae75c16e86898ea80f3996471e2999862479798ce28aa52` |
| Fox tail | `tails_fox_fox.png` | `art/exported/characters/patterns/fox/tails_fox_fox.png` | `72da9673f038e2c3bb8aca19ed99932085fa3b162cab95366901c4e97153dd3e` |
### Tekgator shop icon contribution record
- Requested credit: `Tekgator`.
- Original contributions: cooler-capacity and barrier-power shop icons.
- Repository files and SHA-256:
- `items/icons/equipment/64_cooler_plus.png`:
`b63705be5b78915753c068170323781a90e22b555b57a5b2ca9466e2726539f7`
- `items/icons/shop/64_power_plus.png`:
`164d34ce152aa6d75de79b69f0be2d9074f7891057de9636678889028ff98ae7`
- Permission record: retain the original permission record or a later written
confirmation covering Project use, modification, distribution, commercial
release, and applicable sublicensing.
### 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.
### Character-call source records
#### Bark
- Source page: https://freesound.org/s/328729/
- Creator: ivolipa
- Source title: `Dog_Bark.wav`
- License: Creative Commons Zero (CC0)
- Downloaded source filename: `328729__ivolipa__dog_bark.wav`
- Downloaded source SHA-256:
`c3d542dee7bfcc1901428e0c1408c0bd522d778d8e5e1dbca156cab008f3d712`
- Runtime edit source/destination SHA-256:
`5ac2f32f33724a2fc232d725c5c37d4cfe3e93b3c1f19aa4177d2c8e3009ec78`
- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.446780 seconds;
one-shot.
#### Meow
- Source page: https://freesound.org/s/495694/
- Creator: Christyboy100
- Source title: `Cat meow.m4a`
- License: Attribution 3.0
- Downloaded source filename: `495694__christyboy100__cat-meow.m4a`
- Downloaded source SHA-256:
`afa3f6ef7afa2f7fee1e634d5505d2101cbba4421f8d8ff9adf562939c7a18f8`
- Converted working WAV SHA-256:
`a505e6e230e7d9d76b65c46270d97a35a1acc510b43aa5e7343d7b04f424cade`
- Runtime edit source/destination SHA-256:
`cce22ce1fbbc9325126a153aedc4526fde1aacf78780574fb432197dd44eb6b3`
- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.605420 seconds;
one-shot.
- The downloaded sources and working edits remain in the project owner's
source-work archive; only the finished runtime sounds ship in the game.
### Rain ambience source record
- Source page: https://freesound.org/s/212799/
- Creator: Ayton
- Source title: `Rain Loop Ontario`
- License: Creative Commons Attribution 3.0
- Downloaded source filename: `212799__ayton__rain-loop-ontario.aiff`
- Downloaded source SHA-256:
`b491fc036b78a274d9ac7f6acbd014af1b5d24f5cba9bd7e3fdc05c5432ee66f`
- Runtime edit SHA-256:
`b1979609b20fe34ed6f8902f3de65ae787a09abd71429e8aab850e87b74a4fa2`
- Changes: converted from AIFF to Ogg Vorbis and configured as looping
weather ambience.
## 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. Search exported resources for external filesystem paths.
2. Include or make readily accessible the complete GPL text and identify the
exact corresponding source tag or commit.
3. Include `ASSET-LICENSE.md`, `TRADEMARKS.md`, this attribution/provenance
record, both font notices, and every applicable third-party license.
4. Retain the complete Godot Engine MIT notice above.
5. Preserve third-party terms without adding incompatible restrictions.
6. Avoid referring to a dirty or unavailable source revision.
7. Publish or offer equivalent access to exact corresponding GPL source for
every distributed binary release.
Desktop and PortMaster build scripts stage these authoritative files as
sidecars. Godot export presets include them in exported resource packs for
platforms where sidecar documents are not normally visible. Store and release
pages should link to the exact source revision and public notices.

View file

@ -1,41 +0,0 @@
# 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.

331
docs/DEVELOPMENT.md Normal file
View file

@ -0,0 +1,331 @@
# Development reference
This is the authoritative reference for NETfishing architecture, engineering
decisions, content policy, authoring, and validation.
## 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 and authority
`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. Private single-player uses the same host path. Client evidence is
bounded and reconstructed where possible; UI activation is never proof that a
server-side mutation succeeded.
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 and stable identifiers
`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.
Repository-owned resources are 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. Removing or changing a
stable ID requires an explicit compatibility plan.
### 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.
### Engineering consequences
- Shared mutations must behave consistently for private hosts, open hosts,
dedicated servers, and joined clients.
- Networking changes require local-host and paired host/client validation.
- Protocol payloads and rejection cleanup are explicit and bounded.
- Renaming visible UI does not require a save migration.
- Content validation covers stable-ID uniqueness, catalog completeness, pool
membership, and typed habitat compatibility.
- New authored assets require provenance records as well as resource
references.
## Content and balance
Balance is authored data and should change deliberately. 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 and saltwater habitat is validated by the host in addition to
pool membership.
- Value, rarity, quality, weight ranges, and authored barrier-health bands
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 and 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.
Record affected stable IDs and resource paths, old and new values, intended
player-facing outcome, interactions with quality/availability/economy,
deterministic validation, and save-compatibility impact with each balance
change. Do not bump a save schema or network protocol merely because an
authored number changed.
## Authoring
### World composition
The active test world uses the canonical starter island through
`world/regions/starter_island_region.tscn`.
`world/test_world.tscn` owns the gameplay-wide environment, sun, world bounds,
and below-world failsafe. `StarterIslandRegion` owns the placed island content:
```text
StarterIslandRegion
├── Terrain
│ ├── Visual
│ └── Collision
├── WaterBodies
│ ├── Pond
│ │ ├── VisualWater
│ │ ├── FishingRegion
│ │ └── RecoveryRegion
│ └── Ocean
│ ├── VisualWater
│ ├── FishingRegions
│ └── RecoveryRegions
├── PlayerSpawn
├── SafeRespawns
└── Interactables
├── FishingShopWorld
└── PelicanCoolerPerch
```
Move a meaningful feature root rather than one of its implementation children.
Child transforms are local offsets owned by that feature.
Every fishable region authors its `water_type` explicitly. The starter pond is
`FRESH_WATER`; the starter coast is `SALT_WATER`. Fish species use the same
central type through an allowed-water-type bitmask. Do not infer habitat from
node names, pool filenames, coordinates, or water height.
Select `WaterBodies/Pond` to move or resize the pond. Its transform is the
authoritative surface position; surface size and fishing/recovery coverage are
owned together. Select `WaterBodies/Ocean` to move the surrounding water as one
feature. Its explicit visual, fishing, and recovery lobes remain local to that
root.
Placed-feature ownership:
- `PlayerSpawn` defines the initial player transform and facing.
- `SafeRespawns` contains authoritative recovery destinations. Recovery
preserves current facing.
- `Interactables/FishingShopWorld` owns the shop visual, collision, interaction
area, prompt, and entrance marker.
- `Interactables/PelicanCoolerPerch` owns the Pelican landmark visual; selling
remains a Cooler action.
- `Terrain` owns imported visuals and generated collision.
- `BelowWorldFailsafe/Coverage` owns below-world recovery coverage.
The starter-island GLB hierarchy is the terrain-collision authority. The
region rebuilds one concave collision shape from every imported
`MeshInstance3D` when it loads, so newly exported terrain and props participate
without a separate stale collision bake. Keep purely decorative meshes out of
that hierarchy if they should not block players.
The active `Environment`, `Sun`, and starter-island grass material remain
Inspector-authored and are not recreated by runtime scripts.
### Reusable world props
Use one placed `WorldProp` root for a complete landmark:
```text
WorldProp
├── Visual
└── Collision
└── CollisionShape3D
```
Put optional interaction areas, labels, and markers beneath the same root.
Instance imported GLB content under `Visual` and keep gameplay collision under
`Collision`. Author reusable assets at scale `(1, 1, 1)`. Uniform provisional
root scaling is acceptable when visual and collision scale together; avoid
non-uniform root scaling. Make mutable per-instance shapes, meshes, and
materials local to the scene.
### Shoreline tide ribbons
Maps using generated tide ribbons own a `ShorelineRibbonBaker` and one
`ShorelineRibbonConfig` per water body. Each configuration selects only its
static terrain source, water height, generation bounds, water-facing reference,
smoothing overrides, and generated `.tres` path. Props, players, bobbers, and
gameplay areas are not scanned unless selected explicitly. Only `SALT_WATER`
bodies generate ribbons.
In the editor, select the baker and press **Rebuild Shoreline Ribbons**. The
equivalent validation command is:
```sh
godot --headless --path . --script scripts/bake_shoreline_ribbons.gd
```
Use `debug_path_stage` only while comparing extraction stages and leave it Off
in committed scenes. Rebuild when saltwater terrain at the waterline, water
height, or generation bounds change. Normal gameplay loads committed generated
meshes and never runs extraction.
### Facial-feature textures
Put new PNGs under the matching directory in
`art/exported/characters/faces/`:
```text
eyes/<id>.png
noses/<id>.png
mouth/<id>.png
```
The category directory is authoritative. A category prefix is optional, so
both `sleepy.png` and `eyes_sleepy.png` produce the stable option ID `sleepy`.
Filenames normalize to lowercase snake_case and are stored in appearance
snapshots, so do not casually rename them. Preserve the established RGBA
transparent canvas. Restart a development build after adding an image; rebuild
exports to package new `res://` files.
### Bubble menus
Instance `ui/components/bubble_menu/bubble_button.tscn` for each action, or
attach `bubble_button.gd` to an existing button. Author neutral size, desktop
and compact anchors, font-size limits, and deterministic motion in the
Inspector. A label child may be assigned with `label_control_path`.
Place buttons under a Control using `bubble_cluster.gd`, pass ordered button
references to `configure()`, and call `apply_layout()` when available size or
responsive layout changes. Order defines keyboard/controller focus neighbors.
The shared profile owns palette, styles, proportional-font ratio, hover
response, and contact tuning. Parent menus own labels, actions, anchors,
availability, and confirmation behavior.
`motion_scale = 0.0` disables idle drift/deformation while preserving hover and
focus feedback. Contact correction is deterministic and bounded; do not replace
it with physics that destabilizes layout, focus order, or hit targets.
## 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.
### 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 checks.
- `full` adds socket-free scene/runtime checks.
- `host` runs single-process authority checks that bind local UDP.
- `network` runs loopback host/client pairs.
- `all` runs `full`, `host`, and `network`.
Set `GODOT_BIN` to select an executable and `TEST_TIMEOUT_SECONDS` to change
the per-process timeout. The runner isolates and removes XDG roots.
For 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 point `NETFISHING_DATA_DIR` at an arbitrary empty directory; it is an
explicit portable-data override and must identify a valid data root.
Headless tests cannot prove visual alignment, mouse routing, shader appearance,
controller feel, or resize behavior. Presentation changes require graphical
review at the canonical 1280×720 layout and relevant low/high and ultrawide
resolutions.
Network tests require free loopback UDP ports and local-socket permission. A
release audit additionally requires clean Git/tag verification, editor import,
platform exports, executable smoke tests, archive inspection, and SHA-256
verification; those checks are intentionally outside the development runner.

View file

@ -1,77 +0,0 @@
# NETfishing licensing and release notices
NETfishing uses separate licenses for code, creative assets, third-party
material, and branding. Do not describe the complete repository as being
covered only by the GPL.
## Ownership
Copyright © 2026 Alexander Sellite and Rheannon Eisworth, operating
collectively as the independent development and publishing team Woofmeow.
## License map
| Material | Terms |
| --- | --- |
| Project-owned software code, shaders, scripts, code-oriented scene/resource configuration, tests, build tooling, and server software | GPL-3.0-or-later; full text in `LICENSE` |
| Project-owned artwork, textures, models, animation, music, audio, narrative content, characters, and other creative assets | `ASSET-LICENSE.md` |
| NETfishing and Woofmeow names, logos, icons, and official identity | `TRADEMARKS.md` |
| Third-party engines, fonts, sounds, and other external material | Their original terms, recorded in `THIRD-PARTY-NOTICES.md` and `docs/ASSET-PROVENANCE.md` |
| New outside contributions | `CONTRIBUTOR-TERMS.md` plus any separately signed agreement |
Generated Godot import metadata and deterministic generated resources follow
the terms of the source material or code from which they are derived. Merely
being stored in this repository does not relicense third-party material.
## Modding boundary
The GPL permits community members to study, modify, redistribute, and fork the
covered code under the GPL. It does not grant rights to NETfishing creative
assets or branding.
The NETfishing Asset License separately permits noncommercial add-on Mods that
require and operate with official NETfishing software. It does not permit the
assets to accompany code forks, clones, standalone games, unrelated products,
or general-purpose asset packs.
A fork may exercise its GPL code rights by replacing all NETfishing assets and
reserved branding with independently licensed material and a distinct
identity.
## Contributor intake
Maintainers must obtain affirmative agreement to `CONTRIBUTOR-TERMS.md` before
accepting a new outside contribution. Record the agreement in a durable pull
request, issue, email, or signed document.
For each external asset, preserve the creator, source, original filename,
license, transformations, and available hashes in `docs/ASSET-PROVENANCE.md`.
## Binary-release checklist
Every public binary package must:
1. include or make readily accessible the complete GPL text;
2. identify the exact corresponding source tag or commit and provide
equivalent access to that source;
3. include `ASSET-LICENSE.md`, `TRADEMARKS.md`, `CREDITS.md`, and
`THIRD-PARTY-NOTICES.md`;
4. include the public-domain font records and every required third-party
attribution;
5. retain the Godot Engine MIT notice;
6. avoid referring to a dirty or unavailable source revision; and
7. preserve third-party license terms without adding incompatible
restrictions.
Desktop and PortMaster build scripts stage these notices as sidecar files.
Godot export presets also include the authoritative notice files in exported
resource packs for platforms such as Android and macOS. Store and release
pages should link to the exact source revision and the public notices. A future
in-game legal-notices screen should expose the packed notices directly on
platforms where sidecar documents are not normally visible.
## Changing terms
Project-wide code, asset, branding, or contributor-license changes require
written approval from both Alexander Sellite and Rheannon Eisworth under their
joint ownership agreement.

View file

@ -1,28 +0,0 @@
# PortMaster performance profile
The PortMaster launcher keeps the normal game profile on unknown and stronger
hardware. It enables the low-end profile only when the Linux device tree
reports one of the identifiers used by the Allwinner H616/H700 XX handhelds:
- `allwinner,h616`
- `sun50iw9p1`
- `allwinner,sun50i-h700`
The low-end launch profile passes these options to Godot:
- `--single-window`
- `--disable-vsync`
- `--max-fps 30`
- `--audio-output-latency 40`
It also passes `NETFISHING_LOW_END=1`. The game responds by rendering the 3D
world at 75 percent linear resolution with nearest-neighbor scaling. This
reduces 3D pixel work by about 44 percent while the separately rendered UI
retains its canonical resolution.
Do not use Godot's low processor mode for this profile. It reduces idle CPU
usage by sleeping between updates and is not a game-performance optimization.
When adding another device family, record its exact NUL-separated device-tree
`compatible` value from the hardware before extending the launcher match. Do
not infer detection from a retail product name alone.

View file

@ -1,4 +1,4 @@
# PortMaster release builds
# PortMaster reference
NETfishing's PortMaster release is a canonical PortMaster package, not a
version-named generic ZIP. The installer-facing archive must be named
@ -95,10 +95,10 @@ The remaining catalog metadata assets were copied from the installed official
e2a9d132744684c67865c01eca027a8c9946b4c5a19da57c82f1af0373dc83b7 gameinfo.xml
```
The packages `licenses/` directory is now assembled from the authoritative
root license, asset-license, credits, trademark, font, and third-party-notice
files at build time. It also records the exact release tag and corresponding
GPL source commit. Do not restore stale duplicated license templates beneath
The packages `licenses/` directory is assembled from the authoritative root
licenses and trademarks, the consolidated `docs/ATTRIBUTION.md`, and the font
notices at build time. It also records the exact release tag and corresponding
GPL source commit. Do not restore stale duplicated notice templates beneath
`scripts/portmaster/`.
The original catalog porter credit, `Voyager`, remains in `port.json`.
@ -139,3 +139,31 @@ following in the installed game:
- Both sticks, both bumpers, both triggers, Select, Start, L3, and R3 register.
- A single button never cancels auto-map.
- Holding both bumpers together for 1.25 seconds cancels auto-map.
## Low-end performance profile
The launcher keeps the normal game profile on unknown and stronger hardware.
It enables the low-end profile only when the Linux device tree reports one of
the identifiers used by Allwinner H616/H700 XX handhelds:
- `allwinner,h616`
- `sun50iw9p1`
- `allwinner,sun50i-h700`
The low-end profile passes these Godot options:
- `--single-window`
- `--disable-vsync`
- `--max-fps 30`
- `--audio-output-latency 40`
It also passes `NETFISHING_LOW_END=1`. The game renders the 3D world at 75%
linear resolution with nearest-neighbor scaling, reducing 3D pixel work by
about 44% while the separately rendered UI retains its canonical resolution.
Do not use Godot's low processor mode for this profile. It reduces idle CPU
usage by sleeping between updates and is not a game-performance optimization.
Before adding a device family, record its exact NUL-separated device-tree
`compatible` value from hardware. Do not infer detection from a retail product
name alone.

115
docs/README-PLAYTEST.txt Normal file
View file

@ -0,0 +1,115 @@
NETfishing
v0.6.7-alpha
Alpha 0.6.7
Thank you for trying this early private playtest.
NETfishing is an early multiplayer fishing game. This alpha includes local
progression, player-hosted and dedicated multiplayer sessions, public room
discovery, and direct UDP connections. Expect rough edges and please keep a
backup of any save or identity data you care about.
INSTALLATION
1. Extract the entire ZIP into a new folder.
2. Keep the executable and netfishing.pck together.
3. Launch netfishing.exe on Windows or netfishing on Linux.
Windows may show a warning for an unsigned application. This private build is
not code signed. Only run a copy received from the playtest organizer.
Linux users may need to allow execution:
chmod +x netfishing
CONTROLS
Move W / A / S / D or left stick
Jump Space
Sprint Shift
Sneak Ctrl
Slow walk Alt
Rotate camera Hold right mouse, or use right stick
Cycle active hotbar slot Mouse wheel
Select hotbar slot 1 through 9
Zoom camera Shift + mouse wheel
Cast / withdraw / reel Left mouse
Cooler, Bag, and Logbook Tab
Game Menu / back Escape
Open Fishing Shop E while near the shop
FISHING
- Hold left mouse to select cast distance, then release to cast.
- The target preview shows whether the selected landing point is fishable.
- While waiting, hold left mouse to withdraw the bobber.
- A bite starts the chase automatically.
- Hold left mouse to advance the green catch meter.
- At barriers, use distinct left-click presses to damage the barrier.
- Do not let the red chase meter catch the green meter.
- Accessibility auto-click can be enabled in Settings.
- Approach the bright Fishing Shop booth and press E to open it.
- The Fishing Shop buys one Cooler fish at a time for full base value.
- Buy Coffee, Energy Drinks, Snacks, and Fish Finders as Bag supplies.
- Drag supplies from Bag to the hotbar and left-click in READY to use one.
- Coffee improves movement; other supplies temporarily improve fishing.
- The Cooler starts at 12 fish; buy permanent capacity expansions at the shop.
- Reel Speed upgrades increase authoritative green reeling progress.
- Rod Power upgrades increase damage per valid barrier action.
- Shop upgrades persist in the local progression save.
- Escape closes shop confirmations before closing the shop itself.
FEATURES TO TRY
- Hosting a private or public room and joining compatible online sessions
- Direct-IP, saved-server, recent-server, and public-room connection flows
- Text chat, player calls, player lists, relationships, and moderation tools
- Movement, jumping, camera rotation, and zoom
- Short, medium, and maximum-distance casts
- Valid water and invalid land casts
- Manual withdrawal before a bite
- Barrier-and-chase catching
- Accessibility auto-click settings
- Catch showcase and fish size variation
- Cooler, Bag, Logbook, favorites, and sorting
- Basic Fishing Rod equipment and the 19 hotbar
- Pelican selling and wallet updates
- Physical Fishing Shop sales and persistent fishing upgrades
- Save, Continue, New Game, and Delete Save
- Game Menu and persistent camera settings
- Water-entry recovery from several shores
SAVES AND SETTINGS
Progression and settings are stored in Godot's per-user application-data
directory, outside this extracted game folder. Delete Save removes progression
but preserves settings.
Windows:
%APPDATA%\Godot\app_userdata\NETFISHING\
Linux:
~/.local/share/godot/app_userdata/NETFISHING/
This is an early save format. Keep expectations modest and report any failure
to Continue, save, sell, favorite, or retain an individual fish.
FEEDBACK
Please include:
- Your operating system and whether you used mouse/keyboard or controller
- What you were doing when a problem occurred
- Whether the issue repeated after restarting
- Screenshots or a short recording when useful
- How movement, casting, chase pressure, barrier clicking, menus, and camera
controls felt
KNOWN ALPHA LIMITATIONS
- Public sessions remain direct connections; restrictive NAT or carrier-grade
networks may prevent some players from joining.
- Multiplayer, dedicated-server deployment, UI, and balance are still alpha.
- Some fish and character artwork remains temporary.
- There is no installer or automatic updater.
- Windows builds are unsigned.

60
docs/README.md Normal file
View file

@ -0,0 +1,60 @@
# NETfishing documentation
This directory is the single home for maintained project documentation.
Start here instead of searching feature, asset, world, or script directories
for local README files.
## Authoritative references
- [`DEVELOPMENT.md`](DEVELOPMENT.md): architecture, engineering decisions,
content and balance policy, authoring guidance, and validation.
- [`ATTRIBUTION.md`](ATTRIBUTION.md): ownership, credits, licensing map,
third-party notices, asset provenance, and redistribution requirements.
- [`PORTMASTER.md`](PORTMASTER.md): PortMaster packaging, installation,
controller mapping, performance behavior, and hardware release checks.
- [`README-PLAYTEST.txt`](README-PLAYTEST.txt): the player-facing README staged
into desktop playtest packages.
## Related repositories
- [Discovery service API](https://forge.makearmy.io/woofmeow/netfishing-discovery-server/src/branch/main/docs/API.md)
stays with the service implementation and defines its versioned HTTP
contract.
- [Dedicated-server packaging](https://forge.makearmy.io/woofmeow/netfishing-dedicated-server/src/branch/main/README.md)
stays with its installer and update scripts. It consumes this repository's
attribution and legal notices from the exact pinned game commit instead of
maintaining copies.
Those code-coupled references remain in their own repositories. Game-wide
architecture, authoring, licensing, credits, and provenance are not duplicated
there.
Exact runtime values and behavior remain authoritative in source code, scenes,
and resources. These documents describe boundaries, policy, and maintenance
procedures; they should not duplicate changing constants or inventories that
can be derived reliably from the project.
## Files intentionally kept at the repository root
The following are entry points or governing legal documents rather than
general project documentation, so they remain at conventional root paths:
- `README.md`
- `CONTRIBUTING.md`
- `LICENSE`
- `ASSET-LICENSE.md`
- `TRADEMARKS.md`
- `CONTRIBUTOR-TERMS.md`
Third-party font license texts stay beside their font files under `ui/fonts/`
so the licensed files and their original notices cannot drift apart. Build
scripts collect those legal files and the authoritative attribution record
when assembling releases.
## Maintenance rule
Do not add feature-specific README files elsewhere in the repository. Add or
update the appropriate reference above and link to its heading when source
comments need more context. Player-facing package instructions belong only in
`README-PLAYTEST.txt`; source and scripts remain authoritative for command-line
usage.

View file

@ -1,63 +0,0 @@
# 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.

View file

@ -1,27 +0,0 @@
# 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.

View file

@ -1,27 +0,0 @@
# 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.