🐐
This commit is contained in:
+15
-27
@@ -15,13 +15,10 @@
|
||||
<meta property="og:image" content="https://www.gade.gg/nikolaj.jpg" />
|
||||
<meta property="og:image:alt" content="Nikolaj Gade" />
|
||||
|
||||
<link rel="icon" type="image/png" href="goat.png" />
|
||||
<link rel="stylesheet" href="/fonts/fonts.css" />
|
||||
<link rel="stylesheet" href="/fa/css/all.min.css" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<!-- Runs before the body paints, so the pre-reveal styles in style.css apply
|
||||
from the very first frame instead of flashing. -->
|
||||
<script>document.documentElement.classList.add('js');</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- CANVAS BACKGROUND -->
|
||||
@@ -51,7 +48,7 @@
|
||||
<!-- HERO -->
|
||||
<section id="home" class="hero">
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-name"><span class="hero-name-static">Nikolaj Gade</span></h1>
|
||||
<h1 class="hero-name">Nikolaj Gade</h1>
|
||||
<p class="hero-role">Software Developer</p>
|
||||
<p class="hero-pronouns">they/them · he/him</p>
|
||||
|
||||
@@ -85,18 +82,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-hint">
|
||||
<span>scroll</span>
|
||||
<div class="scroll-line"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ABOUT -->
|
||||
<section id="about" class="section">
|
||||
<div class="section-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-num">01</span>
|
||||
<h2 class="section-title" aria-label="About"><span class="bracket"><</span>About<span class="bracket">/></span></h2>
|
||||
<h2 class="section-title">About</h2>
|
||||
<div class="section-rule"></div>
|
||||
</div>
|
||||
<div class="about-grid">
|
||||
@@ -121,8 +113,7 @@
|
||||
<section id="skills" class="section">
|
||||
<div class="section-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-num">02</span>
|
||||
<h2 class="section-title" aria-label="Skills"><span class="bracket"><</span>Skills<span class="bracket">/></span></h2>
|
||||
<h2 class="section-title">Skills</h2>
|
||||
<div class="section-rule"></div>
|
||||
</div>
|
||||
|
||||
@@ -131,7 +122,7 @@
|
||||
<div class="lang-cloud">
|
||||
<span class="lang-tag lang-primary" data-tip="My main language across hundreds of projects throughout more than a decade.">Python</span>
|
||||
<span class="lang-tag lang-primary" data-tip="Technically I prefer Fish, but who's counting?">Bash</span>
|
||||
<span class="lang-tag lang-primary" data-tip="Only academic use so far, but one I genuinely enjoy. Especially when pointers are involved.">C</span>
|
||||
<span class="lang-tag lang-primary" data-tip="Mostly academic, plus Centvrion's hand-written C runtime. One I genuinely enjoy, especially when pointers are involved.">C</span>
|
||||
<span class="lang-tag lang-primary" data-tip="A handful of small MonoGame projects, alongside academic work.">C#</span>
|
||||
<span class="lang-tag lang-primary" data-tip="Used heavily across several of my jobs.">SQL</span>
|
||||
<span class="lang-tag lang-primary" data-tip="Experience from a (now abandoned) web project.">Go</span>
|
||||
@@ -158,8 +149,7 @@
|
||||
<section id="projects" class="section">
|
||||
<div class="section-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-num">03</span>
|
||||
<h2 class="section-title" aria-label="Projects"><span class="bracket"><</span>Projects<span class="bracket">/></span></h2>
|
||||
<h2 class="section-title">Projects</h2>
|
||||
<div class="section-rule"></div>
|
||||
</div>
|
||||
|
||||
@@ -187,7 +177,7 @@
|
||||
<p>Both are projects I actively maintain and support, with a small but dedicated community of around 500 players.</p>
|
||||
</div>
|
||||
<div class="project-tags">
|
||||
<span data-tip="The clients and all the randomizer logic are Python.">Python</span><span data-tip="PCSX2 is the PS2 emulator; PINE is the protocol I use to read and write its memory while the game runs.">PCSX2 / PINE</span><span data-tip="A lot of poking at the game's RAM to work out where it keeps everything.">Reverse engineering</span><span data-tip="The multiworld platform both randomizers plug into, so a Sly run can share an item pool with any other supported game.">Archipelago</span><span data-tip="Both randomizers are public on GitHub for anyone to read, fork, or build on.">Open source</span>
|
||||
<span data-tip="The clients and all the randomizer logic are Python.">Python</span><span data-tip="A fast socket IPC into the emulator. Built on the PINE code from the Ratchet & Clank 2 randomizer, then heavily extended.">PCSX2 / PINE</span><span data-tip="Hundreds of hand-mapped memory addresses per game, found by diffing emulator memory.">Reverse engineering</span><span data-tip="Sly isn't in Archipelago core, so each randomizer ships as an apworld package that players drop into their installs.">Archipelago</span><span data-tip="The client is an asyncio app juggling the Archipelago server connection and emulator polling at the same time.">asyncio</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -209,7 +199,7 @@
|
||||
<p>The language includes a tree-walking interpreter and a compiler that targets C. Optional modules extend the standard library with <code>FORS</code> (random numbers), <code>FRACTIO</code> (base-12 fractions for floats), <code>MAGNVM</code> (higher numbers than standard roman numerals), and <code>SVBNVLLA</code> (negative numbers).</p>
|
||||
</div>
|
||||
<div class="project-tags">
|
||||
<span data-tip="Both the interpreter and the compiler are written in Python.">Python</span><span data-tip="Designed deliberately: grammar, keywords, and semantics planned out with the rigor of my programming-language coursework.">Language design</span><span data-tip="Targets C, which then compiles down to a native binary.">Compiler</span><span data-tip="A tree-walking interpreter for running code directly.">Interpreter</span>
|
||||
<span data-tip="Both the interpreter and the compiler are written in Python.">Python</span><span data-tip="Planned like my programming-language coursework: keywords, semantics, and a formal grammar written up in LaTeX.">Language design</span><span data-tip="Emits C against a small hand-written runtime (Roman-numeral formatting included), then hands off to the system compiler.">Compiler</span><span data-tip="A pygls language server with live diagnostics and hover docs, so your editor can correct your Latin.">LSP</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -235,11 +225,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="project-body">
|
||||
<p>A trading card game where every card is generated from a Wikipedia article. Built for friends, it features booster pack opening, a fully implemented card game, and trading between players. It also, naturally, includes predatory microtransactions.</p>
|
||||
<p>A trading card game where every card is generated from a Wikipedia article. Built for friends, it features booster pack opening, a fully implemented card game, and trading between players. Matches run in real time against friends or AI opponents, one of which is a neural network trained through self-play. It also, naturally, includes predatory microtransactions.</p>
|
||||
<p>The frontend is built in Svelte and the backend in Python, deployed with Docker Compose.</p>
|
||||
</div>
|
||||
<div class="project-tags">
|
||||
<span data-tip="The whole frontend: pack opening, trading, and the card game itself.">Svelte</span><span data-tip="Backend, card generation, and game logic.">Python</span><span data-tip="I hardly know 'er!">Docker</span><span data-tip="Every card is generated from a real Wikipedia article, and the data is gathered from calls to the Wikipedia, Wikimedia, and WikiRank APIs.">APIs</span><span data-tip="Frontend, backend, and everything between.">Full-stack</span>
|
||||
<span data-tip="SvelteKit with the static adapter, so the whole frontend is static files talking to the API.">Svelte</span><span data-tip="A FastAPI app: REST for the site, WebSockets for live games and trades.">Python</span><span data-tip="I hardly know 'er!">Docker</span><span data-tip="Wikipedia, Wikimedia, and WikiRank for card generation; Stripe and Resend for payments and email.">APIs</span><span data-tip="Eight AI personalities to play against, including one driven by a neural network written from scratch in numpy and trained by self-play.">Game AI</span><span data-tip="SQLAlchemy with Alembic migrations. The app role can't touch the schema; only the migration role can.">PostgreSQL</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -254,12 +244,12 @@
|
||||
</div>
|
||||
<div class="project-body">
|
||||
<p>Born out of a deep distrust of Microsoft and Google, this project is my ongoing effort to self-host as much of my digital life as possible. Every device on my network is named after a Pokémon and assigned a local IP of <code>10.0.0.x</code>, where <code>x</code> is its Pokédex number.</p>
|
||||
<p>The primary server, <strong>Charizard</strong>, runs Unraid OS and manages a disk array totalling 44 TB. It hosts a Gitea instance for personal projects, a file server, and a media server, all running in Docker containers and exposed to the internet through <strong>Nginx Proxy Manager</strong> with SSL certificates from Let's Encrypt.</p>
|
||||
<p>The primary server, <strong>Charizard</strong>, runs Unraid OS and manages a disk array totalling 44 TB. It hosts a Gitea instance for personal projects, a file server, and a media server, exposed to the internet through <strong>Nginx Proxy Manager</strong> with SSL certificates from Let's Encrypt.</p>
|
||||
<p>An extension of the setup lives on <strong>Bulbasaur</strong>, a Raspberry Pi running Pi-hole for network-wide ad blocking and a WireGuard VPN server for secure remote access.</p>
|
||||
<p>Charizard is turning five this year. In that time I've learned an enormous amount about networking, Linux administration, and the particular satisfaction of fixing something broken at 2 in the morning that nobody asked you to build in the first place.</p>
|
||||
</div>
|
||||
<div class="project-tags">
|
||||
<span data-tip="The OS on Charizard, managing the 44 TB disk array.">Unraid</span><span data-tip="Every service runs in its own container.">Docker</span><span data-tip="Nginx Proxy Manager routes traffic to each service, with Let's Encrypt SSL.">Reverse Proxy</span><span data-tip="Subnetting, DNS, and a VPN.">Networking</span><span data-tip="The thing that it is.">Self-hosting</span>
|
||||
<span data-tip="The OS on Charizard, chosen mainly because it supports mixed-size drives. Currently it sports 3 different sizes of data disks (4x6TB + 12TB + 8TB).">Unraid</span><span data-tip="Every service runs in its own container.">Docker</span><span data-tip="Each service gets its own subdomain; no container publishes a port directly.">Reverse Proxy</span><span data-tip="Subnetting, DNS, and a VPN.">Networking</span><span data-tip="The thing that it is.">Self-hosting</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -271,8 +261,7 @@
|
||||
<section id="experience" class="section">
|
||||
<div class="section-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-num">04</span>
|
||||
<h2 class="section-title" aria-label="Experience"><span class="bracket"><</span>Experience<span class="bracket">/></span></h2>
|
||||
<h2 class="section-title">Experience</h2>
|
||||
<div class="section-rule"></div>
|
||||
</div>
|
||||
<div class="timeline">
|
||||
@@ -280,7 +269,7 @@
|
||||
<div class="timeline-marker"></div>
|
||||
<div class="timeline-card">
|
||||
<div class="timeline-meta">
|
||||
<span class="timeline-date">Sep 2024 — Present</span>
|
||||
<span class="timeline-date">Sep 2024 — Jul 2026</span>
|
||||
<span class="timeline-tag">Part-time</span>
|
||||
</div>
|
||||
<h3 class="timeline-role">Junior Developer</h3>
|
||||
@@ -331,8 +320,7 @@
|
||||
<section id="education" class="section">
|
||||
<div class="section-inner">
|
||||
<div class="section-header">
|
||||
<span class="section-num">05</span>
|
||||
<h2 class="section-title" aria-label="Education"><span class="bracket"><</span>Education<span class="bracket">/></span></h2>
|
||||
<h2 class="section-title">Education</h2>
|
||||
<div class="section-rule"></div>
|
||||
</div>
|
||||
<div class="education-grid">
|
||||
|
||||
Reference in New Issue
Block a user