Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ hashes. These development-mode runtime files are a fidelity bridge for the first
local packaged surface; release hardening should replace Babel-in-browser with a
compiled bundle while keeping all assets local.

## Bundled OpenWorlds icon assets

OpenWorlds vendors a small curated subset of **Game Icons** under
`viewer/openworlds/assets/icons/game-icons/` for gameplay affordances such as
attacks, dice, travel, quests, camp, settlements, consumables, and coins.

- **Source:** <https://game-icons.net> / `game-icons/icons`
- **License:** Creative Commons Attribution 3.0 (CC-BY-3.0), unless an upstream
contributor is explicitly marked CC0.
- **Attribution:** see `viewer/openworlds/assets/icons/ATTRIBUTION.md`.
- **Authors in this subset:** Lorc, Delapouite, and Willdabeast.

The imported SVGs were normalized only for presentation by removing the opaque
background rectangle so the app can tint them as local CSS masks. ClawDnD does
not vendor the full icon set and does not fetch icon assets from a network CDN.

## Structural references — learn-from only (NO code copied)

These projects informed ClawDnD's design. After verifying their licensing
Expand Down
41 changes: 41 additions & 0 deletions scripts/license_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,46 @@ def _check_authored_bestiary() -> list[str]:
bestiary._index.cache_clear()


def _check_game_icons_attribution(tracked: list[str]) -> list[str]:
"""The OpenWorlds UI may vendor a small subset of Game Icons, but every SVG
must stay covered by the local attribution file and top-level notices."""
errors: list[str] = []
icons = [
f for f in tracked
if f.startswith("viewer/openworlds/assets/icons/game-icons/") and f.endswith(".svg")
]
if not icons:
return errors

attr_path = ROOT / "viewer/openworlds/assets/icons/ATTRIBUTION.md"
notice_path = ROOT / "THIRD_PARTY_NOTICES.md"
if not attr_path.exists():
errors.append("Game Icons assets are missing viewer/openworlds/assets/icons/ATTRIBUTION.md")
attr_text = ""
else:
try:
attr_text = attr_path.read_text(encoding="utf-8")
except OSError as exc:
errors.append(f"Game Icons attribution file is unreadable: {exc}")
attr_text = ""
if notice_path.exists():
try:
notice_text = notice_path.read_text(encoding="utf-8")
except OSError as exc:
errors.append(f"THIRD_PARTY_NOTICES.md is unreadable: {exc}")
notice_text = ""
else:
notice_text = ""

if "Game Icons" not in notice_text or "CC-BY-3.0" not in notice_text:
errors.append("THIRD_PARTY_NOTICES.md is missing Game Icons CC-BY-3.0 attribution")
for f in icons:
local = f.removeprefix("viewer/openworlds/assets/icons/")
if local not in attr_text:
errors.append(f"Game Icons SVG missing attribution row: {f}")
return errors


def tracked_files() -> list[str]:
out = subprocess.run(
["git", "ls-files"], cwd=ROOT, capture_output=True, text=True, check=True
Expand Down Expand Up @@ -121,6 +161,7 @@ def main() -> int:
# Ingested (wiki-derived) records/pages must each carry per-source attribution.
errors.extend(_check_ingested_attribution(tracked))
errors.extend(_check_authored_bestiary())
errors.extend(_check_game_icons_attribution(tracked))

if errors:
print("LICENSE CHECK FAILED:")
Expand Down
31 changes: 31 additions & 0 deletions viewer/openworlds/assets/icons/ATTRIBUTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# OpenWorlds Icon Attributions

OpenWorlds imports a small curated subset of [Game Icons](https://game-icons.net)
from `game-icons/icons`, not the whole repository. The source repository license
text says icons are Creative Commons 3.0 BY unless a contributor is explicitly
marked CC0, and asks derivative works to include `Icons made by {author}`.

Imported SVGs were normalized only for presentation by removing the opaque
background rectangle so the app can color them through CSS masks. The underlying
icon silhouettes are unchanged.

| Local semantic id | Local path | Source path | Author | License |
| --- | --- | --- | --- | --- |
| `atlas.travel` | `game-icons/lorc/compass.svg` | `lorc/compass.svg` | Lorc | CC-BY-3.0 |
| `camp.rest` | `game-icons/lorc/campfire.svg` | `lorc/campfire.svg` | Lorc | CC-BY-3.0 |
| `codex.book` | `game-icons/lorc/open-book.svg` | `lorc/open-book.svg` | Lorc | CC-BY-3.0 |
| `combat.attack` | `game-icons/lorc/sword-clash.svg` | `lorc/sword-clash.svg` | Lorc | CC-BY-3.0 |
| `dice.d20` | `game-icons/delapouite/dice-twenty-faces-twenty.svg` | `delapouite/dice-twenty-faces-twenty.svg` | Delapouite | CC-BY-3.0 |
| `dice.roll` | `game-icons/delapouite/rolling-dices.svg` | `delapouite/rolling-dices.svg` | Delapouite | CC-BY-3.0 |
| `economy.coins` | `game-icons/delapouite/coins.svg` | `delapouite/coins.svg` | Delapouite | CC-BY-3.0 |
| `inventory.locked` | `game-icons/lorc/locked-chest.svg` | `lorc/locked-chest.svg` | Lorc | CC-BY-3.0 |
| `inventory.potion` | `game-icons/delapouite/health-potion.svg` | `delapouite/health-potion.svg` | Delapouite | CC-BY-3.0 |
| `party.shield` | `game-icons/willdabeast/round-shield.svg` | `willdabeast/round-shield.svg` | Willdabeast | CC-BY-3.0 |
| `quest.scroll` | `game-icons/lorc/tied-scroll.svg` | `lorc/tied-scroll.svg` | Lorc | CC-BY-3.0 |
| `settlement.tavern` | `game-icons/delapouite/tavern-sign.svg` | `delapouite/tavern-sign.svg` | Delapouite | CC-BY-3.0 |

Author home pages from the upstream license text:

- Icons made by Lorc: <http://lorcblog.blogspot.com>
- Icons made by Delapouite: <http://delapouite.com>
- Icons made by Willdabeast: <http://wjbstories.blogspot.com>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading