// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Five-cell diffusion lab // Not compiled or tested in-world // Setup: Enter step, or heat to add one unit at center. Owner-touch initializes; enter reset to restart. Text input closes after90seconds. // Stop / restore: Close or ignore the text box, or remove the script. It changes no world objects, avatar state or inventory. // Notes: Original bounded, manually stepped educational toy. Not a calibrated simulator, real-world control system, or live scientific measurement. Illustrates diffusion with a stable fixed coefficient; units are arbitrary. Floating-point rounding may cause small conservation errors. // License: see LICENSE in this distribution. // Original Incoprea. MIT. Not compiled or tested in-world. integer channel; integer handle; list values; integer steps; close() { if(handle)llListenRemove(handle); handle=0; llSetTimerEvent(0.0); } start() { values=[0.0,0.0,10.0,0.0,0.0]; steps=0; } string view() { return "Step "+(string)steps+": "+llList2CSV(values); } show() { llOwnerSay(view()); if(!handle) { channel=-1000-(integer)llFrand(1000000.0); handle=llListen(channel,"",llGetOwner(),""); } llTextBox(llGetOwner(),"Enter step, or heat to add one unit at center. Type reset to restart.",channel); llSetTimerEvent(90.0); } default { touch_start(integer n) { if(llDetectedKey(0)!=llGetOwner())return; close(); start(); show(); } listen(integer incomingChannel,string name,key id,string s) { if(!handle||incomingChannel!=channel||id!=llGetOwner())return; s=llToLower(llStringTrim(s,STRING_TRIM)); if(s=="reset")start(); else { if(s=="heat") { float center=llList2Float(values,2); if(center<100.0)values=llListReplaceList(values,[center+1.0],2,2); } else if(s=="step") { list next=[]; integer i; for(i=0;i<5;++i) { float here=llList2Float(values,i); float left=here; float right=here; if(i>0)left=llList2Float(values,i-1); if(i<4)right=llList2Float(values,i+1); next+=[here+0.25*(left+right-2.0*here)]; } values=next; ++steps; } } show(); } timer() { close(); } }