MCCF as a read-only Web of Worlds participant: design note.

Watch the MCCF demo

A short video of the Multi-Channel Coherence Field working in an X3D scene. Watch it on YouTube.

 


An MCCF world can take part in the Web of Worlds as a read-only provider: at export it publishes one JSON document set shaped like WoWAPI 0.0.1, plus X3D assets named by content hash. Nothing in MCCF's core changes, nothing in the WoW draft has to change, and nothing writable is exposed. A reference implementation and tests accompany this note; the open questions for the engineers are at the end.

Why this design

Each choice answers something the WoWAPI 0.0.1 specs or the Metaverse Standards Forum whitepaper ask for. Where the spec is silent, the choice says so.

WoW requirementWhat the WoW material saysMCCF design response
A world is one URIJoin, follow and preview are URL fragments (#join, #follow, #preview=aspect.id); persist and share mean store or send the URL/ redirects (302) to the MCCF player; browsers keep the fragment across a redirect, so the URL still carries the intent. #preview maps to the unattended performance of the scene, #join to free navigation
World status as dataOptional /wow/world returns a world summary: content, presence, technology, users, views, portalsGenerated once at export, served as a static document. MCCF knows the label, version, duration and number of views at that moment, so nothing is computed per request
Assets detect change and negotiate formatHEAD plus ETag for change; content negotiation over IANA model/* types, including model/x3d+xml and model/gltf-binaryEvery published asset is named by a hash of its bytes. The ETag is that hash, so a cached copy never goes stale and Cache-Control: immutable is safe. The scene stays X3D 4.0 and GLB inlines pass through unchanged
A spatial composition graphNodes carry id, label, names, localTransform, spatialAssetURIOnly authored scene content is exposed: named Transforms and Inlines. Timers, interpolators, routes and scripts are the cue machinery and stay private, so another engine could re-implement the same behaviour
Read and write are separateUser delete and node POST/PUT/DELETE exist, but the README lists writing nodes as optional, "if this is exposed"No write endpoint is provided. Mutating methods answer 405 with an Allow header. Outside writes could corrupt a character's narrative state, and a static provider has nothing to write to
Portable, user-controlled identityThe whitepaper puts identity in the user's own manifest (DIDs, verifiable credentials); the world consumes itMCCF stores and trusts no identity. Visitors are anonymous, /wow/user/{id} answers 404, and users counts report 0
Open standards, no lock-inThe whitepaper names glTF, X3D and USD as IANA-registered, and asks for decentralisationNo MCCF-specific format. The provider can be a folder of files on any host. Extra MCCF facts sit under one x-mccf key a client can ignore
Versioned worldsWorld.content.version is a number; the spec does not say how a link pins a versionAn integer per publish, assets pinned by hash, older versions stay fetchable with ?v=N

The shape

Foreign clients read hashed files; the cue machinery stays in MCCFIn MCCFPublished folder, static filesRead-only accessScene exportX3D 4.0 and scene XMLCue machineryTimers, interpolators,routes, scripts, statenever publishedpublishHashes files, rewrites urlsassets/name-hash.ext, immutableversions/N/wow.jsonWorld, views, portals, graphapp_urlGET /302 to the MCCF player;#join, #preview surviveGET /wow/assets/fileETag, HEAD, 304, 406GET /wow/worldview, portal, spatial, nodeAny other method: 405

Publishing turns an export into plain files. The cue machinery is not described anywhere in them, and any host that can serve files can be the provider; the Flask facade only adds ETag handling, content negotiation and the 405s.

What MCCF generates

One file per version, versions/N/wow.json, holds everything the endpoints return; each endpoint serves a slice of it. The excerpt below comes from publishing the real Garden of the Goddess export, trimmed. The scene's asset files were not available in the test environment, so their bytes were stand-ins and the hashes are illustrative; the structure is exact.

{
  "world": {
    "content": { "label": "GardenOfTheGoddess_Scene01", "version": 1 },
    "presence": { "navigation": "FLY, WALK, EXAMINE, ANY" },
    "technology": { "runtime": "X3D 4.0 (X_ITE) with the MCCF cue runtime" },
    "users": { "active_user_count": 0, "total_user_count": 0 },
    "views": { "view_count": 2 },
    "portals": { "portal_count": 1 },
    "x-mccf": { "sceneAsset": "/wow/assets/GardenOfTheGoddess_Scene01-b714bf8f.x3d" }
  },
  "views": [{ "id": 1, "x-mccf": {
    "def": "VP_Garden01", "label": "The Garden of Innana",
    "localPose": { "frame": "scene-local", "units": "m", "up": "+y",
                   "position": [171.48, 3, 196.99], "orientation": [0, 0, 0, 0] } } }],
  "portals": [{ "id": 1, "x-mccf": {
    "label": "Back to the Library", "target": "https://example.org/library#preview" } }],
  "nodes": { "id": 1, "label": "GardenOfTheGoddess_Scene01", "children": [
    { "id": 5, "label": "Avatar_Anna", "names": ["Avatar_Anna"], "parent": 1,
      "localTransform": [1,0,0,0, 0,1,0,0, 0,0,1,0, 186.5,2.1,200.5,1],
      "spatialAssetURI": "/wow/assets/Anna-c9ff85d2.x3d" } ] },
  "assets": [{ "id": 16, "uri": "/wow/assets/GardenOfTheGoddess_Scene01-b714bf8f.x3d",
               "mediaType": "model/x3d+xml", "etag": "\"b714bf8f...\"", "role": "scene" }]
}

The rules behind it:

  • Nodes. Only Transforms named Avatar_, PlacedAsset_, Zone_ or ZoneAsset_ are described (the list is configurable). Anything the Composer generates for cues, such as PathTimer_EC_..., is never described.
  • Views. Named Viewpoints, minus the free camera and the terrain-capture camera, which are authoring tools.
  • Portals. X3D Anchor nodes that link outward, plus portals listed in the publish config. Neither is in the Garden today, so the sample portal comes from config.
  • Ids. Integers in document order, as the spec requires. They are stable within a version only; the stable key is names[0].
  • Transforms. localTransform is 16 numbers, column-major as in glTF. The spec does not say; see the questions. x-mccf.transform repeats the same data as translation, rotation and scale.
  • Assets. The scene is itself an asset. Its url attributes are rewritten to hashed names, so a foreign X3D viewer resolves everything beside it without MCCF's server.
  • Versions. The integer rises only when the content changes; publishing the same export twice is a no-op. When the scene's XML is supplied, content.duration is the end of the last cue.

Endpoints: what is served, what is refused

Every JSON and asset response below carries a strong ETag, answers 304 to If-None-Match, and sends Access-Control-Allow-Origin: *, which is safe because nothing is writable.

PathIn WoWAPI 0.0.1MCCF behaviour
GET /Provisions the web app as text/html302 to the MCCF player. The Location has no fragment, so the browser re-applies #join, #follow or #preview
GET /wow/worldWorld summaryThe world object. no-cache, so a client revalidates and gets a 304 until the next publish
GET /wow/view/{id}View statusOne view; 404 outside 1..view_count
GET /wow/portal/{id}Portal statusOne portal; 404 outside the range
GET /wow/spatial/{id}Spatial composition graph{id: 1, rootNodeID: 1}
GET /wow/spatial/{id}/node/{nodeId}A node and its subtreeThe node with nested children
POST, PUT, DELETE on a nodeCreate, update, delete nodes405 with Allow: GET, HEAD, OPTIONS
GET /wow/user/{id} and DELETEUser status; delete userGET answers 404 (no user records); DELETE answers 405
GET /wow/assets/{file}Asset content, negotiated by IANA media type, HEAD and ETag for changeBytes with the stored media type and Cache-Control: immutable. 406 if Accept excludes that type. Files of older versions stay served
GET /wow/assets/{file}/wow/assetAsset statusLabel, media type, size, ETag, role
any JSON path with ?v=Nnot in the specPins version N and marks it immutable. A bad value answers 400, an unknown version 404

To run it: python mccf_wow.py publish --x3d <exported.x3d> --scene-xml <scene.xml> --config publish.json --out wow_publish, then register_wow(app, "wow_publish", "<scene>", app_url=...) on a Flask app, or point any static host at the folder. 21 tests cover the publisher and the facade, including every refusal in the table.

Gaps found in WoWAPI 0.0.1

Found while mapping MCCF onto the actual API.yaml files. Each has a stopgap in the sample, marked x-mccf where it adds fields.

GapWhereEffect on MCCFStopgap
Two path sets for the same graphOpenSpatialWorld README says /wow/scene/ and /wow/scene/node; API.yaml says /wow/spatial/{id} and /wow/spatial/{id}/node/{nodeId}A client may probe eitherFollow API.yaml
Placement is geographic onlygeoPose on World, User, View, Portal, Spatial, Asset; the longitude field is spelled lanA local Cartesian world (the Garden's header says Grid: 500mx500m) cannot say where a view or portal isx-mccf.localPose with frame, units and up axis
View and Portal have only id and geoPosecomponents/schemasNo label, no destination world, no entry viewx-mccf.label, target, entry
localTransform has no conventionNode schema: array of numbersA reader cannot know length or order16 numbers, column-major; x-mccf.transform repeats it
Node paths omit a declared parameterPOST, GET, PUT on .../node/{nodeId} do not declare spatialID; DELETE declares nodeid for {nodeId}A generated client or validator will reject the fileNot needed: MCCF serves GET only
Nothing is requiredNo required lists; world.schema.json has empty propertiesA conformance test cannot fail, so "conformant" cannot be shownClaim only "shape-compatible"
Version has no stated meaningWorld.content.version is a number; assets use HTTP ETagA link cannot say which version it meansInteger per publish, ?v=N, assets by hash

Questions for the engineers

  1. Static provider. Is a world whose /wow/* documents are pre-generated and immutable, with every write operation answering 405, an acceptable provider? Or must the node write operations exist?
  2. Local frames. For a world with no geographic anchor, should geoPose become optional with a local-pose alternative in the schema, or is a namespaced extension like x-mccf.localPose the intended route?
  3. Portal destination. Where does a portal's target world URI and entry view belong? Today the schema cannot express either.
  4. `localTransform`. What are the length and order? We assumed 16 numbers, column-major.
  5. Asset base. Is the asset's base URL the file URL itself, with /wow/asset appended? We chose that so relative url attributes inside the X3D keep resolving.
  6. Fragments. May #preview run with no session, and may a world define what it shows? We map it to an unattended performance of the scene.
  7. Counts without tracking. A world that keeps no visitor records: should users report 0, or be omitted?

Sources

Pages opened for this note, as of 2026-10-07. The WoWAPI files were read from a local clone of the repository (version 0.0.1 of each API).

Comments

Popular posts from this blog

MCCF Philosophy & Manifesto

Domain Awareness: Trust But Verify: Schemas, Metacognition, and the Limits of LLM Intelligence

AI Folk Art