After a GitHub snapshot loads, the viewer's code scanning and Dependabot
alerts are fetched and grouped by file. In the city, affected buildings
smoke, and those with a critical or high alert also burn: GPU particles
whose age derives from time and seed, so emitters upload once. Hazard
tape runs diagonally across every wall, yellow DEPENDABOT ALERT rising
and red CODE SCANNING ALERT falling, crossing as an X when a file has
both; the tape tiles a striped label cut to the wall's diagonal.
The minimap marks alert buildings, the coverage panel shows the alert
count (or why none could be loaded, e.g. signed out or no permission),
and a selected file lists its alerts with severity and GitHub links.
Little glowing green stick figures, in the spirit of Darwinia, stroll
the streets: each walks toward a random reachable point in plain sight
on the navigation grid, pauses, and about a third of the time heads
toward a nearby resident instead, so they gather in small crowds. They
are camera-facing sprites drawn procedurally in the fragment shader
with a walk cycle, flicker and halo, grown with altitude so crowds stay
visible from the helicopter, and fogged like everything else.
About one resident per 2,500 m² of city (40 to 600), spawned only on
the city's own streets. Because they keep the city animating, Settings
has a City residents switch (saved with the other preferences). The
simulation is seedable and tested to keep everyone on walkable ground.
City mode builds a 3 m occupancy grid (buildings grown by half a metre
blocked, pavements slightly dearer than roads). Selecting a file runs
one Dijkstra from its building's street doors that stops once every
imported file's doors are settled, then straightens each route to its
necessary turns. Buildings boxed in by neighbours route to the nearest
reachable street. Routes are drawn as glowing ground ribbons with
chevrons flowing toward each dependency (cyan known, amber inferred)
and on the minimap; walking from the helicopter starts at the first
route's door facing along it.
Distances are float64: float32 rounding made equal-cost paths look
like improvements and flooded the queue (a hang on real cities). Tests
cover detours, enclosed targets and a large-city time budget; real
prometheus data routes 24 imports in about 60 ms.
Flat wall signs vanish at grazing angles. Walls facing a walker now
also carry blade signs projecting perpendicular to the wall, repeated
along long walls and offset from the flat signs. Each blade is two
back-to-back faces; the sign shader discards whichever face would read
mirrored from the viewer's side. Blades shorten to the free space in
front of the wall and are skipped when a neighbouring building is
closer than 1.2 m of sign.
Landscape 2D/3D shared one fragment shader with the city's fog, window
and beacon code. Building two variants from the same source with a
CITY define brought 3D frame cost back near its pre-city level in the
profiling setup (native 708 -> ~300 ms/frame under software GL, JS and
canvas 71 -> ~33 ms/frame).
City mode now renders as a night scene: exponential fog into a dark sky
tuned per camera, brighter neon edges, and procedural window grids on
every wall whose lit share grows with the file's definition count.
Selecting a file draws animated screen-space ribbons from each importer
to each imported building, arcing higher with distance: cyan and solid
for known links, amber and dashed for inferred ones. Search hits raise
light columns over their buildings so matches are visible across the
city. Both effects are additive and never occlude. District names hide
when the helicopter is close.
City labels were a 2D overlay that showed through buildings at street
level. labels.js rasterises each label once into a shelf-packed atlas
(partial texSubImage uploads, mipmapped for grazing angles), and a new
instanced quad pass draws them depth-tested but not depth-writing.
District names float above each district's tallest tower facing the
camera, file names sit on roofs near the focus, walls facing a walker
carry name signs repeated every 24 m, and street names are painted on
nearby kerbs. Walking up to the building in the crosshair shows its
source on the facing wall. Signs rebuild only when the focus, heading
or selection changes; an overflowing atlas is cleared and refilled with
the nearest labels first. Placement helpers are unit tested.
Adds walk and fly cameras alongside the helicopter view, switched with
1/2/3 or the city toolbar. Walking uses mouse-look with pointer lock
(or drag), WASD, Shift to run and circle-vs-footprint collision with
sub-stepping so long frames cannot tunnel through buildings; flying
follows the view pitch with Space/C for altitude and clears low roofs.
Double-clicking a street drops you there with an animated descent,
facing the longest open street. A crosshair names the building ahead
(E or click inspects it), the address bar shows the folder you are in,
and a minimap shows your heading and teleports on click.
city.js lays the directory tree out at human scale: top-level folders
become districts separated by 18 m avenues, nested folders become
blocks with narrower streets and raised pavements, and files become
buildings whose footprint follows their lines and whose height follows
their complexity. The squarified treemap moves into city.js and is
shared with the landscape.
The renderer gains a second instance layer with per-instance kind,
code-atlas rectangle and selection flag, a helicopter camera in metres,
screen-to-world rays, and geometry lookup per mode. City mode supports
orbit, pan, dolly, ray picking, focusing a building and district names.
Node tests cover layout invariants, heights, ray/box hits and the
spatial index.
Adds camera.js with perspective, lookAt and matrix helpers. The orbit
view is now a lookAt pose feeding one view-projection matrix shared by
the shaders and project(), replacing the hand-rolled projection with
its clamped depth. A node test checks the new camera reproduces the old
projection to within 0.05 px, so the landscape looks the same; this is
the base the city's walk and fly cameras need (near plane, correct w).
The overlay used to clip and affine-map a code texture onto every
visible roof and punch every roof out of a 2D ground grid each frame
(about 13,600 saves and 6,800 clips per frame on a 1,676-file repo).
The existing code overview canvas already matches the world layout, so
it is uploaded once as a mipmapped texture and sampled by the roof
shader. The overlay now only draws sharper text for the few roofs close
enough to magnify that texture, and the grid is a WebGL line pass. The
vertex shader emits a real clip-space w so the texture is perspective-
correct; screen positions are unchanged. JS and canvas time per 3D
frame fell from 284 ms to 27 ms in the same profile.
project() read canvas.clientWidth/clientHeight on every call, and it
runs for every tile corner each frame. Profiling a 1,676-file repo put
216 ms of each 3D frame in project(); with the size cached per frame
and the trigonometry per camera change it drops to about 7 ms.
Deep blue-black theme with a violet-to-cyan accent, frosted floating
panels, self-hosted Inter, a welcome screen with a call to action, a
card-style inspector, accent tabs and toggles, animated progress, and
a restyled open dialog. In 3D the WebGL walls are now lit per side
with a darker foot so buildings read as solids, and the canvas clears
to transparent over the new background. Renamed to CodeNavigator.
Implements the API routes (jobs, progress events, snapshots, search,
entities, source delivery with release) to net/http and serves the
static frontend from the same binary on the same origin.