{
  "name": "Living Solar Orrery",
  "dimension": "3d",
  "slot": "action_bar",
  "width": 256,
  "height": 128,
  "textBaseline": 128,
  "placement": {
    "x": 0,
    "y": 0
  },
  "shapes": [],
  "texts": [],
  "heads": [],
  "images": [],
  "bars": [],
  "triggers": [],
  "world": {
    "glsl": "const float OR_PI = 3.14159265;\r\nvec3 orTilt(vec3 p) { p.yz = rpw_rot(0.20) * p.yz; p.xy = rpw_rot(-0.11) * p.xy; return p; }\r\nvec3 orUntilt(vec3 p) { p.xy = rpw_rot(0.11) * p.xy; p.yz = rpw_rot(-0.20) * p.yz; return p; }\r\nvec2 orSphere(vec3 ro, vec3 rd, vec3 c, float r) {\r\n    vec3 q = ro-c; float b = dot(q,rd); float h = b*b-dot(q,q)+r*r;\r\n    if(h<0.0) return vec2(-1.0);\r\n    h=sqrt(h); return vec2(-b-h,-b+h);\r\n}\r\nfloat orRadius(int i) {\r\n    if(i==0) return 0.205; if(i==1) return 0.285; if(i==2) return 0.370; if(i==3) return 0.455;\r\n    if(i==4) return 0.610; if(i==5) return 0.735; if(i==6) return 0.850; return 0.944;\r\n}\r\nfloat orSize(int i) {\r\n    if(i==0) return 0.021; if(i==1) return 0.036; if(i==2) return 0.040; if(i==3) return 0.032;\r\n    if(i==4) return 0.072; if(i==5) return 0.058; if(i==6) return 0.045; return 0.044;\r\n}\r\nfloat orAngle(int i, float time) {\r\n    float a=0.0; float v=0.0;\r\n    if(i==0){a=0.8;v=0.70;} if(i==1){a=3.8;v=0.46;} if(i==2){a=2.8;v=0.31;} if(i==3){a=5.7;v=0.23;}\r\n    if(i==4){a=5.65;v=0.13;} if(i==5){a=3.6;v=0.088;} if(i==6){a=2.1;v=0.061;} if(i==7){a=5.2;v=0.043;}\r\n    return a+time*v;\r\n}\r\nvec3 orPlanet(int id, vec3 n, float time) {\r\n    vec3 p=n; p.xz=rpw_rot(time*0.16+float(id))*p.xz;\r\n    float tex=rpw_noise(p*17.0+float(id));\r\n    if(id==0) return mix(vec3(0.21,0.23,0.26),vec3(0.62,0.59,0.53),tex);\r\n    if(id==1) { float v=rpw_noise(p*5.0+vec3(0.0,time*0.06,0.0)); return mix(vec3(0.65,0.40,0.13),vec3(1.0,0.89,0.58),v*0.7+0.25); }\r\n    if(id==2) {\r\n        float land=rpw_fbm(p*4.8+vec3(2.0,7.0,1.0));\r\n        vec3 c=mix(vec3(0.018,0.12,0.53),vec3(0.025,0.36,0.82),tex);\r\n        c=mix(c,mix(vec3(0.08,0.30,0.065),vec3(0.43,0.49,0.17),tex),smoothstep(0.48,0.53,land));\r\n        float cloud=rpw_fbm(p*9.0+vec3(time*0.035,0.0,0.0));\r\n        c=mix(c,vec3(0.95,0.99,1.0),smoothstep(0.51,0.66,cloud));\r\n        c=mix(c,vec3(0.82,0.95,1.0),smoothstep(0.86,0.99,abs(p.y)));\r\n        return c;\r\n    }\r\n    if(id==3) return mix(vec3(0.36,0.09,0.035),vec3(0.91,0.38,0.14),rpw_noise(p*6.0)*0.6+tex*0.4);\r\n    if(id==4) {\r\n        float lat=p.y+0.026*sin(p.x*14.0+p.z*10.0+time*0.08)+0.018*tex;\r\n        float bands=sin(lat*37.0)+0.38*sin(lat*79.0);\r\n        vec3 c=mix(vec3(0.53,0.26,0.11),vec3(0.96,0.82,0.59),smoothstep(-0.9,0.8,bands));\r\n        float spot=length(vec2((p.x-0.24)/0.29,(p.y+0.26)/0.13));\r\n        c=mix(c,vec3(0.65,0.16,0.065), (1.0-smoothstep(0.7,1.0,spot))*smoothstep(0.3,0.65,p.z));\r\n        return c;\r\n    }\r\n    if(id==5) { float b=0.5+0.5*sin(p.y*39.0+tex*0.8); return mix(vec3(0.66,0.48,0.25),vec3(0.95,0.84,0.57),0.35+b*0.65); }\r\n    if(id==6) return mix(vec3(0.30,0.70,0.75),vec3(0.66,0.92,0.90),0.5+0.2*sin(p.y*21.0));\r\n    return mix(vec3(0.035,0.12,0.52),vec3(0.09,0.39,0.94),0.5+0.25*sin(p.y*20.0+tex));\r\n}\r\nvec4 object(vec3 ro, vec3 rd, float t0, float t1, float time, vec3 light, inout float depth) {\r\n    vec3 o=orUntilt(ro), d=orUntilt(rd);\r\n    float hit=t1+1.0; int body=-2; vec3 centre=vec3(0.0); float rad=0.12;\r\n    vec2 sh=orSphere(o,d,vec3(0.0),0.12);\r\n    float st=sh.x>=t0?sh.x:sh.y;\r\n    if(st>=t0 && st<=t1){hit=st;body=-1;}\r\n    vec3 saturn=vec3(0.0);\r\n    for(int i=0;i<8;i++) {\r\n        float a=orAngle(i,time); vec3 c=vec3(cos(a),0.0,sin(a))*orRadius(i);\r\n        if(i==5) saturn=c;\r\n        vec2 h=orSphere(o,d,c,orSize(i)); float t=h.x>=t0?h.x:h.y;\r\n        if(t>=t0 && t<hit && t<=t1){hit=t;body=i;centre=c;rad=orSize(i);}\r\n    }\r\n    float planeT=abs(d.y)>0.00001?-o.y/d.y:-1.0;\r\n    // Intersect three orbital cylinders, then test only the nearby rocks.\r\n    float qa=dot(d.xz,d.xz), qb=dot(o.xz,d.xz);\r\n    if(qa>0.00001) {\r\n        for(int track=0;track<3;track++) {\r\n            float ft=float(track); float r=0.505+ft*0.024;\r\n            float disc=qb*qb-qa*(dot(o.xz,o.xz)-r*r);\r\n            if(disc<0.0) continue;\r\n            float root=sqrt(disc);\r\n            for(int side=0;side<2;side++) {\r\n                float tc=(-qb+(side==0?-root:root))/qa;\r\n                vec3 cp=o+d*tc;\r\n                if(tc<t0-0.05 || tc>min(hit,t1)+0.05 || abs(cp.y)>0.06) continue;\r\n                float motion=time*(0.178-ft*0.008)+ft*1.73;\r\n                float angle=atan(cp.z,cp.x)-motion;\r\n                float cell=floor(angle*5.411268);\r\n                for(int nearRock=0;nearRock<3;nearRock++) {\r\n                    float id=mod(cell+float(nearRock)-1.0,34.0);\r\n                    float h=rpw_hash(vec3(id,ft,9.0));\r\n                    float a=(id+0.2+0.6*h)/5.411268+motion;\r\n                    vec3 c=vec3(cos(a)*r,(rpw_hash(vec3(id,ft,2.0))-0.5)*0.014,sin(a)*r);\r\n                    float size=0.0016+0.0021*h;\r\n                    vec2 hh=orSphere(o,d,c,size); float t=hh.x;\r\n                    if(t>=t0 && t<hit && t<=t1){hit=t;body=8;centre=c;rad=size;}\r\n                }\r\n            }\r\n        }\r\n    }\r\n    vec3 col=vec3(0.0); float alpha=0.0; float first=t1;\r\n    if(body!=-2) {\r\n        vec3 p=o+d*hit; vec3 n=normalize(p-centre);\r\n        if(body==-1) {\r\n            vec3 q=n; q.xz=rpw_rot(time*0.10)*q.xz;\r\n            float boil=rpw_noise(q*20.0+vec3(0.0,time*0.45,0.0));\r\n            float fine=rpw_noise(q*66.0-vec3(time*0.4,0.0,0.0));\r\n            float heat=boil*0.55+fine*0.45;\r\n            col=mix(vec3(1.55,0.24,0.008),vec3(2.5,1.50,0.39),smoothstep(0.17,0.86,heat));\r\n            col*=0.76+0.24*pow(max(dot(n,-d),0.0),0.35);\r\n        } else {\r\n            vec3 sun=normalize(-centre); float lam=max(dot(n,sun),0.0);\r\n            vec3 base=body==8?vec3(0.48,0.41,0.32)*(0.7+0.4*rpw_noise(n*7.0)):orPlanet(body,n,time);\r\n            col=base*(vec3(0.17,0.19,0.25)+vec3(1.55,1.42,1.20)*pow(lam,0.8));\r\n            if(body==2 || body==6 || body==7) {\r\n                float rim=pow(1.0-max(dot(n,-d),0.0),3.0);\r\n                col+=vec3(0.10,0.32,0.80)*rim*(0.14+lam*0.60);\r\n            }\r\n        }\r\n        alpha=1.0;first=hit;\r\n    }\r\n    // Saturn's real inclined annulus, with a dark Cassini gap.\r\n    vec3 rn=normalize(vec3(0.30,0.87,0.39));\r\n    float den=dot(d,rn); float rt=abs(den)>0.00001?dot(saturn-o,rn)/den:-1.0;\r\n    if(rt>=t0 && rt<=t1 && rt<hit) {\r\n        vec3 q=o+d*rt-saturn; float r=length(q);\r\n        if(r>0.069 && r<0.121) {\r\n            float grain=0.5+0.5*sin(r*2600.0);\r\n            float gap=1.0-0.86*(smoothstep(0.099,0.1005,r)-smoothstep(0.106,0.1075,r));\r\n            float ra=(0.65+grain*0.22)*gap*smoothstep(0.069,0.073,r)*(1.0-smoothstep(0.118,0.121,r));\r\n            vec3 sun=normalize(-saturn); vec2 shadow=orSphere(o+d*rt+sun*0.001,sun,saturn,0.058);\r\n            float lit=shadow.y>0.0?0.20:1.15;\r\n            vec3 rc=mix(vec3(0.43,0.31,0.16),vec3(0.96,0.83,0.54),grain*0.5+0.35)*lit;\r\n            col=rc*ra+col*(1.0-ra); alpha=ra+alpha*(1.0-ra); if(ra>0.2) first=min(first,rt);\r\n        }\r\n    }\r\n    // Distance-softened filaments stay continuous when the orrery is viewed from afar.\r\n    if(planeT>=t0 && planeT<=t1 && planeT<hit) {\r\n        vec3 p=o+d*planeT; float r=length(p.xz); float line=0.0;\r\n        float width=clamp(planeT*0.0022,0.0020,0.010);\r\n        for(int i=0;i<8;i++) {\r\n            float dist=abs(r-orRadius(i)); float x=dist/width;\r\n            line+=0.40*exp(-x*x)+0.16*exp(-x*x*3.7)+0.045*exp(-x*x*0.25);\r\n        }\r\n        float la=min(0.64,line);\r\n        vec3 lc=vec3(0.44,0.73,1.08);\r\n        col=lc*la+col*(1.0-la);alpha=la+alpha*(1.0-la);if(la>0.02)first=min(first,planeT);\r\n    }\r\n    // Compact volumetric solar atmosphere, clipped at the first opaque surface.\r\n    vec2 ch=orSphere(o,d,vec3(0.0),0.195);\r\n    if(ch.y>=t0 && ch.x<hit) {\r\n        float begin=max(t0,ch.x), end=min(min(t1,ch.y),hit); float dt=max(0.0,end-begin)/28.0;\r\n        vec3 glow=vec3(0.0); float ga=0.0;\r\n        for(int k=0;k<28;k++) {\r\n            float t=begin+(float(k)+0.5)*dt; vec3 p=o+d*t; float r=length(p); vec3 n=p/max(r,0.0001);\r\n            float v=rpw_noise(n*10.0+vec3(0.0,time*0.30,0.0));\r\n            float flare=smoothstep(0.51,0.77,v);\r\n            float density=15.0*exp(-max(r-0.12,0.0)*92.0)+flare*35.0*exp(-max(r-0.124,0.0)*53.0);\r\n            vec3 spin=p; spin.xz=rpw_rot(time*0.10)*spin.xz;\r\n            float arches=0.0;\r\n            for(int arc=0;arc<3;arc++) {\r\n                vec3 c=vec3(0.107,0.035,0.036); vec3 axis=normalize(vec3(-0.3,0.1,0.9));\r\n                if(arc==1){c=vec3(-0.080,-0.061,0.059);axis=normalize(vec3(0.6,-0.6,0.2));}\r\n                if(arc==2){c=vec3(0.018,0.096,-0.064);axis=normalize(vec3(0.9,-0.1,0.1));}\r\n                vec3 q=spin-c; float axial=dot(q,axis);\r\n                float ringRadius=0.033+0.005*sin(time*0.38+float(arc)*2.1);\r\n                float tube=length(vec2(length(q-axis*axial)-ringRadius,axial));\r\n                arches+=100.0*exp(-tube*tube/0.00002025);\r\n            }\r\n            density+=arches*smoothstep(0.118,0.124,r);\r\n            density*=1.0-smoothstep(0.168,0.195,r);\r\n            float a=1.0-exp(-density*dt);\r\n            vec3 c=mix(vec3(2.2,0.34,0.012),vec3(2.6,1.20,0.20),exp(-max(r-0.12,0.0)*90.0));\r\n            glow+=(1.0-ga)*c*a; ga+=(1.0-ga)*a;\r\n        }\r\n        col=glow+(1.0-ga)*col;alpha=ga+(1.0-ga)*alpha;if(ga>0.15)first=min(first,begin+0.3*(end-begin));\r\n    }\r\n    // Broad, transparent solar halo; it never covers a nearer planet.\r\n    float closest=clamp(-dot(o,d),t0,min(hit,t1));\r\n    float impact=length(o+d*closest);\r\n    float halo=0.13*exp(-max(impact-0.12,0.0)*27.0)*(1.0-smoothstep(0.22,0.30,impact));\r\n    if(halo>0.001 && hit>closest-0.12) {\r\n        col=vec3(1.9,0.62,0.07)*halo+col*(1.0-halo);alpha=halo+alpha*(1.0-halo);\r\n        if(alpha<0.3)first=min(first,closest);\r\n    }\r\n    if(alpha<0.001)return vec4(0.0);\r\n    depth=clamp(first,t0,t1);\r\n    return vec4(col/max(alpha,0.0001),alpha);\r\n}",
    "prompt": "the whole solar system as a glowing orrery in space: a blazing Sun in the middle with a boiling, flaring surface and a soft corona, and all eight planets orbiting it on a flat, slightly tilted plane at different speeds (inner planets fast, outer slow) - Mercury grey, Venus pale yellow, Earth blue with white clouds and green land, Mars rusty red, Jupiter big with banded stripes and a red spot, Saturn with its wide tilted rings, Uranus pale cyan, Neptune deep blue. A faint thin glowing line traces each orbit, and a sparse asteroid belt of tiny rocks circles between Mars and Jupiter. The planets are lit by the Sun (day side bright, night side dark). Placed 64 blocks across floating in the sky, so use nearly the whole unit sphere for the orbits (Neptune's orbit radius about 0.95), keep the Sun around radius 0.12 and make planets big enough to read (Jupiter ~0.05, Earth ~0.025), not to scale.",
    "size": 64,
    "summary": "A blazing, boiling Sun with a soft corona and curling prominences anchors eight individually textured, Sun-lit planets orbiting at different speeds on a tilted plane, with glowing orbit trails, Saturn’s inclined rings, and a sparse drifting asteroid belt."
  }
}