aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-04-22 08:32:07 +0530
committerBobby <[email protected]>2026-04-22 08:32:07 +0530
commit8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63 (patch)
treec8df32d7104c784ed70a9e7541a2548762108317
parent8dc6d80aefb11cd3f2ef4fac4e34e8768eb9601b (diff)
downloadhollowdark-8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63.tar.xz
hollowdark-8a5e40f778de2bc82a4fc261d9c0923fd3ab5a63.zip
Add Credits screen with initial font and audio attributions
-rw-r--r--credits/credits.ts48
-rw-r--r--eslint.config.js7
-rw-r--r--lib/screens/CreditsScreen.svelte185
-rw-r--r--routes/+page.svelte6
-rw-r--r--routes/credits/+page.svelte11
-rw-r--r--tsconfig.json1
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",