No description
  • GDScript 77%
  • Shell 19%
  • Nix 4%
Find a file
Daniel Flanagan 0bf722a8dc docs: vendoring is the route; there is no submodule option
jj has no git submodules and the games are jj repositories, so half the
previous advice was something nobody could follow. And the nix half was
already ruled out for a different reason: nix git-tree filtering does not
follow submodule CONTENTS, so a submodule arrives as an empty directory
that builds cleanly and ships a game with no intro.

Submodules therefore fail for both consumers this repo has, which leaves
vendoring as the only route that works everywhere. Stated as a reason
rather than a silence, so nobody helpfully reintroduces them.

Vendoring loses the one thing a submodule gave for free — provenance —
so bin/vendor-into copies the addon and stamps the upstream revision into
VENDORED.md, which also says plainly that nothing in the copy is safe to
edit because the next sync discards it. A script rather than a documented
procedure, because the stamp is only reliable if writing it is not a step
somebody can skip.

The flake input stays, correctly labelled as the nix-native option rather
than as the alternative to a submodule: it is hash-pinned and strictly
better where it applies, and deck-slice keeps using it.
2026-08-05 23:52:19 -05:00
addons/lyte_brand chore: commit the script .uid files 2026-08-05 20:22:52 -05:00
bin docs: vendoring is the route; there is no submodule option 2026-08-05 23:52:19 -05:00
issues/open docs: the marks are not under the code licence 2026-08-05 20:30:05 -05:00
flake.nix feat: the lyte.dev intro and footer mark, as a shared addon 2026-08-05 20:02:04 -05:00
LICENSE feat: the lyte.dev intro and footer mark, as a shared addon 2026-08-05 20:02:04 -05:00
README.md docs: vendoring is the route; there is no submodule option 2026-08-05 23:52:19 -05:00
TRADEMARKS.md docs: the marks are not under the code licence 2026-08-05 20:30:05 -05:00

godot-branding

The lyte.dev studio branding, as a Godot 4 addon: the boot intro and the footer mark. One copy, shared by every game, instead of a fourth that has quietly drifted from the other three.

The repository is named for what it is rather than for any game — nothing in here knows about a particular game, and that is enforced rather than hoped for (see It does not know about your game below).

addons/lyte_brand/
  lyte_splash.gd/.tscn   the boot intro
  lyte_mark.gd           the footer mark (attach to a Button you position)
  assets/                LED art, the typing recording, Iosevka
  LICENSES/OFL-Iosevka.txt

Using it

Drop addons/lyte_brand/ into a Godot project. Then:

var splash := preload("res://addons/lyte_brand/lyte_splash.tscn").instantiate()
splash.finished.connect(_on_intro_done)
splash.audio_bus = "Sfx"                 # optional; "Master" by default
splash.skip_when = func() -> bool:       # optional; your own reasons to skip
    return OS.get_cmdline_user_args().has("--skip-title")
add_child(splash)

The footer mark is a script for a Button you have already placed in your own layout:

[node name="LyteMark" type="Button" parent="Footer"]
script = ExtResource("res://addons/lyte_brand/lyte_mark.gd")

It does not know about your game

This is the property that makes it shared rather than copied, so it is worth being explicit about what was deliberately removed.

The splash emits finished rather than changing scene, plays only audio it ships with (plus an optional ignite_sound you provide), and depends on no autoload. The version this was extracted from called one game's Sfx singleton and ended by loading that game's menu — both are exactly what stops a component travelling, so both are gone.

It skips itself when headless or given --skip-intro. Those are universal; everything project-specific belongs in skip_when.

How to consume it

Two routes. Vendor by default; use the flake input if you build with nix.

Vendoring (the default, works anywhere)

cd /path/to/godot-branding
bin/vendor-into /path/to/your-project

That copies addons/lyte_brand into the project and writes VENDORED.md recording the upstream revision. Re-run it to update.

There is no submodule route. Not an oversight, and please do not helpfully add one — it does not work for either of the two consumers this repo has:

  • jj does not support git submodules, and the games are jj repositories.
  • Nix's git-tree filtering does not follow submodule contents, so in a nix build a submodule arrives as an empty directory — which builds cleanly and ships a game with no intro. Green build, broken product, no error until somebody launches it.

Vendoring is the only route that works everywhere.

Nothing in a vendored copy is safe to edit. The next sync replaces the directory wholesale and silently discards local changes. Change it here, upstream, and re-vendor. VENDORED.md says so in the copy itself, where somebody about to edit it will actually be.

The script exists rather than instructions because the provenance stamp is the one thing a submodule gave for free — "which version is this?" and "has upstream moved?" — and a documented step is the step that gets skipped. Compare the recorded revision with git -C /path/to/godot-branding rev-parse HEAD to answer the second question.

Flake input (nix-built projects)

Strictly better where it applies: hash-pinned, and updated by nix flake update like any other dependency.

inputs.godot-branding.url = "git+ssh://forgejo@git.lyte.dev/lytedev/godot-branding.git";

# then, in the derivation that assembles your project directory:
#   cp -r ${godot-branding}/addons/lyte_brand "$PROJECT/addons/lyte_brand"

deck-slice consumes it this way.

Assert it arrived. A missing addon is a silent failure whichever route you take: Godot leaves the scene's ext_resource unresolved and reports it at runtime as a script-less node, so the build is green and the game has no intro. deck-slice tests for lyte_splash.gd after copying, and so should you.

The addon directory stays addons/lyte_brand/ inside this repo. Godot references addon paths as strings inside scenes, so renaming it would break every consumer for no gain.

Brand

background #0d1017
primary #df3c59
shine #f591a6
type Iosevka (custom IosevkaLyteTerm build)

Building without the branding

The marks are all rights reserved (see TRADEMARKS.md), so a consumer must be able to build without them — and that path should be exercised by a build rather than assumed. deck-slice builds an unbranded variant for exactly this reason.

Nothing here makes the marks structural: the wordmark is the WORD constant in lyte_splash.gd and the logo is three SVGs. Replacing them is a substitution, not a fork. Keep it that way.

Licences

The code here is MIT (LICENSE). The marks are not — the LED logo, the "lyte.dev" wordmark and the typed-wordmark recording are all rights reserved and included with permission for lyte.dev's own games. See TRADEMARKS.md, which also explains why that is the ordinary free-software pattern rather than an aggressive one.

Iosevka is SIL OFL 1.1, and that has obligations a game shipping this addon inherits: LICENSES/OFL-Iosevka.txt must accompany any distribution that includes the font, and the font may not be sold on its own. Bundling it inside a game is fine; the licence text has to travel with it.

IosevkaLyteTerm is a custom Iosevka build, and the usual worry about those — a Reserved Font Namedoes not apply. OFL 1.1 restricts naming only for names "specified as such after the copyright statement", and Iosevka's copyright statement specifies none: see LICENSE.md @ 8ca00e3 (permalinked so it cannot drift). The licence carries the standard definition of a Reserved Font Name and declares none — which is why Iosevka custom builds circulate freely under their own names. The text shipped here is byte-identical to that file.

Checked rather than assumed, and recorded so nobody re-opens it.

The LED art and the typing recording are lyte.dev's own.