Re: Thread for your script-related questions
Posted: November 29th, 2025, 8:37 am
There are always the CatForce-type search programs that can find high-period oscillators but return whatever they find and don't look for a specific period.
Forums for Conway's Game of Life
https://conwaylife.com/forums/
If infinite growth exists and isn't destroyed in a soup, it ends up running the pattern for 21,000 generations (this is why explosive rules hang), and then running for up to 120,000 more generations while running a linear-growth detector based on hashing the center of the soup (in particular the best approximation to a circle of radius 120) and looking for collisions (I think this is how the detector works, I could be wrong). If this fails, it will cause a "Failed to detect periodic behavior!". The relevant code for this is at https://gitlab.com/apgoucher/apgmera/-/ ... tabilise.h.get_snackeTWO wrote: December 4th, 2025, 8:25 pm when the last object created in a soup is a linear growth how does apgsearch figure out what generation the soup stabilizes on
so will a soup with a linear growth in it always end up having 21k generations or more?speedydelete wrote: January 7th, 2026, 5:51 pm If infinite growth exists and isn't destroyed in a soup, it ends up running the pattern for 21,000 generations (this is why explosive rules hang), and then running for up to 120,000 more generations while running a linear-growth detector based on hashing the center of the soup (in particular the best approximation to a circle of radius 120) and looking for collisions (I think this is how the detector works, I could be wrong). If this fails, it will cause a "Failed to detect periodic behavior!". The relevant code for this is at https://gitlab.com/apgoucher/apgmera/-/ ... tabilise.h.
Lifelib is a C/C++ library and therefore Python can't use it.I6_I6 wrote: December 4th, 2025, 12:17 pm How do I use lifelib in Python in Golly 5.0? It keeps saying "No module named lifelib".
Those are what I've been using to test a lifelib program that randomly places copies of unstable engines and outputs the RLEs, with the intention being to help with finding corderisations.b-engine wrote: January 8th, 2026, 9:23 am What are the corderise_stdin and corderise_test_stdin censuses in Catagolue?
Code: Select all
rule = 'b34a5is23-a68'
rle = '''x = 13, y = 36, rule = B34a5i/S23-a68
2o$o3bo$5o5b3o$b4o4bo2bo$10b2o13$10b2o$9bo2bo$10bobo$11bo12$5b2o$4bo2b
o$4bobo$5bo!
'''
period = 292
import lifelib, random, time, hashlib
sess = lifelib.load_rules(rule)
lt = sess.lifetree(n_layers = 1, memory = 1000)
pt = lt.pattern(rle)
print(pt.population)
seed = hashlib.sha256(str(time.time()).encode('utf-8')).hexdigest()
engines = 4
def mkpt(num):
pt2 = lt.pattern('b!')
for e in range(engines):
amnt = random.randint(1, period)
pt2 = pt2 + (pt[amnt](random.randint(-30, 30), random.randint(-30, 30)))
rle = pt2.rle_string()
for _ in range(2):
rle = rle[rle.find('\n')+1:]
rle = rle.replace('\n', '')
rle = 'x = 0, y = 0, rule = B3/S23\n' + rle + '\n'
return rle
fullstring = ''
f = open('\\\\wsl.localhost\\Ubuntu\\home\\pk22linux\\apgmera\\engines.txt', 'w')
f.write('')
f.close()
for x in range(100000):
fullstring = fullstring + mkpt(x)
if x%1000 == 999:
print(x)
f = open('\\\\wsl.localhost\\Ubuntu\\home\\pk22linux\\apgmera\\engines.txt', 'a')
f.write(fullstring)
f.close()
fullstring = ''
There are instructions for using the Python version at https://conwaylife.com/wiki/Tutorials/lifelib. You don't need to use a Jupyter notebook, you should be able to just import it once it is installed. On Windows/Mac, it is more complicated (see the wiki page for more instructions) and running it in a Golly script specifically might fail.I6_I6 wrote: December 4th, 2025, 12:17 pm How do I use lifelib in Python in Golly 5.0? It keeps saying "No module named lifelib".
It can, due to the Python bindings.b-engine wrote: January 7th, 2026, 10:56 pm Lifelib is a C/C++ library and therefore Python can't use it.
Yes.get_snackeTWO wrote: January 7th, 2026, 6:13 pm so will a soup with a linear growth in it always end up having 21k generations or more?
If all else fails, just copy the lifelib directory to the folder where you keep your scripts, and it should work.I6_I6 wrote: December 4th, 2025, 12:17 pm How do I use lifelib in Python in Golly 5.0? It keeps saying "No module named lifelib".
Where's the lifelib directory?
I mean the directory with lifelib in it.
Code: Select all
import lifelib
print(lifelib.__file__)
get_snackeTWO wrote: November 9th, 2025, 6:03 pm this happened when trying to run make on barristerhow fixCode: Select all
In file included from Barrister.cpp:12: ./LifeStableState.hpp:833:12: warning: unused variable 'result' [-Wunused-variable] 833 | auto result = SynchroniseStateKnownColumn(c); | ^~~~~~ In file included from Barrister.cpp:13: ./LifeUnknownState.hpp:144:43: warning: unused parameter 'stable' [-Wunused-parameter] 144 | void SanityCheck(const LifeStableState &stable) { | ^ ./LifeUnknownState.hpp:215:14: warning: unused variable 'on3' [-Wunused-variable] 215 | uint64_t on3 = stateCount.bit3[i]; | ^~~ ./LifeUnknownState.hpp:216:14: warning: unused variable 'on2' [-Wunused-variable] 216 | uint64_t on2 = stateCount.bit2[i]; | ^~~ ./LifeUnknownState.hpp:217:14: warning: unused variable 'on1' [-Wunused-variable] 217 | uint64_t on1 = stateCount.bit1[i]; | ^~~ ./LifeUnknownState.hpp:218:14: warning: unused variable 'on0' [-Wunused-variable] 218 | uint64_t on0 = stateCount.bit0[i]; | ^~~ ./LifeUnknownState.hpp:220:14: warning: unused variable 'unk3' [-Wunused-variable] 220 | uint64_t unk3 = unknownCount.bit3[s][i]; | ^~~~ ./LifeUnknownState.hpp:221:14: warning: unused variable 'unk2' [-Wunused-variable] 221 | uint64_t unk2 = unknownCount.bit2[s][i]; | ^~~~ ./LifeUnknownState.hpp:222:14: warning: unused variable 'unk1' [-Wunused-variable] 222 | uint64_t unk1 = unknownCount.bit1[s][i]; | ^~~~ ./LifeUnknownState.hpp:223:14: warning: unused variable 'unk0' [-Wunused-variable] 223 | uint64_t unk0 = unknownCount.bit0[s][i]; | ^~~~ ./LifeUnknownState.hpp:265:12: warning: unused variable 'stateon' [-Wunused-variable] 265 | uint64_t stateon = state[i]; | ^~~~~~~ ./LifeUnknownState.hpp:266:12: warning: unused variable 'stateunk' [-Wunused-variable] 266 | uint64_t stateunk = unknown[i]; | ^~~~~~~~ ./LifeUnknownState.hpp:267:12: warning: unused variable 'stateunkstable' [-Wunused-variable] 267 | uint64_t stateunkstable = unknownStable[i]; | ^~~~~~~~~~~~~~ ./LifeUnknownState.hpp:271:12: warning: unused variable 'stable_on' [-Wunused-variable] 271 | uint64_t stable_on = stable.state[i]; | ^~~~~~~~~ ./LifeUnknownState.hpp:272:12: warning: unused variable 'stable_unknown' [-Wunused-variable] 272 | uint64_t stable_unknown = stable.unknown[i]; | ^~~~~~~~~~~~~~ ./LifeUnknownState.hpp:358:14: warning: unused variable 'on3' [-Wunused-variable] 358 | uint64_t on3 = state3[i-1]; | ^~~ ./LifeUnknownState.hpp:370:14: warning: unused variable 'stable_on' [-Wunused-variable] 370 | uint64_t stable_on = nearbyStableState[i]; | ^~~~~~~~~ ./LifeUnknownState.hpp:371:14: warning: unused variable 'stable_unknown' [-Wunused-variable] 371 | uint64_t stable_unknown = nearbyStableUnknown[i]; | ^~~~~~~~~~~~~~ In file included from Barrister.cpp:14: ./RotorDescription.hpp:26:13: warning: enumeration values 'NORESULT', 'STABLE', and 'OTHER' not handled in switch [-Wswitch] 26 | switch (type) { | ^~~~ ./RotorDescription.hpp:51:48: warning: unused parameter 'resType' [-Wunused-parameter] 51 | RotorType resType) { | ^ ./RotorDescription.hpp:86:13: warning: 8 enumeration values not handled in switch: 'ReflectAcrossXEven', 'ReflectAcrossYEven', 'Rotate90Even'... [-Wswitch] 86 | switch (transf) { | ^~~~~~ Barrister.cpp:300:22: warning: unused parameter 'everActive' [-Wunused-parameter] 300 | const LifeState &everActive, | ^ Barrister.cpp:301:51: warning: unused parameter 'activeTimer' [-Wunused-parameter] 301 | const LifeCountdown<maxCellActiveWindowGens> &activeTimer, | ^ Barrister.cpp:302:51: warning: unused parameter 'streakTimer' [-Wunused-parameter] 302 | const LifeCountdown<maxCellActiveStreakGens> &streakTimer) | ^ 24 warnings generated. /usr/bin/ld: Warning: grouped short command line options are deprecated: -stack_size /usr/bin/ld: Error: unable to disambiguate: -stack_size (did you mean --stack_size ?) clang++: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [Makefile:20: Barrister] Error
Code: Select all
.../toStandard.lua:92:
Given rule is not valid in any algorithm.Unfortunately all I can say is that that I had some trouble with error messages along those lines, when I was developing those Lua conversion scripts. The errors were mysteriously irreproducible -- i.e., they went away after a few test cycles, and I was never able to figure out how to re-create them or what caused them.I6_I6 wrote: March 5th, 2026, 3:51 pm I tried to use toStandard.lua (using macOS), but it keeps saying:even though the rule was set to LifeSuper. It changes the rule to SuperToStandard with the correct 2-state conversion. (The script seems to create a SuperToStandard.rule file in my rules folder.) How do I fix this problem? (Note: I have absolutely no Lua knowledge whatsoever.)Code: Select all
.../toStandard.lua:92: Given rule is not valid in any algorithm.
Code: Select all
g.note(baserule .. suffix)Yes, I am using Golly 5.0.dvgrn wrote: March 6th, 2026, 10:07 amUnfortunately all I can say is that that I had some trouble with error messages along those lines, when I was developing those Lua conversion scripts. The errors were mysteriously irreproducible -- i.e., they went away after a few test cycles, and I was never able to figure out how to re-create them or what caused them.I6_I6 wrote: March 5th, 2026, 3:51 pm I tried to use toStandard.lua (using macOS), but it keeps saying:even though the rule was set to LifeSuper. It changes the rule to SuperToStandard with the correct 2-state conversion. (The script seems to create a SuperToStandard.rule file in my rules folder.) How do I fix this problem? (Note: I have absolutely no Lua knowledge whatsoever.)Code: Select all
.../toStandard.lua:92: Given rule is not valid in any algorithm.
We can try troubleshooting, and it will probably only be mildly painful. First, are you working with Golly 5.0? There were some maybe-related fixes a few years ago.
Second, can you try temporarily adding a new line in front of line 92 in toStandard.lua --
-- and just report here what the pop-up message says?Code: Select all
g.note(baserule .. suffix)
Code: Select all
-- Fast [Rule][History|Super] to [Rule] converter by Michael Simkin,
-- intended to be mapped to a keyboard shortcut, e.g., Alt+J
-- Sanity checks and Lua translation by Dave Greene, May 2017
-- Creates special rule and runs it for one generation, then switches to Life
-- Replace 2k + 1-> 1 and 2k -> 0
-- Preserves step and generation count
-- v1.1, 11 May 2024: support [Rule]Investigator patterns
local g = golly()
local rule = g.getrule()
local algo = g.getalgo()
local function CreateRule(filename, ruletext)
local fname = g.getdir("rules")..filename..".rule"
local f=io.open(fname,"r")
if f~=nil then
io.close(f) -- rule already exists
else
local f = io.open(fname, "w")
if f then
f:write(ruletext)
f:close()
else
g.warn("Can't save SuperToStandard rule in filename:\n"..filename)
end
end
end
-- deal with bounded-universe syntax appropriately
ind = string.find(rule, ":")
suffix = ""
baserule = rule
if ind then
suffix = rule:sub(ind)
baserule = rule:sub(1,ind-1)
end
-- No effect if the current rule is not a Super algo rule
if algo ~= "Super" then g.exit("The current rule is not a [Rule]History, [Rule]Super, or [Rule]Investigator rule.") end
ruletextSuper = [[@RULE SuperToStandard
@TABLE
n_states:26
neighborhood:oneDimensional
symmetries:none
var a={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}
var b={a}
var c={2,4,6,8,10,12,14,16,18,20,22,24}
var d={3,5,7,9,11,13,15,17,19,21,23,25}
c,a,b,0
d,a,b,1]]
CreateRule("SuperToStandard", ruletextSuper)
ruletextInvestigator = [[@RULE InvestigatorToStandard
@TABLE
n_states:21
neighborhood:oneDimensional
symmetries:none
var a={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
var b={a}
var c={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
c,a,b,0]]
CreateRule("InvestigatorToStandard", ruletextInvestigator)
-- If rulestring contains "Super", "History", or "Investigator" suffix, remove it and continue
if baserule:sub(-5) == "Super" then
baserule = baserule:sub(1,#baserule-5)
g.setrule("SuperToStandard")
elseif baserule:sub(-7) == "History" then
baserule = baserule:sub(1, #baserule-7)
g.setrule("SuperToStandard")
elseif baserule:sub(-12) == "Investigator" then
baserule = baserule:sub(1,#baserule-12)
g.setrule("InvestigatorToStandard")
else
g.show("Rule is not one of the known formats supported by the Super algorithm.")
g.exit()
end
-- If rulestring is "LifeV" then convert it to B3/S23V
if baserule:lower() == "lifev" then baserule = "B3/S23V" end
-- If rulestring is "LifeH" then convert it to B3/S23H
if baserule:lower() == "lifeh" then baserule = "B3/S23H" end
g.run(1)
step = g.getstep()
g.setrule(baserule .. suffix)
g.setalgo("HashLife")
g.setstep(step)
g.setgen("-1")Have another look -- I asked for the addition of precisely this new line -- g.note, not g.setrule:I6_I6 wrote: March 6th, 2026, 11:57 am There was already a blank line in front of line 92. I added another new line and it gave me the same error.
Code: Select all
g.note(baserule .. suffix)I thought you meant that I should add a blank line theredvgrn wrote: March 6th, 2026, 12:59 pmHave another look -- I asked for the addition of precisely this new line -- g.note, not g.setrule:I6_I6 wrote: March 6th, 2026, 11:57 am There was already a blank line in front of line 92. I added another new line and it gave me the same error.
That will pop up a window showing the exact name of the rule that Golly is trying to switch to, before it actually switches to it.Code: Select all
g.note(baserule .. suffix)
Copy and paste here whatever message comes up, and then we can think about it a little more.
Code: Select all
Golly note:
LifeOkay, and then you still get the same "Given rule is not valid in any algorithm." error message right after that? And you end up with Golly stranded in the rule "SuperToStandard"?I6_I6 wrote: March 6th, 2026, 1:02 pm Alright, here's what it says:Code: Select all
Golly note: Life
From what I understand, toStandard.lua does this:dvgrn wrote: March 6th, 2026, 5:25 pmOkay, and then you still get the same "Given rule is not valid in any algorithm." error message right after that? And you end up with Golly stranded in the rule "SuperToStandard"?I6_I6 wrote: March 6th, 2026, 1:02 pm Alright, here's what it says:Code: Select all
Golly note: Life
dvgrn wrote: March 6th, 2026, 5:25 pm That's weird, of course, because Golly generally knows that "Life" is an alias for "B3/S23", and it sets the rule appropriately without complaining. But now I don't remember why exactly it knows about that alias, or what could possibly get in the way of it remembering that alias.
What happens in your Golly 5.0 if you choose "Set Rule" from the menu and try changing the rule to "Life" manually?
Code: Select all
Given rule is not valid in any algorithm.This is the problem.dvgrn wrote: March 6th, 2026, 5:25 pm There's a "Life.rule" that is installed into Golly's pre-installed Rules table, so it should certainly be finding that even if the alias isn't operational for some reason! Can you find "Life.rule" in your Rules folder?
The solution is very simple: I just had to move my custom rules in Desktop/Rules over to golly-5.0-mac/Rules, then make sure my Golly checks in that folder for ruletables. Now there are no more errors!dvgrn wrote: March 6th, 2026, 5:25 pm As I mentioned, I have a very vague memory of this exact error message happening once, back when I was QA-testing the new Lua script. It was an annoyingly persistent error... and then it went away mysteriously for no reason and I was unable to get it to happen again, even after starting all over again with a new copy of Golly.
So even though this is annoying, it might be really useful if this error keeps happening to you -- maybe we can finally figure out what's going wrong here.
Very likely I could invent three lines of Lua code that would work around the mysterious problem without understanding it -- but I'd rather actually solve the problem than just put a Band-Aid over it.
Code: Select all
#C [[ RLE Tetromino 3o$bo!|RANDCELLS 4 2 ]]
#C [[ T 10 PASTE Tetromino|3o$bo!|RANDCELLS 4 2 ]]Code: Select all
x = 4, y = 5, rule = B3/S13
#C [[ RLE Tetromino 3o$bo!|RANDCELLS 4 2 ]]
#C [[ T 10 PASTE Tetromino|3o$bo!|RANDCELLS 4 2 ]]
o2bo$o2bo2$3o$bo!
How could I use this tool myself? I've been searching for stabilizations of this engine:PK22 wrote: January 8th, 2026, 11:31 am
Those are what I've been using to test a lifelib program that randomly places copies of unstable engines and outputs the RLEs, with the intention being to help with finding corderisations.
Here's the source code, but it's messy and bespoke:
<blah>
Code: Select all
x = 3, y = 2, rule = B2-ak3ik4c5k7e/S12-c3k4c6i
bo$obo!But I don't know how I would run something like that, maybe due to my limited coding skills and/or my unfamiliarity with apgsearch.
Here is a version that's easier to use:UnbihexiumFan wrote: March 16th, 2026, 6:33 pmHow could I use this tool myself? I've been searching for stabilizations of this engine:PK22 wrote: January 8th, 2026, 11:31 am
Those are what I've been using to test a lifelib program that randomly places copies of unstable engines and outputs the RLEs, with the intention being to help with finding corderisations.
Here's the source code, but it's messy and bespoke:
<blah>
as some stabilizations have already yielded new puffer speeds which have been corderized into spaceships:Code: Select all
x = 3, y = 2, rule = B2-ak3ik4c5k7e/S12-c3k4c6i bo$obo!But I don't know how I would run something like that, maybe due to my limited coding skills and/or my unfamiliarity with apgsearch.
Code: Select all
rule = input('Enter the rule.\n>')
rle = input('Enter the headerless RLE of the unstable engine.\n>')
period = int(input('Enter the period.\n>'))
rule = rule.lower().replace('/', '')
import lifelib, random, time, hashlib, os
sess = lifelib.load_rules(rule)
lt = sess.lifetree(n_layers = 1, memory = 1000)
pt = lt.pattern(rle)
seed = hashlib.sha256(str(time.time()).encode('utf-8')).hexdigest()
engines = int(input('How many engines do you wish to place?\n>'))
area = input('Enter the area you wish to place engines in; e.g \'50x50\' or \'24x48\'.\n>')
dx = int(area.lower().split('x')[0])
dy = int(area.lower().split('x')[1])
def mkpt():
pt2 = lt.pattern('b!')
for e in range(engines):
amnt = random.randint(1, period)
pt2 = pt2 + (pt[amnt](random.randint(0, dx), random.randint(0, dy)))
rle = pt2.rle_string()
for _ in range(2):
rle = rle[rle.find('\n')+1:]
rle = rle.replace('\n', '')
rle = 'x = 0, y = 0, rule = B3/S23\n' + rle + '\n'
return rle
fullstring = ''
file = os.getcwd() + '/engines.txt'
file = file.replace('\\', '/')
f = open(file, 'w', encoding='utf-8')
f.write('')
f.close()
rles = set()
count = -1
print('Generating engines, use Ctrl+C to exit...')
while True:
try:
count += 1
if count%1000 == 0:
print(count)
if count%10000 == 0:
f = open(file, 'a', encoding='utf-8')
f.write(''.join(rles))
f.close()
rles = set()
rles.add(mkpt())
except KeyboardInterrupt:
break
f = open(file, 'a', encoding='utf-8')
f.write(''.join(rles))
f.close()
print('Engines saved to '+file)
Code: Select all
python3 corderise.py
./recompile.sh --rule <rule> --symmetry corderise_stdin
./apgluxe -n 100000 -k <your_payosha_key> < engines.txt
After running this for a while and ending the search (~239000 configurations), I got this error when running with cygwin:
Code: Select all
Traceback (most recent call last):
File "/home/***/apgspaceinvaders/lifelib/pythlib/lowlevel.py", line 247, in <module>
remote_load()
File "/home/***/apgspaceinvaders/lifelib/pythlib/lowlevel.py", line 160, in remote_load
obj = pickle.load(stdin)
KeyboardInterrupt
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/home/***/apgspaceinvaders/lifelib/pythlib/session.py", line 214, in cleanup_sessions
sess.lifelib.annihilate()
File "/home/***/apgspaceinvaders/lifelib/pythlib/lowlevel.py", line 237, in annihilate
self.the_library.stdin.close()
BrokenPipeError: [Errno 32] Broken pipe