Lock asset pipeline to free sources
This commit is contained in:
@@ -22,7 +22,8 @@ not look cartoonish, old-west, or exaggerated apocalypse junkyard.
|
|||||||
|
|
||||||
## Approved Sources
|
## Approved Sources
|
||||||
|
|
||||||
- Fab free assets or assets explicitly owned for this project.
|
- Fab free assets. Paid Fab assets are blocked unless Nathan explicitly approves
|
||||||
|
the purchase in a later task.
|
||||||
- Quixel/Megascans assets available under the current Epic/Unreal terms.
|
- Quixel/Megascans assets available under the current Epic/Unreal terms.
|
||||||
- CC0/public-domain art libraries.
|
- CC0/public-domain art libraries.
|
||||||
- Assets created internally.
|
- Assets created internally.
|
||||||
@@ -31,6 +32,16 @@ not look cartoonish, old-west, or exaggerated apocalypse junkyard.
|
|||||||
Do not scrape random internet images or models. If an asset cannot be traced to
|
Do not scrape random internet images or models. If an asset cannot be traced to
|
||||||
a usable license, reject it.
|
a usable license, reject it.
|
||||||
|
|
||||||
|
## Free-Only Lockdown
|
||||||
|
|
||||||
|
The asset pipeline is currently free-only. Before download or import, verify
|
||||||
|
that the asset page is marked free or that the asset is project-owned/internal.
|
||||||
|
Record the cost in `Docs/Art/AssetLicenses.md` as `Free`, `$0`, `0`, or `N/A`.
|
||||||
|
|
||||||
|
Do not click purchase, checkout, add payment, subscription, or paid-license
|
||||||
|
flows. If an asset looks useful but is not free, record it as a candidate in
|
||||||
|
notes outside the import flow and wait for explicit approval.
|
||||||
|
|
||||||
## Staging Workflow
|
## Staging Workflow
|
||||||
|
|
||||||
1. Place downloaded/manual assets in:
|
1. Place downloaded/manual assets in:
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ before it is used in a playable map, packaged demo, screenshot, or trailer.
|
|||||||
|
|
||||||
Allowed default sources:
|
Allowed default sources:
|
||||||
|
|
||||||
- Fab assets explicitly marked free or otherwise purchased/owned for this
|
- Fab assets explicitly marked free. Paid Fab assets are blocked unless Nathan
|
||||||
project.
|
explicitly approves a purchase in a later task.
|
||||||
- Quixel/Megascans assets available under the current Epic/Unreal terms for
|
- Quixel/Megascans assets available under the current Epic/Unreal terms for
|
||||||
this project.
|
this project.
|
||||||
- CC0 or public-domain assets.
|
- CC0 or public-domain assets.
|
||||||
@@ -30,6 +30,16 @@ Expected subfolders:
|
|||||||
- `Processed`: assets imported, optimized, renamed, and verified.
|
- `Processed`: assets imported, optimized, renamed, and verified.
|
||||||
- `Rejected`: assets that should not be used.
|
- `Rejected`: assets that should not be used.
|
||||||
|
|
||||||
|
## Free-Only Acquisition Gate
|
||||||
|
|
||||||
|
Until Nathan explicitly approves a paid purchase, every third-party asset must
|
||||||
|
have `Cost` recorded as `Free`, `$0`, `0`, or `N/A` for project-owned/internal
|
||||||
|
assets. Do not use "purchased", "paid", a dollar amount above zero, or blank
|
||||||
|
cost values in the register.
|
||||||
|
|
||||||
|
Any asset with uncertain cost, marketplace bundle requirements, subscription
|
||||||
|
requirements, or unclear entitlement belongs in `Rejected` until reviewed.
|
||||||
|
|
||||||
## Naming Policy
|
## Naming Policy
|
||||||
|
|
||||||
Use project-readable names before import:
|
Use project-readable names before import:
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Fail if tracked Agrarian assets include paid or unclear costs."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
REGISTER = ROOT / "Docs" / "Art" / "AssetLicenses.md"
|
||||||
|
|
||||||
|
ALLOWED_COSTS = {"free", "$0", "0", "n/a", "na"}
|
||||||
|
BLOCKED_WORDS = {
|
||||||
|
"paid",
|
||||||
|
"purchased",
|
||||||
|
"purchase",
|
||||||
|
"subscription",
|
||||||
|
"unknown",
|
||||||
|
"unclear",
|
||||||
|
"tbd",
|
||||||
|
"marketplace bundle",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_markdown_table_rows(text: str) -> list[list[str]]:
|
||||||
|
rows: list[list[str]] = []
|
||||||
|
for line in text.splitlines():
|
||||||
|
stripped = line.strip()
|
||||||
|
if not stripped.startswith("|") or "---" in stripped:
|
||||||
|
continue
|
||||||
|
cells = [cell.strip() for cell in stripped.strip("|").split("|")]
|
||||||
|
if cells and cells[0] != "Asset":
|
||||||
|
rows.append(cells)
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
if not REGISTER.exists():
|
||||||
|
raise SystemExit(f"Missing asset license register: {REGISTER}")
|
||||||
|
|
||||||
|
rows = parse_markdown_table_rows(REGISTER.read_text(encoding="utf-8"))
|
||||||
|
failures: list[str] = []
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
if len(row) < 5:
|
||||||
|
failures.append(f"Malformed asset license row: {' | '.join(row)}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
asset = row[0]
|
||||||
|
cost = row[4].strip().lower()
|
||||||
|
full_row = " ".join(row).lower()
|
||||||
|
|
||||||
|
if not cost:
|
||||||
|
failures.append(f"{asset}: cost is blank")
|
||||||
|
elif cost not in ALLOWED_COSTS:
|
||||||
|
failures.append(f"{asset}: cost {row[4]!r} is not free-only")
|
||||||
|
|
||||||
|
for blocked in BLOCKED_WORDS:
|
||||||
|
if blocked in full_row:
|
||||||
|
failures.append(f"{asset}: blocked free-only word found: {blocked!r}")
|
||||||
|
|
||||||
|
if failures:
|
||||||
|
raise SystemExit("\n".join(failures))
|
||||||
|
|
||||||
|
print(f"Asset license free-only verification complete: {len(rows)} entries.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -12,12 +12,16 @@ REQUIRED = {
|
|||||||
"CC0 or public-domain",
|
"CC0 or public-domain",
|
||||||
"/home/nathan/AssetStaging/Agrarian",
|
"/home/nathan/AssetStaging/Agrarian",
|
||||||
"Do not import random internet images",
|
"Do not import random internet images",
|
||||||
|
"Free-Only Acquisition Gate",
|
||||||
|
"Paid Fab assets are blocked",
|
||||||
"Native Ground Zero proxy vegetation",
|
"Native Ground Zero proxy vegetation",
|
||||||
],
|
],
|
||||||
"Docs/Art/AgrarianAssetPipeline.md": [
|
"Docs/Art/AgrarianAssetPipeline.md": [
|
||||||
"realistic modern post-collapse frontier survival",
|
"realistic modern post-collapse frontier survival",
|
||||||
"Old abandoned equipment",
|
"Old abandoned equipment",
|
||||||
"Do not scrape random internet images or models",
|
"Do not scrape random internet images or models",
|
||||||
|
"Free-Only Lockdown",
|
||||||
|
"Do not click purchase",
|
||||||
"LicenseEvidence",
|
"LicenseEvidence",
|
||||||
"Run visual and placeholder verifiers",
|
"Run visual and placeholder verifiers",
|
||||||
"Water should be handled as a shader/system problem",
|
"Water should be handled as a shader/system problem",
|
||||||
|
|||||||
Reference in New Issue
Block a user