Compare commits
No commits in common. "main" and "v0.18.0-alpha" have entirely different histories.
main
...
v0.18.0-al
|
|
@ -1,15 +1,15 @@
|
|||
# straywild Asset License 1.1
|
||||
# NETfishing Asset License 1.1
|
||||
|
||||
Copyright © 2026 Woofmeow. All rights reserved except for the permissions
|
||||
expressly granted below.
|
||||
|
||||
## 1. Scope
|
||||
|
||||
This license applies to original straywild artwork, graphics, textures,
|
||||
This license applies to original NETfishing artwork, graphics, textures,
|
||||
models, animations, music, sound recordings, narrative content, visual
|
||||
designs, characters, and other creative assets owned by the straywild owners
|
||||
designs, characters, and other creative assets owned by the NETfishing owners
|
||||
or licensed to them with authority to sublicense, publishing as Woofmeow (the
|
||||
**“straywild Assets”**).
|
||||
**“NETfishing Assets”**).
|
||||
|
||||
It does not apply to:
|
||||
|
||||
|
|
@ -17,77 +17,77 @@ It does not apply to:
|
|||
- third-party material identified in the source repository's
|
||||
`docs/ATTRIBUTION.md` or the packaged `ATTRIBUTION.md` notice;
|
||||
- material accompanied by a different license; or
|
||||
- the straywild and Woofmeow names and logos, which are addressed in
|
||||
- the NETfishing and Woofmeow names and logos, which are addressed in
|
||||
`TRADEMARKS.md`.
|
||||
|
||||
Repository location alone does not change third-party ownership or licensing.
|
||||
|
||||
## 2. Definitions
|
||||
|
||||
**Official straywild Software** means:
|
||||
**Official NETfishing Software** means:
|
||||
|
||||
- an unmodified binary release published by the straywild owners through an
|
||||
official straywild distribution channel; or
|
||||
- a build made from an unmodified official straywild source release or tagged
|
||||
- an unmodified binary release published by the NETfishing owners through an
|
||||
official NETfishing distribution channel; or
|
||||
- a build made from an unmodified official NETfishing source release or tagged
|
||||
revision.
|
||||
|
||||
**Mod** means a non-standalone add-on created to operate with Official
|
||||
straywild Software. A Mod may add, replace, or alter content loaded by the
|
||||
Official straywild Software, but it may not redistribute a replacement copy
|
||||
NETfishing Software. A Mod may add, replace, or alter content loaded by the
|
||||
Official NETfishing Software, but it may not redistribute a replacement copy
|
||||
of the game or represent a fork, clone, sequel, or separate game.
|
||||
|
||||
**Contribution Fork** means a source-control fork or clone of an official
|
||||
straywild source repository that is created and maintained in good faith
|
||||
NETfishing source repository that is created and maintained in good faith
|
||||
primarily to prepare, test, review, or submit changes for possible inclusion
|
||||
in Official straywild Software. It does not include a fork presented or
|
||||
in Official NETfishing Software. It does not include a fork presented or
|
||||
developed as an independent game, community edition, replacement distribution,
|
||||
or ongoing product separate from the official straywild project.
|
||||
or ongoing product separate from the official NETfishing project.
|
||||
|
||||
## 3. Permission to use the official game
|
||||
|
||||
You may reproduce straywild Assets as technically necessary to install, run,
|
||||
back up, and privately modify a lawfully obtained copy of Official straywild
|
||||
You may reproduce NETfishing Assets as technically necessary to install, run,
|
||||
back up, and privately modify a lawfully obtained copy of Official NETfishing
|
||||
Software.
|
||||
|
||||
You may capture, publish, and monetize screenshots, gameplay videos,
|
||||
livestreams, reviews, tutorials, and similar commentary showing a lawfully
|
||||
obtained copy of straywild. This permission does not authorize redistribution
|
||||
obtained copy of NETfishing. This permission does not authorize redistribution
|
||||
of the source asset files or imply endorsement.
|
||||
|
||||
## 4. Community Mod license
|
||||
|
||||
Subject to this license, you may create, modify, and distribute straywild
|
||||
Assets solely as part of a Mod for Official straywild Software.
|
||||
Subject to this license, you may create, modify, and distribute NETfishing
|
||||
Assets solely as part of a Mod for Official NETfishing Software.
|
||||
|
||||
This permission is worldwide, nonexclusive, royalty-free, and available for
|
||||
as long as you comply with this license. It permits only the copies of
|
||||
straywild Assets reasonably necessary for the Mod to function. It does not
|
||||
NETfishing Assets reasonably necessary for the Mod to function. It does not
|
||||
permit distributing the original game, a substantially complete collection of
|
||||
its assets, or a general-purpose asset pack.
|
||||
|
||||
A distributed Mod must:
|
||||
|
||||
1. require a separately obtained copy of Official straywild Software;
|
||||
1. require a separately obtained copy of Official NETfishing Software;
|
||||
2. be presented as unofficial community content;
|
||||
3. include the following notice in its documentation or distribution page:
|
||||
|
||||
> Contains or adapts straywild assets © 2026 Woofmeow, used under the
|
||||
> straywild Asset License 1.1. This Mod is unofficial and is not endorsed
|
||||
> Contains or adapts NETfishing assets © 2026 Woofmeow, used under the
|
||||
> NETfishing Asset License 1.1. This Mod is unofficial and is not endorsed
|
||||
> by Woofmeow.
|
||||
|
||||
4. identify material created by the Mod author separately from straywild
|
||||
4. identify material created by the Mod author separately from NETfishing
|
||||
Assets; and
|
||||
5. comply with `TRADEMARKS.md`.
|
||||
|
||||
Mods may be shared without charge and may accept voluntary donations that do
|
||||
not purchase access, features, or preferential treatment. Selling a Mod,
|
||||
charging for access to it, licensing it commercially, or using straywild
|
||||
charging for access to it, licensing it commercially, or using NETfishing
|
||||
Assets in paid products requires separate written permission from both
|
||||
straywild owners.
|
||||
NETfishing owners.
|
||||
|
||||
## 5. Contribution Fork license
|
||||
|
||||
Subject to this license, you may reproduce, modify, and distribute straywild
|
||||
Subject to this license, you may reproduce, modify, and distribute NETfishing
|
||||
Assets within a Contribution Fork. You may also make the nonpublic builds
|
||||
reasonably necessary to develop, test, and review its proposed contribution.
|
||||
|
||||
|
|
@ -99,8 +99,8 @@ fork are permitted distributions.
|
|||
A Contribution Fork must:
|
||||
|
||||
1. remain primarily directed toward preparing changes for possible inclusion
|
||||
in the official straywild project;
|
||||
2. preserve this license and the official straywild project's applicable
|
||||
in the official NETfishing project;
|
||||
2. preserve this license and the official NETfishing project's applicable
|
||||
attribution, third-party license, and copyright notices;
|
||||
3. remain visibly linked to or identified as a fork of the official source
|
||||
repository and not be presented as official or endorsed;
|
||||
|
|
@ -109,63 +109,63 @@ A Contribution Fork must:
|
|||
contribution;
|
||||
5. not publish general-audience binaries, releases, packages, or downloads,
|
||||
operate a persistent public alternative service, or monetize access;
|
||||
6. not distribute the straywild Assets as a standalone extraction, archive,
|
||||
6. not distribute the NETfishing Assets as a standalone extraction, archive,
|
||||
or general-purpose asset pack; and
|
||||
7. comply with `TRADEMARKS.md`.
|
||||
|
||||
Temporary access-controlled servers may be operated when reasonably necessary
|
||||
to test a proposed contribution. They may not be promoted or maintained as a
|
||||
public alternative to Official straywild Software or its services.
|
||||
public alternative to Official NETfishing Software or its services.
|
||||
|
||||
Submitting work from a Contribution Fork is governed separately by
|
||||
`CONTRIBUTOR-TERMS.md` and does not require the straywild owners to accept the
|
||||
`CONTRIBUTOR-TERMS.md` and does not require the NETfishing owners to accept the
|
||||
work. Declining or closing a proposed contribution does not retroactively
|
||||
invalidate good-faith use under this section. A compliant Contribution Fork
|
||||
may remain publicly accessible as an archival development record, but it may
|
||||
not be repurposed for continued development or distribution of a separate
|
||||
product containing straywild Assets.
|
||||
product containing NETfishing Assets.
|
||||
|
||||
## 6. Uses not permitted
|
||||
|
||||
Except as expressly permitted by Sections 3, 4, and 5 or by separate written
|
||||
permission from both straywild owners, you may not use or distribute
|
||||
straywild Assets:
|
||||
permission from both NETfishing owners, you may not use or distribute
|
||||
NETfishing Assets:
|
||||
|
||||
- in a fork, clone, remake, sequel, or standalone game that is not a qualifying
|
||||
Contribution Fork;
|
||||
- with a modified distribution of the GPL-covered straywild code that is not
|
||||
Official straywild Software, except for nonpublic contribution-testing
|
||||
- with a modified distribution of the GPL-covered NETfishing code that is not
|
||||
Official NETfishing Software, except for nonpublic contribution-testing
|
||||
builds permitted by Section 5;
|
||||
- in another game, application, asset library, template, or merchandise;
|
||||
- as a substantially complete asset extraction or archive;
|
||||
- in a way that implies sponsorship, endorsement, or official status;
|
||||
- to register a confusingly similar trademark, domain, account, or product
|
||||
identity; or
|
||||
- under terms that claim ownership of the straywild Assets themselves.
|
||||
- under terms that claim ownership of the NETfishing Assets themselves.
|
||||
|
||||
The GPL permits forks and redistribution of the GPL-covered code. Except for a
|
||||
qualifying Contribution Fork under Section 5, this asset license does not
|
||||
permit those forks to carry straywild Assets. A code fork that is not a
|
||||
Contribution Fork must remove or replace the straywild Assets and reserved
|
||||
permit those forks to carry NETfishing Assets. A code fork that is not a
|
||||
Contribution Fork must remove or replace the NETfishing Assets and reserved
|
||||
branding unless both owners grant separate written permission.
|
||||
|
||||
## 7. Ownership of Mods and contribution work
|
||||
|
||||
You retain ownership of your original Mod material and original material
|
||||
created in a Contribution Fork. The straywild owners retain ownership of the
|
||||
straywild Assets and adaptations of those assets to the extent provided by
|
||||
created in a Contribution Fork. The NETfishing owners retain ownership of the
|
||||
NETfishing Assets and adaptations of those assets to the extent provided by
|
||||
applicable law.
|
||||
|
||||
This license does not require you to assign or submit your original material.
|
||||
It also does not grant you ownership of the underlying straywild Assets. If
|
||||
you intentionally submit material for inclusion in straywild,
|
||||
It also does not grant you ownership of the underlying NETfishing Assets. If
|
||||
you intentionally submit material for inclusion in NETfishing,
|
||||
`CONTRIBUTOR-TERMS.md` applies separately.
|
||||
|
||||
## 8. Termination and cure
|
||||
|
||||
Your permissions under this license terminate automatically if you violate
|
||||
its terms. They are reinstated provisionally when you stop the violation and
|
||||
permanently if both straywild owners do not notify you of the violation
|
||||
permanently if both NETfishing owners do not notify you of the violation
|
||||
within sixty days after it has been cured.
|
||||
|
||||
Termination does not limit remedies available for activity outside this
|
||||
|
|
@ -173,15 +173,15 @@ license.
|
|||
|
||||
## 9. No warranty
|
||||
|
||||
THE straywild ASSETS ARE PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND,
|
||||
THE NETFISHING ASSETS ARE PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, TITLE, OR NON-INFRINGEMENT. TO THE MAXIMUM EXTENT
|
||||
PERMITTED BY LAW, THE OWNERS WILL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR
|
||||
OTHER LIABILITY ARISING FROM THIS LICENSE OR USE OF THE straywild ASSETS.
|
||||
OTHER LIABILITY ARISING FROM THIS LICENSE OR USE OF THE NETFISHING ASSETS.
|
||||
|
||||
## 10. Additional permission
|
||||
|
||||
Uses not granted here require written permission from both straywild owners.
|
||||
Uses not granted here require written permission from both NETfishing owners.
|
||||
A permission granted to one person or project does not amend this license for
|
||||
others.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Contribution policy
|
||||
|
||||
straywild is an owner-directed Woofmeow project and is not accepting
|
||||
NETfishing is an owner-directed Woofmeow project and is not accepting
|
||||
unsolicited contributions. Please do not submit pull requests, patches, code,
|
||||
artwork, models, audio, writing, documentation, translations, designs, or
|
||||
other implementation work. Pull requests are disabled for the official
|
||||
|
|
@ -17,7 +17,7 @@ work; it is not a standing invitation to contribute.
|
|||
|
||||
## Contribution forks
|
||||
|
||||
The [straywild Asset License](ASSET-LICENSE.md) contains limited permissions
|
||||
The [NETfishing Asset License](ASSET-LICENSE.md) contains limited permissions
|
||||
for qualifying Contribution Forks. Those permissions do not promise review or
|
||||
acceptance and do not override the policy above. Keep the hosting platform's
|
||||
fork relationship visible, preserve all license and attribution notices, and
|
||||
|
|
@ -79,4 +79,4 @@ using display strings as persistent identifiers.
|
|||
|
||||
New standalone source files should use `SPDX-License-Identifier:
|
||||
GPL-3.0-or-later` where the file format permits comments. Do not add that
|
||||
identifier to asset files governed by the straywild Asset License.
|
||||
identifier to asset files governed by the NETfishing Asset License.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# straywild contributor terms
|
||||
# NETfishing contributor terms
|
||||
|
||||
straywild does not accept unsolicited contributions. These terms are retained
|
||||
NETfishing does not accept unsolicited contributions. These terms are retained
|
||||
as the governing record for contributions previously accepted after their
|
||||
publication and for specific future work that both Owners expressly invite in
|
||||
writing before submission. They are not a request or standing invitation for
|
||||
|
|
@ -9,9 +9,9 @@ patches, pull requests, assets, or other material.
|
|||
These terms do not retroactively change ownership of earlier work or replace a
|
||||
separately signed agreement.
|
||||
|
||||
“Owners” means the two straywild co-owners who publish the Project as
|
||||
“Owners” means the two NETfishing co-owners who publish the Project as
|
||||
Woofmeow and are publicly credited as Voyager and Endeavour. “Project” means
|
||||
the official straywild game, its servers, tools, documentation, websites,
|
||||
the official NETfishing game, its servers, tools, documentation, websites,
|
||||
ports, updates, and promotional materials.
|
||||
|
||||
## 1. Your ownership and authority
|
||||
|
|
@ -56,8 +56,8 @@ royalty-free, transferable, and sublicensable license to:
|
|||
- license it to Project users under `ASSET-LICENSE.md` or a later Project asset
|
||||
license jointly approved by the Owners.
|
||||
|
||||
This grant is limited to straywild, its promotion, and official successor or
|
||||
derived straywild products. It does not transfer your copyright or authorize
|
||||
This grant is limited to NETfishing, its promotion, and official successor or
|
||||
derived NETfishing products. It does not transfer your copyright or authorize
|
||||
the Owners to sell your contribution as an unrelated standalone asset.
|
||||
|
||||
## 4. Documentation accompanying code
|
||||
|
|
@ -78,7 +78,7 @@ or release.
|
|||
|
||||
## 6. No automatic ownership, employment, or payment
|
||||
|
||||
Submitting a contribution does not provide ownership of straywild, create an
|
||||
Submitting a contribution does not provide ownership of NETfishing, create an
|
||||
employment, agency, partnership, or fiduciary relationship, or create a right
|
||||
to compensation. Any payment, ownership, or employment arrangement requires a
|
||||
separate written agreement signed by the appropriate parties.
|
||||
|
|
|
|||
28
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# straywild
|
||||
# NETfishing
|
||||
|
||||
straywild is a multiplayer-first fishing game built with Godot 4.7. The
|
||||
NETfishing is a multiplayer-first fishing game built with Godot 4.7. The
|
||||
current pre-alpha includes host-authoritative fishing and economy flows,
|
||||
freshwater and saltwater habitats, persistent player data, social features,
|
||||
customization, jobs, and a controller-aware interface.
|
||||
|
|
@ -8,39 +8,39 @@ customization, jobs, and a controller-aware interface.
|
|||
The project is under active development. Interfaces, balance, content, and
|
||||
save migrations may continue to change before a stable release.
|
||||
|
||||
straywild is developed and published by **Woofmeow**, the independent team of
|
||||
NETfishing is developed and published by **Woofmeow**, the independent team of
|
||||
co-owners publicly credited as Voyager and Endeavour.
|
||||
|
||||
## Links
|
||||
Patreon: https://www.patreon.com/cw/woofmeowgames
|
||||
|
||||
Steam: https://store.steampowered.com/app/5068950/straywild/
|
||||
Steam: https://store.steampowered.com/app/5068950/NETfishing/
|
||||
|
||||
Itch.io: https://sol6-vi.itch.io/straywild
|
||||
Itch.io: https://sol6-vi.itch.io/netfishing
|
||||
|
||||
Discord: https://discord.gg/5gP22447kc
|
||||
|
||||
Matrix: https://matrix.to/#/#straywild:matrix.makearmy.io
|
||||
Matrix: https://matrix.to/#/#netfishing:matrix.makearmy.io
|
||||
|
||||
Repo: https://forge.makearmy.io/woofmeow/straywild
|
||||
Repo: https://forge.makearmy.io/woofmeow/netfishing
|
||||
|
||||
Releases: https://forge.makearmy.io/woofmeow/straywild/releases
|
||||
Releases: https://forge.makearmy.io/woofmeow/netfishing/releases
|
||||
|
||||
|
||||
## Installing release builds
|
||||
|
||||
Download and extract the archive for your platform from the official release
|
||||
page, then run straywild from the extracted platform folder.
|
||||
page, then run NETfishing from the extracted platform folder.
|
||||
|
||||
### macOS
|
||||
|
||||
Current macOS builds are not signed or notarized. macOS may block the first
|
||||
launch because it cannot verify the developer. Control-click the straywild
|
||||
launch because it cannot verify the developer. Control-click the NETfishing
|
||||
application, choose **Open**, then confirm **Open**. If that option is not
|
||||
available, attempt to open the application once, then use **System Settings →
|
||||
Privacy & Security → Open Anyway**.
|
||||
|
||||
Only bypass this warning for a straywild build downloaded from an official
|
||||
Only bypass this warning for a NETfishing build downloaded from an official
|
||||
project release.
|
||||
|
||||
## Requirements
|
||||
|
|
@ -110,10 +110,10 @@ world and UI authoring, and testing are consolidated in
|
|||
- Project-owned software code is licensed under
|
||||
[GPL-3.0-or-later](LICENSE).
|
||||
- Project-owned artwork, models, music, and other creative assets are covered
|
||||
by the [straywild Asset License](ASSET-LICENSE.md). It permits community
|
||||
Mods for official straywild software and narrowly scoped contribution forks,
|
||||
by the [NETfishing Asset License](ASSET-LICENSE.md). It permits community
|
||||
Mods for official NETfishing software and narrowly scoped contribution forks,
|
||||
but not independent forks, clones, or unrelated products.
|
||||
- The straywild and Woofmeow names and branding are reserved as described in
|
||||
- The NETfishing and Woofmeow names and branding are reserved as described in
|
||||
[TRADEMARKS.md](TRADEMARKS.md).
|
||||
- Third-party materials retain their own terms; see the consolidated
|
||||
[credits, notices, and provenance record](docs/ATTRIBUTION.md).
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# straywild and Woofmeow branding
|
||||
# NETfishing and Woofmeow branding
|
||||
|
||||
The straywild and Woofmeow names, logos, icons, trade dress, and other source
|
||||
identifiers are reserved by the straywild owners, publishing as Woofmeow.
|
||||
The NETfishing and Woofmeow names, logos, icons, trade dress, and other source
|
||||
identifiers are reserved by the NETfishing owners, publishing as Woofmeow.
|
||||
Their presence in a GPL-licensed repository does not grant trademark rights or
|
||||
imply permission to represent another product as official.
|
||||
|
||||
|
|
@ -10,30 +10,30 @@ exist through use and other law.
|
|||
|
||||
## Permitted references
|
||||
|
||||
You may use the names straywild and Woofmeow truthfully to:
|
||||
You may use the names NETfishing and Woofmeow truthfully to:
|
||||
|
||||
- refer to the official game or development team;
|
||||
- state that software interoperates with or is a Mod for straywild;
|
||||
- state that software interoperates with or is a Mod for NETfishing;
|
||||
- link to an official repository or distribution page; and
|
||||
- discuss, review, criticize, or report on the Project.
|
||||
|
||||
Use only the amount of branding reasonably necessary to identify the Project.
|
||||
Do not imply sponsorship, certification, endorsement, or official status.
|
||||
|
||||
An unofficial Mod may use wording such as “Example Mod for straywild” if its
|
||||
An unofficial Mod may use wording such as “Example Mod for NETfishing” if its
|
||||
name and presentation remain clearly distinct and it displays an unofficial
|
||||
notice.
|
||||
|
||||
## Contribution forks
|
||||
|
||||
A qualifying Contribution Fork under `ASSET-LICENSE.md` may retain the
|
||||
straywild and Woofmeow names, logos, icons, and trade dress already present in
|
||||
NETfishing and Woofmeow names, logos, icons, and trade dress already present in
|
||||
the official source repository solely as necessary to reproduce, modify, and
|
||||
test the Project while preparing a proposed contribution. The source-control
|
||||
host's visible fork relationship or an equivalent repository notice must make
|
||||
its unofficial contribution purpose clear.
|
||||
|
||||
This permission does not allow a Contribution Fork to use straywild or
|
||||
This permission does not allow a Contribution Fork to use NETfishing or
|
||||
Woofmeow branding to advertise a public build, release, service, community
|
||||
edition, or independent product. It does not imply acceptance, sponsorship,
|
||||
endorsement, or official status.
|
||||
|
|
@ -44,7 +44,7 @@ The GNU GPL permits forks and redistribution of covered code. A fork or
|
|||
modified distribution that is not a qualifying Contribution Fork must:
|
||||
|
||||
- use a distinct product name;
|
||||
- remove straywild and Woofmeow logos, icons, and official trade dress;
|
||||
- remove NETfishing and Woofmeow logos, icons, and official trade dress;
|
||||
- avoid confusingly similar names, domains, package identifiers, and account
|
||||
names; and
|
||||
- clearly identify itself as independent and unofficial.
|
||||
|
|
@ -53,4 +53,4 @@ These branding terms do not limit rights granted by the GPL to the software
|
|||
code or lawful nominative, descriptive, comparative, or fair use.
|
||||
|
||||
Permission for broader branding use must be obtained in writing from both
|
||||
straywild owners.
|
||||
NETfishing owners.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[plugin]
|
||||
|
||||
name="straywild Shoreline Auto-Baker"
|
||||
name="NETfishing Shoreline Auto-Baker"
|
||||
description="Rebuilds configured static shoreline ribbons after authored terrain reimports."
|
||||
author="woofmeow"
|
||||
version="1.0.0"
|
||||
|
|
@ -4,12 +4,12 @@ importer="scene"
|
|||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://w7n4gjqq1juc"
|
||||
path="res://.godot/imported/straywild_base_character.glb-65021653e51a906d3b4a3494f170317f.scn"
|
||||
path="res://.godot/imported/netfishing_base_character.glb-0167c087f16181d405afb962dc877d2c.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/characters/base/straywild_base_character.glb"
|
||||
dest_files=["res://.godot/imported/straywild_base_character.glb-65021653e51a906d3b4a3494f170317f.scn"]
|
||||
source_file="res://art/exported/characters/base/netfishing_base_character.glb"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character.glb-0167c087f16181d405afb962dc877d2c.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dyjwgkgw0syo8"
|
||||
path.s3tc="res://.godot/imported/straywild_base_character_eyes_simple_shine.png-200a946ddace2078bbe44addb4e4524c.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_base_character_eyes_simple_shine.png-200a946ddace2078bbe44addb4e4524c.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/characters/base/straywild_base_character_eyes_simple_shine.png"
|
||||
dest_files=["res://.godot/imported/straywild_base_character_eyes_simple_shine.png-200a946ddace2078bbe44addb4e4524c.s3tc.ctex", "res://.godot/imported/straywild_base_character_eyes_simple_shine.png-200a946ddace2078bbe44addb4e4524c.etc2.ctex"]
|
||||
source_file="res://art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.s3tc.ctex", "res://.godot/imported/netfishing_base_character_eyes_simple_shine.png-140bfa3aa0b6f662e8ff9e5721213a61.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dt5gitdtjdvcd"
|
||||
path.s3tc="res://.godot/imported/straywild_base_character_mouth_three.png-5bcf329b31a11eff496760a63e62d0e2.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_base_character_mouth_three.png-5bcf329b31a11eff496760a63e62d0e2.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/characters/base/straywild_base_character_mouth_three.png"
|
||||
dest_files=["res://.godot/imported/straywild_base_character_mouth_three.png-5bcf329b31a11eff496760a63e62d0e2.s3tc.ctex", "res://.godot/imported/straywild_base_character_mouth_three.png-5bcf329b31a11eff496760a63e62d0e2.etc2.ctex"]
|
||||
source_file="res://art/exported/characters/base/netfishing_base_character_mouth_three.png"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.s3tc.ctex", "res://.godot/imported/netfishing_base_character_mouth_three.png-90b4a98403d2a291a56a8ed42aaa8473.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bmho1ryst3smt"
|
||||
path.s3tc="res://.godot/imported/straywild_base_character_nose_dog_round.png-e6909a2c139cf4a2748c2b79d1e12d92.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_base_character_nose_dog_round.png-e6909a2c139cf4a2748c2b79d1e12d92.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/characters/base/straywild_base_character_nose_dog_round.png"
|
||||
dest_files=["res://.godot/imported/straywild_base_character_nose_dog_round.png-e6909a2c139cf4a2748c2b79d1e12d92.s3tc.ctex", "res://.godot/imported/straywild_base_character_nose_dog_round.png-e6909a2c139cf4a2748c2b79d1e12d92.etc2.ctex"]
|
||||
source_file="res://art/exported/characters/base/netfishing_base_character_nose_dog_round.png"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.s3tc.ctex", "res://.godot/imported/netfishing_base_character_nose_dog_round.png-0008adff5271dd0403e610ef13dd52cf.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://dsa6yss1sxfcy"
|
||||
path="res://.godot/imported/net.glb-cbbc53905aec6a50c4a3322ca7a93b1e.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/items/equipment/net.glb"
|
||||
dest_files=["res://.godot/imported/net.glb-cbbc53905aec6a50c4a3322ca7a93b1e.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
mesh_library/use_node_names_as_mesh_names=false
|
||||
array_mesh/deduplicate_surfaces=true
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
gltf/texture_map_mode=1
|
||||
|
Before Width: | Height: | Size: 276 KiB |
|
|
@ -1,45 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://binoqhg45vgbs"
|
||||
path.s3tc="res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={
|
||||
"md5": "ef2c2ae657c9460c90eb808ba5217f39"
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/items/equipment/net_Material.png"
|
||||
dest_files=["res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.s3tc.ctex", "res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
|
Before Width: | Height: | Size: 42 KiB |
|
|
@ -1,45 +0,0 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cdsabucjy5rpk"
|
||||
path.s3tc="res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
}
|
||||
generator_parameters={
|
||||
"md5": "a6001c381d4c8e16bd2d64ea74ccff82"
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/items/equipment/net_Plane Base Color.png"
|
||||
dest_files=["res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.s3tc.ctex", "res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=2
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=0
|
||||
BIN
art/exported/system_icons/netfishing.ico
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
art/exported/system_icons/netfishing_1024.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bkh5hw8wwu8pc"
|
||||
path="res://.godot/imported/straywild_1024.png-b9b5c159c9fcecc21b04324370d4522f.ctex"
|
||||
path="res://.godot/imported/netfishing_1024.png-7c53a099ed2743b4a623c258641b1d29.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/system_icons/straywild_1024.png"
|
||||
dest_files=["res://.godot/imported/straywild_1024.png-b9b5c159c9fcecc21b04324370d4522f.ctex"]
|
||||
source_file="res://art/exported/system_icons/netfishing_1024.png"
|
||||
dest_files=["res://.godot/imported/netfishing_1024.png-7c53a099ed2743b4a623c258641b1d29.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
BIN
art/exported/system_icons/netfishing_256.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cty16m8ydla06"
|
||||
path="res://.godot/imported/straywild_256.png-87b7e62e710eae4d3e3ed24a8454ca6d.ctex"
|
||||
path="res://.godot/imported/netfishing_256.png-d9dfc9c7871ac38bc73d09d00df679be.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/exported/system_icons/straywild_256.png"
|
||||
dest_files=["res://.godot/imported/straywild_256.png-87b7e62e710eae4d3e3ed24a8454ca6d.ctex"]
|
||||
source_file="res://art/exported/system_icons/netfishing_256.png"
|
||||
dest_files=["res://.godot/imported/netfishing_256.png-d9dfc9c7871ac38bc73d09d00df679be.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 362 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
|
@ -4,12 +4,12 @@ importer="scene"
|
|||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cb4bcakhoprm8"
|
||||
path="res://.godot/imported/straywild_base_character.blend-02abbfdb9b1d393f1bd3cfface615e27.scn"
|
||||
path="res://.godot/imported/netfishing_base_character.blend-65bf3bc5b77cc1a37fa3f81ebd808d37.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_base_character.blend"
|
||||
dest_files=["res://.godot/imported/straywild_base_character.blend-02abbfdb9b1d393f1bd3cfface615e27.scn"]
|
||||
source_file="res://art/source/characters/base/netfishing_base_character.blend"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character.blend-65bf3bc5b77cc1a37fa3f81ebd808d37.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -4,12 +4,12 @@ importer="scene"
|
|||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://bfhnup14638r7"
|
||||
path="res://.godot/imported/straywild_base_character.glb-c9650c715a1b5b9ae0d8541191f7d7a9.scn"
|
||||
path="res://.godot/imported/netfishing_base_character.glb-cbdc33eaa4fcd1d2d2a8f4a463b228d6.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_base_character.glb"
|
||||
dest_files=["res://.godot/imported/straywild_base_character.glb-c9650c715a1b5b9ae0d8541191f7d7a9.scn"]
|
||||
source_file="res://art/source/characters/base/netfishing_base_character.glb"
|
||||
dest_files=["res://.godot/imported/netfishing_base_character.glb-cbdc33eaa4fcd1d2d2a8f4a463b228d6.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -4,12 +4,12 @@ importer="scene"
|
|||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://d38y8blk2w5c5"
|
||||
path="res://.godot/imported/straywild_character_source.blend-0e7b8a87008f88e309ad73a63561ef5b.scn"
|
||||
path="res://.godot/imported/netfishing_character_source.blend-1d18c95606937d4c8bcb87e334e02ee5.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source.blend"
|
||||
dest_files=["res://.godot/imported/straywild_character_source.blend-0e7b8a87008f88e309ad73a63561ef5b.scn"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source.blend"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source.blend-1d18c95606937d4c8bcb87e334e02ee5.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -4,12 +4,12 @@ importer="scene"
|
|||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://3uq4cxiomttt"
|
||||
path="res://.godot/imported/straywild_character_source.glb-3a8ccc55dbe60da1b70b62110b206353.scn"
|
||||
path="res://.godot/imported/netfishing_character_source.glb-9c98ee44b142c5b3d06f0838b7d2c9c4.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source.glb"
|
||||
dest_files=["res://.godot/imported/straywild_character_source.glb-3a8ccc55dbe60da1b70b62110b206353.scn"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source.glb"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source.glb-9c98ee44b142c5b3d06f0838b7d2c9c4.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bdomsntfeovnc"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_eyes1_eyebrows1.png-3c638377e631a94b998336d0ca1d8b8e.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_eyes1_eyebrows1.png-3c638377e631a94b998336d0ca1d8b8e.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_eyes1_eyebrows1.png-a0b9f287e407afd9688e141dc5f2b801.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_eyes1_eyebrows1.png-a0b9f287e407afd9688e141dc5f2b801.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_eyes1_eyebrows1.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_eyes1_eyebrows1.png-3c638377e631a94b998336d0ca1d8b8e.s3tc.ctex", "res://.godot/imported/straywild_character_source_eyes1_eyebrows1.png-3c638377e631a94b998336d0ca1d8b8e.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_eyes1_eyebrows1.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_eyes1_eyebrows1.png-a0b9f287e407afd9688e141dc5f2b801.s3tc.ctex", "res://.godot/imported/netfishing_character_source_eyes1_eyebrows1.png-a0b9f287e407afd9688e141dc5f2b801.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://du4u6meapay05"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_eyes_simple_shine.png-97500ad873e0da3aaf0e9e3c3198e38a.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_eyes_simple_shine.png-97500ad873e0da3aaf0e9e3c3198e38a.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_eyes_simple_shine.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_eyes_simple_shine.png-97500ad873e0da3aaf0e9e3c3198e38a.s3tc.ctex", "res://.godot/imported/straywild_character_source_eyes_simple_shine.png-97500ad873e0da3aaf0e9e3c3198e38a.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_eyes_simple_shine.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.s3tc.ctex", "res://.godot/imported/netfishing_character_source_eyes_simple_shine.png-965743f3716320bbc385096956ffef2d.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://css0k0virgoph"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_mouth1.png-ff2ed280ca7e84bdd0749ed5b5b16f54.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_mouth1.png-ff2ed280ca7e84bdd0749ed5b5b16f54.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_mouth1.png-b323b9153acd3f552f35c1d1108567c8.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_mouth1.png-b323b9153acd3f552f35c1d1108567c8.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_mouth1.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_mouth1.png-ff2ed280ca7e84bdd0749ed5b5b16f54.s3tc.ctex", "res://.godot/imported/straywild_character_source_mouth1.png-ff2ed280ca7e84bdd0749ed5b5b16f54.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_mouth1.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_mouth1.png-b323b9153acd3f552f35c1d1108567c8.s3tc.ctex", "res://.godot/imported/netfishing_character_source_mouth1.png-b323b9153acd3f552f35c1d1108567c8.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://di20c1x8vksi1"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_mouth_three.png-adf40ee30e725bafadf6a8fa4dbd8abf.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_mouth_three.png-adf40ee30e725bafadf6a8fa4dbd8abf.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_mouth_three.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_mouth_three.png-adf40ee30e725bafadf6a8fa4dbd8abf.s3tc.ctex", "res://.godot/imported/straywild_character_source_mouth_three.png-adf40ee30e725bafadf6a8fa4dbd8abf.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_mouth_three.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.s3tc.ctex", "res://.godot/imported/netfishing_character_source_mouth_three.png-6bf79d4c9c660d30fb7fc365f0039313.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://7dwa0bfev1rk"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_nose1.2.png-0a8355472731651768eaa5fc2ee168d4.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_nose1.2.png-0a8355472731651768eaa5fc2ee168d4.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_nose1.2.png-ef4dd456c5b0f0db73b3dc063bfba941.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_nose1.2.png-ef4dd456c5b0f0db73b3dc063bfba941.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_nose1.2.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_nose1.2.png-0a8355472731651768eaa5fc2ee168d4.s3tc.ctex", "res://.godot/imported/straywild_character_source_nose1.2.png-0a8355472731651768eaa5fc2ee168d4.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_nose1.2.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_nose1.2.png-ef4dd456c5b0f0db73b3dc063bfba941.s3tc.ctex", "res://.godot/imported/netfishing_character_source_nose1.2.png-ef4dd456c5b0f0db73b3dc063bfba941.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
|
@ -3,8 +3,8 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b0p55hwdry2cr"
|
||||
path.s3tc="res://.godot/imported/straywild_character_source_nose_dog_round.png-d1ea0db61e41dfeeed3b599286ffb82c.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/straywild_character_source_nose_dog_round.png-d1ea0db61e41dfeeed3b599286ffb82c.etc2.ctex"
|
||||
path.s3tc="res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.s3tc.ctex"
|
||||
path.etc2="res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.etc2.ctex"
|
||||
metadata={
|
||||
"imported_formats": ["s3tc_bptc", "etc2_astc"],
|
||||
"vram_texture": true
|
||||
|
|
@ -15,8 +15,8 @@ generator_parameters={
|
|||
|
||||
[deps]
|
||||
|
||||
source_file="res://art/source/characters/base/straywild_character_source_nose_dog_round.png"
|
||||
dest_files=["res://.godot/imported/straywild_character_source_nose_dog_round.png-d1ea0db61e41dfeeed3b599286ffb82c.s3tc.ctex", "res://.godot/imported/straywild_character_source_nose_dog_round.png-d1ea0db61e41dfeeed3b599286ffb82c.etc2.ctex"]
|
||||
source_file="res://art/source/characters/base/netfishing_character_source_nose_dog_round.png"
|
||||
dest_files=["res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.s3tc.ctex", "res://.godot/imported/netfishing_character_source_nose_dog_round.png-1c89150861ebff3f930698c1747a0369.etc2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ prove authorship or licensing.
|
|||
|
||||
## Ownership and credits
|
||||
|
||||
straywild is jointly owned, developed, and published by its creators,
|
||||
NETfishing is jointly owned, developed, and published by its creators,
|
||||
publicly credited as Voyager and Endeavour and operating collectively as the
|
||||
independent team Woofmeow.
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ independent team Woofmeow.
|
|||
|
||||
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 straywild, Woofmeow, or its owners.
|
||||
credits do not imply endorsement of NETfishing, Woofmeow, or its owners.
|
||||
|
||||
## License map
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ Do not describe the complete repository as covered only by the GPL.
|
|||
| --- | --- |
|
||||
| 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` |
|
||||
| straywild and Woofmeow names, logos, icons, and official identity | Source-root or packaged `TRADEMARKS.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 |
|
||||
| Previously accepted or expressly invited outside contributions | Source-root `CONTRIBUTOR-TERMS.md` plus any separately signed agreement |
|
||||
|
||||
|
|
@ -50,22 +50,22 @@ 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 straywild creative assets or branding. The
|
||||
straywild Asset License separately permits qualifying noncommercial add-on
|
||||
Mods for official straywild software and narrowly scoped Contribution Forks
|
||||
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 and narrowly scoped Contribution Forks
|
||||
used to prepare changes for possible upstream inclusion. It does not permit
|
||||
those assets to accompany independent code forks, clones, standalone games,
|
||||
unrelated products, or general-purpose asset packs. A GPL fork that is not a
|
||||
qualifying Contribution Fork must replace straywild assets and reserved
|
||||
qualifying Contribution 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 straywild owners under their private joint
|
||||
written approval from both NETfishing owners under their private joint
|
||||
ownership agreement.
|
||||
|
||||
## Godot Engine notice
|
||||
|
||||
straywild uses Godot Engine under the MIT License:
|
||||
NETfishing uses Godot Engine under the MIT License:
|
||||
|
||||
> Copyright (c) 2014-present Godot Engine contributors.
|
||||
> Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
|
||||
|
|
@ -103,7 +103,7 @@ FreeType for font rendering; portions are copyright The FreeType Project
|
|||
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 straywild Asset License.
|
||||
Public-domain fonts are not governed by the NETfishing Asset License.
|
||||
|
||||
## Intake policy
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ owners' private project records. This public document should contain the
|
|||
credits and license notices needed by recipients; it should not duplicate a
|
||||
changing file inventory that can be derived from the repository itself.
|
||||
|
||||
straywild does not accept unsolicited contributions. For work expressly
|
||||
NETfishing does not accept unsolicited contributions. For work expressly
|
||||
invited by both Owners, maintainers must obtain affirmative agreement to the
|
||||
source-root `CONTRIBUTOR-TERMS.md` and retain the written invitation and
|
||||
agreement in a durable Project record.
|
||||
|
|
@ -159,8 +159,8 @@ against the repository when this record was revised.
|
|||
|
||||
| Material | Runtime location | Credit or terms |
|
||||
| --- | --- | --- |
|
||||
| Kat animalese alphabet and number sounds | `sound/dialogue/animalese/alphanumeric/` | Project-processed derivatives of the original source voice recording supplied by straywild community member kat. |
|
||||
| Kim animalese alphabet and number sounds | `sound/dialogue/animalese/kim/` | Project-processed derivatives of the original source voice recording supplied by straywild community member kim. |
|
||||
| Kat animalese alphabet and number sounds | `sound/dialogue/animalese/alphanumeric/` | Project-processed derivatives of the original source voice recording supplied by NETfishing community member kat. |
|
||||
| Kim animalese alphabet and number sounds | `sound/dialogue/animalese/kim/` | Project-processed derivatives of the original source voice recording supplied by NETfishing community member kim. |
|
||||
| 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; notice in `ui/fonts/Seattle-Avenue-LICENSE.txt`. |
|
||||
| Fishing fight loop | `audio/sfx/fishing/fighting.wav` | Edited from “Spinning reel.wav” by Freesound user tosha73, sound 509902, CC0. |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Development reference
|
||||
|
||||
This is the authoritative reference for straywild architecture, engineering
|
||||
This is the authoritative reference for NETfishing architecture, engineering
|
||||
decisions, content policy, authoring, and validation.
|
||||
|
||||
## Architecture
|
||||
|
|
@ -43,7 +43,7 @@ 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 `straywild_DISCOVERY_URL` available as a
|
||||
`network/discovery/base_url`, with `NETFISHING_DISCOVERY_URL` available as a
|
||||
development/deployment override.
|
||||
|
||||
Friendships are local identity relationships shared across save slots. A live,
|
||||
|
|
@ -261,7 +261,7 @@ copies of the entire customization catalog.
|
|||
|
||||
### Texture sampling
|
||||
|
||||
straywild artwork uses nearest-neighbor sampling. Do not enable linear,
|
||||
NETfishing artwork uses nearest-neighbor sampling. Do not enable linear,
|
||||
bilinear, trilinear, or anisotropic texture filtering. Shader samplers must
|
||||
declare `filter_nearest`. The three canonical repeating terrain textures are
|
||||
the sole mipmap exception: their projected shader uses nearest-filtered
|
||||
|
|
@ -351,10 +351,10 @@ godot --headless --path . --script tests/fish_catalog_content_validation.gd
|
|||
rm -rf -- "$test_root"
|
||||
```
|
||||
|
||||
Do not point `straywild_DATA_DIR` at an arbitrary empty directory; it is an
|
||||
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. The
|
||||
PortMaster launcher is the narrow exception: it also sets
|
||||
`straywild_CREATE_DATA_DIR=1`, allowing the game to initialize its known empty
|
||||
`NETFISHING_CREATE_DATA_DIR=1`, allowing the game to initialize its known empty
|
||||
external save directory on first launch.
|
||||
|
||||
Headless tests cannot prove visual alignment, mouse routing, shader appearance,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# PortMaster reference
|
||||
|
||||
straywild's PortMaster release is a canonical PortMaster package, not a
|
||||
NETfishing's PortMaster release is a canonical PortMaster package, not a
|
||||
version-named generic ZIP. The installer-facing archive must be named
|
||||
`straywild.zip`, and its root must contain exactly:
|
||||
`netfishing.zip`, and its root must contain exactly:
|
||||
|
||||
```text
|
||||
straywild.sh
|
||||
straywild/
|
||||
NETfishing.sh
|
||||
netfishing/
|
||||
```
|
||||
|
||||
`port.json` belongs at `straywild/port.json` in the distributable archive.
|
||||
`port.json` belongs at `netfishing/port.json` in the distributable archive.
|
||||
The upstream source-submission layout keeps it beside the launcher and port
|
||||
directory, but PortMaster's release builder relocates it into the declared
|
||||
port directory. Do not copy the source-submission layout directly into a
|
||||
|
|
@ -17,7 +17,7 @@ release ZIP.
|
|||
|
||||
HarbourMaster's installer also relocates recognized non-script files found at
|
||||
an archive root into the detected port directory. That compatibility behavior
|
||||
masked straywild's former root-level `port.json` during auto-install tests.
|
||||
masked NETfishing's former root-level `port.json` during auto-install tests.
|
||||
Directly extracting the same archive into `/ports` did not perform the repair.
|
||||
Do not rely on installer relocation; build the distributable layout correctly.
|
||||
|
||||
|
|
@ -26,34 +26,30 @@ directory. The templates in `scripts/portmaster/` are authoritative.
|
|||
|
||||
## Release contract
|
||||
|
||||
- `port.json` uses schema version 4, names `straywild.zip`, and marks the
|
||||
- `port.json` uses schema version 4, names `netfishing.zip`, and marks the
|
||||
self-contained package ready to run.
|
||||
- `straywild.sh` does not contain a `# PORTMASTER:` signature in the source or
|
||||
- `NETfishing.sh` does not contain a `# PORTMASTER:` signature in the source or
|
||||
distributable archive. HarbourMaster adds that installation marker when it
|
||||
installs the port.
|
||||
- The executable is `straywild/straywild.aarch64`.
|
||||
- The executable is `netfishing/NETfishing.aarch64`.
|
||||
- The package declares AArch64, two analog sticks, GLIBC 2.28, and
|
||||
`weston_pkg_0.2.squashfs`.
|
||||
- The launcher starts GPTOKEYB with the explicit `straywild.gptk` no-op map.
|
||||
- The launcher starts GPTOKEYB with the explicit `netfishing.gptk` no-op map.
|
||||
Every keyboard and mouse binding is disabled, leaving only GPTOKEYB's
|
||||
device-specific force-quit chord while Godot and straywild's controller
|
||||
device-specific force-quit chord while Godot and NETfishing's controller
|
||||
mapping manager handle gameplay input. The explicit map also avoids the
|
||||
anomalous controller behavior observed on ROCKNIX without a passthrough map.
|
||||
- The launcher calls `pm_platform_helper` for the game executable after
|
||||
starting GPTOKEYB and calls `pm_finish` after the game exits.
|
||||
- straywild automatically creates player data for new installations under
|
||||
`ports/saves/straywild/` and does not present the in-game folder picker.
|
||||
- NETfishing automatically creates player data for new installations under
|
||||
`ports/saves/netfishing/` and does not present the in-game folder picker.
|
||||
- Existing installations with a selected data root keep that location when
|
||||
upgraded. Device-local data, configuration, and cache remain under
|
||||
`straywild/conf/data`, `straywild/conf/config`, and
|
||||
`straywild/conf/cache`.
|
||||
- A rebrand upgrade copies an existing `netfishing/conf/` tree into the new
|
||||
`straywild/conf/` tree when the latter does not exist. It also reuses an
|
||||
existing `ports/saves/netfishing/` data root rather than creating an empty
|
||||
replacement. New installations use straywild paths exclusively.
|
||||
`netfishing/conf/data`, `netfishing/conf/config`, and
|
||||
`netfishing/conf/cache`.
|
||||
- The archive must not contain `conf/`, saves, identities, logs, source files,
|
||||
`.git`, or `.godot` content.
|
||||
- Release downloads must publish only the canonical `straywild.zip` for this
|
||||
- Release downloads must publish only the canonical `netfishing.zip` for this
|
||||
platform. Do not also publish a byte-identical versioned PortMaster ZIP;
|
||||
HarbourMaster identifies the port by its canonical archive name and the
|
||||
Forgejo release tag already supplies the version.
|
||||
|
|
@ -71,7 +67,7 @@ The script deletes and regenerates the Linux ARM64 export, stages the package,
|
|||
validates its structure, and writes:
|
||||
|
||||
```text
|
||||
builds/v<project-version>/straywild.zip
|
||||
builds/v<project-version>/netfishing.zip
|
||||
```
|
||||
|
||||
`--package-only` is reserved for repackaging an already validated ARM64 export.
|
||||
|
|
@ -87,7 +83,7 @@ bash scripts/build_portmaster.sh --package-only --hotfix
|
|||
|
||||
The hotfix keeps the game executable and PCK tied to the release tag while
|
||||
recording the newer packaging commit separately in `BUILD-INFO.txt`. Replace
|
||||
the release's existing `straywild.zip`; never move the game release tag.
|
||||
the release's existing `netfishing.zip`; never move the game release tag.
|
||||
|
||||
## Local muOS installation
|
||||
|
||||
|
|
@ -97,22 +93,22 @@ The muOS auto-install directory is:
|
|||
/mnt/mmc/MUOS/PortMaster/autoinstall/
|
||||
```
|
||||
|
||||
For an explicit offline installation test, copy `straywild.zip` to a temporary
|
||||
For an explicit offline installation test, copy `netfishing.zip` to a temporary
|
||||
device directory and run:
|
||||
|
||||
```bash
|
||||
/mnt/mmc/MUOS/PortMaster/harbourmaster \
|
||||
--offline --no-check install ./straywild.zip
|
||||
--offline --no-check install ./netfishing.zip
|
||||
```
|
||||
|
||||
Before upgrading an existing installation, preserve either the current
|
||||
`/mnt/mmc/ports/straywild/` paths or the former `/mnt/mmc/ports/netfishing/`
|
||||
paths on the device. After installation:
|
||||
Before upgrading an existing installation, preserve
|
||||
`/mnt/mmc/ports/netfishing/conf/` and `/mnt/mmc/ports/saves/netfishing/` on the
|
||||
device. After installation:
|
||||
|
||||
1. Confirm the installed executable and PCK hashes match the staged release.
|
||||
2. Confirm HarbourMaster added its `# PORTMASTER:` installation signature to
|
||||
the installed launcher, then confirm the launcher starts GPTOKEYB with
|
||||
`straywild.gptk` and calls `pm_platform_helper` for the game executable.
|
||||
`netfishing.gptk` and calls `pm_platform_helper` for the game executable.
|
||||
3. Confirm `conf/` and the external save directory were not replaced or
|
||||
removed.
|
||||
4. Launch the installed port through the normal muOS menu.
|
||||
|
|
@ -121,7 +117,7 @@ paths on the device. After installation:
|
|||
Start+Select on most devices.
|
||||
|
||||
Installing the public PortMaster catalog entry can still install an older
|
||||
catalog build until the upstream `straywild.zip` is updated. A local release
|
||||
catalog build until the upstream `netfishing.zip` is updated. A local release
|
||||
test must install the generated local archive explicitly.
|
||||
|
||||
## Template provenance
|
||||
|
|
@ -134,7 +130,7 @@ f24daae48f543b3a270a5aa46b5e73a31904bf0c7216d4c8a9e15a8dc48a5eed screenshot.png
|
|||
```
|
||||
|
||||
The remaining catalog metadata assets were copied from the installed official
|
||||
`straywild.zip` package and are intentionally preserved byte-for-byte:
|
||||
`netfishing.zip` package and are intentionally preserved byte-for-byte:
|
||||
|
||||
```text
|
||||
e2a9d132744684c67865c01eca027a8c9946b4c5a19da57c82f1af0373dc83b7 gameinfo.xml
|
||||
|
|
@ -164,7 +160,7 @@ The device-verified Godot mapping is:
|
|||
- left-stick click `b9`, left trigger `b10`, right trigger `b11`, right-stick click `b12`
|
||||
- D-pad `h0`; left and right sticks `a0..a3`
|
||||
|
||||
`scripts/portmaster/straywild.sh` must replace the incompatible SDL2 entry
|
||||
`scripts/portmaster/NETfishing.sh` must replace the incompatible SDL2 entry
|
||||
with the Godot entry when that SDL2 GUID is selected. Do not append the two
|
||||
entries with a newline. WestonPack reconstructs the wrapped game command
|
||||
through a shell, so raw mapping values passed in that command can be split into
|
||||
|
|
@ -173,14 +169,14 @@ this failure with the `GO-Super Gamepad` mapping. The outer Weston environment
|
|||
also does not reliably preserve the corrected muOS mapping for the game.
|
||||
|
||||
Write the exact selected mapping to `conf/cache/controller_mapping.txt` before
|
||||
starting Weston. Weston must launch `launch-straywild.sh`, which reads that
|
||||
starting Weston. Weston must launch `launch-netfishing.sh`, which reads that
|
||||
file, exports `SDL_GAMECONTROLLERCONFIG`, and immediately replaces itself with
|
||||
the game process. This applies the mapping at the same point as the working
|
||||
0.10.1 launcher without passing its raw text through WestonPack's command
|
||||
reconstruction. Do not move the mapping back to either side of
|
||||
`westonwrap.sh`.
|
||||
|
||||
Always pass `straywild.gptk`, which explicitly unassigns every direct and
|
||||
Always pass `netfishing.gptk`, which explicitly unassigns every direct and
|
||||
hotkey binding with GPTOKEYB's `\"` value. This keeps GPTOKEYB from injecting
|
||||
keyboard or mouse events on top of Godot's native controller input and retains
|
||||
the device-specific kill chord. Supplying the explicit passthrough map also
|
||||
|
|
@ -213,8 +209,8 @@ The light profile passes these Godot options:
|
|||
- `--max-fps 30`
|
||||
- `--audio-output-latency 40`
|
||||
|
||||
It also passes `straywild_PERFORMANCE_PROFILE=light` and
|
||||
`straywild_LOW_END=1`. The game renders the 3D world at 37.5% linear
|
||||
It also passes `NETFISHING_PERFORMANCE_PROFILE=light` and
|
||||
`NETFISHING_LOW_END=1`. The game renders the 3D world at 37.5% linear
|
||||
resolution with nearest-neighbor scaling, reducing 3D pixel work by about 86%
|
||||
while the separately rendered UI retains its canonical resolution. The light
|
||||
profile also:
|
||||
|
|
@ -248,7 +244,7 @@ omitted ambience or replace the micro textures with desktop-resolution assets.
|
|||
The normal profile otherwise retains the full visual presentation.
|
||||
|
||||
To opt a capable device into the normal profile, create the persistent file
|
||||
`straywild/conf/performance_profile` containing exactly:
|
||||
`netfishing/conf/performance_profile` containing exactly:
|
||||
|
||||
```text
|
||||
normal
|
||||
|
|
@ -257,13 +253,13 @@ normal
|
|||
On a typical muOS installation, the full path is:
|
||||
|
||||
```text
|
||||
/mnt/mmc/ports/straywild/conf/performance_profile
|
||||
/mnt/mmc/ports/netfishing/conf/performance_profile
|
||||
```
|
||||
|
||||
Set the file to `light`, or remove it, to restore the default. An externally
|
||||
provided `straywild_PERFORMANCE_PROFILE=normal` or `light` environment value
|
||||
provided `NETFISHING_PERFORMANCE_PROFILE=normal` or `light` environment value
|
||||
takes precedence over the persistent file. Invalid values safely fall back to
|
||||
the light profile and are reported in `straywild/log.txt`.
|
||||
the light profile and are reported in `netfishing/log.txt`.
|
||||
|
||||
Do not use Godot's low processor mode for the light profile. It reduces idle
|
||||
CPU usage by sleeping between updates and is not a game-performance
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
straywild
|
||||
v0.19.0-alpha
|
||||
Alpha 0.19.0
|
||||
NETfishing
|
||||
v0.18.0-alpha
|
||||
Alpha 0.18.0
|
||||
|
||||
Thank you for trying this early private playtest.
|
||||
|
||||
straywild is an early multiplayer fishing game. This alpha includes local
|
||||
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.
|
||||
|
|
@ -12,15 +12,15 @@ 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 straywild.pck together.
|
||||
3. Launch straywild.exe on Windows or straywild on Linux.
|
||||
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 straywild
|
||||
chmod +x netfishing
|
||||
|
||||
CONTROLS
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# straywild documentation
|
||||
# NETfishing documentation
|
||||
|
||||
This directory is the single home for maintained project documentation.
|
||||
Start here instead of searching feature, asset, world, or script directories
|
||||
|
|
@ -17,10 +17,10 @@ for local README files.
|
|||
|
||||
## Related repositories
|
||||
|
||||
- [Discovery service API](https://forge.makearmy.io/woofmeow/straywild-discovery-server/src/branch/main/docs/API.md)
|
||||
- [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/straywild-dedicated-server/src/branch/main/README.md)
|
||||
- [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.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*"
|
||||
export_path="builds/v0.19.0-alpha/windows-x86_64/straywild.exe"
|
||||
export_path="builds/v0.18.0-alpha/windows-x86_64/NETfishing.exe"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
@ -32,16 +32,16 @@ codesign/digest_algorithm=1
|
|||
codesign/description=""
|
||||
codesign/custom_options=PackedStringArray()
|
||||
application/modify_resources=true
|
||||
application/icon="res://art/exported/system_icons/straywild.ico"
|
||||
application/icon="res://art/exported/system_icons/netfishing.ico"
|
||||
application/console_wrapper_icon=""
|
||||
application/icon_interpolation=0
|
||||
application/file_version="0.19.0.0"
|
||||
application/product_version="0.19.0.0"
|
||||
application/icon_interpolation=4
|
||||
application/file_version="0.18.0.0"
|
||||
application/product_version="0.18.0.0"
|
||||
application/company_name="Woofmeow"
|
||||
application/product_name="straywild"
|
||||
application/file_description="straywild v0.19.0-alpha"
|
||||
application/product_name="NETfishing"
|
||||
application/file_description="NETfishing v0.18.0-alpha"
|
||||
application/copyright="Copyright © 2026 Woofmeow"
|
||||
application/trademarks="straywild and Woofmeow branding is reserved; see TRADEMARKS.md"
|
||||
application/trademarks="NETfishing and Woofmeow branding is reserved; see TRADEMARKS.md"
|
||||
application/export_angle=0
|
||||
ssh_remote_deploy/enabled=false
|
||||
ssh_remote_deploy/host="user@host_ip"
|
||||
|
|
@ -62,7 +62,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*"
|
||||
export_path="builds/v0.19.0-alpha/linux-arm64/straywild.arm64"
|
||||
export_path="builds/v0.18.0-alpha/linux-arm64/NETfishing.arm64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
@ -92,7 +92,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*"
|
||||
export_path="builds/v0.19.0-alpha/macos/straywild.zip"
|
||||
export_path="builds/v0.18.0-alpha/macos/NETfishing.zip"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
@ -106,10 +106,10 @@ script_export_mode=2
|
|||
custom_template/debug=""
|
||||
custom_template/release=""
|
||||
application/bundle_identifier="io.woofmeow.netfishing"
|
||||
application/icon="res://art/exported/system_icons/straywild_1024.png"
|
||||
application/icon="res://art/exported/system_icons/netfishing_1024.png"
|
||||
application/icon_interpolation=0
|
||||
application/short_version="0.19.0"
|
||||
application/version="0.19.0"
|
||||
application/short_version="0.18.0"
|
||||
application/version="0.18.0"
|
||||
application/architecture="universal"
|
||||
codesign/enable=false
|
||||
notarization/enable=false
|
||||
|
|
@ -125,7 +125,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*,tests/*"
|
||||
export_path="builds/v0.19.0-alpha/server-linux-x86_64/straywildServer.x86_64"
|
||||
export_path="builds/v0.18.0-alpha/server-linux-x86_64/NETfishingServer.x86_64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
@ -155,7 +155,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*"
|
||||
export_path="builds/v0.19.0-alpha/android/straywild.apk"
|
||||
export_path="builds/v0.18.0-alpha/android/NETfishing.apk"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
@ -176,10 +176,10 @@ architectures/armeabi-v7a=false
|
|||
architectures/arm64-v8a=true
|
||||
architectures/x86=false
|
||||
architectures/x86_64=false
|
||||
version/code=190000
|
||||
version/name="v0.19.0-alpha"
|
||||
version/code=180000
|
||||
version/name="v0.18.0-alpha"
|
||||
package/unique_name="io.woofmeow.netfishing"
|
||||
package/name="straywild"
|
||||
package/name="NETfishing"
|
||||
package/signed=true
|
||||
package/app_category=0
|
||||
package/retain_data_on_uninstall=false
|
||||
|
|
@ -187,7 +187,7 @@ package/exclude_from_recents=false
|
|||
package/show_in_android_tv=false
|
||||
package/show_in_app_library=true
|
||||
package/show_as_launcher_app=true
|
||||
launcher_icons/main_192x192="res://art/exported/system_icons/straywild_256.png"
|
||||
launcher_icons/main_192x192="res://art/exported/system_icons/netfishing_256.png"
|
||||
graphics/opengl_debug=false
|
||||
screen/immersive_mode=true
|
||||
screen/edge_to_edge=false
|
||||
|
|
@ -214,7 +214,7 @@ custom_features=""
|
|||
export_filter="all_resources"
|
||||
include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
|
||||
exclude_filter="builds/*,scripts/*"
|
||||
export_path="builds/v0.19.0-alpha/linux-x86_64/straywild.x86_64"
|
||||
export_path="builds/v0.18.0-alpha/linux-x86_64/NETfishing.x86_64"
|
||||
patches=PackedStringArray()
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@ var _network_session: NetworkSessionType
|
|||
var _network_fishing: NetworkFishingServiceType
|
||||
var _world_time: WorldTimeServiceType
|
||||
var _world_weather: WorldWeatherServiceType
|
||||
var _fishable_water_regions_resolver := Callable()
|
||||
var _active_player: PlayerType
|
||||
var _state_time_remaining: float = 0.0
|
||||
var _cast_charge: float = 0.0
|
||||
|
|
@ -223,7 +222,6 @@ func setup(
|
|||
network_fishing: NetworkFishingServiceType = null,
|
||||
world_time: WorldTimeServiceType = null,
|
||||
world_weather: WorldWeatherServiceType = null,
|
||||
fishable_water_regions_resolver: Callable = Callable(),
|
||||
) -> void:
|
||||
_local_player = local_player
|
||||
_local_inventory = local_inventory
|
||||
|
|
@ -244,7 +242,6 @@ func setup(
|
|||
_network_fishing = network_fishing
|
||||
_world_time = world_time
|
||||
_world_weather = world_weather
|
||||
_fishable_water_regions_resolver = fishable_water_regions_resolver
|
||||
if (
|
||||
_network_session != null
|
||||
and not _network_session.state_changed.is_connected(
|
||||
|
|
@ -1667,47 +1664,6 @@ func build_network_context(
|
|||
return _build_fishing_context(region)
|
||||
|
||||
|
||||
func is_species_available_now(fish: FishDataType) -> bool:
|
||||
if fish == null or not fish.is_selectable():
|
||||
return false
|
||||
var season := (
|
||||
_world_time.get_season()
|
||||
if _world_time != null
|
||||
else CalendarSeason.UNKNOWN
|
||||
)
|
||||
if not fish.is_available_in_season(season):
|
||||
return false
|
||||
if fish.collection_method != FishDataType.CollectionMethod.FISHING:
|
||||
return true
|
||||
for region: FishableWaterRegionType in _get_logbook_water_regions():
|
||||
if (
|
||||
region == null
|
||||
or region.fish_pool == null
|
||||
or region.fish_pool.get_fish_by_id(fish.id) == null
|
||||
):
|
||||
continue
|
||||
var context := _build_fishing_context(region)
|
||||
if not fish.is_allowed_in_water(context.water_type):
|
||||
continue
|
||||
if fish.availability == null or fish.availability.is_available(context):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _get_logbook_water_regions() -> Array[FishableWaterRegionType]:
|
||||
var regions: Array[FishableWaterRegionType] = []
|
||||
if not _fishable_water_regions_resolver.is_valid():
|
||||
return regions
|
||||
var resolved: Variant = _fishable_water_regions_resolver.call()
|
||||
if resolved is not Array:
|
||||
return regions
|
||||
for value: Variant in resolved:
|
||||
var region := value as FishableWaterRegionType
|
||||
if region != null and is_instance_valid(region):
|
||||
regions.append(region)
|
||||
return regions
|
||||
|
||||
|
||||
func _get_active_bait_tags() -> Array[StringName]:
|
||||
if _local_player == null or _item_catalog == null:
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -29,16 +29,12 @@ func configure(
|
|||
entity_id = configured_entity_id
|
||||
data = configured_data
|
||||
type_id = data.type_id if data != null else StringName()
|
||||
# Establish the authoritative transform before constructing transient visuals.
|
||||
# Effects emitted before this point would begin at the default world origin.
|
||||
apply_network_state(position, yaw, true)
|
||||
if data != null and data.is_stationary_hotspot():
|
||||
_ensure_water_spurt_visual()
|
||||
_water_spurt_elapsed = (
|
||||
float(abs(hash(entity_id)) % 1000) / 1000.0
|
||||
* WATER_SPURT_INTERVAL_SECONDS
|
||||
)
|
||||
_emit_water_spurt()
|
||||
else:
|
||||
_ensure_visual()
|
||||
if data != null and data.catch_data != null and _sprite != null:
|
||||
|
|
@ -54,6 +50,7 @@ func configure(
|
|||
)
|
||||
)
|
||||
_sprite.rotation_degrees.x = data.sprite_tilt_degrees
|
||||
apply_network_state(position, yaw, true)
|
||||
|
||||
|
||||
func apply_network_state(
|
||||
|
|
@ -150,6 +147,7 @@ func _ensure_water_spurt_visual() -> void:
|
|||
hole.mesh = hole_mesh
|
||||
hole.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
_water_spurt_root.add_child(hole)
|
||||
_emit_water_spurt()
|
||||
|
||||
|
||||
func _emit_water_spurt() -> void:
|
||||
|
|
@ -161,7 +159,6 @@ func _emit_water_spurt() -> void:
|
|||
particles.amount = 6
|
||||
particles.lifetime = 0.42
|
||||
particles.one_shot = true
|
||||
particles.local_coords = true
|
||||
particles.explosiveness = 1.0
|
||||
particles.direction = Vector3.UP
|
||||
particles.spread = 32.0
|
||||
|
|
|
|||
67
main/main.gd
|
|
@ -277,7 +277,6 @@ var _rain_ambience: RainAmbienceType
|
|||
|
||||
|
||||
func _ready() -> void:
|
||||
_data_root.prepare_legacy_user_data()
|
||||
_performance_profile = RuntimePerformanceProfileType.from_environment()
|
||||
_dedicated_runtime = _is_dedicated_server_runtime()
|
||||
if _dedicated_runtime:
|
||||
|
|
@ -295,7 +294,7 @@ func _ready() -> void:
|
|||
_configure_presentation_performance_profile(
|
||||
_performance_profile.is_light()
|
||||
)
|
||||
DisplayServer.window_set_title("straywild")
|
||||
DisplayServer.window_set_title("NETfishing")
|
||||
_rain_ambience = RainAmbienceType.new()
|
||||
_rain_ambience.name = "RainAmbience"
|
||||
add_child(_rain_ambience)
|
||||
|
|
@ -325,12 +324,11 @@ func _ready() -> void:
|
|||
|
||||
|
||||
func _configure_presentation_performance_profile(light_profile: bool) -> void:
|
||||
_game_ui.get_title_screen().set_minimal_presentation(light_profile)
|
||||
_game_ui.set_light_performance_profile(light_profile)
|
||||
var title_background_material := (
|
||||
_title_background.material as ShaderMaterial
|
||||
)
|
||||
if title_background_material != null:
|
||||
title_background_material.set_shader_parameter(
|
||||
var title_water_material := _title_background.material as ShaderMaterial
|
||||
if title_water_material != null:
|
||||
title_water_material.set_shader_parameter(
|
||||
"animation_enabled",
|
||||
not light_profile,
|
||||
)
|
||||
|
|
@ -463,7 +461,7 @@ func _print_dedicated_metrics() -> void:
|
|||
metrics["gatherables"] = _network_world_spawns.call(
|
||||
"get_network_metrics"
|
||||
)
|
||||
print("straywild server metrics: %s" % JSON.stringify(metrics))
|
||||
print("NETfishing server metrics: %s" % JSON.stringify(metrics))
|
||||
|
||||
|
||||
func _start_dedicated_server() -> void:
|
||||
|
|
@ -472,7 +470,10 @@ func _start_dedicated_server() -> void:
|
|||
_fail_dedicated_server(config.error_message)
|
||||
return
|
||||
var data_path: String = config.data_directory
|
||||
if not _data_root.has_data_manifest(data_path):
|
||||
var manifest_path: String = data_path.path_join(
|
||||
PlayerDataRoot.MANIFEST_FILENAME
|
||||
)
|
||||
if not FileAccess.file_exists(manifest_path):
|
||||
var created: Dictionary = _data_root.create_unbound_root(data_path)
|
||||
if not bool(created.get("ok", false)):
|
||||
_fail_dedicated_server(str(created.get(
|
||||
|
|
@ -555,7 +556,7 @@ func _start_dedicated_server() -> void:
|
|||
_fail_dedicated_server(_discovery.get_host_status_message())
|
||||
return
|
||||
print(
|
||||
"straywild dedicated server ready: %s on %s:%d (%d players, %s, timezone %s)"
|
||||
"NETfishing dedicated server ready: %s on %s:%d (%d players, %s, timezone %s)"
|
||||
% [
|
||||
config.server_name,
|
||||
config.bind_address,
|
||||
|
|
@ -920,7 +921,6 @@ func _initialize_application(dedicated: bool) -> void:
|
|||
_network_fishing,
|
||||
_world_time,
|
||||
_world_weather,
|
||||
Callable(_test_world, "get_fishable_water_regions"),
|
||||
)
|
||||
if dedicated:
|
||||
return
|
||||
|
|
@ -972,7 +972,6 @@ func _initialize_application(dedicated: bool) -> void:
|
|||
_network_session,
|
||||
_interface_fonts,
|
||||
)
|
||||
_game_ui.data_root_changed.connect(_on_data_root_changed)
|
||||
_game_ui.setup_controller_mapping(_controller_mapping_manager)
|
||||
_ui_pixelation.setup_controller_mapping(_controller_mapping_manager)
|
||||
_game_ui.setup_keyboard_mouse_mapping(_keyboard_mouse_mapping_manager)
|
||||
|
|
@ -1007,8 +1006,7 @@ func _initialize_application(dedicated: bool) -> void:
|
|||
_game_ui,
|
||||
_game_ui.get_screen_fade(),
|
||||
_test_world.get_player_water_triggers(),
|
||||
_test_world.get_safe_respawn_points(),
|
||||
Callable(_test_world, "get_water_recovery_position"),
|
||||
_test_world.get_safe_respawn_points()
|
||||
)
|
||||
_ui_pixelation.effective_pixel_size_changed.connect(
|
||||
_on_effective_ui_pixel_size_changed
|
||||
|
|
@ -1098,7 +1096,7 @@ func _initialize_application(dedicated: bool) -> void:
|
|||
func _show_data_root_setup() -> void:
|
||||
if _data_setup_dialog == null:
|
||||
_data_setup_dialog = ConfirmationDialog.new()
|
||||
_data_setup_dialog.title = "straywild player data"
|
||||
_data_setup_dialog.title = "NETfishing player data"
|
||||
_data_setup_dialog.ok_button_text = "Use This Folder"
|
||||
_data_setup_dialog.cancel_button_text = "Quit"
|
||||
_data_setup_dialog.confirmed.connect(_use_default_data_root)
|
||||
|
|
@ -1115,14 +1113,14 @@ func _show_data_root_setup() -> void:
|
|||
var default_path: String = _data_root.default_visible_path()
|
||||
var legacy: bool = PortableDataMigration.legacy_files_present()
|
||||
_data_setup_dialog.dialog_text = (
|
||||
("Move your existing straywild data to an easy-to-find folder."
|
||||
if legacy else "Choose where straywild stores your player data.")
|
||||
("Move your existing NETfishing data to an easy-to-find folder."
|
||||
if legacy else "Choose where NETfishing stores your player data.")
|
||||
+ "\n\n%s\n\nYou can choose a Syncthing folder."
|
||||
% (default_path if not default_path.is_empty() else "Choose a folder")
|
||||
)
|
||||
_data_setup_dialog.ok_button_text = (
|
||||
(
|
||||
"Move to Documents/straywild"
|
||||
"Move to Documents/NETFISHING"
|
||||
if legacy else "Use This Folder"
|
||||
)
|
||||
if not default_path.is_empty()
|
||||
|
|
@ -1131,7 +1129,7 @@ func _show_data_root_setup() -> void:
|
|||
_data_setup_current_button.visible = not default_path.is_empty()
|
||||
if not _data_root.error_message.is_empty():
|
||||
_data_setup_dialog.dialog_text = (
|
||||
"Your straywild data folder is unavailable.\n\n%s"
|
||||
"Your NETfishing data folder is unavailable.\n\n%s"
|
||||
% _data_root.error_message
|
||||
)
|
||||
_data_setup_dialog.popup_centered(Vector2i(640, 360))
|
||||
|
|
@ -1267,11 +1265,11 @@ func _activate_selected_data_path(path: String, app_data: bool = false) -> void:
|
|||
func _show_existing_root_choice(path: String) -> void:
|
||||
_pending_existing_root_path = path
|
||||
var dialog: ConfirmationDialog = ConfirmationDialog.new()
|
||||
dialog.title = "Existing straywild data"
|
||||
dialog.title = "Existing NETfishing data"
|
||||
dialog.ok_button_text = "Use Data Already in Selected Folder"
|
||||
dialog.cancel_button_text = "Cancel"
|
||||
dialog.dialog_text = (
|
||||
"This folder already contains straywild player data.\n\n"
|
||||
"This folder already contains NETfishing player data.\n\n"
|
||||
+ "Choose which complete data set to use. Data is never merged automatically."
|
||||
)
|
||||
dialog.add_button(
|
||||
|
|
@ -1345,18 +1343,6 @@ func _on_data_root_status(message: String) -> void:
|
|||
_configure_popup_dialog.call_deferred(dialog, dialog.get_ok_button())
|
||||
|
||||
|
||||
func _on_data_root_changed() -> void:
|
||||
_save_manager.set_autosave_enabled(false)
|
||||
_save_manager.cancel_pending_autosave()
|
||||
_configure_portable_stores()
|
||||
if not _network_profile_service.reload_persisted_profile():
|
||||
push_warning("The selected data folder's player profile could not be loaded.")
|
||||
_network_session.set_local_appearance_snapshot(
|
||||
_appearance_store.get_snapshot()
|
||||
)
|
||||
_game_ui.get_title_screen().refresh_after_data_root_change()
|
||||
|
||||
|
||||
func _on_server_trust_required(
|
||||
endpoint: String,
|
||||
expected_fingerprint: String,
|
||||
|
|
@ -2346,9 +2332,17 @@ func _on_remote_recovery_requested(
|
|||
peer_id,
|
||||
"Fishing attempt ended."
|
||||
)
|
||||
var target_position := _test_world.get_water_recovery_position(
|
||||
entry_position
|
||||
)
|
||||
var target_position: Vector3 = _test_world.get_player_spawn_transform().origin
|
||||
var nearest_distance: float = INF
|
||||
for point: SafeRespawnPoint in _test_world.get_safe_respawn_points():
|
||||
if point == null or not point.enabled:
|
||||
continue
|
||||
var distance: float = point.get_horizontal_distance_squared(
|
||||
entry_position
|
||||
)
|
||||
if distance < nearest_distance:
|
||||
nearest_distance = distance
|
||||
target_position = point.global_position
|
||||
target_position.y += _water_recovery.respawn_height_offset
|
||||
avatar.global_position = target_position
|
||||
avatar.velocity = Vector3.ZERO
|
||||
|
|
@ -2426,7 +2420,6 @@ func _apply_world(
|
|||
spawn_transform,
|
||||
_test_world.get_player_water_triggers(),
|
||||
_test_world.get_safe_respawn_points(),
|
||||
Callable(_test_world, "get_water_recovery_position"),
|
||||
)
|
||||
_shoreline_ambience.configure(
|
||||
_player,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
[ext_resource type="Script" uid="uid://dpiv6wttry0j4" path="res://network/player_data_root.gd" id="37_data_root"]
|
||||
[ext_resource type="Script" uid="uid://bu5q4a8jfvxkf" path="res://network/identity_backup_service.gd" id="38_identity_backup"]
|
||||
[ext_resource type="Script" uid="uid://djmxy6jibi5y3" path="res://ui/interface_font_controller.gd" id="39_fonts"]
|
||||
[ext_resource type="Texture2D" uid="uid://doju2lbj2ghwa" path="res://world/generation/chunks/assets/chunk_0000_grass_lite.png" id="40_title_grass"]
|
||||
[ext_resource type="Shader" uid="uid://c8s1g7tn771du" path="res://ui/title_water_background.gdshader" id="40_title_water"]
|
||||
[ext_resource type="Texture2D" uid="uid://f8a0cs0s7ler" path="res://art/patterns/pattern_tealdot.png" id="41_menu_pattern"]
|
||||
[ext_resource type="Shader" uid="uid://byw3iub66qvog" path="res://ui/player_menu_pattern.gdshader" id="42_menu_pattern"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6xws1d2dnbnn" path="res://art/patterns/pattern_moneyfish.png" id="43_shop_pattern"]
|
||||
|
|
@ -59,12 +59,18 @@
|
|||
[ext_resource type="Script" path="res://network/network_world_spawn_service.gd" id="59_world_spawns"]
|
||||
[ext_resource type="Script" path="res://gathering/gathering_controller.gd" id="60_gathering_controller"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_grass_native"]
|
||||
shader = ExtResource("42_menu_pattern")
|
||||
shader_parameter/pattern_texture = ExtResource("40_title_grass")
|
||||
shader_parameter/source_tile_size = Vector2(128, 128)
|
||||
shader_parameter/display_scale = 1.0
|
||||
shader_parameter/scroll_velocity_pixels = Vector2(-7.5, -7.5)
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water_native"]
|
||||
shader = ExtResource("40_title_water")
|
||||
shader_parameter/surface_color = Color(0.1, 0.45, 0.62, 1)
|
||||
shader_parameter/middle_color = Color(0.055, 0.285, 0.4, 1)
|
||||
shader_parameter/depth_color = Color(0.02, 0.16, 0.27, 1)
|
||||
shader_parameter/virtual_pixel_density = Vector2(320, 180)
|
||||
shader_parameter/color_step_count = 14.0
|
||||
shader_parameter/continuous_depth_blend = 0.12
|
||||
shader_parameter/wave_speed = 0.1
|
||||
shader_parameter/wave_scale = 2.4
|
||||
shader_parameter/wave_strength = 0.012
|
||||
shader_parameter/caustic_strength = 0.018
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_player_menu_pattern"]
|
||||
shader = ExtResource("42_menu_pattern")
|
||||
|
|
@ -133,7 +139,7 @@ layer = -1
|
|||
|
||||
[node name="TitleBackground" type="ColorRect" parent="TitleBackgroundLayer" unique_id=1768697365]
|
||||
unique_name_in_owner = true
|
||||
material = SubResource("ShaderMaterial_title_grass_native")
|
||||
material = SubResource("ShaderMaterial_title_water_native")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
|
|
|||
|
|
@ -2,13 +2,9 @@ class_name RuntimePerformanceProfile
|
|||
extends RefCounted
|
||||
|
||||
const PROFILE_ENVIRONMENT_VARIABLE: String = (
|
||||
"straywild_PERFORMANCE_PROFILE"
|
||||
)
|
||||
const LEGACY_LIGHT_ENVIRONMENT_VARIABLE: String = "straywild_LOW_END"
|
||||
const NETFISHING_PROFILE_ENVIRONMENT_VARIABLE := (
|
||||
"NETFISHING_PERFORMANCE_PROFILE"
|
||||
)
|
||||
const NETFISHING_LIGHT_ENVIRONMENT_VARIABLE := "NETFISHING_LOW_END"
|
||||
const LEGACY_LIGHT_ENVIRONMENT_VARIABLE: String = "NETFISHING_LOW_END"
|
||||
const NORMAL_PROFILE: StringName = &"normal"
|
||||
const LIGHT_PROFILE: StringName = &"light"
|
||||
const NORMAL_WORLD_RENDER_SCALE: float = 1.0
|
||||
|
|
@ -18,19 +14,9 @@ var _profile_name: StringName = NORMAL_PROFILE
|
|||
|
||||
|
||||
static func from_environment() -> RuntimePerformanceProfile:
|
||||
var profile_name: String = OS.get_environment(
|
||||
PROFILE_ENVIRONMENT_VARIABLE
|
||||
)
|
||||
if profile_name.is_empty():
|
||||
profile_name = OS.get_environment(
|
||||
NETFISHING_PROFILE_ENVIRONMENT_VARIABLE
|
||||
)
|
||||
return from_name(
|
||||
StringName(profile_name),
|
||||
(
|
||||
OS.get_environment(LEGACY_LIGHT_ENVIRONMENT_VARIABLE) == "1"
|
||||
or OS.get_environment(NETFISHING_LIGHT_ENVIRONMENT_VARIABLE) == "1"
|
||||
),
|
||||
StringName(OS.get_environment(PROFILE_ENVIRONMENT_VARIABLE)),
|
||||
OS.get_environment(LEGACY_LIGHT_ENVIRONMENT_VARIABLE) == "1",
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
extends Node
|
||||
|
||||
## Enforces straywild's nearest-neighbor-only artwork policy at runtime.
|
||||
## Enforces NETfishing's nearest-neighbor-only artwork policy at runtime.
|
||||
##
|
||||
## Godot uses separate texture-filter enums for CanvasItem and 3D materials.
|
||||
## Applying both here prevents imported models, dynamically created controls,
|
||||
|
|
|
|||
|
|
@ -20,13 +20,12 @@ signal friend_invite_received(
|
|||
signal friend_invite_finished(success: bool, message: String)
|
||||
|
||||
const BASE_URL_SETTING: String = "network/discovery/base_url"
|
||||
const BASE_URL_ENVIRONMENT: String = "straywild_DISCOVERY_URL"
|
||||
const LEGACY_BASE_URL_ENVIRONMENT: String = "NETFISHING_DISCOVERY_URL"
|
||||
const BASE_URL_ENVIRONMENT: String = "NETFISHING_DISCOVERY_URL"
|
||||
const SETTINGS_PATH: String = "user://network_discovery.cfg"
|
||||
const DEFAULT_ROOM_NAME: String = "Player's Server"
|
||||
const LEGACY_DEFAULT_ROOM_NAME: String = "straywild Room"
|
||||
const LEGACY_DEFAULT_ROOM_NAME: String = "NETfishing Room"
|
||||
const LEGACY_DEDICATED_DEFAULT_ROOM_NAME: String = (
|
||||
"straywild Dedicated Server"
|
||||
"NETfishing Dedicated Server"
|
||||
)
|
||||
const ROOM_NAME_SUFFIX: String = "'s Server"
|
||||
const MAX_ROOM_NAME_LENGTH: int = 48
|
||||
|
|
@ -34,7 +33,7 @@ const HEARTBEAT_INTERVAL_SECONDS: float = 15.0
|
|||
const REQUEST_TIMEOUT_SECONDS: float = 8.0
|
||||
const TRAVERSAL_POLL_INTERVAL_SECONDS: float = 1.0
|
||||
const JOIN_PROBE_INTERVAL_SECONDS: float = 0.35
|
||||
const TRAVERSAL_PACKET_PREFIX: String = "straywild_TRAVERSAL_V1 "
|
||||
const TRAVERSAL_PACKET_PREFIX: String = "NETFISHING_TRAVERSAL_V1 "
|
||||
const UPNP_MAPPING_DURATION_SECONDS: int = 3600
|
||||
const UPNP_RENEW_INTERVAL_SECONDS: float = 2700.0
|
||||
const UPNP_RETRY_INTERVAL_SECONDS: float = 300.0
|
||||
|
|
@ -554,10 +553,6 @@ func is_own_room(room: Dictionary) -> bool:
|
|||
|
||||
func _configured_base_url() -> String:
|
||||
var value: String = OS.get_environment(BASE_URL_ENVIRONMENT).strip_edges()
|
||||
if value.is_empty():
|
||||
value = OS.get_environment(
|
||||
LEGACY_BASE_URL_ENVIRONMENT
|
||||
).strip_edges()
|
||||
if value.is_empty():
|
||||
value = str(ProjectSettings.get_setting(BASE_URL_SETTING, "")).strip_edges()
|
||||
while value.ends_with("/"):
|
||||
|
|
@ -565,7 +560,7 @@ func _configured_base_url() -> String:
|
|||
if not value.is_empty() and not (
|
||||
value.begins_with("https://") or value.begins_with("http://")
|
||||
):
|
||||
push_warning("Ignored invalid straywild discovery URL.")
|
||||
push_warning("Ignored invalid NETfishing discovery URL.")
|
||||
return ""
|
||||
return value
|
||||
|
||||
|
|
@ -814,7 +809,7 @@ func _on_traversal_request_completed(
|
|||
var port: int = int(endpoint.get("port", 0))
|
||||
if address.is_empty() or port < 1 or port > 65535:
|
||||
continue
|
||||
var punch: PackedByteArray = "straywild_PUNCH_V1".to_utf8_buffer()
|
||||
var punch: PackedByteArray = "NETFISHING_PUNCH_V1".to_utf8_buffer()
|
||||
for _attempt: int in 3:
|
||||
_session.send_traversal_packet(address, port, punch)
|
||||
|
||||
|
|
@ -900,13 +895,13 @@ func _configure_upnp_mapping(port: int) -> Dictionary:
|
|||
var mapping_result: int = upnp.add_port_mapping(
|
||||
port,
|
||||
port,
|
||||
"straywild",
|
||||
"NETfishing",
|
||||
"UDP",
|
||||
UPNP_MAPPING_DURATION_SECONDS,
|
||||
)
|
||||
if mapping_result == UPNP.UPNP_RESULT_ONLY_PERMANENT_LEASE_SUPPORTED:
|
||||
mapping_result = upnp.add_port_mapping(
|
||||
port, port, "straywild", "UDP", 0
|
||||
port, port, "NETfishing", "UDP", 0
|
||||
)
|
||||
return {
|
||||
"success": mapping_result == UPNP.UPNP_RESULT_SUCCESS,
|
||||
|
|
@ -1379,18 +1374,18 @@ func _discovery_version_mismatch_message(required_version: String) -> String:
|
|||
match rejection:
|
||||
NetworkProtocol.RejectionCode.CLIENT_OUTDATED:
|
||||
return (
|
||||
"Your straywild version is out of date. Update to %s to "
|
||||
"Your NETfishing version is out of date. Update to %s to "
|
||||
+ "enable public discovery. This room will not be listed "
|
||||
+ "until you update."
|
||||
) % required_version
|
||||
NetworkProtocol.RejectionCode.SERVER_OUTDATED:
|
||||
return (
|
||||
"Public discovery is still on straywild %s. This room "
|
||||
"Public discovery is still on NETfishing %s. This room "
|
||||
+ "will not be listed until discovery is updated for %s."
|
||||
) % [required_version, local_version]
|
||||
_:
|
||||
return (
|
||||
"Public discovery requires straywild %s. This room will "
|
||||
"Public discovery requires NETfishing %s. This room will "
|
||||
+ "not be listed until both versions match."
|
||||
) % required_version
|
||||
|
||||
|
|
@ -1582,4 +1577,4 @@ func _save_settings() -> void:
|
|||
config.set_value("social", "share_presence", _presence_sharing)
|
||||
var error: Error = config.save(SETTINGS_PATH)
|
||||
if error != OK:
|
||||
push_warning("Could not save local straywild discovery settings.")
|
||||
push_warning("Could not save local NETfishing discovery settings.")
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_store_path = path
|
||||
_data_root = data_root
|
||||
_namespaces.clear()
|
||||
_loaded = false
|
||||
_write_blocked = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func is_banned(host_fingerprint: String, target_fingerprint: String) -> bool:
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ extends Node
|
|||
|
||||
signal operation_finished(success: bool, message: String)
|
||||
|
||||
const MAGIC := "straywild_IDENTITY_BACKUP"
|
||||
const LEGACY_MAGIC := "NETFISHING_IDENTITY_BACKUP"
|
||||
const MAGIC := "NETFISHING_IDENTITY_BACKUP"
|
||||
const FORMAT_VERSION := 1
|
||||
const MAX_BACKUP_BYTES := 256 * 1024
|
||||
const MIN_PASSPHRASE_LENGTH := 12
|
||||
|
|
@ -111,9 +110,8 @@ func inspect_backup(
|
|||
if json.parse(text) != OK or typeof(json.data) != TYPE_DICTIONARY:
|
||||
return {"ok": false}
|
||||
var data: Dictionary = json.data
|
||||
var legacy_backup: bool = data.get("magic") == LEGACY_MAGIC
|
||||
if (
|
||||
data.get("magic") not in [MAGIC, LEGACY_MAGIC]
|
||||
data.get("magic") != MAGIC
|
||||
or data.get("format_version") != FORMAT_VERSION
|
||||
or data.get("identity_type") != expected_type
|
||||
or data.get("algorithm") != NetworkIdentityCrypto.ALGORITHM
|
||||
|
|
@ -136,23 +134,12 @@ func inspect_backup(
|
|||
var signature: PackedByteArray = Marshalls.base64_to_raw(
|
||||
str(data.get("self_signature", ""))
|
||||
)
|
||||
var public_key: CryptoKey = NetworkIdentityCrypto.load_public_key(public_pem)
|
||||
var backup_signature_valid: bool = (
|
||||
NetworkIdentityCrypto.verify_legacy_fields(
|
||||
public_key,
|
||||
"identity_backup_self_test",
|
||||
[expected_type, fingerprint],
|
||||
signature,
|
||||
)
|
||||
if legacy_backup
|
||||
else NetworkIdentityCrypto.verify_fields(
|
||||
public_key,
|
||||
"identity_backup_self_test",
|
||||
[expected_type, fingerprint],
|
||||
signature,
|
||||
)
|
||||
)
|
||||
if not backup_signature_valid:
|
||||
if not NetworkIdentityCrypto.verify_fields(
|
||||
NetworkIdentityCrypto.load_public_key(public_pem),
|
||||
"identity_backup_self_test",
|
||||
[expected_type, fingerprint],
|
||||
signature,
|
||||
):
|
||||
return {"ok": false}
|
||||
var fresh: PackedByteArray = NetworkIdentityCrypto.sign_fields(
|
||||
key, "identity_import_self_test", [fingerprint]
|
||||
|
|
@ -202,7 +189,7 @@ func import_backup(
|
|||
)
|
||||
_finish(
|
||||
bool(result.get("ok", false)),
|
||||
"Identity imported. Restart straywild before multiplayer."
|
||||
"Identity imported. Restart NETfishing before multiplayer."
|
||||
if bool(result.get("ok", false))
|
||||
else "Could not install this identity backup.",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_store_path = path
|
||||
_data_root = data_root
|
||||
_records.clear()
|
||||
_loaded = false
|
||||
_write_blocked = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func observe(fingerprint: String, display_name: String) -> String:
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ const ALGORITHM: String = "RSA-3072-SHA256"
|
|||
const FINGERPRINT_LENGTH: int = 64
|
||||
const MAX_PUBLIC_KEY_BYTES: int = 8192
|
||||
const MAX_SIGNATURE_BYTES: int = 1024
|
||||
const DOMAIN_PREFIX: String = "straywild"
|
||||
const LEGACY_DOMAIN_PREFIX: String = "NETFISHING"
|
||||
const DOMAIN_PREFIX: String = "NETFISHING"
|
||||
const IDENTITY_VERSION: String = "identity_v1"
|
||||
|
||||
|
||||
|
|
@ -51,16 +50,8 @@ static func secure_id(byte_count: int = 16) -> String:
|
|||
|
||||
|
||||
static func canonical_bytes(domain: String, fields: Array) -> PackedByteArray:
|
||||
return canonical_bytes_for_prefix(DOMAIN_PREFIX, domain, fields)
|
||||
|
||||
|
||||
static func canonical_bytes_for_prefix(
|
||||
prefix: String,
|
||||
domain: String,
|
||||
fields: Array,
|
||||
) -> PackedByteArray:
|
||||
var output := PackedByteArray()
|
||||
_append_string(output, prefix)
|
||||
_append_string(output, DOMAIN_PREFIX)
|
||||
_append_string(output, IDENTITY_VERSION)
|
||||
_append_string(output, domain)
|
||||
for value: Variant in fields:
|
||||
|
|
@ -126,37 +117,6 @@ static func verify_fields(
|
|||
)
|
||||
|
||||
|
||||
static func verify_legacy_fields(
|
||||
public_key: CryptoKey,
|
||||
domain: String,
|
||||
fields: Array,
|
||||
signature: PackedByteArray,
|
||||
) -> bool:
|
||||
if (
|
||||
public_key == null
|
||||
or signature.is_empty()
|
||||
or signature.size() > MAX_SIGNATURE_BYTES
|
||||
):
|
||||
return false
|
||||
var bytes: PackedByteArray = canonical_bytes_for_prefix(
|
||||
LEGACY_DOMAIN_PREFIX,
|
||||
domain,
|
||||
fields,
|
||||
)
|
||||
if bytes.is_empty():
|
||||
return false
|
||||
var context := HashingContext.new()
|
||||
if context.start(HashingContext.HASH_SHA256) != OK:
|
||||
return false
|
||||
context.update(bytes)
|
||||
return Crypto.new().verify(
|
||||
HashingContext.HASH_SHA256,
|
||||
context.finish(),
|
||||
signature,
|
||||
public_key,
|
||||
)
|
||||
|
||||
|
||||
static func load_public_key(public_pem: String) -> CryptoKey:
|
||||
var normalized := normalize_public_pem(public_pem)
|
||||
if normalized.is_empty() or normalized.to_utf8_buffer().size() > MAX_PUBLIC_KEY_BYTES:
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ var _future_version := false
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_profile_path = path
|
||||
_data_root = data_root
|
||||
_expected_hash = ""
|
||||
_future_version = false
|
||||
|
||||
|
||||
func _temp_path() -> String:
|
||||
|
|
|
|||
|
|
@ -51,17 +51,6 @@ func setup(
|
|||
_apply_local_voice_to_avatar()
|
||||
|
||||
|
||||
func reload_persisted_profile() -> bool:
|
||||
if (
|
||||
not _preferences.load_or_create()
|
||||
or not _appearance_store.load_preferences()
|
||||
):
|
||||
return false
|
||||
_apply_to_avatar(1, _appearance_store.get_snapshot())
|
||||
_apply_local_voice_to_avatar()
|
||||
return true
|
||||
|
||||
|
||||
func get_persisted_name() -> String:
|
||||
return _preferences.display_name
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ extends RefCounted
|
|||
|
||||
const WorldLayoutType = preload("res://world/world_layout.gd")
|
||||
|
||||
const PROTOCOL_VERSION: int = 11
|
||||
const PROTOCOL_VERSION: int = 10
|
||||
const GAME_BUILD: String = "prealpha"
|
||||
const MAX_GAME_VERSION_LENGTH: int = 64
|
||||
const MAX_DISPLAY_NAME_LENGTH: int = 24
|
||||
|
|
@ -304,7 +304,7 @@ static func make_server_hello(
|
|||
assigned_peer_id: int,
|
||||
player_count: int,
|
||||
max_players: int,
|
||||
server_display_name: String = "straywild",
|
||||
server_display_name: String = "NETfishing",
|
||||
world_seed: int = DEFAULT_WORLD_SEED,
|
||||
world_layout: StringName = WorldLayoutType.GENERATED,
|
||||
) -> Dictionary:
|
||||
|
|
@ -372,17 +372,17 @@ static func rejection_text(code: int) -> String:
|
|||
return "You are not permitted to join this server."
|
||||
RejectionCode.CLIENT_OUTDATED:
|
||||
return (
|
||||
"Your straywild version is out of date. "
|
||||
"Your NETfishing version is out of date. "
|
||||
+ "Update the game to join this server."
|
||||
)
|
||||
RejectionCode.SERVER_OUTDATED:
|
||||
return (
|
||||
"This server is out of date. "
|
||||
+ "The host needs to update straywild."
|
||||
+ "The host needs to update NETfishing."
|
||||
)
|
||||
RejectionCode.VERSION_MISMATCH:
|
||||
return (
|
||||
"This game and server use different straywild versions. "
|
||||
"This game and server use different NETfishing versions. "
|
||||
+ "Update both to the latest release."
|
||||
)
|
||||
_:
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ var _local_appearance_snapshot: Dictionary = (
|
|||
)
|
||||
var _moderation_disconnect_message := ""
|
||||
var _host_port: int = 0
|
||||
var _session_display_name: String = "straywild Room"
|
||||
var _session_display_name: String = "NETfishing Room"
|
||||
var _dedicated_host: bool = false
|
||||
var _configured_operator_fingerprints: Dictionary[String, bool] = {}
|
||||
var _session_operator_fingerprints: Dictionary[String, bool] = {}
|
||||
|
|
@ -432,7 +432,7 @@ func set_peer_operator(
|
|||
func set_session_display_name(value: String) -> void:
|
||||
var cleaned: String = value.strip_edges().left(48)
|
||||
if cleaned.is_empty():
|
||||
cleaned = "straywild Room"
|
||||
cleaned = "NETfishing Room"
|
||||
if cleaned == _session_display_name:
|
||||
return
|
||||
_session_display_name = cleaned
|
||||
|
|
@ -1187,7 +1187,7 @@ func resolve_server_trust(accepted: bool) -> void:
|
|||
if not _server_trust.trust(
|
||||
get_current_endpoint(),
|
||||
str(_pending_server_proof["server_fingerprint"]),
|
||||
"straywild",
|
||||
"NETfishing",
|
||||
):
|
||||
_fail_identity("The server identity could not be pinned.")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -879,7 +879,7 @@ func export_canvas_png(canvas_id: String) -> String:
|
|||
_emit_hud_state("paint something before exporting")
|
||||
return ""
|
||||
if _data_root == null or _data_root.root_path.is_empty():
|
||||
_emit_hud_state("choose a straywild data folder before exporting")
|
||||
_emit_hud_state("choose a NETfishing data folder before exporting")
|
||||
return ""
|
||||
var export_directory: String = _artwork_directory()
|
||||
if DirAccess.make_dir_recursive_absolute(export_directory) != OK:
|
||||
|
|
@ -990,7 +990,7 @@ func _stamp_entry_is_unlocked(entry: Dictionary) -> bool:
|
|||
|
||||
func _next_artwork_export_path(directory: String) -> String:
|
||||
var date_time: Dictionary = Time.get_datetime_dict_from_system()
|
||||
var stem: String = "straywild-artwork-%04d%02d%02d-%02d%02d%02d" % [
|
||||
var stem: String = "netfishing-artwork-%04d%02d%02d-%02d%02d%02d" % [
|
||||
int(date_time.get("year", 0)),
|
||||
int(date_time.get("month", 0)),
|
||||
int(date_time.get("day", 0)),
|
||||
|
|
|
|||
|
|
@ -518,12 +518,7 @@ func _sample_surface_position(
|
|||
)
|
||||
if triangles.is_empty() or total_area <= 0.0:
|
||||
return Vector3(INF, INF, INF)
|
||||
var validates_diggable_surface := not entry.diggable_area_id.is_empty()
|
||||
var attempts: int = (
|
||||
48
|
||||
if validates_diggable_surface or is_finite(maximum_distance)
|
||||
else 1
|
||||
)
|
||||
var attempts: int = 48 if is_finite(maximum_distance) else 1
|
||||
var fallback: Vector3 = Vector3(INF, INF, INF)
|
||||
for _attempt: int in attempts:
|
||||
var roll: float = _rng.randf() * total_area
|
||||
|
|
@ -539,22 +534,12 @@ func _sample_surface_position(
|
|||
+ triangle[2] * barycentric_c
|
||||
)
|
||||
fallback = point
|
||||
var within_requested_distance := (
|
||||
if (
|
||||
not is_finite(maximum_distance)
|
||||
or Vector2(point.x - origin.x, point.z - origin.z).length()
|
||||
<= maximum_distance
|
||||
)
|
||||
var valid_diggable_surface := (
|
||||
not validates_diggable_surface
|
||||
or _world.is_diggable_surface_point_valid(
|
||||
entry.diggable_area_id,
|
||||
point,
|
||||
)
|
||||
)
|
||||
if within_requested_distance and valid_diggable_surface:
|
||||
):
|
||||
return point
|
||||
if validates_diggable_surface:
|
||||
return Vector3(INF, INF, INF)
|
||||
if origin.is_finite() and is_finite(maximum_distance):
|
||||
return origin
|
||||
return fallback
|
||||
|
|
|
|||
|
|
@ -9,42 +9,12 @@ const BOOTSTRAP_TEMP_PATH := "user://data_root_bootstrap.json.tmp"
|
|||
const BOOTSTRAP_VERSION := 1
|
||||
const MANIFEST_VERSION := 1
|
||||
const LAYOUT_VERSION := 1
|
||||
const MANIFEST_FILENAME := "straywild_data.json"
|
||||
const LEGACY_MANIFEST_FILENAME := "netfishing_data.json"
|
||||
const MANIFEST_FILENAME := "netfishing_data.json"
|
||||
const README_FILENAME := "README.txt"
|
||||
const ENVIRONMENT_VARIABLE := "straywild_DATA_DIR"
|
||||
const CREATE_ENVIRONMENT_VARIABLE := "straywild_CREATE_DATA_DIR"
|
||||
const LEGACY_ENVIRONMENT_VARIABLE := "NETFISHING_DATA_DIR"
|
||||
const LEGACY_CREATE_ENVIRONMENT_VARIABLE := "NETFISHING_CREATE_DATA_DIR"
|
||||
const APPLICATION_ID := "straywild"
|
||||
const LEGACY_APPLICATION_ID := "netfishing"
|
||||
const ENVIRONMENT_VARIABLE := "NETFISHING_DATA_DIR"
|
||||
const CREATE_ENVIRONMENT_VARIABLE := "NETFISHING_CREATE_DATA_DIR"
|
||||
const APPLICATION_ID := "netfishing"
|
||||
const APP_DATA_PORTABLE_PATH := "user://portable-data"
|
||||
const LEGACY_USER_DIRECTORY_NAME := "NETFISHING"
|
||||
const LEGACY_USER_FILES := [
|
||||
"data_root_bootstrap.json",
|
||||
"data_root_bootstrap.json.backup",
|
||||
"network_discovery.cfg",
|
||||
"player_settings.json",
|
||||
"player_settings.json.backup",
|
||||
"controller_mappings.json",
|
||||
"controller_mappings.json.backup",
|
||||
"keyboard_mouse_bindings.json",
|
||||
"keyboard_mouse_bindings.json.backup",
|
||||
"player_save.json",
|
||||
"network_profile.json",
|
||||
"player_appearance.json",
|
||||
"saved_servers.json",
|
||||
"known_players.json",
|
||||
"player_relationships.json",
|
||||
"server_trust.json",
|
||||
"host_bans.json",
|
||||
"player_identity.key",
|
||||
"player_identity.pub",
|
||||
"player_identity.json",
|
||||
"host_identity.key",
|
||||
"host_identity.pub",
|
||||
"host_identity.json",
|
||||
]
|
||||
const PATH_ALLOWED: StringName = &"allowed"
|
||||
const PATH_SOURCE_PROJECT: StringName = &"source_project"
|
||||
const PATH_INSTALLATION: StringName = &"installation"
|
||||
|
|
@ -67,29 +37,23 @@ var override_active := false
|
|||
|
||||
|
||||
func resolve() -> bool:
|
||||
prepare_legacy_user_data()
|
||||
_load_bootstrap_identity()
|
||||
var command_line: String = _command_line_override()
|
||||
if not command_line.is_empty():
|
||||
override_active = true
|
||||
mode = Mode.COMMAND_LINE_OVERRIDE
|
||||
return _activate_existing(command_line, "", false)
|
||||
var environment_variable: String = _available_environment_variable(
|
||||
ENVIRONMENT_VARIABLE,
|
||||
LEGACY_ENVIRONMENT_VARIABLE,
|
||||
)
|
||||
if not environment_variable.is_empty():
|
||||
if OS.has_environment(ENVIRONMENT_VARIABLE):
|
||||
override_active = true
|
||||
mode = Mode.ENVIRONMENT_OVERRIDE
|
||||
var environment_path: String = OS.get_environment(environment_variable)
|
||||
var environment_path: String = OS.get_environment(ENVIRONMENT_VARIABLE)
|
||||
if not environment_path.is_absolute_path():
|
||||
return _fail("straywild_DATA_DIR must be an absolute path.")
|
||||
return _fail("NETFISHING_DATA_DIR must be an absolute path.")
|
||||
if (
|
||||
_environment_flag(
|
||||
CREATE_ENVIRONMENT_VARIABLE,
|
||||
LEGACY_CREATE_ENVIRONMENT_VARIABLE,
|
||||
OS.get_environment(CREATE_ENVIRONMENT_VARIABLE) == "1"
|
||||
and not FileAccess.file_exists(
|
||||
environment_path.path_join(MANIFEST_FILENAME)
|
||||
)
|
||||
and not has_data_manifest(environment_path)
|
||||
):
|
||||
var created: Dictionary = create_unbound_root(environment_path)
|
||||
if not bool(created.get("ok", false)):
|
||||
|
|
@ -116,35 +80,11 @@ func resolve() -> bool:
|
|||
return false
|
||||
|
||||
|
||||
func prepare_legacy_user_data() -> void:
|
||||
var current_root: String = _normalize(
|
||||
ProjectSettings.globalize_path("user://")
|
||||
)
|
||||
if current_root.is_empty():
|
||||
return
|
||||
var legacy_root: String = _normalize(
|
||||
current_root.get_base_dir().path_join(LEGACY_USER_DIRECTORY_NAME)
|
||||
)
|
||||
if legacy_root == current_root or not DirAccess.dir_exists_absolute(legacy_root):
|
||||
return
|
||||
for filename: String in LEGACY_USER_FILES:
|
||||
var destination: String = current_root.path_join(filename)
|
||||
if FileAccess.file_exists(destination):
|
||||
continue
|
||||
var source: String = legacy_root.path_join(filename)
|
||||
if FileAccess.file_exists(source):
|
||||
_copy_legacy_user_file(source, destination)
|
||||
|
||||
|
||||
func has_data_manifest(path: String) -> bool:
|
||||
return not _existing_manifest_path(_normalize(path)).is_empty()
|
||||
|
||||
|
||||
func default_visible_path() -> String:
|
||||
var documents: String = OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS)
|
||||
if documents.is_empty():
|
||||
return ""
|
||||
var candidate: String = _normalize(documents.path_join("straywild"))
|
||||
var candidate: String = _normalize(documents.path_join("NETFISHING"))
|
||||
if not candidate.is_absolute_path():
|
||||
return ""
|
||||
var classification: StringName = classify_candidate_path(
|
||||
|
|
@ -165,22 +105,20 @@ func select_new_root(path: String, app_data: bool = false) -> bool:
|
|||
normalized = ProjectSettings.globalize_path(APP_DATA_PORTABLE_PATH)
|
||||
if not _validate_candidate(normalized, true):
|
||||
return false
|
||||
var manifest_path: String = _existing_manifest_path(normalized)
|
||||
if not manifest_path.is_empty():
|
||||
var manifest_path: String = normalized.path_join(MANIFEST_FILENAME)
|
||||
if FileAccess.file_exists(manifest_path):
|
||||
var manifest: Dictionary = _read_json(manifest_path)
|
||||
if not _valid_manifest(manifest):
|
||||
return _fail("The selected folder has a malformed straywild manifest.")
|
||||
return _fail("The selected folder has a malformed NETfishing manifest.")
|
||||
root_id = str(manifest["root_id"])
|
||||
if not _upgrade_legacy_manifest(normalized, manifest, manifest_path):
|
||||
return _fail("The legacy data-folder manifest could not be upgraded.")
|
||||
else:
|
||||
if not _directory_is_empty(normalized) and not app_data:
|
||||
return _fail(
|
||||
"Choose an empty folder or an existing straywild data folder."
|
||||
"Choose an empty folder or an existing NETfishing data folder."
|
||||
)
|
||||
root_id = Crypto.new().generate_random_bytes(16).hex_encode()
|
||||
if not _create_layout(normalized, root_id):
|
||||
return _fail("The straywild data folder could not be created.")
|
||||
return _fail("The NETfishing data folder could not be created.")
|
||||
if not _write_bootstrap(normalized, root_id):
|
||||
return _fail("The data-folder pointer could not be saved.")
|
||||
root_path = normalized
|
||||
|
|
@ -207,14 +145,14 @@ func create_app_data_layout_for_migration(path: String) -> Dictionary:
|
|||
var normalized: String = _normalize(path)
|
||||
if not _validate_candidate(normalized, false):
|
||||
return {"ok": false, "message": error_message}
|
||||
var manifest_path: String = _existing_manifest_path(normalized)
|
||||
if not manifest_path.is_empty():
|
||||
var manifest_path: String = normalized.path_join(MANIFEST_FILENAME)
|
||||
if FileAccess.file_exists(manifest_path):
|
||||
var manifest: Dictionary = _read_json(manifest_path)
|
||||
if not _valid_manifest(manifest):
|
||||
return {"ok": false, "message": "The app-data manifest is malformed."}
|
||||
if not _upgrade_legacy_manifest(normalized, manifest, manifest_path):
|
||||
return {"ok": false, "message": "The app-data manifest could not be upgraded."}
|
||||
return {"ok": true, "root_id": str(manifest.get("root_id", ""))}
|
||||
return (
|
||||
{"ok": true, "root_id": str(manifest.get("root_id", ""))}
|
||||
if _valid_manifest(manifest)
|
||||
else {"ok": false, "message": "The app-data manifest is malformed."}
|
||||
)
|
||||
var id: String = Crypto.new().generate_random_bytes(16).hex_encode()
|
||||
if not _create_layout(normalized, id):
|
||||
return {"ok": false, "message": "The app-data layout could not be created."}
|
||||
|
|
@ -298,19 +236,17 @@ func _activate_existing(path: String, expected_id: String, permit_creation: bool
|
|||
var normalized: String = _normalize(path)
|
||||
if not _validate_candidate(normalized, permit_creation):
|
||||
return false
|
||||
var manifest_path: String = _existing_manifest_path(normalized)
|
||||
if manifest_path.is_empty():
|
||||
return _fail("The selected folder is not a straywild data folder.")
|
||||
var manifest_path: String = normalized.path_join(MANIFEST_FILENAME)
|
||||
if not FileAccess.file_exists(manifest_path):
|
||||
return _fail("The selected folder is not a NETfishing data folder.")
|
||||
var manifest: Dictionary = _read_json(manifest_path)
|
||||
if not _valid_manifest(manifest):
|
||||
return _fail("The straywild data-folder manifest is malformed.")
|
||||
if not _upgrade_legacy_manifest(normalized, manifest, manifest_path):
|
||||
return _fail("The legacy data-folder manifest could not be upgraded.")
|
||||
return _fail("The NETfishing data-folder manifest is malformed.")
|
||||
var found_id: String = str(manifest["root_id"])
|
||||
if not expected_id.is_empty() and expected_id != found_id:
|
||||
return _fail("The selected data folder does not match this device pointer.")
|
||||
if not _test_writable(normalized):
|
||||
return _fail("The straywild data folder is unavailable or unwritable.")
|
||||
return _fail("The NETfishing data folder is unavailable or unwritable.")
|
||||
root_path = normalized
|
||||
root_id = found_id
|
||||
requires_selection = false
|
||||
|
|
@ -403,7 +339,7 @@ static func _is_same_or_child_path(candidate: String, reference: String) -> bool
|
|||
|
||||
func _test_writable(path: String) -> bool:
|
||||
var probe: String = path.path_join(
|
||||
".straywild-write-%s.tmp" % device_id.left(12)
|
||||
".netfishing-write-%s.tmp" % device_id.left(12)
|
||||
)
|
||||
var file: FileAccess = FileAccess.open(probe, FileAccess.WRITE)
|
||||
if file == null:
|
||||
|
|
@ -434,7 +370,7 @@ func _create_layout(path: String, id: String) -> bool:
|
|||
):
|
||||
return false
|
||||
var readme: String = (
|
||||
"straywild player data\n\n"
|
||||
"NETfishing player data\n\n"
|
||||
+ "This folder is safe to synchronize with tools such as Syncthing.\n"
|
||||
+ "Active private identity keys remain device-local.\n"
|
||||
+ "Encrypted identity backups require their passphrase.\n"
|
||||
|
|
@ -486,71 +422,12 @@ func _valid_manifest(data: Dictionary) -> bool:
|
|||
return (
|
||||
data.get("format_version") == MANIFEST_VERSION
|
||||
and data.get("layout_version") == LAYOUT_VERSION
|
||||
and data.get("application") in [APPLICATION_ID, LEGACY_APPLICATION_ID]
|
||||
and data.get("application") == APPLICATION_ID
|
||||
and typeof(data.get("root_id")) == TYPE_STRING
|
||||
and str(data["root_id"]).length() == 32
|
||||
)
|
||||
|
||||
|
||||
func _existing_manifest_path(path: String) -> String:
|
||||
var current: String = path.path_join(MANIFEST_FILENAME)
|
||||
if FileAccess.file_exists(current):
|
||||
return current
|
||||
var legacy: String = path.path_join(LEGACY_MANIFEST_FILENAME)
|
||||
return legacy if FileAccess.file_exists(legacy) else ""
|
||||
|
||||
|
||||
func _upgrade_legacy_manifest(
|
||||
path: String,
|
||||
manifest: Dictionary,
|
||||
manifest_path: String,
|
||||
) -> bool:
|
||||
if (
|
||||
manifest_path.get_file() == MANIFEST_FILENAME
|
||||
and manifest.get("application") == APPLICATION_ID
|
||||
):
|
||||
return true
|
||||
var upgraded: Dictionary = manifest.duplicate(true)
|
||||
upgraded["application"] = APPLICATION_ID
|
||||
upgraded["last_opened_at_unix"] = int(Time.get_unix_time_from_system())
|
||||
return _write_text_atomic(
|
||||
path.path_join(MANIFEST_FILENAME),
|
||||
JSON.stringify(upgraded, "\t"),
|
||||
)
|
||||
|
||||
|
||||
func _available_environment_variable(primary: String, legacy: String) -> String:
|
||||
if OS.has_environment(primary):
|
||||
return primary
|
||||
return legacy if OS.has_environment(legacy) else ""
|
||||
|
||||
|
||||
func _environment_flag(primary: String, legacy: String) -> bool:
|
||||
var variable: String = _available_environment_variable(primary, legacy)
|
||||
return not variable.is_empty() and OS.get_environment(variable) == "1"
|
||||
|
||||
|
||||
func _copy_legacy_user_file(source: String, destination: String) -> bool:
|
||||
var bytes: PackedByteArray = PortableFileGuard.read_bytes(
|
||||
source,
|
||||
16 * 1024 * 1024,
|
||||
)
|
||||
if bytes.is_empty() and FileAccess.get_open_error() != OK:
|
||||
return false
|
||||
if DirAccess.make_dir_recursive_absolute(destination.get_base_dir()) != OK:
|
||||
return false
|
||||
var file: FileAccess = FileAccess.open(destination, FileAccess.WRITE)
|
||||
if file == null:
|
||||
return false
|
||||
file.store_buffer(bytes)
|
||||
file.flush()
|
||||
var copied: bool = file.get_error() == OK
|
||||
file.close()
|
||||
if copied and source.ends_with(".key"):
|
||||
FileAccess.set_unix_permissions(destination, 384)
|
||||
return copied
|
||||
|
||||
|
||||
func _directory_is_empty(path: String) -> bool:
|
||||
var access: DirAccess = DirAccess.open(path)
|
||||
if access == null:
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ const FORMAT_VERSION := 2
|
|||
const MAX_RECORDS := 500
|
||||
const MAX_FRIENDS := 200
|
||||
const SOCIAL_TOKEN_LENGTH := 64
|
||||
const PRESENCE_CHANNEL_DOMAIN := "straywild_PRESENCE_V1:"
|
||||
const INVITE_INBOX_DOMAIN := "straywild_INVITE_V1:"
|
||||
const PRESENCE_CHANNEL_DOMAIN := "NETFISHING_PRESENCE_V1:"
|
||||
const INVITE_INBOX_DOMAIN := "NETFISHING_INVITE_V1:"
|
||||
|
||||
var _records: Dictionary = {}
|
||||
var _loaded := false
|
||||
|
|
@ -21,10 +21,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_store_path = path
|
||||
_data_root = data_root
|
||||
_records.clear()
|
||||
_loaded = false
|
||||
_write_blocked = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func is_muted(fingerprint: String) -> bool:
|
||||
|
|
|
|||
|
|
@ -26,16 +26,19 @@ static func migrate_legacy_to(
|
|||
) -> Dictionary:
|
||||
var normalized: String = destination.simplify_path().trim_suffix("/")
|
||||
if DirAccess.dir_exists_absolute(normalized):
|
||||
if data_root.has_data_manifest(normalized):
|
||||
var existing_manifest: String = normalized.path_join(
|
||||
PlayerDataRoot.MANIFEST_FILENAME
|
||||
)
|
||||
if FileAccess.file_exists(existing_manifest):
|
||||
return {
|
||||
"ok": false,
|
||||
"requires_existing_root_decision": true,
|
||||
"message": "The selected folder already contains straywild data.",
|
||||
"message": "The selected folder already contains NETfishing data.",
|
||||
}
|
||||
if not _directory_empty(normalized):
|
||||
return {
|
||||
"ok": false,
|
||||
"message": "Choose an empty folder or create a straywild subfolder.",
|
||||
"message": "Choose an empty folder or create a NETfishing subfolder.",
|
||||
}
|
||||
var staging: String = "%s.migration-%s" % [
|
||||
normalized, Crypto.new().generate_random_bytes(8).hex_encode()
|
||||
|
|
@ -103,16 +106,16 @@ static func migrate_active_to(
|
|||
"message": "This data folder is already active.",
|
||||
}
|
||||
if DirAccess.dir_exists_absolute(normalized) and not _directory_empty(normalized):
|
||||
if data_root.has_data_manifest(normalized):
|
||||
if FileAccess.file_exists(normalized.path_join(PlayerDataRoot.MANIFEST_FILENAME)):
|
||||
return {
|
||||
"ok": false,
|
||||
"requires_existing_root_decision": true,
|
||||
"message": (
|
||||
"The selected folder already contains straywild data. "
|
||||
"The selected folder already contains NETfishing data. "
|
||||
+ "Choose it through the existing-data recovery flow."
|
||||
),
|
||||
}
|
||||
return {"ok": false, "message": "Choose an empty folder or a straywild subfolder."}
|
||||
return {"ok": false, "message": "Choose an empty folder or a NETfishing subfolder."}
|
||||
var staging: String = "%s.migration-%s" % [
|
||||
normalized, Crypto.new().generate_random_bytes(8).hex_encode()
|
||||
]
|
||||
|
|
@ -204,8 +207,9 @@ static func replace_existing_with_legacy(
|
|||
destination: String,
|
||||
) -> Dictionary:
|
||||
var normalized: String = destination.simplify_path().trim_suffix("/")
|
||||
if not data_root.has_data_manifest(normalized):
|
||||
return {"ok": false, "message": "The selected folder is not a straywild data root."}
|
||||
var manifest: String = normalized.path_join(PlayerDataRoot.MANIFEST_FILENAME)
|
||||
if not FileAccess.file_exists(manifest):
|
||||
return {"ok": false, "message": "The selected folder is not a NETfishing data root."}
|
||||
var recovery: String = ProjectSettings.globalize_path(
|
||||
"user://migration-recovery"
|
||||
).path_join(
|
||||
|
|
@ -225,8 +229,8 @@ static func replace_existing_with_active(
|
|||
destination: String,
|
||||
) -> Dictionary:
|
||||
var normalized: String = destination.simplify_path().trim_suffix("/")
|
||||
if not data_root.has_data_manifest(normalized):
|
||||
return {"ok": false, "message": "The selected folder is not a straywild data root."}
|
||||
if not FileAccess.file_exists(normalized.path_join(PlayerDataRoot.MANIFEST_FILENAME)):
|
||||
return {"ok": false, "message": "The selected folder is not a NETfishing data root."}
|
||||
var recovery: String = ProjectSettings.globalize_path(
|
||||
"user://migration-recovery"
|
||||
).path_join(
|
||||
|
|
|
|||
|
|
@ -22,12 +22,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_store_path = path
|
||||
_data_root = data_root
|
||||
_saved_entries.clear()
|
||||
_recent_entries.clear()
|
||||
_loaded = false
|
||||
_recovery_warning = ""
|
||||
_write_blocked = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func _temp_path() -> String:
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_store_path = path
|
||||
_data_root = data_root
|
||||
_records.clear()
|
||||
_loaded = false
|
||||
_write_blocked = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func verify(endpoint: ConnectionEndpoint, fingerprint: String) -> Verification:
|
||||
|
|
|
|||
|
|
@ -1,88 +1,7 @@
|
|||
extends "res://player/tool_socket_attachment.gd"
|
||||
|
||||
const TextureSamplingPolicyScript := preload(
|
||||
"res://main/texture_sampling_policy.gd"
|
||||
)
|
||||
const SPRING_ROOT_BONE: StringName = &"net_mid"
|
||||
const SPRING_END_BONE: StringName = &"net_tip"
|
||||
const IMPACT_BONE: StringName = &"net_rim"
|
||||
|
||||
@export_range(0.0, 10.0, 0.05) var spring_stiffness: float = 1.8
|
||||
@export_range(0.0, 1.0, 0.01) var spring_drag: float = 0.68
|
||||
@export_range(0.0, 10.0, 0.05) var spring_gravity: float = 0.3
|
||||
@export_range(0.01, 0.5, 0.01) var spring_end_length: float = 0.1
|
||||
|
||||
@onready var _catching_net: Node3D = %CatchingNet
|
||||
@onready var _net_model: Node3D = %NetModel
|
||||
|
||||
var _spring: SpringBoneSimulator3D
|
||||
var _spring_was_visible: bool = false
|
||||
var _net_skeleton: Skeleton3D
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
TextureSamplingPolicyScript.enforce_subtree(_net_model)
|
||||
_configure_spring()
|
||||
_sync_spring_activity()
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
_sync_spring_activity()
|
||||
|
||||
|
||||
func _configure_spring() -> void:
|
||||
_net_skeleton = _net_model.find_child(
|
||||
"Skeleton3D", true, false
|
||||
) as Skeleton3D
|
||||
if _net_skeleton == null:
|
||||
push_error("Imported net model is missing its Skeleton3D.")
|
||||
return
|
||||
if _net_skeleton.find_bone(SPRING_ROOT_BONE) < 0:
|
||||
push_error("Imported net model is missing bone %s." % SPRING_ROOT_BONE)
|
||||
return
|
||||
if _net_skeleton.find_bone(SPRING_END_BONE) < 0:
|
||||
push_error("Imported net model is missing bone %s." % SPRING_END_BONE)
|
||||
return
|
||||
if _net_skeleton.find_bone(IMPACT_BONE) < 0:
|
||||
push_error("Imported net model is missing bone %s." % IMPACT_BONE)
|
||||
return
|
||||
|
||||
_spring = SpringBoneSimulator3D.new()
|
||||
_spring.name = "NetSpring"
|
||||
_spring.set_setting_count(1)
|
||||
_spring.set_root_bone_name(0, SPRING_ROOT_BONE)
|
||||
_spring.set_end_bone_name(0, SPRING_END_BONE)
|
||||
_spring.set_extend_end_bone(0, true)
|
||||
_spring.set_end_bone_direction(
|
||||
0, SkeletonModifier3D.BONE_DIRECTION_FROM_PARENT
|
||||
)
|
||||
_spring.set_end_bone_length(0, spring_end_length)
|
||||
_spring.set_stiffness(0, spring_stiffness)
|
||||
_spring.set_drag(0, spring_drag)
|
||||
_spring.set_gravity(0, spring_gravity)
|
||||
_spring.set_gravity_direction(0, Vector3.DOWN)
|
||||
_net_skeleton.add_child(_spring)
|
||||
@onready var _impact_marker: Marker3D = %ImpactMarker
|
||||
|
||||
|
||||
func get_impact_world_position() -> Vector3:
|
||||
if _net_skeleton == null:
|
||||
return _catching_net.global_position
|
||||
var impact_bone_index := _net_skeleton.find_bone(IMPACT_BONE)
|
||||
if impact_bone_index < 0:
|
||||
return _catching_net.global_position
|
||||
return _net_skeleton.global_transform * (
|
||||
_net_skeleton.get_bone_global_pose(impact_bone_index).origin
|
||||
)
|
||||
|
||||
|
||||
func _sync_spring_activity() -> void:
|
||||
if _spring == null:
|
||||
return
|
||||
var is_visible := _catching_net.is_visible_in_tree()
|
||||
if is_visible and not _spring_was_visible:
|
||||
_spring.active = true
|
||||
_spring.reset()
|
||||
elif not is_visible:
|
||||
_spring.active = false
|
||||
_spring_was_visible = is_visible
|
||||
return _impact_marker.global_position
|
||||
|
|
|
|||
|
|
@ -1,7 +1,42 @@
|
|||
[gd_scene load_steps=3 format=3]
|
||||
[gd_scene load_steps=8 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://player/net_attachment.gd" id="1_script"]
|
||||
[ext_resource type="PackedScene" path="res://art/exported/items/equipment/net.glb" id="2_model"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="HandleMaterial"]
|
||||
albedo_color = Color(0.25, 0.13, 0.055, 1)
|
||||
roughness = 0.9
|
||||
|
||||
[sub_resource type="CylinderMesh" id="HandleMesh"]
|
||||
material = SubResource("HandleMaterial")
|
||||
top_radius = 0.025
|
||||
bottom_radius = 0.035
|
||||
height = 1.25
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="HoopMaterial"]
|
||||
albedo_color = Color(0.34, 0.39, 0.4, 1)
|
||||
metallic = 0.25
|
||||
roughness = 0.65
|
||||
|
||||
[sub_resource type="TorusMesh" id="HoopMesh"]
|
||||
material = SubResource("HoopMaterial")
|
||||
inner_radius = 0.24
|
||||
outer_radius = 0.29
|
||||
rings = 12
|
||||
ring_segments = 18
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="NetMaterial"]
|
||||
transparency = 1
|
||||
albedo_color = Color(0.65, 0.78, 0.75, 0.42)
|
||||
shading_mode = 0
|
||||
cull_mode = 2
|
||||
|
||||
[sub_resource type="CylinderMesh" id="NetMesh"]
|
||||
material = SubResource("NetMaterial")
|
||||
top_radius = 0.24
|
||||
bottom_radius = 0.08
|
||||
height = 0.34
|
||||
radial_segments = 12
|
||||
rings = 1
|
||||
|
||||
[node name="NetAttachment" type="BoneAttachment3D"]
|
||||
bone_name = "rod_socket"
|
||||
|
|
@ -12,9 +47,18 @@ aligned_mount_path = NodePath("CatchingNet")
|
|||
unique_name_in_owner = true
|
||||
visible = false
|
||||
|
||||
[node name="ModelMount" type="Node3D" parent="CatchingNet"]
|
||||
position = Vector3(-0.000217, -0.098636, -0.020218)
|
||||
rotation = Vector3(0, 3.1415927, 0)
|
||||
[node name="Handle" type="MeshInstance3D" parent="CatchingNet"]
|
||||
position = Vector3(0, 0.55, 0)
|
||||
mesh = SubResource("HandleMesh")
|
||||
|
||||
[node name="NetModel" parent="CatchingNet/ModelMount" unique_id=1627767240 instance=ExtResource("2_model")]
|
||||
[node name="Hoop" type="MeshInstance3D" parent="CatchingNet"]
|
||||
position = Vector3(0, 1.17, 0)
|
||||
mesh = SubResource("HoopMesh")
|
||||
|
||||
[node name="Bag" type="MeshInstance3D" parent="CatchingNet"]
|
||||
position = Vector3(0, 1, 0)
|
||||
mesh = SubResource("NetMesh")
|
||||
|
||||
[node name="ImpactMarker" type="Marker3D" parent="CatchingNet"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector3(0, 1.17, 0)
|
||||
|
|
|
|||
|
|
@ -1036,8 +1036,6 @@ func _simulate_movement_physics(delta: float) -> void:
|
|||
or (_network_authoritative_simulation and _network_jump_pending)
|
||||
)
|
||||
)
|
||||
if jump_requested:
|
||||
_cancel_sitting_for_jump()
|
||||
# Sitting deliberately stops movement processing, so never allow a stale
|
||||
# grounded flag or a reconciled network state to leave an airborne avatar in
|
||||
# that early-return path. Preserve the intent and sit once landing is real.
|
||||
|
|
@ -1637,7 +1635,6 @@ func _complete_retract_animation() -> void:
|
|||
func toggle_sitting() -> void:
|
||||
if _sit_after_landing:
|
||||
_sit_after_landing = false
|
||||
_set_sitting(false, local_control_enabled)
|
||||
return
|
||||
var should_sit: bool = not _sitting
|
||||
if should_sit:
|
||||
|
|
@ -1670,12 +1667,12 @@ func _set_sitting(
|
|||
should_sit: bool,
|
||||
is_local_intent: bool = false,
|
||||
) -> void:
|
||||
if is_local_intent:
|
||||
_sitting_intent_pending = true
|
||||
_sitting_intent_sequence = -1
|
||||
if _sitting == should_sit:
|
||||
return
|
||||
_sitting = should_sit
|
||||
if is_local_intent:
|
||||
_sitting_intent_pending = true
|
||||
_sitting_intent_sequence = -1
|
||||
if _sitting:
|
||||
velocity = Vector3.ZERO
|
||||
_character_animation_name = &""
|
||||
|
|
@ -1690,23 +1687,11 @@ func _can_begin_sitting() -> bool:
|
|||
return is_on_floor() and velocity.y <= 0.0
|
||||
|
||||
|
||||
func _cancel_sitting_for_jump() -> void:
|
||||
if not _sitting and not _sit_after_landing:
|
||||
return
|
||||
_sit_after_landing = false
|
||||
_set_sitting(false, local_control_enabled)
|
||||
|
||||
|
||||
func get_network_sitting_state() -> bool:
|
||||
return _sitting
|
||||
|
||||
|
||||
func get_network_sitting_intent() -> bool:
|
||||
# Jumping is an explicit cancellation of both a current sit and a deferred
|
||||
# sit. Input capture can run before the matching physics frame, so suppress
|
||||
# the stale seated bit as soon as the reliable jump intent is queued.
|
||||
if _local_network_jump_intent_pending:
|
||||
return false
|
||||
return _sitting or _sit_after_landing
|
||||
|
||||
|
||||
|
|
@ -2367,21 +2352,6 @@ func apply_local_prediction_correction(
|
|||
_local_prediction_hard_corrections += 1
|
||||
_reset_local_prediction_error()
|
||||
return
|
||||
if _should_defer_local_prediction_correction(parsed):
|
||||
# A host and its client do not reach the apex or landing on the same
|
||||
# frame. Correcting that expected vertical disagreement while either
|
||||
# side is airborne can pull the local body off narrow platforms.
|
||||
_reset_local_prediction_error()
|
||||
return
|
||||
# Both simulations agree the player is standing. Let ordinary floor motion
|
||||
# and gravity resolve the vertical component; a stale height sample must not
|
||||
# press a locally controlled player down or turn a horizontal correction
|
||||
# into an early floor collision.
|
||||
error_offset.y = 0.0
|
||||
error_distance = error_offset.length()
|
||||
if error_distance <= LOCAL_PREDICTION_CORRECTION_THRESHOLD:
|
||||
_reset_local_prediction_error()
|
||||
return
|
||||
var error_direction: Vector3 = error_offset.normalized()
|
||||
if (
|
||||
not _local_prediction_error_direction.is_zero_approx()
|
||||
|
|
@ -2416,34 +2386,22 @@ func apply_local_prediction_correction(
|
|||
correction.normalized()
|
||||
* LOCAL_PREDICTION_MAX_SOFT_CORRECTION_STEP
|
||||
)
|
||||
if _apply_camera_safe_local_correction(correction):
|
||||
_local_prediction_soft_corrections += 1
|
||||
_apply_camera_safe_local_correction(correction)
|
||||
_local_prediction_soft_corrections += 1
|
||||
|
||||
|
||||
func _should_defer_local_prediction_correction(parsed: Dictionary) -> bool:
|
||||
if not bool(parsed.get("grounded", true)):
|
||||
return true
|
||||
return _local_network_jump_intent_pending or not is_on_floor()
|
||||
|
||||
|
||||
func _apply_camera_safe_local_correction(correction: Vector3) -> bool:
|
||||
func _apply_camera_safe_local_correction(correction: Vector3) -> void:
|
||||
if correction.is_zero_approx():
|
||||
return false
|
||||
return
|
||||
var previous_visual_position: Vector3 = _visuals.global_position
|
||||
var previous_camera_position: Vector3 = _camera_yaw.global_position
|
||||
var previous_body_position: Vector3 = global_position
|
||||
var base_visual_local_position: Vector3 = (
|
||||
_visuals.position - _local_reconciliation_visual_offset
|
||||
)
|
||||
var base_camera_local_position: Vector3 = (
|
||||
_camera_yaw.position - _local_reconciliation_camera_offset
|
||||
)
|
||||
# Reconciliation is still physical movement. Going through the physics
|
||||
# server prevents a delayed host audit from placing the capsule through a
|
||||
# tree, cliff, or stepping stone on the way to the authoritative position.
|
||||
move_and_collide(correction)
|
||||
if global_position.is_equal_approx(previous_body_position):
|
||||
return false
|
||||
global_position += correction
|
||||
_visuals.global_position = previous_visual_position
|
||||
_camera_yaw.global_position = previous_camera_position
|
||||
_local_reconciliation_visual_offset = (
|
||||
|
|
@ -2452,7 +2410,6 @@ func _apply_camera_safe_local_correction(correction: Vector3) -> bool:
|
|||
_local_reconciliation_camera_offset = (
|
||||
_camera_yaw.position - base_camera_local_position
|
||||
)
|
||||
return true
|
||||
|
||||
|
||||
func _reset_local_prediction_error() -> void:
|
||||
|
|
@ -2668,9 +2625,6 @@ func _parse_network_snapshot(snapshot: Dictionary) -> Dictionary:
|
|||
if snapshot.has("casting") and typeof(snapshot.get("casting")) != TYPE_BOOL:
|
||||
return {}
|
||||
var casting: bool = bool(snapshot.get("casting", false))
|
||||
if snapshot.has("grounded") and typeof(snapshot.get("grounded")) != TYPE_BOOL:
|
||||
return {}
|
||||
var grounded: bool = bool(snapshot.get("grounded", true))
|
||||
if (
|
||||
not parsed_position.is_finite()
|
||||
or not parsed_velocity.is_finite()
|
||||
|
|
@ -2682,7 +2636,6 @@ func _parse_network_snapshot(snapshot: Dictionary) -> Dictionary:
|
|||
"velocity": parsed_velocity,
|
||||
"visual_yaw": visual_yaw,
|
||||
"animation_state": animation_state,
|
||||
"grounded": grounded,
|
||||
"acknowledged_input": acknowledged_input,
|
||||
"sitting": sitting,
|
||||
"casting": casting,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
[ext_resource type="Script" path="res://progression/player_cooler_capacity.gd" id="10_capacity"]
|
||||
[ext_resource type="Script" path="res://player/player_ground_shadow.gd" id="11_ground_shadow"]
|
||||
[ext_resource type="Material" path="res://player/materials/player_blob_shadow.tres" id="12_blob_shadow"]
|
||||
[ext_resource type="PackedScene" path="res://art/exported/characters/base/straywild_base_character.glb" id="13_character"]
|
||||
[ext_resource type="PackedScene" path="res://art/exported/characters/base/netfishing_base_character.glb" id="13_character"]
|
||||
[ext_resource type="Script" path="res://progression/player_art_unlocks.gd" id="14_art_unlocks"]
|
||||
[ext_resource type="Script" path="res://progression/player_experience.gd" id="15_experience"]
|
||||
[ext_resource type="Script" path="res://player/sprint_dust_trail.gd" id="16_sprint_dust"]
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ extends RefCounted
|
|||
|
||||
const PlayerScene: PackedScene = preload("res://player/player.tscn")
|
||||
const FurPatternShader: Shader = preload("res://player/fur_pattern.gdshader")
|
||||
const RUNTIME_MATERIAL_META: StringName = &"straywild_runtime_material"
|
||||
const RUNTIME_MATERIAL_META: StringName = &"netfishing_runtime_material"
|
||||
const RUNTIME_FUR_PATTERN_MATERIAL_META: StringName = (
|
||||
&"straywild_runtime_fur_pattern_material"
|
||||
&"netfishing_runtime_fur_pattern_material"
|
||||
)
|
||||
const EAR_MESH_NAMES: Array[String] = [
|
||||
"ears_antlers_round",
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ var _data_root: PlayerDataRoot
|
|||
func configure_storage(path: String, data_root: PlayerDataRoot) -> void:
|
||||
_profile_path = path
|
||||
_data_root = data_root
|
||||
_snapshot = CharacterCustomizationCatalog.default_snapshot()
|
||||
_loaded = false
|
||||
_future_version = false
|
||||
_expected_hash = ""
|
||||
|
||||
|
||||
func _temp_path() -> String:
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ config_version=5
|
|||
|
||||
[application]
|
||||
|
||||
config/name="straywild"
|
||||
config/version="0.19.0-alpha"
|
||||
config/name="NETFISHING"
|
||||
config/version="0.18.0-alpha"
|
||||
run/main_scene="res://main/main.tscn"
|
||||
config/features=PackedStringArray("4.7", "GL Compatibility")
|
||||
config/icon="res://art/exported/system_icons/straywild_256.png"
|
||||
config/icon="res://art/exported/system_icons/netfishing_256.png"
|
||||
|
||||
[autoload]
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ window/stretch/aspect="expand"
|
|||
|
||||
[editor_plugins]
|
||||
|
||||
enabled=PackedStringArray("res://addons/straywild_shoreline_baker/plugin.cfg")
|
||||
enabled=PackedStringArray("res://addons/netfishing_shoreline_baker/plugin.cfg")
|
||||
|
||||
[gui]
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ alternate_fishing={
|
|||
|
||||
[network]
|
||||
|
||||
discovery/base_url="https://discovery.straywild.io"
|
||||
discovery/base_url="https://discovery.netfishing.org"
|
||||
|
||||
[physics]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
class_name ProgressionSaveCodec
|
||||
extends RefCounted
|
||||
|
||||
const MAGIC := "straywild_PROGRESSION_CONTAINER"
|
||||
const LEGACY_MAGIC := "NETFISHING_PROGRESSION_CONTAINER"
|
||||
const MAGIC := "NETFISHING_PROGRESSION_CONTAINER"
|
||||
const FORMAT_VERSION := 1
|
||||
const LOCAL_KIND := "local_save"
|
||||
const ARCHIVE_KIND := "portable_archive"
|
||||
|
|
@ -10,8 +9,6 @@ const MAX_CONTAINER_BYTES := 16 * 1024 * 1024
|
|||
|
||||
# This key keeps routine progression files opaque to casual editing. Since the
|
||||
# client is open source, it is intentionally not treated as a security secret.
|
||||
# Its original value is a stable file-format detail so released saves remain
|
||||
# readable after the Straywild rebrand.
|
||||
const CONTAINER_PASSPHRASE := (
|
||||
"NETfishing progression container v1 / not an identity credential"
|
||||
)
|
||||
|
|
@ -105,9 +102,15 @@ static func _read_container(path: String, expected_kind: String) -> Dictionary:
|
|||
or FileAccess.get_size(path) > MAX_CONTAINER_BYTES
|
||||
):
|
||||
return {"ok": false, "message": "progression file is unavailable."}
|
||||
var envelope_text: String = _read_encrypted_text(path)
|
||||
if envelope_text.is_empty():
|
||||
var file: FileAccess = FileAccess.open_encrypted_with_pass(
|
||||
path,
|
||||
FileAccess.READ,
|
||||
CONTAINER_PASSPHRASE,
|
||||
)
|
||||
if file == null:
|
||||
return {"ok": false, "message": "progression file could not be opened."}
|
||||
var envelope_text: String = file.get_as_text()
|
||||
file.close()
|
||||
var envelope_json := JSON.new()
|
||||
if (
|
||||
envelope_json.parse(envelope_text) != OK
|
||||
|
|
@ -115,9 +118,8 @@ static func _read_container(path: String, expected_kind: String) -> Dictionary:
|
|||
):
|
||||
return {"ok": false, "message": "progression container is malformed."}
|
||||
var envelope: Dictionary = envelope_json.data
|
||||
var legacy_container: bool = envelope.get("magic") == LEGACY_MAGIC
|
||||
if (
|
||||
envelope.get("magic") not in [MAGIC, LEGACY_MAGIC]
|
||||
envelope.get("magic") != MAGIC
|
||||
or int(envelope.get("format_version", -1)) != FORMAT_VERSION
|
||||
or str(envelope.get("kind", "")) != expected_kind
|
||||
):
|
||||
|
|
@ -142,23 +144,9 @@ static func _read_container(path: String, expected_kind: String) -> Dictionary:
|
|||
"game_version": str(envelope.get("game_version", "")),
|
||||
"created_at_unix": int(envelope.get("created_at_unix", 0)),
|
||||
"legacy_plaintext": false,
|
||||
"legacy_container": legacy_container,
|
||||
}
|
||||
|
||||
|
||||
static func _read_encrypted_text(path: String) -> String:
|
||||
var file: FileAccess = FileAccess.open_encrypted_with_pass(
|
||||
path,
|
||||
FileAccess.READ,
|
||||
CONTAINER_PASSPHRASE,
|
||||
)
|
||||
if file == null:
|
||||
return ""
|
||||
var text: String = file.get_as_text()
|
||||
file.close()
|
||||
return text
|
||||
|
||||
|
||||
static func _read_plaintext_dictionary(path: String) -> Dictionary:
|
||||
var bytes: PackedByteArray = PortableFileGuard.read_bytes(
|
||||
path,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ set -euo pipefail
|
|||
|
||||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||||
readonly OUTPUT_PATH="${PROJECT_ROOT}/builds/android/straywild-debug.apk"
|
||||
readonly OUTPUT_PATH="${PROJECT_ROOT}/builds/android/NETfishing-debug.apk"
|
||||
readonly GODOT_BIN="${GODOT_BIN:-godot}"
|
||||
|
||||
mkdir -p -- "$(dirname -- "${OUTPUT_PATH}")"
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ set -euo pipefail
|
|||
|
||||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||||
readonly BUILD_ROOT="${PROJECT_ROOT}/builds/v0.19.0-alpha"
|
||||
readonly BUILD_ROOT="${PROJECT_ROOT}/builds/v0.18.0-alpha"
|
||||
readonly WINDOWS_DIR="${BUILD_ROOT}/windows-x86_64"
|
||||
readonly LINUX_DIR="${BUILD_ROOT}/linux-x86_64"
|
||||
readonly README_SOURCE="${PROJECT_ROOT}/docs/README-PLAYTEST.txt"
|
||||
readonly SOURCE_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse HEAD)"
|
||||
readonly SOURCE_URL="https://forge.makearmy.io/woofmeow/straywild"
|
||||
readonly WINDOWS_ZIP="${BUILD_ROOT}/straywild-v0.19.0-alpha-windows-x86_64.zip"
|
||||
readonly LINUX_ZIP="${BUILD_ROOT}/straywild-v0.19.0-alpha-linux-x86_64.zip"
|
||||
readonly SOURCE_URL="https://forge.makearmy.io/woofmeow/netfishing"
|
||||
readonly WINDOWS_ZIP="${BUILD_ROOT}/NETfishing-v0.18.0-alpha-windows-x86_64.zip"
|
||||
readonly LINUX_ZIP="${BUILD_ROOT}/NETfishing-v0.18.0-alpha-linux-x86_64.zip"
|
||||
readonly GODOT_BIN="${GODOT_BIN:-godot}"
|
||||
|
||||
if [[ ! -f "${PROJECT_ROOT}/project.godot" ]]; then
|
||||
|
|
@ -31,26 +31,26 @@ mkdir -p -- "${WINDOWS_DIR}" "${LINUX_DIR}"
|
|||
--headless \
|
||||
--path "${PROJECT_ROOT}" \
|
||||
--export-release "Windows Desktop" \
|
||||
"${WINDOWS_DIR}/straywild.exe"
|
||||
"${WINDOWS_DIR}/NETfishing.exe"
|
||||
|
||||
"${GODOT_BIN}" \
|
||||
--headless \
|
||||
--path "${PROJECT_ROOT}" \
|
||||
--export-release "Linux Desktop" \
|
||||
"${LINUX_DIR}/straywild.x86_64"
|
||||
"${LINUX_DIR}/NETfishing.x86_64"
|
||||
|
||||
for required_file in \
|
||||
"${WINDOWS_DIR}/straywild.exe" \
|
||||
"${WINDOWS_DIR}/straywild.pck" \
|
||||
"${LINUX_DIR}/straywild.x86_64" \
|
||||
"${LINUX_DIR}/straywild.pck"; do
|
||||
"${WINDOWS_DIR}/NETfishing.exe" \
|
||||
"${WINDOWS_DIR}/NETfishing.pck" \
|
||||
"${LINUX_DIR}/NETfishing.x86_64" \
|
||||
"${LINUX_DIR}/NETfishing.pck"; do
|
||||
if [[ ! -s "${required_file}" ]]; then
|
||||
echo "error: expected export output is missing: ${required_file}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
chmod +x -- "${LINUX_DIR}/straywild.x86_64"
|
||||
chmod +x -- "${LINUX_DIR}/NETfishing.x86_64"
|
||||
cp -- "${README_SOURCE}" "${WINDOWS_DIR}/README-PLAYTEST.txt"
|
||||
cp -- "${README_SOURCE}" "${LINUX_DIR}/README-PLAYTEST.txt"
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ stage_licenses() {
|
|||
install -m 0644 "${PROJECT_ROOT}/LICENSE" \
|
||||
"${destination}/GPL-3.0-or-later.txt"
|
||||
install -m 0644 "${PROJECT_ROOT}/ASSET-LICENSE.md" \
|
||||
"${destination}/straywild-ASSET-LICENSE.md"
|
||||
"${destination}/NETFISHING-ASSET-LICENSE.md"
|
||||
install -m 0644 "${PROJECT_ROOT}/docs/ATTRIBUTION.md" \
|
||||
"${destination}/ATTRIBUTION.md"
|
||||
install -m 0644 "${PROJECT_ROOT}/TRADEMARKS.md" \
|
||||
|
|
@ -72,7 +72,7 @@ stage_licenses() {
|
|||
cat >"${destination}/SOURCE-CODE.md" <<EOF
|
||||
# Corresponding source
|
||||
|
||||
straywild code is licensed under GPL-3.0-or-later.
|
||||
NETfishing code is licensed under GPL-3.0-or-later.
|
||||
|
||||
Source repository: ${SOURCE_URL}
|
||||
Source revision at build time: ${SOURCE_COMMIT}
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ fi
|
|||
readonly RELEASE_TAG="v${PROJECT_VERSION}"
|
||||
readonly RELEASE_ROOT="${PROJECT_ROOT}/builds/${RELEASE_TAG}"
|
||||
readonly ARM64_ROOT="${RELEASE_ROOT}/linux-arm64"
|
||||
readonly ARM64_EXECUTABLE="${ARM64_ROOT}/straywild.arm64"
|
||||
readonly ARM64_PCK="${ARM64_ROOT}/straywild.pck"
|
||||
readonly ARM64_EXECUTABLE="${ARM64_ROOT}/NETfishing.arm64"
|
||||
readonly ARM64_PCK="${ARM64_ROOT}/NETfishing.pck"
|
||||
readonly STAGE_ROOT="${RELEASE_ROOT}/portmaster-stage"
|
||||
readonly GAME_ROOT="${STAGE_ROOT}/straywild"
|
||||
readonly ARCHIVE="${RELEASE_ROOT}/straywild.zip"
|
||||
readonly OBSOLETE_VERSIONED_ARCHIVE="${RELEASE_ROOT}/straywild-${RELEASE_TAG}-portmaster-arm64.zip"
|
||||
readonly OBSOLETE_LOWERCASE_ARCHIVE="${RELEASE_ROOT}/straywild-${RELEASE_TAG}-portmaster-arm64.zip"
|
||||
readonly GAME_ROOT="${STAGE_ROOT}/netfishing"
|
||||
readonly ARCHIVE="${RELEASE_ROOT}/netfishing.zip"
|
||||
readonly OBSOLETE_VERSIONED_ARCHIVE="${RELEASE_ROOT}/NETfishing-${RELEASE_TAG}-portmaster-arm64.zip"
|
||||
readonly OBSOLETE_LOWERCASE_ARCHIVE="${RELEASE_ROOT}/netfishing-${RELEASE_TAG}-portmaster-arm64.zip"
|
||||
|
||||
readonly HEAD_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse HEAD)"
|
||||
readonly TAG_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse "${RELEASE_TAG}^{commit}")"
|
||||
|
|
@ -74,7 +74,7 @@ elif [[ "${HEAD_COMMIT}" != "${TAG_COMMIT}" ]]; then
|
|||
echo "HEAD does not match ${RELEASE_TAG}. Refusing to package mutable source." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${straywild_ALLOW_DIRTY_RELEASE:-0}" != "1" ]]; then
|
||||
if [[ "${NETFISHING_ALLOW_DIRTY_RELEASE:-0}" != "1" ]]; then
|
||||
dirty_tree=0
|
||||
git -C "${PROJECT_ROOT}" diff --quiet || dirty_tree=1
|
||||
git -C "${PROJECT_ROOT}" diff --cached --quiet || dirty_tree=1
|
||||
|
|
@ -97,7 +97,7 @@ done
|
|||
mkdir -p -- "${ARM64_ROOT}" "${RELEASE_ROOT}"
|
||||
if [[ ${PACKAGE_ONLY} -eq 0 ]]; then
|
||||
readonly EXPORT_PROJECT_ROOT="$(
|
||||
mktemp -d -t straywild-portmaster-export.XXXXXX
|
||||
mktemp -d -t netfishing-portmaster-export.XXXXXX
|
||||
)"
|
||||
cleanup_export_project() {
|
||||
rm -rf -- "${EXPORT_PROJECT_ROOT}"
|
||||
|
|
@ -108,9 +108,9 @@ if [[ ${PACKAGE_ONLY} -eq 0 ]]; then
|
|||
--exclude '/.git/' \
|
||||
--exclude '/.godot/' \
|
||||
--exclude '/art/source/' \
|
||||
--exclude '/art/exported/system_icons/straywild.ico' \
|
||||
--exclude '/art/exported/system_icons/straywild_1024.png' \
|
||||
--exclude '/art/exported/system_icons/straywild_1024.png.import' \
|
||||
--exclude '/art/exported/system_icons/netfishing.ico' \
|
||||
--exclude '/art/exported/system_icons/netfishing_1024.png' \
|
||||
--exclude '/art/exported/system_icons/netfishing_1024.png.import' \
|
||||
--exclude '/audio/ambience/' \
|
||||
--exclude '/builds/' \
|
||||
--exclude '/docs/design/' \
|
||||
|
|
@ -141,14 +141,14 @@ rm -f -- \
|
|||
"${OBSOLETE_LOWERCASE_ARCHIVE}"
|
||||
mkdir -p -- "${GAME_ROOT}/licenses"
|
||||
|
||||
install -m 0755 "${TEMPLATE_ROOT}/straywild.sh" "${STAGE_ROOT}/straywild.sh"
|
||||
install -m 0755 "${TEMPLATE_ROOT}/NETfishing.sh" "${STAGE_ROOT}/NETfishing.sh"
|
||||
install -m 0644 "${TEMPLATE_ROOT}/port.json" "${GAME_ROOT}/port.json"
|
||||
install -m 0644 "${TEMPLATE_ROOT}/straywild.gptk" \
|
||||
"${GAME_ROOT}/straywild.gptk"
|
||||
install -m 0755 "${TEMPLATE_ROOT}/launch-straywild.sh" \
|
||||
"${GAME_ROOT}/launch-straywild.sh"
|
||||
install -m 0755 "${ARM64_EXECUTABLE}" "${GAME_ROOT}/straywild.aarch64"
|
||||
install -m 0644 "${ARM64_PCK}" "${GAME_ROOT}/straywild.pck"
|
||||
install -m 0644 "${TEMPLATE_ROOT}/netfishing.gptk" \
|
||||
"${GAME_ROOT}/netfishing.gptk"
|
||||
install -m 0755 "${TEMPLATE_ROOT}/launch-netfishing.sh" \
|
||||
"${GAME_ROOT}/launch-netfishing.sh"
|
||||
install -m 0755 "${ARM64_EXECUTABLE}" "${GAME_ROOT}/NETfishing.aarch64"
|
||||
install -m 0644 "${ARM64_PCK}" "${GAME_ROOT}/NETfishing.pck"
|
||||
install -m 0644 "${TEMPLATE_ROOT}/gameinfo.xml" "${GAME_ROOT}/gameinfo.xml"
|
||||
install -m 0644 "${TEMPLATE_ROOT}/screenshot.png" "${GAME_ROOT}/screenshot.png"
|
||||
install -m 0644 \
|
||||
|
|
@ -159,7 +159,7 @@ install -m 0644 \
|
|||
"${GAME_ROOT}/licenses/GPL-3.0-or-later.txt"
|
||||
install -m 0644 \
|
||||
"${PROJECT_ROOT}/ASSET-LICENSE.md" \
|
||||
"${GAME_ROOT}/licenses/straywild-ASSET-LICENSE.md"
|
||||
"${GAME_ROOT}/licenses/NETFISHING-ASSET-LICENSE.md"
|
||||
install -m 0644 \
|
||||
"${PROJECT_ROOT}/TRADEMARKS.md" \
|
||||
"${GAME_ROOT}/licenses/TRADEMARKS.md"
|
||||
|
|
@ -171,7 +171,7 @@ install -m 0644 \
|
|||
"${GAME_ROOT}/licenses/Seattle-Avenue-LICENSE.txt"
|
||||
|
||||
cat >"${GAME_ROOT}/BUILD-INFO.txt" <<EOF
|
||||
straywild PortMaster ARM64 build
|
||||
NETfishing PortMaster ARM64 build
|
||||
|
||||
Project version: ${PROJECT_VERSION}
|
||||
Game source commit: ${TAG_COMMIT}
|
||||
|
|
@ -191,109 +191,105 @@ EOF
|
|||
cat >"${GAME_ROOT}/licenses/SOURCE-CODE.md" <<EOF
|
||||
# Corresponding source
|
||||
|
||||
straywild code is licensed under GPL-3.0-or-later.
|
||||
NETfishing code is licensed under GPL-3.0-or-later.
|
||||
|
||||
Source repository: https://forge.makearmy.io/woofmeow/straywild
|
||||
Source repository: https://forge.makearmy.io/woofmeow/netfishing
|
||||
Exact source revision: ${TAG_COMMIT}
|
||||
Release tag: ${RELEASE_TAG}
|
||||
PortMaster packaging revision: ${HEAD_COMMIT}
|
||||
EOF
|
||||
|
||||
cat >"${GAME_ROOT}/README.md" <<EOF
|
||||
# straywild for PortMaster
|
||||
# NETfishing for PortMaster
|
||||
|
||||
This package contains straywild \`${RELEASE_TAG}\`, exported from Godot 4.7.1
|
||||
This package contains NETfishing \`${RELEASE_TAG}\`, exported from Godot 4.7.1
|
||||
for 64-bit ARM Linux and wrapped for PortMaster.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the complete \`straywild.zip\` archive with PortMaster or HarbourMaster.
|
||||
Install the complete \`netfishing.zip\` archive with PortMaster or HarbourMaster.
|
||||
The package requires an ARM64 device, two analog sticks, GLIBC 2.28 or newer,
|
||||
and the \`weston_pkg_0.2\` runtime.
|
||||
|
||||
New installations store player data under \`ports/saves/straywild/\` without
|
||||
New installations store player data under \`ports/saves/netfishing/\` without
|
||||
opening a folder picker. Existing installations preserve their previously
|
||||
selected data root. Device-local configuration remains under
|
||||
\`straywild/conf/\`.
|
||||
\`netfishing/conf/\`.
|
||||
PortMaster launches use the light performance profile by default. Put the word
|
||||
\`normal\` in \`straywild/conf/performance_profile\` to opt a capable device
|
||||
\`normal\` in \`netfishing/conf/performance_profile\` to opt a capable device
|
||||
into the normal rendering profile. PortMaster packages retain title and world
|
||||
music while omitting rain and shoreline ambience in both profiles. See
|
||||
\`straywild/licenses/\` for bundled credits and license information.
|
||||
\`netfishing/licenses/\` for bundled credits and license information.
|
||||
|
||||
## Controls
|
||||
|
||||
straywild reads the handheld controller directly. GPTOKEYB's device-specific
|
||||
NETfishing reads the handheld controller directly. GPTOKEYB's device-specific
|
||||
force-quit chord remains available; this is Start+Select on most devices.
|
||||
EOF
|
||||
|
||||
(
|
||||
cd "${STAGE_ROOT}"
|
||||
zip -qry "${ARCHIVE}" straywild.sh straywild
|
||||
zip -qry "${ARCHIVE}" NETfishing.sh netfishing
|
||||
)
|
||||
|
||||
unzip -tq "${ARCHIVE}" >/dev/null
|
||||
readonly TOP_LEVELS="$(
|
||||
unzip -Z1 "${ARCHIVE}" | cut -d/ -f1 | sort -u
|
||||
)"
|
||||
readonly EXPECTED_TOP_LEVELS="$(printf '%s\n' straywild.sh straywild)"
|
||||
readonly EXPECTED_TOP_LEVELS="$(printf '%s\n' NETfishing.sh netfishing)"
|
||||
if [[ "${TOP_LEVELS}" != "${EXPECTED_TOP_LEVELS}" ]]; then
|
||||
echo "Unexpected PortMaster archive roots:" >&2
|
||||
printf '%s\n' "${TOP_LEVELS}" >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -q '"version": 4' "${GAME_ROOT}/port.json"
|
||||
grep -q '"name": "straywild.zip"' "${GAME_ROOT}/port.json"
|
||||
grep -q '"name": "netfishing.zip"' "${GAME_ROOT}/port.json"
|
||||
grep -q '"rtr": true' "${GAME_ROOT}/port.json"
|
||||
if unzip -Z1 "${ARCHIVE}" | grep -qx 'port.json'; then
|
||||
echo "port.json must be inside straywild/, not at the archive root." >&2
|
||||
echo "port.json must be inside netfishing/, not at the archive root." >&2
|
||||
exit 1
|
||||
fi
|
||||
if grep -Eq '^[[:space:]]*#[[:space:]]*PORTMASTER:' \
|
||||
"${STAGE_ROOT}/straywild.sh"; then
|
||||
"${STAGE_ROOT}/NETfishing.sh"; then
|
||||
echo "The distributable launcher contains an installed PortMaster signature." >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -Fq 'PROFILE_PATH="$CONFDIR/performance_profile"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'straywild_PERFORMANCE_PROFILE=light' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'NETFISHING_PERFORMANCE_PROFILE=light' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'CONTROLLER_MAPPING_FILE="$CONFDIR/cache/controller_mapping.txt"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'SAVEDIR="$PORTS_ROOT/saves/straywild"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'LEGACY_SAVEDIR="$PORTS_ROOT/saves/netfishing"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'cp -a "$LEGACY_CONFDIR/." "$CONFDIR/"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq '"straywild_DATA_DIR=$SAVEDIR"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq '"straywild_CREATE_DATA_DIR=1"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'printf '\''%s\n'\'' "$straywild_controllerconfig" > "$CONTROLLER_MAPPING_FILE"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq '"$GAME_LAUNCHER"' "${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq '"$CONTROLLER_MAPPING_FILE"' "${STAGE_ROOT}/straywild.sh"
|
||||
if grep -Fq 'SDL_GAMECONTROLLERCONFIG="$straywild_controllerconfig"' \
|
||||
"${STAGE_ROOT}/straywild.sh"; then
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'SAVEDIR="$PORTS_ROOT/saves/netfishing"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq '"NETFISHING_DATA_DIR=$SAVEDIR"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq '"NETFISHING_CREATE_DATA_DIR=1"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'printf '\''%s\n'\'' "$netfishing_controllerconfig" > "$CONTROLLER_MAPPING_FILE"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq '"$GAME_LAUNCHER"' "${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq '"$CONTROLLER_MAPPING_FILE"' "${STAGE_ROOT}/NETfishing.sh"
|
||||
if grep -Fq 'SDL_GAMECONTROLLERCONFIG="$netfishing_controllerconfig"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"; then
|
||||
echo "Raw controller mappings must not be passed through westonwrap.sh." >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -Fq 'SDL_GAMECONTROLLERCONFIG="$(<"$CONTROLLER_MAPPING_FILE")"' \
|
||||
"${GAME_ROOT}/launch-straywild.sh"
|
||||
"${GAME_ROOT}/launch-netfishing.sh"
|
||||
grep -Fq 'export SDL_GAMECONTROLLERCONFIG' \
|
||||
"${GAME_ROOT}/launch-straywild.sh"
|
||||
grep -Fq 'exec "$@"' "${GAME_ROOT}/launch-straywild.sh"
|
||||
grep -Fq 'GPTOKEYB_CONFIG="$GAMEDIR/straywild.gptk"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq '$GPTOKEYB "straywild.aarch64" -c "$GPTOKEYB_CONFIG" &' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
"${GAME_ROOT}/launch-netfishing.sh"
|
||||
grep -Fq 'exec "$@"' "${GAME_ROOT}/launch-netfishing.sh"
|
||||
grep -Fq 'GPTOKEYB_CONFIG="$GAMEDIR/netfishing.gptk"' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq '$GPTOKEYB "NETfishing.aarch64" -c "$GPTOKEYB_CONFIG" &' \
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'pm_platform_helper "$GAME_EXECUTABLE"' \
|
||||
"${STAGE_ROOT}/straywild.sh"
|
||||
grep -Fq 'pm_finish' "${STAGE_ROOT}/straywild.sh"
|
||||
"${STAGE_ROOT}/NETfishing.sh"
|
||||
grep -Fq 'pm_finish' "${STAGE_ROOT}/NETfishing.sh"
|
||||
if [[ "$(grep -Ec '^[[:space:]]*\$GPTOKEYB[[:space:]]' \
|
||||
"${STAGE_ROOT}/straywild.sh")" -ne 1 ]]; then
|
||||
echo "straywild must start exactly one GPTOKEYB exit handler." >&2
|
||||
"${STAGE_ROOT}/NETfishing.sh")" -ne 1 ]]; then
|
||||
echo "NETfishing must start exactly one GPTOKEYB exit handler." >&2
|
||||
exit 1
|
||||
fi
|
||||
readonly GPTOKEYB_NOOP_KEYS=(
|
||||
|
|
@ -307,13 +303,13 @@ readonly GPTOKEYB_NOOP_KEYS=(
|
|||
for noop_key in "${GPTOKEYB_NOOP_KEYS[@]}"; do
|
||||
if ! grep -Eq \
|
||||
"^[[:space:]]*${noop_key}[[:space:]]*=[[:space:]]*\\\\\"[[:space:]]*$" \
|
||||
"${GAME_ROOT}/straywild.gptk"; then
|
||||
"${GAME_ROOT}/netfishing.gptk"; then
|
||||
echo "GPTOKEYB no-op mapping is missing: ${noop_key}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
if [[ "$(grep -Ec '^[[:space:]]*[a-z0-9_]+[[:space:]]*=' \
|
||||
"${GAME_ROOT}/straywild.gptk")" -ne "${#GPTOKEYB_NOOP_KEYS[@]}" ]]; then
|
||||
"${GAME_ROOT}/netfishing.gptk")" -ne "${#GPTOKEYB_NOOP_KEYS[@]}" ]]; then
|
||||
echo "GPTOKEYB no-op mapping contains an unexpected assignment." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ if [[ ! "$SAMPLE_SET_DIRECTORY" =~ ^[a-z0-9_-]+$ ]]; then
|
|||
fi
|
||||
|
||||
readonly DESTINATION_DIRECTORY="$PROJECT_ROOT/sound/dialogue/animalese/$SAMPLE_SET_DIRECTORY"
|
||||
readonly WORK_DIRECTORY="$(mktemp -d -t straywild-animalese-import.XXXXXX)"
|
||||
readonly WORK_DIRECTORY="$(mktemp -d -t netfishing-animalese-import.XXXXXX)"
|
||||
|
||||
cleanup() {
|
||||
if [[ "$WORK_DIRECTORY" == /tmp/straywild-animalese-import.* ]]; then
|
||||
if [[ "$WORK_DIRECTORY" == /tmp/netfishing-animalese-import.* ]]; then
|
||||
find "$WORK_DIRECTORY" -depth -delete
|
||||
fi
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ fi
|
|||
|
||||
readonly ROOT_PATH="$1"
|
||||
|
||||
readonly WORK_ROOT="$(mktemp -d -t straywild-godot-data.XXXXXX)"
|
||||
readonly WORK_ROOT="$(mktemp -d -t netfishing-godot-data.XXXXXX)"
|
||||
trap 'rm -rf -- "${WORK_ROOT}"' EXIT
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
|
|
|||
|
|
@ -16,56 +16,35 @@ source "$controlfolder/control.txt"
|
|||
[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
|
||||
get_controls
|
||||
|
||||
GAMEDIR="/${directory}/ports/straywild"
|
||||
GAMEDIR="/${directory}/ports/netfishing"
|
||||
|
||||
CONFDIR="$GAMEDIR/conf"
|
||||
PORTS_ROOT="${GAMEDIR%/straywild}"
|
||||
SAVEDIR="$PORTS_ROOT/saves/straywild"
|
||||
LEGACY_GAMEDIR="$PORTS_ROOT/netfishing"
|
||||
LEGACY_CONFDIR="$LEGACY_GAMEDIR/conf"
|
||||
LEGACY_SAVEDIR="$PORTS_ROOT/saves/netfishing"
|
||||
DATA_BOOTSTRAP_DIR="$CONFDIR/data/godot/app_userdata/straywild"
|
||||
LEGACY_DATA_BOOTSTRAP_DIR="$CONFDIR/data/godot/app_userdata/NETFISHING"
|
||||
GAME_EXECUTABLE="$GAMEDIR/straywild.aarch64"
|
||||
GAME_LAUNCHER="$GAMEDIR/launch-straywild.sh"
|
||||
GPTOKEYB_CONFIG="$GAMEDIR/straywild.gptk"
|
||||
PORTS_ROOT="${GAMEDIR%/netfishing}"
|
||||
SAVEDIR="$PORTS_ROOT/saves/netfishing"
|
||||
DATA_BOOTSTRAP_DIR="$CONFDIR/data/godot/app_userdata/NETFISHING"
|
||||
GAME_EXECUTABLE="$GAMEDIR/NETfishing.aarch64"
|
||||
GAME_LAUNCHER="$GAMEDIR/launch-netfishing.sh"
|
||||
GPTOKEYB_CONFIG="$GAMEDIR/netfishing.gptk"
|
||||
CONTROLLER_MAPPING_FILE="$CONFDIR/cache/controller_mapping.txt"
|
||||
WESTON_DIR="/tmp/straywild-weston"
|
||||
WESTON_DIR="/tmp/netfishing-weston"
|
||||
WESTON_RUNTIME="weston_pkg_0.2"
|
||||
HARBOURMASTER="$controlfolder/harbourmaster"
|
||||
|
||||
mkdir -p "$CONFDIR/data" "$CONFDIR/config" "$CONFDIR/cache" "$WESTON_DIR"
|
||||
chmod +x "$GAME_EXECUTABLE"
|
||||
|
||||
# A renamed PortMaster entry installs beside the former NETfishing port. Copy
|
||||
# its device-local configuration once and continue using its established save
|
||||
# root when present. New installations use straywild paths exclusively.
|
||||
if [ -d "$LEGACY_CONFDIR" ] && [ ! -f "$CONFDIR/.netfishing-imported" ]; then
|
||||
cp -a "$LEGACY_CONFDIR/." "$CONFDIR/"
|
||||
touch "$CONFDIR/.netfishing-imported"
|
||||
fi
|
||||
if [ ! -f "$SAVEDIR/straywild_data.json" ] \
|
||||
&& [ ! -f "$SAVEDIR/netfishing_data.json" ] \
|
||||
&& { [ -f "$LEGACY_SAVEDIR/straywild_data.json" ] \
|
||||
|| [ -f "$LEGACY_SAVEDIR/netfishing_data.json" ]; }; then
|
||||
SAVEDIR="$LEGACY_SAVEDIR"
|
||||
fi
|
||||
|
||||
# straywild uses a predictable save directory beside the port instead of
|
||||
# NETfishing uses a predictable save directory beside the port instead of
|
||||
# presenting a folder picker on a small screen. Preserve an established
|
||||
# data-root choice when upgrading an existing installation.
|
||||
straywild_DATA_ENVIRONMENT=()
|
||||
if [ -f "$SAVEDIR/straywild_data.json" ] \
|
||||
|| [ -f "$SAVEDIR/netfishing_data.json" ] || {
|
||||
NETFISHING_DATA_ENVIRONMENT=()
|
||||
if [ -f "$SAVEDIR/netfishing_data.json" ] || {
|
||||
[ ! -f "$DATA_BOOTSTRAP_DIR/data_root_bootstrap.json" ] &&
|
||||
[ ! -f "$DATA_BOOTSTRAP_DIR/data_root_bootstrap.json.backup" ] &&
|
||||
[ ! -f "$LEGACY_DATA_BOOTSTRAP_DIR/data_root_bootstrap.json" ] &&
|
||||
[ ! -f "$LEGACY_DATA_BOOTSTRAP_DIR/data_root_bootstrap.json.backup" ]
|
||||
[ ! -f "$DATA_BOOTSTRAP_DIR/data_root_bootstrap.json.backup" ]
|
||||
}; then
|
||||
mkdir -p "$SAVEDIR"
|
||||
straywild_DATA_ENVIRONMENT+=(
|
||||
"straywild_DATA_DIR=$SAVEDIR"
|
||||
"straywild_CREATE_DATA_DIR=1"
|
||||
NETFISHING_DATA_ENVIRONMENT+=(
|
||||
"NETFISHING_DATA_DIR=$SAVEDIR"
|
||||
"NETFISHING_CREATE_DATA_DIR=1"
|
||||
)
|
||||
fi
|
||||
|
||||
|
|
@ -73,7 +52,7 @@ fi
|
|||
|
||||
if [ ! -f "$controlfolder/libs/${WESTON_RUNTIME}.squashfs" ]; then
|
||||
if [ ! -x "$HARBOURMASTER" ]; then
|
||||
pm_message "straywild requires the latest PortMaster and WestonPack runtime."
|
||||
pm_message "NETfishing requires the latest PortMaster and WestonPack runtime."
|
||||
sleep 5
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -99,17 +78,17 @@ cd "$GAMEDIR" || exit 1
|
|||
GODOT_MUOS_MAPPING="19004ca6010000000100000000010000,muOS-Keys,a:b0,b:b1,x:b3,y:b2,leftshoulder:b4,rightshoulder:b5,lefttrigger:b10,righttrigger:b11,guide:b8,start:b7,back:b6,dpup:h0.1,dpleft:h0.8,dpright:h0.2,dpdown:h0.4,leftx:a0,lefty:a1,leftstick:b9,rightx:a2,righty:a3,rightstick:b12,platform:Linux,"
|
||||
MUOS_SDL2_GUID="19000000010000000100000000010000"
|
||||
if [[ "$sdl_controllerconfig" == "${MUOS_SDL2_GUID},"* ]]; then
|
||||
straywild_controllerconfig="$GODOT_MUOS_MAPPING"
|
||||
netfishing_controllerconfig="$GODOT_MUOS_MAPPING"
|
||||
elif [ -n "$sdl_controllerconfig" ]; then
|
||||
straywild_controllerconfig="$sdl_controllerconfig"
|
||||
netfishing_controllerconfig="$sdl_controllerconfig"
|
||||
else
|
||||
straywild_controllerconfig="$GODOT_MUOS_MAPPING"
|
||||
netfishing_controllerconfig="$GODOT_MUOS_MAPPING"
|
||||
fi
|
||||
printf '%s\n' "$straywild_controllerconfig" > "$CONTROLLER_MAPPING_FILE"
|
||||
printf '%s\n' "$netfishing_controllerconfig" > "$CONTROLLER_MAPPING_FILE"
|
||||
|
||||
straywild_GODOT_OPTIONS=()
|
||||
straywild_GAME_ENVIRONMENT=()
|
||||
PERFORMANCE_PROFILE="${straywild_PERFORMANCE_PROFILE:-}"
|
||||
NETFISHING_GODOT_OPTIONS=()
|
||||
NETFISHING_GAME_ENVIRONMENT=()
|
||||
PERFORMANCE_PROFILE="${NETFISHING_PERFORMANCE_PROFILE:-}"
|
||||
PROFILE_PATH="$CONFDIR/performance_profile"
|
||||
if [[ -z "$PERFORMANCE_PROFILE" && -r "$PROFILE_PATH" ]]; then
|
||||
IFS= read -r PERFORMANCE_PROFILE < "$PROFILE_PATH" || true
|
||||
|
|
@ -117,16 +96,16 @@ if [[ -z "$PERFORMANCE_PROFILE" && -r "$PROFILE_PATH" ]]; then
|
|||
fi
|
||||
case "$PERFORMANCE_PROFILE" in
|
||||
normal)
|
||||
straywild_GAME_ENVIRONMENT+=(
|
||||
"straywild_PERFORMANCE_PROFILE=normal"
|
||||
NETFISHING_GAME_ENVIRONMENT+=(
|
||||
"NETFISHING_PERFORMANCE_PROFILE=normal"
|
||||
)
|
||||
;;
|
||||
light|"")
|
||||
straywild_GAME_ENVIRONMENT+=(
|
||||
"straywild_PERFORMANCE_PROFILE=light"
|
||||
"straywild_LOW_END=1"
|
||||
NETFISHING_GAME_ENVIRONMENT+=(
|
||||
"NETFISHING_PERFORMANCE_PROFILE=light"
|
||||
"NETFISHING_LOW_END=1"
|
||||
)
|
||||
straywild_GODOT_OPTIONS+=(
|
||||
NETFISHING_GODOT_OPTIONS+=(
|
||||
--single-window
|
||||
--disable-vsync
|
||||
--max-fps 30
|
||||
|
|
@ -135,11 +114,11 @@ case "$PERFORMANCE_PROFILE" in
|
|||
;;
|
||||
*)
|
||||
echo "Unknown performance profile '$PERFORMANCE_PROFILE'; using light." >&2
|
||||
straywild_GAME_ENVIRONMENT+=(
|
||||
"straywild_PERFORMANCE_PROFILE=light"
|
||||
"straywild_LOW_END=1"
|
||||
NETFISHING_GAME_ENVIRONMENT+=(
|
||||
"NETFISHING_PERFORMANCE_PROFILE=light"
|
||||
"NETFISHING_LOW_END=1"
|
||||
)
|
||||
straywild_GODOT_OPTIONS+=(
|
||||
NETFISHING_GODOT_OPTIONS+=(
|
||||
--single-window
|
||||
--disable-vsync
|
||||
--max-fps 30
|
||||
|
|
@ -148,10 +127,10 @@ case "$PERFORMANCE_PROFILE" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# straywild reads gameplay input natively. The explicit no-op map prevents
|
||||
# NETfishing reads gameplay input natively. The explicit no-op map prevents
|
||||
# GPTOKEYB from injecting duplicate keyboard or mouse input while retaining
|
||||
# its device-specific force-quit chord, including on ROCKNIX.
|
||||
$GPTOKEYB "straywild.aarch64" -c "$GPTOKEYB_CONFIG" &
|
||||
$GPTOKEYB "NETfishing.aarch64" -c "$GPTOKEYB_CONFIG" &
|
||||
pm_platform_helper "$GAME_EXECUTABLE"
|
||||
|
||||
$ESUDO env CRUSTY_RESOLUTION="${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}" \
|
||||
|
|
@ -160,12 +139,12 @@ $ESUDO env CRUSTY_RESOLUTION="${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}" \
|
|||
XDG_CONFIG_HOME="$CONFDIR/config" \
|
||||
XDG_CACHE_HOME="$CONFDIR/cache" \
|
||||
GODOT_SILENCE_ROOT_WARNING=1 \
|
||||
"${straywild_DATA_ENVIRONMENT[@]}" \
|
||||
"${straywild_GAME_ENVIRONMENT[@]}" \
|
||||
"${NETFISHING_DATA_ENVIRONMENT[@]}" \
|
||||
"${NETFISHING_GAME_ENVIRONMENT[@]}" \
|
||||
"$GAME_LAUNCHER" \
|
||||
"$CONTROLLER_MAPPING_FILE" \
|
||||
"$GAME_EXECUTABLE" \
|
||||
"${straywild_GODOT_OPTIONS[@]}" \
|
||||
"${NETFISHING_GODOT_OPTIONS[@]}" \
|
||||
--resolution "${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}" \
|
||||
--fullscreen \
|
||||
--rendering-driver opengl3_es \
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<gameList>
|
||||
<game>
|
||||
<path>./straywild.sh</path>
|
||||
<name>straywild</name>
|
||||
<path>./NETfishing.sh</path>
|
||||
<name>NETfishing</name>
|
||||
<desc>A relaxed multiplayer fishing game about exploring a small island, catching and collecting fish, customizing your character, and spending time by the water.</desc>
|
||||
<releasedate>20260804T000000</releasedate>
|
||||
<developer>straywild project</developer>
|
||||
<developer>NETfishing project</developer>
|
||||
<publisher>Independent</publisher>
|
||||
<genre>adventure, simulation</genre>
|
||||
<image>./straywild/screenshot.png</image>
|
||||
<image>./netfishing/screenshot.png</image>
|
||||
</game>
|
||||
</gameList>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# straywild reads the controller directly. GPTOKEYB is retained only for its
|
||||
# NETfishing reads the controller directly. GPTOKEYB is retained only for its
|
||||
# device-specific force-quit chord, so every keyboard and mouse binding is
|
||||
# disabled to prevent duplicate input.
|
||||
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"version": 4,
|
||||
"name": "straywild.zip",
|
||||
"name": "netfishing.zip",
|
||||
"items": [
|
||||
"straywild.sh",
|
||||
"straywild/"
|
||||
"NETfishing.sh",
|
||||
"netfishing/"
|
||||
],
|
||||
"items_opt": null,
|
||||
"attr": {
|
||||
"title": "straywild",
|
||||
"title": "NETfishing",
|
||||
"porter": [
|
||||
"Voyager"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|||
readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||||
readonly GODOT_BIN="${GODOT_BIN:-godot}"
|
||||
readonly TEST_TIMEOUT_SECONDS="${TEST_TIMEOUT_SECONDS:-120}"
|
||||
readonly RUN_ROOT="$(mktemp -d -t straywild-validations.XXXXXX)"
|
||||
readonly RUN_ROOT="$(mktemp -d -t netfishing-validations.XXXXXX)"
|
||||
|
||||
export straywild_ISOLATED_VALIDATION_STORAGE=1
|
||||
export NETFISHING_ISOLATED_VALIDATION_STORAGE=1
|
||||
|
||||
readonly -a QUICK_TESTS=(
|
||||
"scripts/validate_animalese_samples.gd"
|
||||
|
|
|
|||
|
|
@ -336,8 +336,8 @@ check_editor_settings() {
|
|||
run_export_hint() {
|
||||
echo
|
||||
echo "Example export commands:"
|
||||
echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-release \"Android\" builds/${PROJECT_VERSION}/android/straywild.apk"
|
||||
echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-debug \"Android\" builds/android/straywild-debug.apk"
|
||||
echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-release \"Android\" builds/${PROJECT_VERSION}/android/NETfishing.apk"
|
||||
echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-debug \"Android\" builds/android/NETfishing-debug.apk"
|
||||
}
|
||||
|
||||
print_status INFO "Starting Android dependency preflight..."
|
||||
|
|
|
|||
|
|
@ -1,36 +1,36 @@
|
|||
extends SceneTree
|
||||
|
||||
const PROJECT_PATH := "/tmp/straywild"
|
||||
const INSTALL_PATH := "/opt/straywild"
|
||||
const PROJECT_PATH := "/tmp/netfishing"
|
||||
const INSTALL_PATH := "/opt/NETfishing"
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
var root_to_create: String = OS.get_environment("straywild_TEST_CREATE_ROOT")
|
||||
var root_to_create: String = OS.get_environment("NETFISHING_TEST_CREATE_ROOT")
|
||||
if not root_to_create.is_empty():
|
||||
_create_validation_root(root_to_create)
|
||||
return
|
||||
var failures: PackedStringArray = []
|
||||
_expect(
|
||||
"external temporary directory",
|
||||
"/tmp/straywild-test-data",
|
||||
"/tmp/NETfishing-test-data",
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
failures,
|
||||
)
|
||||
_expect(
|
||||
"external trailing slash",
|
||||
"/tmp/straywild-test-data/",
|
||||
"/tmp/NETfishing-test-data/",
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
failures,
|
||||
)
|
||||
_expect(
|
||||
"similar project-name sibling",
|
||||
"/tmp/straywild-data",
|
||||
"/tmp/netfishing-data",
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
failures,
|
||||
)
|
||||
_expect(
|
||||
"documents directory",
|
||||
"/home/player/Documents/straywild",
|
||||
"/home/player/Documents/NETfishing",
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
failures,
|
||||
)
|
||||
|
|
@ -55,7 +55,7 @@ func _initialize() -> void:
|
|||
)
|
||||
_expect_with_references(
|
||||
"empty project reference",
|
||||
"/tmp/straywild-test-data",
|
||||
"/tmp/NETfishing-test-data",
|
||||
"",
|
||||
INSTALL_PATH,
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
|
|
@ -63,7 +63,7 @@ func _initialize() -> void:
|
|||
)
|
||||
_expect_with_references(
|
||||
"root project reference",
|
||||
"/tmp/straywild-test-data",
|
||||
"/tmp/NETfishing-test-data",
|
||||
"/",
|
||||
INSTALL_PATH,
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
|
|
@ -71,9 +71,9 @@ func _initialize() -> void:
|
|||
)
|
||||
_expect_with_references(
|
||||
"Windows component and case normalization",
|
||||
"C:\\Games\\straywild Data",
|
||||
"C:\\Games\\straywild",
|
||||
"C:\\Program Files\\straywild",
|
||||
"C:\\Games\\NETfishing Data",
|
||||
"C:\\Games\\NETfishing",
|
||||
"C:\\Program Files\\NETfishing",
|
||||
PlayerDataRoot.PATH_ALLOWED,
|
||||
failures,
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
class_name DedicatedServerConfig
|
||||
extends RefCounted
|
||||
|
||||
const DEFAULT_NAME: String = "straywild Dedicated Server"
|
||||
const DEFAULT_NAME: String = "NETfishing Dedicated Server"
|
||||
const DEFAULT_BIND_ADDRESS: String = "*"
|
||||
const DEFAULT_PORT: int = 7777
|
||||
const DEFAULT_MAX_PLAYERS: int = 8
|
||||
|
|
@ -31,10 +31,8 @@ static func from_runtime() -> DedicatedServerConfig:
|
|||
result.discovery_url = str(ProjectSettings.get_setting(
|
||||
"network/discovery/base_url", ""
|
||||
)).strip_edges()
|
||||
var config_path: String = _environment_string(
|
||||
"straywild_SERVER_CONFIG",
|
||||
"NETFISHING_SERVER_CONFIG",
|
||||
"",
|
||||
var config_path: String = OS.get_environment(
|
||||
"NETFISHING_SERVER_CONFIG"
|
||||
).strip_edges()
|
||||
for argument: String in OS.get_cmdline_user_args():
|
||||
if argument.begins_with("--config="):
|
||||
|
|
@ -89,44 +87,36 @@ func _load_file(path: String) -> bool:
|
|||
|
||||
func _apply_environment() -> void:
|
||||
server_name = _environment_string(
|
||||
"straywild_SERVER_NAME", "NETFISHING_SERVER_NAME", server_name
|
||||
"NETFISHING_SERVER_NAME", server_name
|
||||
)
|
||||
bind_address = _environment_string(
|
||||
"straywild_SERVER_BIND", "NETFISHING_SERVER_BIND", bind_address
|
||||
)
|
||||
port = _environment_int(
|
||||
"straywild_SERVER_PORT", "NETFISHING_SERVER_PORT", port
|
||||
"NETFISHING_SERVER_BIND", bind_address
|
||||
)
|
||||
port = _environment_int("NETFISHING_SERVER_PORT", port)
|
||||
max_players = _environment_int(
|
||||
"straywild_SERVER_MAX_PLAYERS",
|
||||
"NETFISHING_SERVER_MAX_PLAYERS",
|
||||
max_players,
|
||||
"NETFISHING_SERVER_MAX_PLAYERS", max_players
|
||||
)
|
||||
world_seed = _environment_int(
|
||||
"straywild_WORLD_SEED", "NETFISHING_WORLD_SEED", world_seed
|
||||
"NETFISHING_WORLD_SEED", world_seed
|
||||
)
|
||||
public_listing = _environment_bool(
|
||||
"straywild_SERVER_PUBLIC", "NETFISHING_SERVER_PUBLIC", public_listing
|
||||
"NETFISHING_SERVER_PUBLIC", public_listing
|
||||
)
|
||||
discovery_url = _environment_string(
|
||||
"straywild_DISCOVERY_URL", "NETFISHING_DISCOVERY_URL", discovery_url
|
||||
"NETFISHING_DISCOVERY_URL", discovery_url
|
||||
)
|
||||
data_directory = _environment_string(
|
||||
"straywild_DATA_DIR", "NETFISHING_DATA_DIR", data_directory
|
||||
"NETFISHING_DATA_DIR", data_directory
|
||||
)
|
||||
chat_logging = _environment_bool(
|
||||
"straywild_CHAT_LOGGING", "NETFISHING_CHAT_LOGGING", chat_logging
|
||||
"NETFISHING_CHAT_LOGGING", chat_logging
|
||||
)
|
||||
chat_log_path = _environment_string(
|
||||
"straywild_CHAT_LOG_PATH", "NETFISHING_CHAT_LOG_PATH", chat_log_path
|
||||
"NETFISHING_CHAT_LOG_PATH", chat_log_path
|
||||
)
|
||||
var operators_variable: String = _available_environment_variable(
|
||||
"straywild_SERVER_OPERATORS",
|
||||
"NETFISHING_SERVER_OPERATORS",
|
||||
)
|
||||
if not operators_variable.is_empty():
|
||||
if OS.has_environment("NETFISHING_SERVER_OPERATORS"):
|
||||
operator_fingerprints = _parse_fingerprint_list(
|
||||
OS.get_environment(operators_variable)
|
||||
OS.get_environment("NETFISHING_SERVER_OPERATORS")
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -221,45 +211,21 @@ static func _safe_text(value: String) -> bool:
|
|||
return true
|
||||
|
||||
|
||||
static func _available_environment_variable(
|
||||
name: String,
|
||||
legacy_name: String,
|
||||
) -> String:
|
||||
if OS.has_environment(name):
|
||||
return name
|
||||
return legacy_name if OS.has_environment(legacy_name) else ""
|
||||
static func _environment_string(name: String, fallback: String) -> String:
|
||||
return OS.get_environment(name) if OS.has_environment(name) else fallback
|
||||
|
||||
|
||||
static func _environment_string(
|
||||
name: String,
|
||||
legacy_name: String,
|
||||
fallback: String,
|
||||
) -> String:
|
||||
var variable: String = _available_environment_variable(name, legacy_name)
|
||||
return OS.get_environment(variable) if not variable.is_empty() else fallback
|
||||
|
||||
|
||||
static func _environment_int(
|
||||
name: String,
|
||||
legacy_name: String,
|
||||
fallback: int,
|
||||
) -> int:
|
||||
var variable: String = _available_environment_variable(name, legacy_name)
|
||||
static func _environment_int(name: String, fallback: int) -> int:
|
||||
return (
|
||||
_parse_int(OS.get_environment(variable), fallback)
|
||||
if not variable.is_empty() else fallback
|
||||
_parse_int(OS.get_environment(name), fallback)
|
||||
if OS.has_environment(name) else fallback
|
||||
)
|
||||
|
||||
|
||||
static func _environment_bool(
|
||||
name: String,
|
||||
legacy_name: String,
|
||||
fallback: bool,
|
||||
) -> bool:
|
||||
var variable: String = _available_environment_variable(name, legacy_name)
|
||||
if variable.is_empty():
|
||||
static func _environment_bool(name: String, fallback: bool) -> bool:
|
||||
if not OS.has_environment(name):
|
||||
return fallback
|
||||
var value: String = OS.get_environment(variable).strip_edges().to_lower()
|
||||
var value: String = OS.get_environment(name).strip_edges().to_lower()
|
||||
return value in ["1", "true", "yes", "on"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const TEMP_PATH: String = "user://player_settings.json.tmp"
|
|||
const BACKUP_PATH: String = "user://player_settings.json.backup"
|
||||
const SILENT_VOLUME_DB: float = -80.0
|
||||
const HEADLESS_WRITE_ENVIRONMENT: String = (
|
||||
"straywild_ISOLATED_VALIDATION_STORAGE"
|
||||
"NETFISHING_ISOLATED_VALIDATION_STORAGE"
|
||||
)
|
||||
|
||||
signal settings_changed(settings: PlayerSettings)
|
||||
|
|
|
|||