Download HANDOFF.md from Snapkitty/repoverse: direct link, hf CLI and curl.
- Browser
- Download file 13.2 kB
-
https://huggingface.co/Snapkitty/repoverse/resolve/main/HANDOFF.md
- Command line
-
hf download hf://Snapkitty/repoverse/HANDOFF.md
-
curl -L -o HANDOFF.md https://huggingface.co/Snapkitty/repoverse/resolve/main/HANDOFF.md
Repoverse handoff
From: the cloud session that built the C# core (Master Directive, Part I)
To: whoever builds the engine side and the back end locally (Rider, Unreal, Swift, CAD)
State at handoff: dotnet build -warnaserror is clean and all 72 tests pass. The pipeline has run end to end on real
data (the 15 sub-projects of SNAPKITTYWEST/BOBS-Many-Voxel-Worlds). Nothing has run inside Unreal, Swift or CAD
tooling yet. The Parts II and III directive text has not been received.
1. What exists
Read README.md for the full table. In one line: GitHub or local git β CanonicalRepository β classifier β
deterministic WorldManifest β procedural chunks (32Β³, 16-bit voxels) β greedy-meshed quads, plus snapshot
diff events, a fixed-step clock, versioned saves and repoverse:// URIs.
| Path | Responsibility |
|---|---|
src/Repoverse.Core/Model/ |
Canonical GitHub facts; Derived<T> + Provenance for everything inferred |
src/Repoverse.Core/Ingestion/ |
GitHubIngest (REST, ETag cache, rate limits), LocalGitIngest, SnapshotStore (offline merge) |
src/Repoverse.Core/Generation/ |
Seed, Classifier, Overrides, RoomGraph, ManifestBuilder, WorldManifest |
src/Repoverse.Core/Voxels/ |
Voxel/Chunk, BuildingRasterizer, WorldGenerator, WorldEdits, ChunkStreamer, GreedyMesher |
src/Repoverse.Core/Simulation/ |
WorldEvents + SnapshotDiff, SimulationClock |
src/Repoverse.Core/Persistence/ |
SaveGame (schema 2, v1 migration) |
src/Repoverse.Core/WorldConstants.cs |
Every tunable dimension; change numbers here only |
src/Repoverse.Cli/ |
ingest-local, ingest-github, generate, stats, export-mesh, diff |
preview/index.html |
Three.js viewer for export-mesh output. A debugging aid, not the game |
tests/ |
72 behaviour tests; run dotnet test before and after every change to the core |
2. Contracts the back end must honour
The C# types are the source of truth. The JSON below is what they serialise to (Json.Options: camelCase,
enums as camelCase strings, nulls omitted). If you need a field, add it in C# and bump the schema version.
Don't patch the JSON.
2.1 World manifest (generate β manifest.json, schema 1)
{
"schemaVersion": 1, "generator": "repoverse-gen/1", "worldSeed": "000000005aa4c177",
"snapshots": { "snapkittywest/guppy": "git:<sha>" }, // repo key β snapshot id it was built from
"buildings": [{
"repo": "SNAPKITTYWEST/guppy", // display form; identity is the lower-cased key
"category": { "value": "compiler", "why": { "rule": "classifier:rules", "evidence": "mentions-compiler (score 5)" } },
"district": { "value": "kernel", "why": { ... } },
"archetype": { "value": "foundry", "why": { ... } },
"material": "metal",
"plot": { "district": "kernel", "slot": 0 }, // sticky across regenerations (pass --previous)
"footprint": { "x": 257, "z": 254, "width": 14, "depth": 19 }, // voxel units, ground plane
"floors": 1, "roomsPerSide": 2, "roomDepth": 6, "height": 7,
"activity": { "value": "low", "why": { ... } }, // dormant | low | moderate | high
"construction": { "value": "unreleased", "why": { ... } }, // unreleased | prerelease | released | archived
"landmark": false, "population": 1, "seed": "d17a3db530f2e546",
"interior": {
"rooms": [{ "id": 3, "name": "examples", "purpose": "workshop", "floor": 0, "directories": ["examples"],
"fileCount": 3, "artifacts": [{ "path": "examples/grover_2qubit.py", "kind": "sourceTerminal",
"sizeBytes": 4083, "language": "Python" }] }],
"doors": [{ "a": 0, "b": 1 }]
}
}],
"dependencies": [{ "from": "owner/a", "to": "owner/b" }]
}
Rule: Unreal actors are built from this and never written back into it (Β§5). The same snapshot, seed and
previous manifest must always produce byte-identical JSON; GenerationTests enforces this.
2.2 Voxels and chunks
Voxelis aushort: bits 0β7BlockType, bits 8β11MaterialFamily, bits 12β15 state (activity level for walls, floors and roofs).MeshKey = packed & 0x0FFF, and one material/draw group per key.- A chunk is 32Γ32Γ32, indexed as
(y * 32 + z) * 32 + x. Chunk Y layers run from 0 toWorldGenerator.MaxChunkY(currently 2). - World units are 1 voxel = 1 unit. Pick one Unreal scale and put it in one place. Suggested: 1 voxel = 50 cm, a 6-voxel storey = 3 m.
- Axes: Y is up in the core. Unreal is Z-up, so map core (x, y, z) β UE (x, z, y) and flip winding, or mirror one axis. Do it in exactly one conversion function.
GreedyMesher.Build(chunk, neighbourSampler)βQuad(axis, positive, layer, u, v, width, height, meshKey).GreedyMesher.Corners()returns counter-clockwise world-space corners (core handedness). Pass a neighbour sampler, or chunk-border faces will not be culled.- Interactive things are not voxels.
BuildingRasterizer.Objects(building)yieldsWorldObject(id, repo, x, y, z, kind, sourcePath, roomId, actions). Spawn these as actors or instances. BuildingRasterizer.Plan(building)gives each room's voxel rectangle and floor Y. Use it for cutaway, floor isolation and room highlighting.
2.3 Other formats
| Format | Where | Notes |
|---|---|---|
| Snapshot | Ingestion/SnapshotStore.cs |
schema 1; last-known-good; written atomically |
| Save | Persistence/SaveGame.cs |
schema 2; player + edits + tick only; add migrations to Migrations |
| Events | Simulation/WorldEvents.cs |
typed records; SnapshotDiff.Diff(before, after) produces them |
| URI | RepoverseUri.cs |
repoverse://owner/repo/path#L12, ?room=N, @x,y,z |
| Mesh export | Cli/Program.cs export-mesh |
debug format only: enum names here are PascalCase, unlike the manifest. Don't build the engine on it; use Β§3.1 |
3. What to build next, in order
Order follows the directive's vertical-slice rule (Β§55β57): get one district walkable end to end before scaling.
P0: finish the Part I vertical slice
3.1 C# β Unreal bridge (decide first; everything else depends on it) The core is .NET 8 and Unreal is C++. The options, in my recommended order:
- Sidecar process (recommended to start). Run the core as a local server. An Unreal C++ plugin talks to it
over a named pipe or localhost TCP with length-prefixed binary messages. It's the easiest to debug
(both sides test alone), the core stays engine-free, and the repo already uses this pattern
(
voxel/server/QuantumVoxelServer.csin BOBS-Many-Voxel-Worlds). Minimum messages:LoadManifest,SetFocus(x,z)β streamChunkMesh/ChunkUnloaded,GetObjects(buildingKey),ApplyEdit,Save/Load,Events(push). - Embed .NET in Unreal via
hostfxr. In-process with no IPC cost, but you own the hosting and threading. - UnrealSharp or a similar plugin. Quickest to write gameplay in C#, but it's a third-party dependency on your engine version.
Done when: Unreal shows the chunks around a focus point, updates as the focus moves, and memory stays flat
while travelling (mirror VoxelTests.Streaming_memory_is_bounded_by_radius_while_travelling).
3.2 Unreal chunk rendering (C++)
- Build one mesh section per
MeshKeyfromQuads. UseRealtimeMeshComponentorUProceduralMeshComponent, and do not spawn one actor per voxel (Β§14). - Collision comes from the same quads (complex-as-simple is fine to start).
- Map
MaterialFamilyΓBlockTypeto material instances. Windows are translucent. - Done when: the 15-building district renders at target frame rate, and
stat unitand draw calls are logged (Β§44).
3.3 Player, interaction, camera modes
- First/third-person walk with collision. Enter through the east-wall door (
Plan().Entrance) and climb the ladder shaft between floors. - Interaction comes from
WorldObject.Actions(the object advertises its verbs; the player code doesn't hard-code them, Β§52). - Camera modes World, Architectural Orbit (roof hide via
BlockType.Roof, floor isolation viaPlan().Rooms[].FloorY), Code and City Overview. Selection is onerepoverse://URI shared by all modes (Β§73). - Done when: you can walk the whole Β§57 success path: enter building β pick room β pick file β Code Mode β back outside β travel β quit β reload β same state.
3.4 Source inspection
- Fetch file contents on demand: from the GitHub contents API, via
GitHubIngest's cache pattern, or from a local clone. Page large files (Β§38). Nothing is fetched at manifest time.
3.5 Save/load wiring
- On quit,
SaveGame.Capture(manifest, player, edits, clock.Tick); on boot,ReadthenRestoreEdits. Player position and mode must come back exactly.
3.6 Dependency extraction (core, C#)
- Fill
CanonicalRepository.DependsOnby parsingCargo.toml,package.json,*.csproj,go.mod,pyproject.toml/requirements.txtand.gitmodules, matched against repos in the world. Edges then flow into the manifest automatically, with a test for each format.
P1: control plane and navigation
- Swift control plane (Β§33β34). An
AppStateholding selection, camera, overlays, simulation state and graph filters, bridged to the engine. It controls intent only and must never copy world data. Every toggle in Β§34 must change real filter state (add a test per toggle). - CSS design tokens (Β§35). Spacing, radii, blur, type scale, status colours, focus, hover, selected, disabled and stale states. Pair each colour with a shape or icon (Β§70). Use it for any HTML/UMG-web overlays.
- Graph Mode (Β§21). Draw
dependenciesedges between buildings, filterable by category and depth. - Search, command palette, world map, bookmarks, fast travel (Β§48β50, Β§74β75). The data is already there:
manifest buildings plus artifacts plus
RepoverseUri. - Live sync loop. Periodic
ingest-github, thenSnapshotDiff, then events drive visuals (Β§26, Β§92): release β illumination, archived β archive state, new files β rebuild that building's chunks only.
P2: later
- CAD import pipeline, offline only (Β§24): DWG/DXF/IFC β cleaned mesh + metadata β packaged asset,
referenced from
Overrides(landmark, custom archetype). - Audio, accessibility pass, and diagnostics overlay (Β§61, Β§69β70).
- Parts II and III (agents, simulation, 388-repo scale, packaging), once the directive text is available.
4. Known gaps in the core (fix before scaling to 388 repos)
| Gap | Where | Impact |
|---|---|---|
| District overflow throws. Each district holds 144 plots, and a 145th repo in one district fails the whole build | ManifestBuilder.Build |
Likely to hit at 388 repos if the classifier skews. Needs Β§85 expansion (a new ring or an overflow district) |
DependsOn never populated |
ingesters | Graph Mode has no data (see 3.6) |
| Contributors capped at 100 (1 page); recent commits capped at 300 (3 pages) | GitHubIngest |
Fine for activity levels; wrong as absolute counts |
.v counts as both Coq and Verilog |
Classifier |
Ties break by enum order; provenance shows it. Use overrides |
| One floor plan (a corridor spine) for every archetype | BuildingRasterizer |
Buildings read alike; archetype shells are future work |
Headers are added on every GitHubIngest construction |
GitHubIngest ctor |
Duplicate headers if one HttpClient is reused. Give each ingest its own client, or move the headers onto the request |
| Local ingest treats git tags as releases, whole-repo only | LocalGitIngest |
Sub-project buildings always show unreleased (scaffolding) |
| Classifier is keyword rules | Classifier |
Fine for a slice. An AI classifier must follow Β§82 (cached, versioned, overridable, never blocking) |
5. Setup
# .NET 8 SDK + git
dotnet build -warnaserror && dotnet test
dotnet run --project src/Repoverse.Cli -- ingest-local <any-git-checkout> --owner SNAPKITTYWEST --subprojects --out out/snapshot.json
dotnet run --project src/Repoverse.Cli -- generate --snapshot out/snapshot.json --out out/manifest.json
dotnet run --project src/Repoverse.Cli -- stats --manifest out/manifest.json
GITHUB_TOKEN=<fine-grained, read-only> dotnet run --project src/Repoverse.Cli -- ingest-github SNAPKITTYWEST --out out/snapshot.json
Keep the token in the environment or the OS keychain, never in files (Β§41). GitHubIngest.Redact scrubs
tokens from error text.
6. Decisions you need to make
- Bridge: sidecar, hostfxr or UnrealSharp (3.1). I recommend the sidecar.
- Unreal version and mesh component: RealtimeMesh plugin or built-in ProceduralMesh.
- Voxel scale in Unreal: 50 cm is suggested.
- Swift's target platform: macOS only, or an iPad companion over the network. This decides whether Swift talks to the engine in-process or over the same sidecar protocol.
- Scope of the first live ingest: all 349 public repos plus private ones, or a curated list via
ingest-github --limit/ overrides.