diff options
| author | Bobby <[email protected]> | 2026-04-22 08:32:07 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-04-22 08:32:07 +0530 |
| commit | 8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63 (patch) | |
| tree | c8df32d7104c784ed70a9e7541a2548762108317 | |
| parent | 8dc6d80aefb11cd3f2ef4fac4e34e8768eb9601b (diff) | |
| download | hollowdark-8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63.tar.xz hollowdark-8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63.zip | |
Add Credits screen with initial font and audio attributions
| -rw-r--r-- | credits/credits.ts | 48 | ||||
| -rw-r--r-- | eslint.config.js | 7 | ||||
| -rw-r--r-- | lib/screens/CreditsScreen.svelte | 185 | ||||
| -rw-r--r-- | routes/+page.svelte | 6 | ||||
| -rw-r--r-- | routes/credits/+page.svelte | 11 | ||||
| -rw-r--r-- | tsconfig.json | 1 |
6 files changed, 257 insertions, 1 deletions
diff --git a/credits/credits.ts b/credits/credits.ts new file mode 100644 index 0000000..d86517d --- /dev/null +++ b/credits/credits.ts @@ -0,0 +1,48 @@ +/** + * The kind of third-party resource a credit entry describes. Drives + * grouping on the Credits screen. + */ +export type CreditKind = 'font' | 'audio' | 'library' + +/** + * One entry on the Credits screen. Add a new `Credit` to `CREDITS` below + * whenever a new third-party resource lands in the repo, alongside its + * license file. + */ +export interface Credit { + readonly title: string + readonly kind: CreditKind + readonly author: string + readonly license: string + readonly sourceUrl?: string + readonly note?: string +} + +/** + * The master list of third-party credits. Append a new entry whenever a + * new resource is added to the repo. + */ +export const CREDITS: readonly Credit[] = [ + { + title: 'Literata', + kind: 'font', + author: 'Type Network', + license: 'SIL Open Font License 1.1', + sourceUrl: 'https://fonts.google.com/specimen/Literata' + }, + { + title: 'Inter', + kind: 'font', + author: 'Rasmus Andersson', + license: 'SIL Open Font License 1.1', + sourceUrl: 'https://fonts.google.com/specimen/Inter' + }, + { + title: 'Piano Relaxing', + kind: 'audio', + author: 'atlasaudio', + license: 'Pixabay Content License', + sourceUrl: 'https://pixabay.com/music/ambient-piano-relaxing-510242/', + note: 'Title screen music.' + } +] diff --git a/eslint.config.js b/eslint.config.js index 71da530..84ecd6d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -15,6 +15,7 @@ const gameplayDirectories = [ 'birth/**/*.{ts,js,svelte}', 'death/**/*.{ts,js,svelte}', 'continuation/**/*.{ts,js,svelte}', + 'credits/**/*.{ts,js,svelte}', 'worldgen/**/*.{ts,js,svelte}', 'persistence/**/*.{ts,js,svelte}', 'rng/**/*.{ts,js,svelte}', @@ -94,5 +95,11 @@ export default ts.config( 'no-restricted-syntax': 'off', '@typescript-eslint/no-explicit-any': 'off' } + }, + { + files: ['lib/screens/CreditsScreen.svelte'], + rules: { + 'svelte/no-navigation-without-resolve': 'off' + } } ) diff --git a/lib/screens/CreditsScreen.svelte b/lib/screens/CreditsScreen.svelte new file mode 100644 index 0000000..7482361 --- /dev/null +++ b/lib/screens/CreditsScreen.svelte @@ -0,0 +1,185 @@ +<script lang="ts"> + import { CREDITS, type CreditKind } from '@hollowdark/credits/credits' + + interface Props { + onBack: () => void + } + + let { onBack }: Props = $props() + + const KIND_LABELS: Record<CreditKind, string> = { + font: 'Fonts', + audio: 'Audio', + library: 'Libraries' + } + + const KIND_ORDER: readonly CreditKind[] = ['font', 'audio', 'library'] + + const grouped = $derived( + KIND_ORDER.map((kind) => ({ + kind, + label: KIND_LABELS[kind], + entries: CREDITS.filter((c) => c.kind === kind) + })).filter((section) => section.entries.length > 0) + ) +</script> + +<section class="credits"> + <header class="top"> + <button class="back" onclick={onBack}>← Back</button> + <h1 class="heading">Credits</h1> + </header> + + <div class="body"> + <p class="intro"> + Hollowdark stands on other people's work. The fonts, music, and libraries + below are used under their respective licenses, reproduced alongside the + files in the repository. + </p> + + {#each grouped as section (section.kind)} + <section class="group"> + <h2 class="group-label">{section.label}</h2> + + {#each section.entries as credit (credit.title)} + <article class="entry"> + <p class="entry-title">{credit.title}</p> + <p class="entry-meta"> + <span class="author">{credit.author}</span> + <span class="dot">·</span> + <span class="license">{credit.license}</span> + </p> + {#if credit.note} + <p class="entry-note">{credit.note}</p> + {/if} + {#if credit.sourceUrl} + <a class="entry-source" href={credit.sourceUrl} target="_blank" rel="noopener"> + {credit.sourceUrl} + </a> + {/if} + </article> + {/each} + </section> + {/each} + </div> +</section> + +<style> + .credits { + min-height: 100dvh; + padding: var(--space-8) var(--space-6) var(--space-12); + max-width: 640px; + margin: 0 auto; + display: flex; + flex-direction: column; + } + + .top { + display: flex; + align-items: baseline; + gap: var(--space-6); + margin-bottom: var(--space-12); + } + + .back { + font-family: var(--font-ui); + font-size: var(--text-sm); + color: var(--color-text-secondary); + letter-spacing: 0.3px; + transition: color var(--transition-fast); + } + + .back:hover { + color: var(--color-text); + } + + .heading { + font-family: var(--font-body); + font-size: var(--text-xl); + font-style: italic; + font-weight: 400; + letter-spacing: 1px; + color: var(--color-text); + margin: 0; + } + + .body { + display: flex; + flex-direction: column; + gap: var(--space-8); + } + + .intro { + font-family: var(--font-body); + font-size: var(--text-base); + line-height: var(--leading-normal); + color: var(--color-text-secondary); + margin: 0; + } + + .group { + display: flex; + flex-direction: column; + gap: var(--space-4); + } + + .group-label { + font-family: var(--font-ui); + font-size: var(--text-xs); + color: var(--color-accent); + letter-spacing: 2px; + text-transform: uppercase; + margin: 0 0 var(--space-2); + } + + .entry { + display: flex; + flex-direction: column; + gap: var(--space-1); + } + + .entry-title { + font-family: var(--font-body); + font-size: var(--text-md); + color: var(--color-text); + margin: 0; + } + + .entry-meta { + font-family: var(--font-ui); + font-size: var(--text-sm); + color: var(--color-text-secondary); + margin: 0; + } + + .author, + .license { + color: var(--color-text-secondary); + } + + .dot { + color: var(--color-text-tertiary); + margin: 0 var(--space-1); + } + + .entry-note { + font-family: var(--font-body); + font-size: var(--text-sm); + color: var(--color-text-tertiary); + font-style: italic; + margin: 0; + } + + .entry-source { + font-family: var(--font-ui); + font-size: var(--text-xs); + color: var(--color-text-tertiary); + letter-spacing: 0.3px; + text-decoration: none; + transition: color var(--transition-fast); + } + + .entry-source:hover { + color: var(--color-accent); + } +</style> diff --git a/routes/+page.svelte b/routes/+page.svelte index 3153e35..37c1273 100644 --- a/routes/+page.svelte +++ b/routes/+page.svelte @@ -1,5 +1,7 @@ <script lang="ts"> import { onMount } from 'svelte' + import { goto } from '$app/navigation' + import { resolve } from '$app/paths' import BeginScreen from '@hollowdark/lib/screens/BeginScreen.svelte' import InitialLoadScreen from '@hollowdark/lib/screens/InitialLoadScreen.svelte' import { runStubInitialLoad } from '@hollowdark/loading/stub' @@ -19,7 +21,9 @@ function handleBegin(): void {} function handleContinue(): void {} function handleSettings(): void {} - function handleCredits(): void {} + function handleCredits(): void { + goto(resolve('/credits')) + } </script> {#if view === 'loading'} diff --git a/routes/credits/+page.svelte b/routes/credits/+page.svelte new file mode 100644 index 0000000..e803364 --- /dev/null +++ b/routes/credits/+page.svelte @@ -0,0 +1,11 @@ +<script lang="ts"> + import { goto } from '$app/navigation' + import { resolve } from '$app/paths' + import CreditsScreen from '@hollowdark/lib/screens/CreditsScreen.svelte' + + function handleBack(): void { + goto(resolve('/')) + } +</script> + +<CreditsScreen onBack={handleBack} /> diff --git a/tsconfig.json b/tsconfig.json index 6e2b9d0..d4d45ba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -51,6 +51,7 @@ "birth/**/*.ts", "death/**/*.ts", "continuation/**/*.ts", + "credits/**/*.ts", "worldgen/**/*.ts", "persistence/**/*.ts", "rng/**/*.ts", |
