|
47664
|
Uranometria by @reimunyancat | Stardance
|
reimunyancat
|
0
|
24.21
|
0
|
[]
|
[{"post_id": 59422, "ts": "202 [{"post_id": 59422, "ts": "2026-09-01T07:52:21Z", "hours": 9.0092, "text": "Devlog #3 This one is three small things instead of one big thing. Controls, a code viewer, and a demo mode. The flight controls were bad, so I fixed them The first version had WASD and a speed of 12. That was it. Flying across the galaxy felt like wading through water, vertical movement was on Space/Shift which is apparently not what anyone expects, and the camera started and stopped instantly, which felt robotic. New setup: base speed is 30, Shift is sprint (3.5x), E goes up and Q goes down, and scrolling the wheel multiplies your speed up or down so you can be precise inside a solar system and fast between constellations. Movement also has acceleration and deceleration now via lerping the velocity vector. This alone made it feel like an actual spaceship instead of a camera on rails. Clicking a file moon opens the code The moons in a solar system were just decoration, so now clicking one fetches the file through the server and opens a side panel with syntax highlighting via highlight.js. The trick on the server side is sending Accept: application/vnd.github.raw to the contents API, which hands back the raw file instead of a base64 blob wrapped in JSON. Saved me a decode step and a headache. One small thing I got wrong first: I put a key on the <Canvas> to reset the camera when switching views, then forgot that clicking things while pointer lock is active is its own mess. Tooltips and clicks work fine through drei’s event system, but I did waste ten minutes confused about why my onClick wasn’t firing before realizing I had the handler on the wrong component. Demo mode There was no way to look at anyone’s galaxy except mine, which defeats the entire point of sharing a link. Now there’s a username box in the corner; type any GitHub account and it builds their galaxy from public repos. The server just hits /users/:user/repos anonymously, since public data doesn’t need the app token. Anonymous calls are rate limited to 60/hour, so this will need caching or token routing later, but it works for now. Next up Private repos and the public share link, probably. That means real sessions instead of my hardcoded username, which I’ve been putting off because I know it will be annoying."}, {"post_id": 50957, "ts": "2026-08-20T13:00:32Z", "hours": 6.1617, "text": "Devlog #2 Last time ended with a working pipeline: GitHub App auth on a Rust server, my repo list coming back as JSON. This time the goal was simple to say and fun to do — turn that JSON into an actual galaxy, and make stars clickable so each repo opens up into its own little solar system. Trimming 300 fields down to 7 GitHub’s repo API returns an absurd amount of data per repository. Hundreds of fields, most of which I’ll never touch. So the server got a new /api/galaxy endpoint that maps each repo down to what the galaxy actually needs: name, language, stars, fork/archived flags, last push, description. The frontend never sees the raw GitHub payload, which also keeps the design honest — tokens and GitHub-shaped data stay server-side, the browser only gets our own format. Placing stars without a physics engine The interesting problem was layout. Repos need positions in 3D space, they shouldn’t overlap, and related repos should cluster. I went with constellations: a small heuristic buckets each repo into a group (Web, Systems, Games, AI, Tools) based on language plus keywords in the name and description. Each constellation gets a wedge of the galaxy, and inside the wedge, repos spiral outward from the group center. Star size is log-scaled from star count, because linear scaling either flattens the difference or explodes it. Color comes from GitHub’s own language colors — a Rust repo burns orange-brown, TypeScript blue. Forks and archived repos are hidden by default; a portfolio galaxy shouldn’t be full of other people’s work. Tooltips came from drei’s <Html> component, which pins actual DOM elements to 3D coordinates. Hover a star, get name, language, stars, constellation. Felt like cheating, in a good way. Clicking into a solar system Clicking a star now fetches that repo’s full file tree — one git/trees/HEAD?recursive=1 call through the server proxy — and lays out the top level as a system: directories become planets on an inner orbit, files become moons on an outer one, file size sets moon size, extension sets color. Two thin ring meshes mark the orbits so the structure reads at a glance. One trap I set for myself: switching views without resetting the camera left me stranded inside the old galaxy coordinates staring at nothing. Fixed by keying the <Canvas> on the selected repo so the camera respawns with the view. The back button is a plain HTML button floating over the canvas — sometimes the boring solution is the right one. The bug that wasn’t mine Finished the session with a scary-looking hydration error from Next.js. The diff showed an attribute trancy-version=\"7.9.1\" on the <html> tag that definitely isn’t in my code — because it isn’t. A translation browser extension injects it before React loads, and React correctly reports that server HTML and client HTML differ. Nothing to fix; I just learned to read hydration diffs before panicking. Any attribute that isn’t mine means an extension did it. Next up Moons that actually open files — a code viewer panel with syntax highlighting. And at some point the recursive tree needs real LOD handling, because a big monorepo would currently try to render everything at once."}, {"post_id": 48844, "ts": "2026-08-17T12:04:41Z", "hours": 9.0347, "text": "Devlog #1 Uranometria is the idea of turning a GitHub account into an explorable 3D galaxy repos become star systems, folders become planets, files become moons. This session was about getting the two ends of the stack alive: a Three.js scene you can actually fly around in, and a Rust server that talks to GitHub as a proper GitHub App. As a high school senior in Korea, I had to juggle studying for exams alongside this, so I ended up making quite a few silly mistakes. Flying between spheres Step zero was a playground: Next.js + react-three-fiber, a sun in the middle, a few planets around it, pointer-lock mouse look, and WASD flight. The flight part is a small FlyControls component that reads keys into a ref and moves the camera along camera.getWorldDirection() inside useFrame , so W always means “wherever I’m looking.” Simple, but it immediately felt like a spaceship, which is the whole point. (To be honest, I reused a lot of code from the previous project. I also know the current design is pretty bland, but I just couldn’t be bothered to change it. I’ll fix it later.) The scene itself took ten minutes. The ecosystem took the rest of the day. Talking to GitHub as an App The actual goal of the session: an axum server that authenticates as a GitHub App — sign a short-lived RS256 JWT with the app’s private key, trade it for an installation token, then call /installation/repositories . Read-only Contents permission, tokens never leaving the server, exactly like the design doc says. Where Uranometria stands Next.js + R3F scene: sun, planets, stars, pointer-lock + WASD flight working Rust (axum) server: GitHub App JWT auth, installation token flow, /api/repos proxy returning real data Three version-ecosystem traps documented so future-me never pays for them again Next up Rendering the actual galaxy — mapping the repo list onto star systems, with language picking the star color and stars deciding the corona. The fun part, finally."}]...
|
Title: Uranometria by @reimunyancat | Stardance
D Title: Uranometria by @reimunyancat | Stardance
Devlogs:
Devlog #1 Uranometria is the idea of turning a GitHub account into an explorable 3D galaxy repos become star systems, folders become planets, files become moons. This session was about getting the two ends of the stack alive: a Three.js scene you can actually fly around in, and a Rust server that talks to GitHub as a proper GitHub App. As a high school senior in Korea, I had to juggle studying for exams alongside this, so I ended up making quite a few silly mistakes. Flying between spheres Step zero was a playground: Next.js + react-three-fiber, a sun in the middle, a few planets around it, pointer-lock mouse look, and WASD flight. The flight part is a small FlyControls component that reads keys into a ref and moves the camera along camera.getWorldDirection() inside useFrame , so W always means “wherever I’m looking.” Simple, but it immediately felt like a spaceship, which is the whole point. (To be honest, I reused a lot of code from the previous project. I also know the current design is pretty bland, but I just couldn’t be bothered to change it. I’ll fix it later.) The scene itself took ten minutes. The ecosystem took the rest of the day. Talking to GitHub as an App The actual goal of the session: an axum server that authenticates as a GitHub App — sign a short-lived RS256 JWT with the app’s private key, trade it for an installation token, then call /installation/repositories . Read-only Contents permission, tokens never leaving the server, exactly like the design doc says. Where Uranometria stands Next.js + R3F scene: sun, planets, stars, pointer-lock + WASD flight working Rust (axum) server: GitHub App JWT auth, installation token flow, /api/repos proxy returning real data Three version-ecosystem traps documented so future-me never pays for them again Next up Rendering the actual galaxy — mapping the repo list onto star systems, with language picking the star color and stars deciding the corona. The fun part, finally.
Devlog #2 Last time ended with a working pipeline: GitHub App auth on a Rust server, my repo list coming back as JSON. This time the goal was simple to say and fun to do — turn that JSON into an actual galaxy, and make stars clickable so each repo opens up into its own little solar system. Trimming 300 fields down to 7 GitHub’s repo API returns an absurd amount of data per repository. Hundreds of fields, most of which I’ll never touch. So the server got a new /api/galaxy endpoint that maps each repo down to what the galaxy actually needs: name, language, stars, fork/archived flags, last push, description. The frontend never sees the raw GitHub payload, which also keeps the design honest — tokens and GitHub-shaped data stay server-side, the browser only gets our own format. Placing stars without a physics engine The interesting problem was layout. Repos need positions in 3D space, they shouldn’t overlap, and related repos should cluster. I went with constellations: a small heuristic buckets each repo into a group (Web, Systems, Games, AI, Tools) based on language plus keywords in the name and description. Each constellation gets a wedge of the galaxy, and inside the wedge, repos spiral outward from the group center. Star size is log-scaled from star count, because linear scaling either flattens the difference or explodes it. Color comes from GitHub’s own language colors — a Rust repo burns orange-brown, TypeScript blue. Forks and archived repos are hidden by default; a portfolio galaxy shouldn’t be full of other people’s work. Tooltips came from drei’s <Html> component, which pins actual DOM elements to 3D coordinates. Hover a star, get name, language, stars, constellation. Felt like cheating, in a good way. Clicking into a solar system Clicking a star now fetches that repo’s full file tree — one git/trees/HEAD?recursive=1 call through the server proxy — and lays out the top level as a system: directories become planets on an inner orbit, files become moons on an outer one, file size sets moon size, extension sets color. Two thin ring meshes mark the orbits so the structure reads at a glance. One trap I set for myself: switching views without resetting the camera left me stranded inside the old galaxy coordinates staring at nothing. Fixed by keying the <Canvas> on the selected repo so the camera respawns with the view. The back button is a plain HTML button floating over the canvas — sometimes the boring solution is the right one. The bug that wasn’t mine Finished the session with a scary-looking hydration error from Next.js. The diff showed an attribute trancy-version="7.9.1" on the <html> tag that definitely isn’t in my code — because it isn’t. A translation browser extension injects it before React loads, and React correctly reports that server HTML and client HTML differ. Nothing to fix; I just learned to read hydration diffs before panicking. Any attribute that isn’t mine means an extension did it. Next up Moons that actually open files — a code viewer panel with syntax highlighting. And at some point the recursive tree needs real LOD handling, because a big monorepo would currently try to render everything at once.
Devlog #3 This one is three small things instead of one big thing. Controls, a code viewer, and a demo mode. The flight controls were bad, so I fixed them The first version had WASD and a speed of 12. That was it. Flying across the galaxy felt like wading through water, vertical movement was on Space/Shift which is apparently not what anyone expects, and the camera started and stopped instantly, which felt robotic. New setup: base speed is 30, Shift is sprint (3.5x), E goes up and Q goes down, and scrolling the wheel multiplies your speed up or down so you can be precise inside a solar system and fast between constellations. Movement also has acceleration and deceleration now via lerping the velocity vector. This alone made it feel like an actual spaceship instead of a camera on rails. Clicking a file moon opens the code The moons in a solar system were just decoration, so now clicking one fetches the file through the server and opens a side panel with syntax highlighting via highlight.js. The trick on the server side is sending Accept: application/vnd.github.raw to the contents API, which hands back the raw file instead of a base64 blob wrapped in JSON. Saved me a decode step and a headache. One small thing I got wrong first: I put a key on the <Canvas> to reset the camera when switching views, then forgot that clicking things while pointer lock is active is its own mess. Tooltips and clicks work fine through drei’s event system, but I did waste ten minutes confused about why my onClick wasn’t firing before realizing I had the handler on the wrong component. Demo mode There was no way to look at anyone’s galaxy except mine, which defeats the entire point of sharing a link. Now there’s a username box in the corner; type any GitHub account and it builds their galaxy from public repos. The server just hits /users/:user/repos anonymously, since public data doesn’t need the app token. Anonymous calls are rate limited to 60/hour, so this will need caching or token routing later, but it works for now. Next up Private repos and the public share link, probably. That means real sessions instead of my hardcoded username, which I’ve been putting off because I know it will be annoying....
|
1792896594.7119265
|
1793760594.7119265
|
|
37932
|
Newt by @xerneas | Stardance
|
|
0
|
22.43
|
0
|
[]
|
[{"post_id": 39093, "ts": "202 [{"post_id": 39093, "ts": "2026-08-01T19:51:12Z", "hours": 12.11, "text": "my terminal browser reads wikipedia the same as chrome now last time it did the exact opposite. newt could technically read wikipedia, but it showed you EVERYTHING first, the nav bar, the search box, and every single one of wikipedia’s 93 language links (“Afrikaans, Aragonés, العربية…” for a whole screen) before one word of the actual article the hard part of a browser was figuring out which 10% of the slop on the page that’s actually useful. so i built a baby version of reader mode: find the part that’s actually the article and render ONLY that. pages leave breadcrumbs a main tag, an article tag, a role=main and wikipedia hides its article in a div called mw-content-text. newt hunts those down and throws the rest away. It opens straight on “Salamanders are a group of amphibians…” like it should also made it stop looking like a ransom note: text in a centered column with a margin now, headings get an underline sized to the actual heading (not a random 60-char bar), and the bullet lists stopped leaving a blank line between every item! current problem it nails wikipedia and normal articles but’ll flop on weird sites, and wikipedia’s info box still renders as a sad stack of one-word lines bc i don’t have tables yet. grrr ##next: color. been doing everything in grayscale on purpose and it’s finally time"}, {"post_id": 34572, "ts": "2026-07-25T12:34:05Z", "hours": 10.3233, "text": "BIG BROWSER DOESN’T WANT YOU TO KNOW THIS real talk: every terminal web browser you’ve heard of is faking it . browsh, carbonyl, all of them, they boot up a full headless chrome in the background and just screenshot it into your terminal. it’s chrome wearing a terminal costume. so i’m building the real thing. you type a URL, and my code fetches the page, parses the HTML, and lays it out as text in your shell, with a custom engine no chromium. no webkit. no html library doing the hard part. it’s called newt . and it already works?? (kinda) it’s reading the wikipedia article on salamanders right now: headings get a rule under them, paragraphs wrap to my terminal, links and refs work. my biggest bug so far: whitespace (grrr). my first render had a space before every comma and printed refs as “[ 2 ]” instead of “[2]”. turns out a link and the comma after it are separate chunks of text in HTML, and i was gluing them back with spaces that were never there. the fix is genuinely the hard part of a browser: layout has to remember whether real whitespace existed between two chunks. so now every word knows if it has a space in front of it, and it only wraps at real spaces (also why “lizard-like” doesn’t snap in half). So dumb next: teaching it to read CSS so pages look like themselves. no color, clicking links, or scroll yet. This is gonna be amazing"}]...
|
Title: Newt by @xerneas | Stardance
Devlogs:
BIG Title: Newt by @xerneas | Stardance
Devlogs:
BIG BROWSER DOESN’T WANT YOU TO KNOW THIS real talk: every terminal web browser you’ve heard of is faking it . browsh, carbonyl, all of them, they boot up a full headless chrome in the background and just screenshot it into your terminal. it’s chrome wearing a terminal costume. so i’m building the real thing. you type a URL, and my code fetches the page, parses the HTML, and lays it out as text in your shell, with a custom engine no chromium. no webkit. no html library doing the hard part. it’s called newt . and it already works?? (kinda) it’s reading the wikipedia article on salamanders right now: headings get a rule under them, paragraphs wrap to my terminal, links and refs work. my biggest bug so far: whitespace (grrr). my first render had a space before every comma and printed refs as “[ 2 ]” instead of “[2]”. turns out a link and the comma after it are separate chunks of text in HTML, and i was gluing them back with spaces that were never there. the fix is genuinely the hard part of a browser: layout has to remember whether real whitespace existed between two chunks. so now every word knows if it has a space in front of it, and it only wraps at real spaces (also why “lizard-like” doesn’t snap in half). So dumb next: teaching it to read CSS so pages look like themselves. no color, clicking links, or scroll yet. This is gonna be amazing
my terminal browser reads wikipedia the same as chrome now last time it did the exact opposite. newt could technically read wikipedia, but it showed you EVERYTHING first, the nav bar, the search box, and every single one of wikipedia’s 93 language links (“Afrikaans, Aragonés, العربية…” for a whole screen) before one word of the actual article the hard part of a browser was figuring out which 10% of the slop on the page that’s actually useful. so i built a baby version of reader mode: find the part that’s actually the article and render ONLY that. pages leave breadcrumbs a main tag, an article tag, a role=main and wikipedia hides its article in a div called mw-content-text. newt hunts those down and throws the rest away. It opens straight on “Salamanders are a group of amphibians…” like it should also made it stop looking like a ransom note: text in a centered column with a margin now, headings get an underline sized to the actual heading (not a random 60-char bar), and the bullet lists stopped leaving a blank line between every item! current problem it nails wikipedia and normal articles but’ll flop on weird sites, and wikipedia’s info box still renders as a sad stack of one-word lines bc i don’t have tables yet. grrr ##next: color. been doing everything in grayscale on purpose and it’s finally time...
|
1792896592.258539
|
1793760592.258539
|