// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Four-by-four Life board // Not compiled or tested in-world // Setup: Enter1-16 to toggle a row-major cell or step to advance. 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. Cells outside the4x4 board are dead, not wrapped. No unbounded automatic generations. // License: see LICENSE in this distribution. // Original Incoprea. MIT. Not compiled or tested in-world. integer channel; integer handle; list cells; integer generation; close() { if(handle)llListenRemove(handle); handle=0; llSetTimerEvent(0.0); } start() { cells=[0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0]; generation=0; } string view() { string text="Generation "+(string)generation+": "; integer i; for(i=0;i<16;++i) { if(llList2Integer(cells,i))text+="X"; else text+="."; if(i%4==3)text+=" / "; } return text; } show() { llOwnerSay(view()); if(!handle) { channel=-1000-(integer)llFrand(1000000.0); handle=llListen(channel,"",llGetOwner(),""); } llTextBox(llGetOwner(),"Enter1-16 to toggle a row-major cell or step to advance. 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=="step") { list next=[]; integer i; for(i=0;i<16;++i) { integer count=0; integer dx; integer dy; for(dy=-1;dy<=1;++dy)for(dx=-1;dx<=1;++dx) { integer x=i%4+dx; integer y=i/4+dy; if((dx||dy)&&x>=0&&x<4&&y>=0&&y<4)count+=llList2Integer(cells,y*4+x); } integer alive=count==3||(count==2&&llList2Integer(cells,i)); next+=[alive]; } cells=next; ++generation; } else { integer cell=(integer)s-1; if(cell>=0&&cell<16&&(string)(cell+1)==s)cells=llListReplaceList(cells,[!llList2Integer(cells,cell)],cell,cell); } } show(); } timer() { close(); } }