Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions MANIFEST.sha256
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ b45d388c901b6a0397d644ddf85c88a71bbdfd8ed91e2c1fbb5e2e26287afa9e docs/superpowe
b512e17d600965bac02492f9e0dbbd30b0e68771c1c3ebdda0992a4c498453b4 functions/_lib/http.js
b04ee5d5fd478ac6b37de485dae8f826fdd854706a5d2d5323114614ef617773 functions/_lib/identity.js
bf407a093caf22903d96c3eaa4ed7dbe5fcebdb16273527efa552681cf27d4ff functions/api/auth/[[path]].js
0a65c39e81d3662dddf3aeee1d98ba77df573664d3d402eef5dcc1d8c164e1d6 functions/api/v2/[[path]].js
5eafb513d50a902f785940fd601076daf60ca0eee21c1306b21807b90c431f8a functions/api/v2/[[path]].js
0f1859c6cc1c232919c4e79372b169d1beef3900181e553c188de63d0d1f1f50 migrations/0001_identity.sql
7a2e3055d95dfc251ffad07f0f2b9bf9f90ace5092654fb8fa92fa261d56a29c scripts/build_sovereign_genesis.mjs
2b2bf8698b2951203307e384e441e43645b345ff5dd84b32d1183d8121473db5 scripts/patch_current_v2.mjs
Expand All @@ -33,15 +33,15 @@ efd1af2bcdd0939bda2432e6823f09135f6d8345796e8a6f9690886b0b104b05 site/assets/wo
27eaa1da60c9ae26c54512c6b986e2d568f5ec9a968d6a46d3d785f9117e5e4e site/cinematic-world.css
6c2c82fb1de7d8a0051edaa1e5f5711fc8881865ad8638fa0c41a709dce54696 site/data/sovereign-genesis.json
0670d7be3b270c8e627c5f0089e25ba065c3326f6bcf0f06ce9ae5cf3c5cf64b site/icon.svg
37edda29fd3d7dc28535024733ec4e770cf16b8e2e8dc1ceeda73d1c1bc154b2 site/index.html
f7f882e7c491d86e5bc54c57033192b52cd28da593a70175564f612a187d3a06 site/index.html
a31f15ff86c87f9eafb1723fb3fc59186f27fb32a75b00d287fc7efbdeec5b1c site/medieval-art.js
49897b8d946b85c84a4e0f177a3c7773a0c6f9acfef0025d308ccec2ac3a7ef1 site/medieval-world.css
82197a81454575b5c941ec0c52924c0a53f1d92bf70371e9c16df0912a29dcf0 site/observer-connection.js
f57bf13a527ada7c6c792760f6ab976412df64a4a125f305be7e86dda6a32cbf site/pixi-observer.js
3deafe2d73b4c47ac240cc5ab9b335d89b005f98f43f704e27b6b59f218a2e24 site/pixi-observer.js
5edab258856c44d89ea1df51472037697db95909c2d696607ef7c30a503a4838 site/preview.png
772ee873b012f6ddf0f36b79c8c95b737c1a45b4362f0b997afcb7a68b77b233 site/sovereign-renderer.js
59d83fee261298ef4c90a650ab3b350d4533ab61e7ad3f315e45cdd83443de74 site/sovereign-world.css
d639481c2258cfabfaa97bead83e2009cffa3a5535fca4c8c14729dade54fce4 site/sovereign-world.js
5dcf19ad709016f22bf7d1f2e099b94c34a41861c14aa1c9fb6a7d6ef27fab11 site/sovereign-renderer.js
9d1a63c705106bb23e92accd232f509cba550ba47dcab1d1d13681351f457e30 site/sovereign-world.css
ca3d652f16c7b2ebd4781d0db1640f51089f738a905285a0bc6df229e41a4b9a site/sovereign-world.js
aaa5a63cab5926e0355e8257bd562ec2db4c8890904ef1894767063925ceadf1 site/terrain-model.js
c98fca62534d141f285a6c92bfd6257c26d462a3daff72672a4d76f2399d1f21 site/transient-physics.js
d179b80fb34aae0db437dfa72c1a6e6704209a8119b8d991ad49321d8584da8f tests/browser-art.mjs
Expand Down Expand Up @@ -84,7 +84,7 @@ f6c7f2623eeeeea2faebe84c30e135c6357403b3c44aee379dc5f8058064ecac tests/test_sov
3addb20df209d6f6ad84ff37adaa7dd67bf2c10adfc4c372559bc32543311415 tests/test_sovereign_shelter_environment.mjs
218e8e718765fa3e19aead2359ab5cec36778c6fda596176d8b016a38843da00 tests/test_sovereign_society.mjs
5357326e16f8493d08ecc0a56bae1a48773c1f2e979f830f99181054e144ce7a tests/test_sovereign_transient_physics_upgrade.mjs
f19d6c322cd8b17bd8f65560e4602d523899f8546d70dd40a783cc8a285ab0a7 worker/src/index.js
0fb98d54388b831fdf91bf0ac02de518e1c0b65b176e8f305801e816bd858fff worker/src/index.js
2eac2b46fb9337eb62b4b716be26eb11f92359c58e6c6685039f3506346a09fb world/actions.js
79cdf84d53e19cb1500f2a782aad657d49281005c7809e06bfcf190f7411f294 world/artifacts.js
251ef01a7616cef68bba68b1bc81ac62d30b0bd1685a8beb9784c4ba55fa469b world/beliefs.js
Expand Down Expand Up @@ -122,3 +122,4 @@ dab555575cd5a79e1e1be63a155033788d40995f6b5c69b3b82fe87132233009 site/spine-cit
4fd200df9a9fc14a16eb12445665f4dfd58777fdba8426da4f00ca99b21d8fbe docs/SPINE_OBSERVER_INTEGRATION.md
164c56738f05469e36d0cb3c913656154381bda6a177505d5d2f06d87d1665ad tests/test_sovereign_observer_readability_upgrade.mjs
98d88f126a1bca9443485b2cbc2f4614dbc975f9f96d0dfb72ed37465e2c3e56 tests/test_sovereign_citizen_animation_upgrade.mjs
f0d644436e621ebd5b6e28cb8af3673b6884fbb487725e5816ef1dc08291d7b8 tests/test_sovereign_avatar_observer_upgrade.mjs
21 changes: 20 additions & 1 deletion functions/api/v2/[[path]].js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,26 @@ export async function onRequest({request,env}){
if(request.method==='GET'&&p.startsWith('/why/'))return proxy(request,env);
if(request.method==='GET'&&p==='/stream')return proxy(request,env);
if(request.method==='POST'&&p==='/avatar'){
await readJson(request).catch(()=>({}));const actor=await requireActor(request,env);return proxy(request,env,{body:{actor},path:'/avatar'});
await readJson(request).catch(()=>({}));
const actor=await requireActor(request,env);
const ensured=await proxy(request,env,{body:{actor},path:'/avatar'});
const avatar=await ensured.json();

if(!avatar.ok)return json(avatar,ensured.status);

return json({
ok:true,
authenticated:true,
actor:{
displayName:actor.display_name||actor.github_login||null,
githubLogin:actor.github_login||null,
avatarUrl:actor.avatar_url||null
},
avatar:{
citizenId:avatar.citizenId,
created:Boolean(avatar.created)
}
});
}
if(request.method==='POST'&&p==='/intent'){
const actor=await requireActor(request,env);const body=await readJson(request);const avatar=await proxy(new Request(request.url,{method:'POST'}),env,{body:{actor},path:'/avatar'});const av=await avatar.json();if(!av.ok)return json(av,avatar.status);return proxy(request,env,{body:{citizenId:av.citizenId,intent:body.intent},path:'/intent'});
Expand Down
31 changes: 29 additions & 2 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<button id="overlayKnowledge"><span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 5q5-3 9 0 4-3 9 0v15q-5-3-9 0-4-3-9 0zM12 5v15"/></svg></span><b>Knowledge</b></button>
<button id="overlayRelations"><span><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="5" cy="12" r="3"/><circle cx="19" cy="5" r="3"/><circle cx="19" cy="19" r="3"/><path d="m8 11 8-5M8 13l8 5"/></svg></span><b>Relations</b></button>
<button id="fullscreenWorld"><span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M8 3H3v5M16 3h5v5M3 16v5h5M21 16v5h-5"/></svg></span><b>Fullscreen</b></button>
<button id="agentOpen"><span><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="7" r="4"/><path d="M4 22v-3a8 8 0 0 1 16 0v3"/></svg></span><b>My Avatar</b></button>
<button id="agentOpen"><span><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="7" r="4"/><path d="M4 22v-3a8 8 0 0 1 16 0v3"/></svg></span><b>My Avatar</b><small id="myAvatarStatus">SIGN IN</small></button>
</nav>

<section id="societyHistory" class="game-window parchment-panel history-window" hidden aria-label="Society History">
Expand All @@ -61,7 +61,34 @@

<section id="agentWindow" class="game-window parchment-panel agent-window" hidden aria-label="Personal Agent">
<header><div><span>HUMAN-LINKED CITIZEN</span><h2>Your direction, their world.</h2><p>Your intent may influence your avatar. It grants no knowledge or privilege.</p></div><button class="panel-close" id="agentClose" aria-label="Close agent">×</button></header>
<div class="agent-copy"><p>Your avatar is subject to the same biology, scarcity, physical terrain, social consequences and mortality as every other Citizen.</p><textarea id="humanIntent" rows="5" placeholder="Example: avoid violence, learn their language, build trust, and seek a sustainable way to improve transport."></textarea><button id="sendIntent" class="primary">Send direction to my avatar</button><a id="loginLink" href="/api/auth/github?return_to=%2F">Enter the world with GitHub</a><p id="agentFeedback" role="status"></p></div>
<div class="agent-copy">
<div id="avatarGuest">
<p>Sign in to embody one persistent Citizen inside CYMONIA. Your Citizen receives no Earth knowledge or privilege.</p>
<a id="loginLink" class="avatar-login" href="/api/auth/github?return_to=%2F">Enter the world with GitHub</a>
</div>
<div id="avatarDashboard" hidden>
<div class="avatar-identity">
<img id="avatarIdentityImage" alt="" hidden>
<div><span class="eyebrow">YOUR CITIZEN</span><h3 id="avatarIdentityName">—</h3><small id="avatarIdentityStatus">—</small></div>
</div>
<div class="avatar-actions">
<button id="avatarLocate">Locate</button>
<button id="avatarFollow">Follow</button>
<button id="avatarInspect">Inspect</button>
</div>
<div id="avatarStats" class="avatar-stats"></div>
<div class="avatar-section"><h3>Current life</h3><div id="avatarNow"></div></div>
<div class="avatar-section"><h3>Evolution</h3><div id="avatarEvolution"></div></div>
<div class="avatar-section"><h3>Recent life</h3><div id="avatarTimeline" class="avatar-timeline"></div></div>
<div class="avatar-section avatar-direction">
<h3>Direction</h3>
<p>Your intent is a preference. Your Citizen can interpret it, fail, refuse through circumstances, or die.</p>
<textarea id="humanIntent" rows="4" placeholder="Example: avoid violence, learn their language, build trust, and seek a sustainable way to improve transport."></textarea>
<button id="sendIntent" class="primary">Send direction to my avatar</button>
<p id="agentFeedback" role="status"></p>
</div>
</div>
</div>
</section>

<div id="toastLayer" class="toast-layer" aria-live="polite"></div>
Expand Down
7 changes: 6 additions & 1 deletion site/pixi-observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class PixiObserverLayer{
constructor(canvasFallback,art){
this.canvasFallback=canvasFallback;this.art=art;this.app=null;this.ready=false;this.failed=false;this.state=null;this.staticKey='';this.hits=[];this.citizenSprites=new Map();this.frames=[];this.groundSource=null;this.staticEntries=[];
// Logical object layers share a depth-sorted container, so trees can occlude people correctly.
this.vegetationLayer=[];this.resourceLayer=[];this.structureLayer=[];this.citizenLayer=null;this.spineAdapter=null;
this.vegetationLayer=[];this.resourceLayer=[];this.structureLayer=[];this.citizenLayer=null;this.spineAdapter=null;this.ownedCitizenId=null;
this.init();
}
async init(){
Expand All @@ -40,6 +40,7 @@ export class PixiObserverLayer{
}catch(error){console.warn('Pixi observer unavailable; Canvas fallback remains active.',error);this.app?.destroy(true,{children:true});this.app=null;this.failed=true;}
}
setState(state){this.state=state;}
setOwnedCitizen(id){this.ownedCitizenId=id||null;}
staticSignature(state){return `${staticSceneKey(state)}|${this.art.revision}`;}
clearLayer(layer){for(const child of layer.removeChildren())child.destroy({children:true});}
sprite(frame,size){const s=new globalThis.PIXI.Sprite(this.frames[frame]);s.anchor.set(.5,.94);s.scale.set(size/s.texture.width);return s;}
Expand Down Expand Up @@ -74,6 +75,9 @@ export class PixiObserverLayer{
task.anchor.set(.5);task.position.set(0,-41);container.addChild(shadow,body,task);
entry={container,body,task,shadow,baseScale:Math.abs(body.scale.x),spine:false};
}
const ownedRing=new PIXI.Graphics();ownedRing.ellipse(0,1,11,5).stroke({width:1.5,color:0x8fd7ff,alpha:.95});ownedRing.visible=false;
const ownerMark=new PIXI.Text({text:'YOU',style:{fontFamily:'system-ui',fontSize:8,fontWeight:'700',fill:0xbfe8ff,stroke:{color:0x17251f,width:2}}});ownerMark.anchor.set(.5);ownerMark.position.set(0,-49);ownerMark.visible=false;
entry.container.addChildAt(ownedRing,0);entry.container.addChild(ownerMark);entry.ownedRing=ownedRing;entry.ownerMark=ownerMark;
this.citizenLayer.addChild(entry.container);this.citizenSprites.set(c.id,entry);
}
for(const [id,e] of this.citizenSprites)if(!alive.has(id)){e.container.destroy({children:true});this.citizenSprites.delete(id);}
Expand All @@ -97,6 +101,7 @@ export class PixiObserverLayer{
e.body.scale.set((flip?-1:1)*e.baseScale*pose.scaleX,e.baseScale*pose.scaleY);
if(e.shadow)e.shadow.scale.x=pose.shadowScale;
}
const owned=c.id===this.ownedCitizenId;if(e.ownedRing)e.ownedRing.visible=owned;if(e.ownerMark)e.ownerMark.visible=owned;
e.task.text=a&&(active||camera.zoom>2)?ACTION_ICON[a.type]||'·':'';
const sp=this.screenPoint(pos.x,pos.y,t.elevation,camera);hits.push({...this.art.hitRecord({id:c.id,kind:'citizen',frame:citizenFrame(c),size:19},{x:sp.x,y:sp.y+e.body.y*camera.zoom},camera.zoom,e.body.scale.x<0),depth:p.y});
}
Expand Down
Loading
Loading