INT version of gliderdb

For discussion of other cellular automata.
Post Reply
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

INT version of gliderdb

Post by MDA »

I recently became interested in gliderdb and how it aimed to be a collection of all known spaceship speeds in outer-totalistic 2-state CA. I also learned about 5S, which only collected the smallest known example for every speed. Then, I read about Project Omniraumschiff, which was meant to be a web version of gliderdb, kept up-to-date by the community. However, it was never implemented and it only focused on outer-totalistic CA.

I am now planning to combine the two and develop a database across all spaceship-supporting 2-state INT rules (including B0) listing the smallest spaceships known for every speed (except for adjustable speeds). I will name the database “GlidINT” and it will be on my GitHub. Rules:

Every spaceship shall have an RLE associated with it, oriented to move between north and northwest. The phase used should have minimum population and bounding box.

Every spaceship shall be listed by its population, speed, minrule, and maxrule.

Whenever a new (smaller) spaceship is discovered, it will replace the older spaceship in all the rules where it works.

“Oversized” spaceships (whose minpop phases are larger than 400x400) shall be added as compressed files.

All scripts necessary for the database will be stored in a folder called “src”.

All discovery information (name, date, discoverer, and program used) should be added to attribution.txt, if known. Names should be written with the last name first (such as “Callahan, Paul”). Dates should follow YYYY-MM-DD or YYYY-MM or just YYYY.

Attribution format:

Code: Select all

Glider    Guy, Richard    manual    1969
Format:

Code: Select all

{minpop}P{period}H{dx}V{dy} {minrule} - {maxrule} {headerless RLE}
This project will obviously need much attention and care, but I’m confident that it will work. I will also need script help. The script this project needs should:

- Identify patterns

- Check whether they are spaceships

- Orient the resulting spaceship correctly

- Return a line which can be pasted into the database.

Link: https://github.com/HavenMDA/GlidINT

Edit (October 23rd, 2026, 10:34 AM): The above link is dead and outdated. The latest version of the database can be found at https://sim.zpsou.eu/interna242/~mamara ... lidINT.txt.
Last edited by MDA on October 23rd, 2026, 5:35 am, edited 3 times in total.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
NNlk05
Posts: 848
Joined: January 14th, 2026, 8:42 pm
Location: Exploring in the Jungle of the INT Rulespace
Contact:

Re: INT version of gliderdb

Post by NNlk05 »

MDA wrote: July 11th, 2026, 5:08 am *snip*
- Return a line which can be pasted into the database.
Why not run it on a server? You'll need one anyways for the front-end, and free serverless platforms are good enough.
Feci quod potui, faciant meliora potentes.

Code: Select all

x = 10, y = 3, rule = B34twz/S23
b2o4b2o$obo4bobo$2bo4bo!
[[ AUTOSTART AUTOHIDEGUI TRACK 0 -47/270 ZOOM 4 GPS 45 STEP 3 THEME BOOK ]]
https://nnlk05.github.io

=3
The world is my country, science my religion.
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

NNlk05 wrote: July 11th, 2026, 5:13 am
[…]

Why not run it on a server? You'll need one anyways for the front-end, and free serverless platforms are good enough.
I don’t know how. Maybe you can do that part and I’ll work on a script to clone the repository, check for the presence of a specific spaceship, compare it to the submitted one, and add it if it’s smaller.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
NNlk05
Posts: 848
Joined: January 14th, 2026, 8:42 pm
Location: Exploring in the Jungle of the INT Rulespace
Contact:

Re: INT version of gliderdb

Post by NNlk05 »

MDA wrote: July 11th, 2026, 5:28 am I don’t know how. Maybe you can do that part and I’ll work on a script to clone the repository, check for the presence of a specific spaceship, compare it to the submitted one, and add it if it’s smaller.
I don't have access to my various accounts until about 2026-8-10, so I won't be able to work on this until then.
Feci quod potui, faciant meliora potentes.

Code: Select all

x = 10, y = 3, rule = B34twz/S23
b2o4b2o$obo4bobo$2bo4bo!
[[ AUTOSTART AUTOHIDEGUI TRACK 0 -47/270 ZOOM 4 GPS 45 STEP 3 THEME BOOK ]]
https://nnlk05.github.io

=3
The world is my country, science my religion.
User avatar
PK22
Posts: 633
Joined: January 25th, 2025, 11:38 am
Location: United Kingdom
Contact:

Re: INT version of gliderdb

Post by PK22 »

MDA wrote: July 11th, 2026, 5:08 am (...)

This project will obviously need much attention and care, but I’m confident that it will work. I will also need script help. The script this project needs should:

- Identify patterns

- Check whether they are spaceships

- Orient the resulting spaceship correctly

- Return a line which can be pasted into the database.

Link: https://github.com/HavenMDA/GlidINT
Questions:
1. What language should the script be written in? Using TypeScript and lifeweb would probably be ideal, since lifeweb can easily find minrule and maxrule, and might allow some processing to be shifted client-side if you want to go with a server frontend. Lifelib (which can be used with either Python or C++) has several problems for this idea, namely needing recompilation for new rules (which can take >20 seconds in the case of Python, so finding minrule and maxrule could take over half an hour), and requiring x86 architecture to run. I have a Python package which can simulate patterns without requiring recompilation for new rules, but it might be too slow for some of the more chaotic spaceships. (EDIT: I could also do a mix of C++ and Python, with simulation in C++ and the database processing in Python).

2. Under what circumstances should a line be replaced? You stated that the format is:

Code: Select all

{minpop}P{period}H{dx}V{dy} {minrule} - {maxrule} {headerless RLE}
Should a ship always replace the old one if it has a lower minpop and matches the period and displacement? If not, what variables need to match to force replacement?
User:PK22
Learning miscellaneous programming languages.
User avatar
speedydelete
Posts: 135
Joined: October 7th, 2025, 9:44 pm
Contact:

Re: INT version of gliderdb

Post by speedydelete »

This doesn't seem possible to me. The compressed size of the 5S database for INT is more than 30 MiB, this database is likely to be thousands of times larger than it.

EPE can easily give thousands of ships in just a few minutes with the right commands, which would quickly fill up the database.
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

PK22 wrote: July 11th, 2026, 8:00 am
[…]

Questions:
1. What language should the script be written in? Using TypeScript and lifeweb would probably be ideal, since lifeweb can easily find minrule and maxrule, and might allow some processing to be shifted client-side if you want to go with a server frontend. Lifelib (which can be used with either Python or C++) has several problems for this idea, namely needing recompilation for new rules (which can take >20 seconds in the case of Python, so finding minrule and maxrule could take over half an hour), and requiring x86 architecture to run. I have a Python package which can simulate patterns without requiring recompilation for new rules, but it might be too slow for some of the more chaotic spaceships. (EDIT: I could also do a mix of C++ and Python, with simulation in C++ and the database processing in Python).
It doesn’t matter much what language you choose to write it in. You could write it in Python because of its vast library of helpful functions, at the cost of being an interpreted language, and thus, slower to run. You could also use C/C++ which is compiled, and thus faster, but at the cost of having to define almost all helpful functions yourself. Using lifelib is also not very advantageous, because, as you said, it has to be recompiled every time a rule is changed, so, in my opinion, the fastest solution is to write a custom C/C++ program for pattern analysis with a Python frontend.
PK22 wrote: July 11th, 2026, 8:00 am
2. Under what circumstances should a line be replaced? You stated that the format is:

Code: Select all

{minpop}P{period}H{dx}V{dy} {minrule} - {maxrule} {headerless RLE}
Should a ship always replace the old one if it has a lower minpop and matches the period and displacement? If not, what variables need to match to force replacement?
A spaceship in the database should only be fully replaced if

- The unsimplified displacement and period are the same in both spaceships

- The older spaceship has a higher min-population (or, if both minpops are equal, measure bounding-box)

- The new spaceship works in the older spaceship’s minrule and maxrule

Alternatively, if, by “replace”, you meant partial replacement, then spaceships should be replaced if

- The unsimplified displacement and period are the same in both spaceships

- The older spaceship has a higher min-population (again, if both minpops are equal, measure bounding-box)
speedydelete wrote: July 11th, 2026, 10:19 am This doesn't seem possible to me. The compressed size of the 5S database for INT is more than 30 MiB, this database is likely to be thousands of times larger than it.

EPE can easily give thousands of ships in just a few minutes with the right commands, which would quickly fill up the database.
As for your objection, speedydelete, both points are valid, but I think this problem is inevitable. I will likely have to rethink my formatting decisions once we get there. Perhaps a rule stating that rules with spaceships found by EPE or similar tools should not be added unless at least one spaceship is known in such rules found without EPE or other similar programs.

Edit (July 11th, 2026, 6:42 PM): Replying to both PK22 and speedydelete, a good rule of thumb to memorize these rules and how to apply them is that GlidINT only collects one spaceship for every known non-adjustable speed in a given rule.

Edit (July 11th, 2026, 6:56 PM): Actually, on second thought, I believe adjustable spaceships should be included in the GlidINT database. However, the attribution text file should state that the speed is adjustable and the formula defining the speeds which can be achieved (e.g. c/n or (n, n-1)c/(2 * (2n - 1))). The common RLE file should contain only the smallest member of the adjustable family and it should also mention the range of the adjustable family, not the individual spaceship included in the database.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
speedydelete
Posts: 135
Joined: October 7th, 2025, 9:44 pm
Contact:

Re: INT version of gliderdb

Post by speedydelete »

MDA wrote: July 11th, 2026, 1:38 pm
speedydelete wrote: July 11th, 2026, 10:19 am This doesn't seem possible to me. The compressed size of the 5S database for INT is more than 30 MiB, this database is likely to be thousands of times larger than it.

EPE can easily give thousands of ships in just a few minutes with the right commands, which would quickly fill up the database.
As for your objection, speedydelete, both points are valid, but I think this problem is inevitable. I will likely have to rethink my formatting decisions once we get there. Perhaps a rule stating that rules with spaceships found by EPE or similar tools should not be added unless at least one spaceship is known in such rules found without EPE or other similar programs.
This still doesn't fix the problem. You could write a script that runs qfind on random rules looking for endemic c/2o's, and submitting them once it finds them. Also, what's the point of maintaining this database if the multi-rule search programs aren't allowed?
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

speedydelete wrote: July 12th, 2026, 10:33 am
MDA wrote: July 11th, 2026, 1:38 pm
[…]

As for your objection, speedydelete, both points are valid, but I think this problem is inevitable. I will likely have to rethink my formatting decisions once we get there. Perhaps a rule stating that rules with spaceships found by EPE or similar tools should not be added unless at least one spaceship is known in such rules found without EPE or other similar programs.
This still doesn't fix the problem. You could write a script that runs qfind on random rules looking for endemic c/2o's, and submitting them once it finds them. Also, what's the point of maintaining this database if the multi-rule search programs aren't allowed?
I still haven’t finalized much regarding this project, so there’s still some wiggle room regarding what kinds of spaceships or rules are/aren’t allowed. This is meant to be a community project, so if you disagree with my assertion that “rules with spaceships found by EPE or similar tools should not be added unless at least one spaceship is known in such rules found without EPE or other similar programs”, we can decide to remove that rule. Also, keep in mind that since for a c/2o spaceship to be isotropically endemic, it has to be high-period or high-population, if you decide to “write a script that runs qfind on random rules looking for endemic c/2o’s, and submitting them once it finds them”, the database should mostly reject them unless no other c/2os are known if they’re large in population. Alternatively, if they’re large in period, they could be quite hard to find with qfind.

Perhaps we can implement a prototype version of GlidINT which only accepts spaceships which work in at least one rule at most 10 isotropic transitions from Life? This could help us understand whether or not your arguments hold in this simpler case before transitioning to the whole of the (spaceship-supporting) INT rulespace.

A restriction which could be added is that B0 rules with S8 are not allowed because they are always complementary to some rule with neither of those conditions and thus, any spaceship submitted in those rules is always present in the complement version (no B0 or S8).

Edit (July 13th, 2026, 12:08 PM): I’ve come up with another idea. Instead of hosting the database on GitHub, the repository will contain only the necessary scripts and the database itself will be hosted on my website.

Edit (July 15th, 2026, 2:16 PM): Retracted last edit, replaced with this message.

Edit (July 16th, 2026, 10:05 AM): GlidINT should be up and running by the beginning of August.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

I am expecting to open GlidINT today or tomorrow. I will edit this post to include a Python script for uploading to the database once I have it ready.

Edit (August 1st, 2026, 3:13 PM): I probably won't be able to finish the database code today, but I'll keep trying.

Uploading script:

Code: Select all

from random import randint

from subprocess import run

rle = input("Spaceship RLE: ")

rule = input("Rule: ")

dx = int(input("Spaceship dx: "))

dy = int(input("Spaceship dy: "))

period = int(input("Spaceship period: "))

r = randint(0, 100000000000000)

path = "/Users/YOUR USERNAME HERE/tmp"

with open(f"{path}/{r}.entry", "w") as file:
	
	file.write(f"{dx} : {dy} : {period} : {rule} : {rle},\n")
	
run(f"/usr/local/bin/curl -T {path}/{r}.entry https://sim.zpsou.eu/interna242/~mamaral/gliders/uncommitted/{r}.entry", shell = True)

run(f"cd {path} && rm -rf *.entry", shell = True)
Some notes:

- Please don't submit too many spaceships until I finish the database code.

- Spaceships run between southward and southeastward.

- There is currently no attribution system. I'll prepare one as soon as I finish the main database updater.

- B0 rules are currently not supported.
Last edited by MDA on August 14th, 2026, 8:29 am, edited 1 time in total.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

Edit (August 10th, 2026, 1:57 PM): GlidINT is now open. It doesn't support B0 rules yet, and all patterns have to be oriented between south and southeast to be accepted.

I took the liberty of uploading the glider, LWSS, MWSS, Glider 3736, and the bomber to the database. It can be accessed at https://sim.zpsou.eu/interna242/~mamara ... lidINT.txt.

Python uploader (requires Curl to work):

Code: Select all

from random import randint

from subprocess import run

rle = input("Spaceship RLE: ")

rule = input("Rule: ")

dx = int(input("Spaceship dx: "))

dy = int(input("Spaceship dy: "))

if dx <= 0 or dy < 0:
	
	raise ValueError("dx must be positive and dy must be nonnegative")
	
if dy > dx:
	
	raise ValueError("dx must be greater than or equal to dy")
	
period = int(input("Spaceship period: "))

r = randint(0, 100000000000000)

path = "/Users/YOUR USERNAME HERE/tmp"

with open(f"{path}/{r}.entry", "w") as file:
	
	file.write(f"{dy} : {dx} : {period} : {rule} : {rle},\n")
	
run(f"curl -T {path}/{r}.entry https://sim.zpsou.eu/interna242/~mamaral/gliders/uncommitted/{r}.entry", shell = True)
To make this work, I rewrote the database updater in Java instead of C.

Old post:
MDA wrote: August 1st, 2026, 3:09 pm I'm sorry for tripleposting, but I just wanted to increase this request's visibility.

I have finished writing the database updater. Unfortunately, the code's not working right now. The updater was never meant to be public, but I felt that it was important for me to post it here.

Could anyone try fixing the bugs in this program so I can use it for the database?

Code:

Code: Select all

#include <stdlib.h>

#include <stdio.h>

#include <ctype.h>

#include "dict.h"

#define RLE 160401

typedef struct Speed {
	
	long long dx;
	
	long long dy;
	
	long long period;
	
} Speed;

typedef struct Rulespace {
	
	char minrule[274];
	
	char rule[274];
	
	char maxrule[274];
	
} Rulespace;

typedef struct Conds {
	
	int bconds[117];
	
	int sconds[117];
	
} Conds;

typedef struct Glider {
	
	long long dx;
	
	long long dy;
	
	long long period;
	
	int minpop;
	
	char minrule[274];
	
	char maxrule[274];
	
} Glider;

void open(char filepath[], Speed * speed, Rulespace * rulespace, char (* rle)[RLE]) {
	
	int n = 0;
	
	char c;
	
	(*speed).dx = 0;
	
	(*speed).dy = 0;
	
	(*speed).period = 0;
	
	FILE * file;
	
	file = fopen(filepath, "r");
	
	c = getc(file);
	
	while (isdigit(c)) {
		
		(*speed).dx *= 10;
		
		(*speed).dx += (c - '0');
		
		c = getc(file);
		
	}
	
	/* SPACE */
	
	c = getc(file);
	
	/* COLON */
	
	c = getc(file);
	
	/* SPACE */
	
	c = getc(file);
	
	while (isdigit(c)) {
		
		(*speed).dy *= 10;
		
		(*speed).dy += (c - '0');
		
		c = getc(file);
		
	}
	
	/* SPACE */
	
	c = getc(file);
	
	/* COLON */
	
	c = getc(file);
	
	/* SPACE */
	
	c = getc(file);
	
	while (isdigit(c)) {
		
		(*speed).period *= 10;
		
		(*speed).period += (c - '0');
		
		c = getc(file);
		
	}
	
	/* SPACE */
	
	c = getc(file);
	
	/* COLON */
	
	c = getc(file);
	
	/* SPACE */
	
	c = getc(file);
	
	while (c != ' ') {
		
		(*rulespace).rule[n] = c;
		
		n++;
		
		c = getc(file);
		
	}
	
	(*rulespace).rule[n] = 0;
	
	n = 0;
	
	/* SPACE */
	
	c = getc(file);
	
	/* COLON */
	
	c = getc(file);
	
	/* SPACE */
	
	c = getc(file);
	
	while (c != ',') {
		
		(*rle)[n] = c;
		
		n++;
		
		c = getc(file);
		
	}
	
	(*rle)[n] = 0;
	
	fclose(file);
	
}

void rparse(char rule[274], Conds * conds) {
	
	int n = 1; /* Skip the leading B */
	
	int negating = 0;
	
	int lastdigit = -1;
	
	char letters[14] = "cekainyqjrtwz";
	
	for (int nn = 0; nn < 117; nn++) {
		
		(*conds).bconds[nn] = 0;
		
		(*conds).sconds[nn] = 0;
		
	}
	
	while (rule[n] != '/') {
		
		if (isdigit(rule[n])) {
			
			for (int nn = 0; nn < 13; nn++) {
				
				(*conds).bconds[((rule[n] - '0') * 13) + nn] = 2;
				
				negating = 0;
				
				lastdigit = rule[n] - '0';
				
			}
			
		}
		
		if (isalpha(rule[n])) {
			
			if (negating) {
				
				for (int nn = 0; nn < 13; nn++) {
					
					if (rule[n] == letters[nn]) {
						
						(*conds).bconds[((rule[n] - '0') * 13) + nn] = 0;
						
					}
					
				}
				
			} else {
				
				for (int nn = 0; nn < 13; nn++) {
					
					if ((*conds).bconds[((rule[n] - '0') * 13) + nn] == 2) (*conds).bconds[((rule[n] - '0') * 13) + nn] = 0;
					
					if (rule[n] == letters[nn]) (*conds).bconds[((rule[n] - '0') * 13) + nn] = 1;
					
				}
				
			}
			
		}
		
		if (rule[n] == '-') negating = 1;
		
		n++;
		
	}
	
	n += 2; /* Skip "/S" */
	
	negating = 0;
	
	lastdigit = -1;
	
	while (rule[n]) {
		
		if (isdigit(rule[n])) {
			
			for (int nn = 0; nn < 13; nn++) {
				
				(*conds).sconds[((rule[n] - '0') * 13) + nn] = 2;
				
				negating = 0;
				
				lastdigit = rule[n] - '0';
				
			}
			
		}
		
		if (isalpha(rule[n])) {
			
			if (negating) {
				
				for (int nn = 0; nn < 13; nn++) {
					
					if (rule[n] == letters[nn]) {
						
						(*conds).sconds[((rule[n] - '0') * 13) + nn] = 0;
						
					}
					
				}
				
			} else {
				
				for (int nn = 0; nn < 13; nn++) {
					
					if ((*conds).sconds[((rule[n] - '0') * 13) + nn] == 2) (*conds).sconds[((rule[n] - '0') * 13) + nn] = 0;
					
					if (rule[n] == letters[nn]) (*conds).sconds[((rule[n] - '0') * 13) + nn] = 1;
					
				}
				
			}
			
		}
		
		if (rule[n] == '-') negating = 1;
		
		n++;
		
	}
	
}

void makebb(char rle[RLE], int * bx, int * by) {
	
	int bbx = 0, bbxr = 0, bby = 0;
	
	int n = 0;
	
	int run;
	
	while (rle[n] != '!') {
		
		if (isdigit(rle[n])) {
			
			run *= 10;
			
			run += (rle[n] - '0');
			
		}
		
		if ((rle[n] == 'b') || (rle[n] == 'o')) {
			
			int r = (run == 0) ? 1 : run;
			
			for (int nn = 0; nn < r; nn++) {
				
				if (bbx > bbxr) {
					
					bbx++;
					
					bbxr++;
					
				} else {
					
					bbx++;
					
				}
				
			}
			
		}
		
		if (rle[n] == '$') {
			
			bbx = 0;
			
			bby++;
			
		}
		
		n++;
		
	}
	
	*bx = bbxr;
	
	*by = bby;
	
}

void makeworld(char rle[RLE], int bbx, int bby, int (* world)[bby][bbx], Speed speed) {
	
	int x = speed.period, y = speed.period;
	
	int n = 0;
	
	int run;
	
	while (rle[n] != '!') {
		
		if (isdigit(rle[n])) {
			
			run *= 10;
			
			run += (rle[n] - '0');
			
		}
		
		if (rle[n] == 'b') {
			
			int r = (run == 0) ? 1 : run;
			
			for (int nn = 0; nn < r; nn++) {
				
				(*world)[y][x] = 0;
				
				x++;
				
			}
			
		}
		
		if (rle[n] == 'o') {
			
			int r = (run == 0) ? 1 : run;
			
			for (int nn = 0; nn < r; nn++) {
				
				(*world)[y][x] = 1;
				
				x++;
				
			}
			
		}
		
		if (rle[n] == '$') {
			
			y++;
			
			x = speed.period;
			
		}
		
		n++;
		
	}
	
}

void advance(int bbx, int bby, int (* world)[bby][bbx], Conds conds) {
	
	int binary;
	
	int neigh[8][2] = {{1, 1}, {1, 0}, {1, -1}, {0, 1}, {0, -1}, {-1, 1}, {-1, 0}, {-1, -1}};
	
	int next[bby][bbx];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) next[y][x] = 0;
	
	for (int y = 0; y < bby; y++) {
		
		for (int x = 0; x < bbx; x++) {
			
			binary = 0;
			
			for (int n = 0; n < 8; n++) {
				
				binary *= 2;
				
				if ((y + neigh[n][0] < 0) || (y + neigh[n][0] >= bby) || (x + neigh[n][1] < 0) || (x + neigh[n][1] >= bbx)) continue;
				
				binary += (*world)[y][x];
				
			}
			
			if (!(*world)[y][x] && (conds.bconds[dict[binary]])) next[y][x] = 1;
			
			if ((*world)[y][x] && (conds.sconds[dict[binary]])) next[y][x] = 1;
			
		}
		
	}
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) (*world)[y][x] = next[y][x];
	
}

int getpop(int bbx, int bby, int world[bby][bbx]) {
	
	int pop = 0;
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) if (world[y][x]) pop++;
	
	return pop;
	
}

int verify(int bbx, int bby, int world[bby][bbx], Speed speed, Conds conds) {
	
	int equal = 1;
	
	int orig[bby][bbx];
	
	int iter[bby][bbx];
	
	int comp[bby][bbx];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) {
		
		orig[y][x] = world[y][x];
		
		iter[y][x] = world[y][x];
		
		comp[y][x] = 0;
		
	}
	
	for (int n = 0; n < speed.period; n++) advance(bbx, bby, &iter, conds);
	
	for (int y = speed.dy; y < bby; y++) for (int x = speed.dx; x < bbx; x++) comp[y - speed.dy][x - speed.dx] = iter[y][x];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) if (comp[y][x] != orig[y][x]) equal = 0;
	
	return equal;
	
}

void sort(char (* letters)[14]) { /* Basic selection sort */
	
	int n = 0;
	
	int current;
	
	char sorted[14] = "";
	
	for (int current = 'a'; current <= 'z'; current++) {
		
		for (int nn = 0; nn < 13; nn++) {
			
			if ((*letters)[nn] == current) {
				
				sorted[n] = current;
				
				n++;
				
			}
			
		}
		
	}
	
	for (int n = 0; n < 13; n++) (*letters)[n] = sorted[n];
	
}

void writerule(char (* rulestring)[274], Conds conds) { /* Does the opposite of rparse */
	
	int negating;
	
	int positive;
	
	int n = 0;
	
	int vals[9] = {1, 2, 6, 10, 13, 10, 6, 2, 1};
	
	char letters[14] = "cekainyqjrtwz";
	
	char used[14] = "";
	
	(*rulestring)[n] = 'B';
	
	n++;
	
	for (int c = 0; c < 9; c++) {
		
		positive = 0;
		
		for (int m = 0; m < vals[c]; m++) if (conds.bconds[(c * 13) + m]) positive++;
		
		if (!positive) continue;
		
		(*rulestring)[n] = c + '0';
		
		n++;
		
		if ((vals[c] - positive) < (vals[c] / 2)) negating = 1;
		
		int nn = 0;
		
		if (negating) {
			
			(*rulestring)[n] = '-';
			
			n++;
			
			for (int m = 0; m < vals[c]; m++) {
				
				if (!(conds.bconds[(c * 13) + m])) {
					
					used[nn] = letters[m];
					
					nn++;
					
				}
				
			}
			
			sort(&used);
			
			nn = 0;
			
			while (used[nn]) {
				
				(*rulestring)[n] = used[nn];
				
				nn++;
				
				n++;
				
			}
			
		} else {
			
			for (int m = 0; m < vals[c]; m++) {
				
				if ((conds.bconds[(c * 13) + m])) {
					
					used[nn] = letters[m];
					
					nn++;
					
				}
				
			}
			
			sort(&used);
			
			nn = 0;
			
			while (used[nn]) {
				
				(*rulestring)[n] = used[nn];
				
				nn++;
				
				n++;
				
			}
			
		}
		
	}
	
	(*rulestring)[n] = '/';
	
	n++;
	
	(*rulestring)[n] = 'S';
	
	n++;
	
	for (int c = 0; c < 9; c++) {
		
		positive = 0;
		
		for (int m = 0; m < vals[c]; m++) if (conds.sconds[(c * 13) + m]) positive++;
		
		if (!positive) continue;
		
		(*rulestring)[n] = c + '0';
		
		n++;
		
		if ((vals[c] - positive) < (vals[c] / 2)) negating = 1;
		
		int nn = 0;
		
		if (negating) {
			
			(*rulestring)[n] = '-';
			
			n++;
			
			for (int m = 0; m < vals[c]; m++) {
				
				if (!(conds.sconds[(c * 13) + m])) {
					
					used[nn] = letters[m];
					
					nn++;
					
				}
				
			}
			
			sort(&used);
			
			nn = 0;
			
			while (used[nn]) {
				
				(*rulestring)[n] = used[nn];
				
				nn++;
				
				n++;
				
			}
			
		} else {
			
			for (int m = 0; m < vals[c]; m++) {
				
				if ((conds.sconds[(c * 13) + m])) {
					
					used[nn] = letters[m];
					
					nn++;
					
				}
				
			}
			
			sort(&used);
			
			nn = 0;
			
			while (used[nn]) {
				
				(*rulestring)[n] = used[nn];
				
				nn++;
				
				n++;
				
			}
			
		}
		
	}
	
}

void getmaxrule(int bbx, int bby, int world[bby][bbx], Speed speed, Conds (* conds)) {
	
	for (int nn = 0; nn < 117; nn++) {
		
		(*conds).bconds[nn] = 0;
		
		(*conds).sconds[nn] = 0;
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		(*conds).bconds[n] = 1;
		
		if (!(verify(bbx, bby, world, speed, *conds))) (*conds).bconds[n] = 0;
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		(*conds).sconds[n] = 1;
		
		if (!(verify(bbx, bby, world, speed, *conds))) (*conds).sconds[n] = 0;
		
	}
	
}

void getminrule(int bbx, int bby, int world[bby][bbx], Speed speed, Conds (* conds)) {
	
	for (int nn = 0; nn < 117; nn++) {
		
		(*conds).bconds[nn] = 0;
		
		(*conds).sconds[nn] = 0;
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		(*conds).bconds[n] = 0;
		
		if (!(verify(bbx, bby, world, speed, *conds))) (*conds).bconds[n] = 1;
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		(*conds).sconds[n] = 0;
		
		if (!(verify(bbx, bby, world, speed, *conds))) (*conds).sconds[n] = 1;
		
	}
	
}

int getminpop(int bbx, int bby, int world[bby][bbx], int (* target)[bby][bbx], Speed speed, Conds conds) {
	
	int pop = getpop(bbx, bby, world);
	
	int min[bby][bbx];
	
	int iter[bby][bbx];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) {
		
		min[y][x] = world[y][x];
		
		iter[y][x] = world[y][x];
		
	}
	
	for (int n = 0; n < speed.period; n++) {
		
		if (getpop(bbx, bby, iter) < pop) {
			
			pop = getpop(bbx, bby, iter);
			
			for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) (*target)[y][x] = iter[y][x];
			
		}
		
		advance(bbx, bby, &iter, conds);
		
	}
	
	return pop;
	
}

int sgmp(int bbx, int bby, int world[bby][bbx], Speed speed, Conds conds) { /* Silently get minpop */
	
	int pop = getpop(bbx, bby, world);
	
	int iter[bby][bbx];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) {
		
		iter[y][x] = world[y][x];
		
	}
	
	for (int n = 0; n < speed.period; n++) {
		
		if (getpop(bbx, bby, iter) < pop) {
			
			pop = getpop(bbx, bby, iter);
			
		}
		
		advance(bbx, bby, &iter, conds);
		
	}
	
	return pop;
	
}

int power(int a, int b) {
	
	int x = 1;
	
	for (int n = 0; n < b; n++) x *= a;
	
	return x;
	
}

int calcpow(int n) {
	
	int nn;
	
	for (nn = 0; n < power(10, nn); nn++);
	
	return nn;
	
}

void makerle(int bbx, int bby, int world[bby][bbx], char (* rle)[RLE]) {
	
	int n = 0;
	
	int run = 1;
	
	int lastdigit = -1;
	
	for (int nn = 0; nn < RLE; nn++) (*rle)[nn] = 0;
	
	for (int y = 0; y < bby; y++) {
		
		for (int x = 0; x < bbx; x++) {
			
			if (world[y][x] == lastdigit) {
				
				run++;
				
			} else {
				
				if (run == 1) {
					
					if (world[y][x]) {
						
						(*rle)[n] = 'o';
						
					} else {
						
						(*rle)[n] = 'b';
						
					}
					
					n++;
					
				} else {
					
					for (int nn = calcpow(run); nn > 0; nn--) {
						
						(*rle)[n] = '0' + ((run % power(10, nn)) / power(10, (nn - 1)));
						
						n++;
						
					}
					
					if (world[y][x]) {
						
						(*rle)[n] = 'o';
						
					} else {
						
						(*rle)[n] = 'b';
						
					}
					
					n++;
					
				}
				
			}
			
		}
		
		(*rle)[n] = '$';
		
		n++;
		
	}
	
	(*rle)[n - 1] = '!';
	
}

int abovelower(Conds test, Conds lower) {
	
	int above = 1;
	
	for (int n = 0; n < 117; n++) {
		
		if (((test.bconds)[n] == 0) && ((lower.bconds)[n] == 1)) {
			
			above = 0;
			
			return above;
			
		}
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		if (((test.sconds)[n] == 0) && ((lower.sconds)[n] == 1)) {
			
			above = 0;
			
			return above;
			
		}
		
	}
	
	return above;
	
}

int belowupper(Conds test, Conds upper) {
	
	int below = 1;
	
	for (int n = 0; n < 117; n++) {
		
		if (((test.bconds)[n] == 1) && ((upper.bconds)[n] == 0)) {
			
			below = 0;
			
			return below;
			
		}
		
	}
	
	for (int n = 0; n < 117; n++) {
		
		if (((test.sconds)[n] == 1) && ((upper.sconds)[n] == 0)) {
			
			below = 0;
			
			return below;
			
		}
		
	}
	
	return below;
	
}

int getglidid(int processed) { /* Returns an ID from a line number */
	
	int commacount = 0;
	
	int id = 1; /* Raw ID */
	
	FILE * gliders;
	
	gliders = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "r");
	
	while (commacount != (processed - 1)) {
		
		if (getc(gliders) == ',') commacount++;
		
	}
	
	char c;
	
	while ((c = getc(gliders)) != '!'); /* Scans until the end of the RLE */
	
	getc(gliders); /* Gets ' ' */
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ',') {
		
		id *= 10;
		
		id += (c - '0');
		
	}
	
	return id;
	
}

int processid(int id, int maxid) { /* Looks for a specific ID */
	
	int n = 1;
	
	FILE * gliders;
	
	gliders = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "r");
	
	for (int n = 1; ; n++) {
		
		if (getglidid(n) == id) return n;
		
		if (n > maxid) break;
		
	}
	
	return -1;
	
}

void getdata(int processed, Glider * glider) {
	
	int commacount = 0;
	
	FILE * gliders;
	
	gliders = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "r");
	
	while (commacount != (processed - 1)) {
		
		if (getc(gliders) == ',') commacount++;
		
	}
	
	getc(gliders); /* Gets '\n' */
	
	char c;
	
	(*glider).dx = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).dx *= 10;
		
		(*glider).dx += (c - '0');
		
	}
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	(*glider).dy = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).dy *= 10;
		
		(*glider).dy += (c - '0');
		
	}
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	(*glider).period = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).period *= 10;
		
		(*glider).period += (c - '0');
		
	}
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	(*glider).minpop = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).minpop *= 10;
		
		(*glider).minpop += (c - '0');
		
	}
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	for (int n = 0; n < 274; n++) (*glider).minrule[n] = 0;
	
	int nn = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).minrule[nn] = c;
		
		nn++;
		
	}
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	for (int n = 0; n < 274; n++) (*glider).maxrule[n] = 0;
	
	nn = 0;
	
	while ((c = getc(gliders)) != ' ') {
		
		(*glider).maxrule[nn] = c;
		
		nn++;
		
	}
	
	fclose(gliders);
	
}

int getid(void) {
	
	int id = 0;
	
	FILE * num;
	
	num = fopen("/Users/mamaral/Sites/gliders/ngliders.txt", "r");
	
	char c;
	
	while ((c = getc(num)) != EOF) {
		
		id *= 10;
		
		id += (c - '0');
		
	}
	
	fclose(num);
	
	return id;
	
}

void putid(void) {
	
	int id = getid();
	
	id++;
	
	FILE * num;
	
	num = fopen("/Users/mamaral/Sites/gliders/ngliders.txt", "w");
	
	for (int n = calcpow(id); n > 0; n--) {
		
		putc(('0' + ((id % power(10, n)) / power(10, n - 1))), num);
		
	}
	
	fclose(num);
	
}

void transpose(int processed, Speed speed, int (* world)[400 + (speed.period * 2)][400 + (speed.period * 2)]) { /* Get a glider RLE and put it in a world */
	
	int commacount = 0;
	
	int bbx = 400 + (speed.period * 2);
	
	int bby = bbx;
	
	char rle[RLE] = "";
	
	FILE * gliders;
	
	gliders = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "r");
	
	while (commacount != (processed - 1)) {
		
		if (getc(gliders) == ',') commacount++;
		
	}
	
	getc(gliders); /* Gets '\n' */
	
	char c;
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	while ((c = getc(gliders)) != ' ');
	
	getc(gliders); /* Gets ':' */
	
	getc(gliders); /* Gets ' ' */
	
	int nn;
	
	while ((c = getc(gliders)) != ' ') {
		
		rle[nn] = c;
		
	}
	
	makeworld(rle, bbx, bby, world, speed);
	
}

void getredundantgliders(int (* list)[65536] /* Assume a maximum of 65,536 gliders made redundant */, int maxid, int bbex, int bbey, int exworld[bbey][bbex], Speed speed, Rulespace rulespace) { /* Gets the IDs of all redundant gliders */
	
	int n = 0;
	
	int processed;
	
	int bbx = 400 + (2 * speed.period);
	
	int bby = bbx;
	
	int world[bby][bbx];
	
	int oldmp = 0;
	
	int newmp = 0;
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) world[y][x] = 0;
	
	char minrule[274] = "";
	
	char maxrule[274] = "";
	
	Glider current;
	
	Conds conds;
	
	Conds oldlower;
	
	Conds oldupper;
	
	Conds newlower;
	
	Conds newupper;
	
	rparse(rulespace.rule, &conds);
	
	for (int nn = 0; nn < 65536; nn++) (*list)[nn] = 0;
	
	for (int nn = 1; nn <= maxid; nn++) {
		
		processed = processid(nn, maxid);
		
		if (processed == -1) continue; /* Skips deleted ships */
		
		getdata(processed, &current);
		
		if ((current.dx != speed.dx) || (current.dy != speed.dy) || (current.period != speed.period)) continue;
		
		transpose(processed, speed, &world);
		
		oldmp = sgmp(bbx, bby, world, speed, conds);
		
		newmp = sgmp(bbex, bbey, exworld, speed, conds);
		
		getminrule(bbex, bbey, world, speed, &newlower);
		
		getmaxrule(bbex, bbey, world, speed, &newlower);
		
		getminrule(bbx, bby, world, speed, &oldlower);
		
		getmaxrule(bbx, bby, world, speed, &oldupper);
		
		if (newmp > oldmp) continue; /* Some gliders may be made redundant but this one won't since it's smaller */
		
		if (abovelower(oldlower, newlower) && belowupper(oldupper, newupper)) { /* The new glider supports every rule the old glider does */
			
			(*list)[n] = nn; /* Found a redundant glider; add to list */
			
		}
		
	}
	
}

int isnotable(int maxid, int bbex, int bbey, int exworld[bbey][bbex], Speed speed, Rulespace rulespace) { /* Preliminary check */
	
	/* Logical values */
	
	// int docrule = 0;
	
	int docspeed = 0;
	
	int versatile = 0;
	
	int optimal = 0;
	
	/* ---------------- */
	
	int processed;
	
	int bbx = 400 + (2 * speed.period);
	
	int bby = bbx;
	
	int oldmp = 0;
	
	int newmp = 0;
	
	int world[bby][bbx];
	
	Glider current;
	
	Conds conds;
	
	Conds oldlower;
	
	Conds oldupper;
	
	Conds medrule;
	
	Conds newlower;
	
	Conds newupper;
	
	rparse(rulespace.rule, &medrule);
	
	for (int nn = 1; nn <= maxid; nn++) {
		
		processed = processid(nn, maxid);
		
		if (processed == -1) continue; /* Skips deleted ships */
		
		transpose(processed, speed, &world);
		
		getminrule(bbex, bbey, exworld, speed, &newlower);
		
		getmaxrule(bbex, bbey, exworld, speed, &newlower);
		
		getminrule(bbx, bby, world, speed, &oldlower);
		
		getmaxrule(bbx, bby, world, speed, &oldupper);
		
		if (!(abovelower(medrule, oldlower) && belowupper(medrule, oldupper))) continue; /* Skips spaceships alien to the selected rule */
		
		if (abovelower(newlower, oldlower) && belowupper(newupper, oldupper)) { /* The new spaceship works in a strict subset of the old one's rulespace */
			
			getdata(processed, &current);
			
			if ((current.dx == speed.dx) && (current.dy == speed.dy) && (current.period == speed.period)) {
				
				docspeed = 1;
				
				oldmp = sgmp(bbx, bby, world, speed, conds);
				
				newmp = sgmp(bbex, bbey, exworld, speed, conds);
				
				if (newmp < oldmp) {
					
					return 1;
					
				} else {
					
					return 0;
					
				}
				
			}
			
		} else { /* The new spaceship works in a different ruleset */
			
			versatile = 1;
			
			return 1;
			
		}
		
	}
	
	return 1;
	
}

int in(int id, int list[65536]) {
	
	for (int n = 0; n < 65536; n++) {
		
		if (!(list[n])) break;
		
		if (list[n] == id) return 1;
		
	}
	
	return 0;
	
}

void move(int (* list)[65536], int maxid) {
	
	int n = 0;
	
	while ((*list)[n]) {
		
		(*list)[n] = processid((*list)[n], maxid);
		
	}
	
	FILE * original;
	
	FILE * buffer;
	
	original = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "r");
	
	buffer = fopen("/Users/mamaral/Sites/gliders/buffer.json", "w");
	
	int commacount = 0;
	
	char c;
	
	while ((c = getc(original))) {
		
		if (!(in((commacount + 1), *list))) {
			
			putc(c, buffer);
			
		}
		
	}
	
	fclose(original);
	
	fclose(buffer);
	
}

void compose(char (* entry)[200000], int minpop, int id, Speed speed, Rulespace rulespace, char rle[RLE]) {
	
	for (int n = 0; n < 200000; n++) (*entry)[n] = 0;
	
	int n = 0;
	
	for (int nn = calcpow(speed.dx); nn > 0; nn--) {
		
		(*entry)[n] = '0' + ((speed.dx % power(10, nn)) / power(10, (nn - 1)));
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	for (int nn = calcpow(speed.dy); nn > 0; nn--) {
		
		(*entry)[n] = '0' + ((speed.dy % power(10, nn)) / power(10, (nn - 1)));
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	for (int nn = calcpow(speed.period); nn > 0; nn--) {
		
		(*entry)[n] = '0' + ((speed.period % power(10, nn)) / power(10, (nn - 1)));
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	for (int nn = calcpow(minpop); nn > 0; nn--) {
		
		(*entry)[n] = '0' + ((minpop % power(10, nn)) / power(10, (nn - 1)));
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	int nn = 0;
	
	while (rulespace.minrule[nn]) {
		
		(*entry)[n] = rulespace.minrule[nn];
		
		nn++;
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	nn = 0;
	
	while (rulespace.maxrule[nn]) {
		
		(*entry)[n] = rulespace.maxrule[nn];
		
		nn++;
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	nn = 0;
	
	while (rle[nn]) {
		
		(*entry)[n] = rle[nn];
		
		nn++;
		
		n++;
		
	}
	
	(*entry)[n] = ' '; n++;
	
	(*entry)[n] = ':'; n++;
	
	(*entry)[n] = ' '; n++;
	
	for (int nn = calcpow(id); nn > 0; nn--) {
		
		(*entry)[n] = '0' + ((id % power(10, nn)) / power(10, (nn - 1)));
		
		n++;
		
	}
	
	(*entry)[n] = ','; n++;
	
	(*entry)[n] = '\n';
	
}

void write(char entry[200000]) {
	
	int n = 0;
	
	FILE * gliders;
	
	gliders = fopen("/Users/mamaral/Sites/gliders/GlidINT.json", "a");
	
	while (entry[n]) {
		
		putc(entry[n], gliders);
		
		n++;
		
	}
	
	fclose(gliders);
	
}

int main(int argc, char * argv[]) {
	
	int bx = 0, by = 0;
	
	int bbx, bby;
	
	int maxid = getid();
	
	int minpop;
	
	int list[65536] = {0};
	
	char rle[RLE] = {0};
	
	char entry[200000] = "";
	
	if (argc == 1) {
		
		printf("Usage: commit (filepath)\n");
		
		return 0;
		
	}
	
	Speed speed;
	
	Rulespace rulespace;
	
	Conds conds;
	
	Conds minc;
	
	Conds maxc;
	
	for (int cn = 0; cn < 117; cn++) {
		
		minc.bconds[cn] = conds.bconds[cn];
		
		minc.sconds[cn] = conds.sconds[cn];
		
		maxc.bconds[cn] = conds.bconds[cn];
		
		maxc.sconds[cn] = conds.sconds[cn];
		
	}
	
	open(argv[1], &speed, &rulespace, &rle);
	
	makebb(rle, &bx, &by);
	
	bbx = bx + (2 * speed.period);
	
	bby = by + (2 * speed.period);
	
	int world[bby][bbx];
	
	for (int y = 0; y < bby; y++) for (int x = 0; x < bbx; x++) world[y][x] = 0;
	
	makeworld(rle, bbx, bby, &world, speed);
	
	if (!verify(bbx, bby, world, speed, conds)) return 0; /* Removes faulty spaceships */
	
	if (!getpop(bbx, bby, world)) return 0; /* Filters zero-population ships */
	
	if (!isnotable(maxid, bbx, bby, world, speed, rulespace)) return 0; /* Filters duplicates or completely suboptimal ships */
	
	getredundantgliders(&list, maxid, bbx, bby, world, speed, rulespace);
	
	move(&list, maxid);
	
	system("/Users/mamaral/Sites/gliders/ mv buffer.json GlidINT.json");
	
	getminrule(bbx, bby, world, speed, &minc);
	
	getmaxrule(bbx, bby, world, speed, &maxc);
	
	writerule(&(rulespace.minrule), minc);
	
	writerule(&(rulespace.maxrule), maxc);
	
	minpop = getminpop(bbx, bby, world, &world, speed, conds); /* Assigns the ship's minpop to "minpop" and shifts the ship to the minpop phase */
	
	makerle(bbx, bby, world, &rle);
	
	maxid++;
	
	compose(&entry, minpop, maxid, speed, rulespace, rle);
	
	write(entry);
	
	/* Format: dx : dy : period : minpop : minrule : maxrule : rle : entrynum, */
	
}
It requires a header file called "dict.h", available here.

Fixes of any size are welcome.
Edit (August 11th, 2026, 7:15 PM): I wrote a searcher for the database in Java:

Code: Select all

import java.io.*;

// import java.util.Scanner;

class Parser {
	
	public String rulestring;
	
	Parser() {
		
		this.rulestring = "";
		
	}
	
	void parse(String arg) {
		
		this.rulestring = arg;
		
	}
	
}

class Funcs {
	
	private String rulestring;
	
	public int[] bconds = new int[117], sconds = new int[117];
	
	private int[] getminrule_bconds = new int[117], getminrule_sconds = new int[117], getmaxrule_bconds = new int[117], getmaxrule_sconds = new int[117];
	
	String gliders = "/path/to/GlidINT/directory";
	
	String idpath = "/path/to/ngliders/directory";
	
	FileInputStream nextg;
	
	Funcs(String rulestring) throws FileNotFoundException {
		
		this.rulestring = rulestring;
		
		nextg = new FileInputStream(gliders + "GlidINT.txt");
		
	}
	
	void rparse() {
		
		int lastdigit = -1;
		
		char c;
		
		boolean birth = false, survival = false;
		
		boolean negating = false;
		
		String configs = "cekainyqjrtwz";
		
		for (int n = 0; n < this.rulestring.length(); n++) {
			
			c = this.rulestring.charAt(n);
			
			if (c == '/') continue;
			
			if (Character.isDigit(c)) {
				
				lastdigit = c - '0';
				
				negating = false;
				
				for (int nn = 0; nn < 13; nn++) {
					
					if (birth) {
						
						this.bconds[(lastdigit * 13) + nn] = 2;
						
					}
					
					if (survival) {
						
						this.sconds[(lastdigit * 13) + nn] = 2;
						
					}
					
				}
				
			}
			
			if (c == 'B') {
				
				lastdigit = -1;
				
				birth = true;
				
				survival = false;
				
				negating = false;
				
			} else if (c == 'S') {
				
				lastdigit = -1;
				
				birth = false;
				
				survival = true;
				
				negating = false;
				
			} else if (Character.isLetter(c)) {
				
				if (birth) {
					
					if (negating) {
						
						this.bconds[(lastdigit * 13) + configs.indexOf(c)] = 0;
						
					} else {
						
						for (int nn = 0; nn < 13; nn++) {
							
							if (this.bconds[(lastdigit * 13) + nn] == 2) {
								
								this.bconds[(lastdigit * 13) + nn] = 0;
								
							}
							
							if (nn == configs.indexOf(c)) {
								
								this.bconds[(lastdigit * 13) + nn] = 1;
								
							}
							
						}
						
					}
					
				}
				
				if (survival) {
					
					if (negating) {
						
						this.sconds[(lastdigit * 13) + configs.indexOf(c)] = 0;
						
					} else {
						
						for (int nn = 0; nn < 13; nn++) {
							
							if (nn == configs.indexOf(c)) {
								
								this.sconds[(lastdigit * 13) + nn] = 1;
								
							} else if (this.sconds[(lastdigit * 13) + nn] == 2) {
								
								this.sconds[(lastdigit * 13) + nn] = 0;
								
							}
							
						}
						
					}
					
				}
				
			}
			
			if (c == '-') {
				
				negating = true;
				
			}
			
		}
		
	}
	
	int[][] rparse(String rulestring) {
		
		int lastdigit = -1;
		
		int[] bconds = new int[117];
		
		int[] sconds = new int[117];
		
		char c;
		
		boolean birth = false, survival = false;
		
		boolean negating = false;
		
		String configs = "cekainyqjrtwz";
		
		for (int n = 0; n < rulestring.length(); n++) {
			
			c = rulestring.charAt(n);
			
			if (c == '/') continue;
			
			if (Character.isDigit(c)) {
				
				lastdigit = c - '0';
				
				negating = false;
				
				for (int nn = 0; nn < 13; nn++) {
					
					if (birth) {
						
						bconds[(lastdigit * 13) + nn] = 2;
						
					}
					
					if (survival) {
						
						sconds[(lastdigit * 13) + nn] = 2;
						
					}
					
				}
				
			}
			
			if (c == 'B') {
				
				lastdigit = -1;
				
				birth = true;
				
				survival = false;
				
				negating = false;
				
			} else if (c == 'S') {
				
				lastdigit = -1;
				
				birth = false;
				
				survival = true;
				
				negating = false;
				
			} else if (Character.isLetter(c)) {
				
				if (birth) {
					
					if (negating) {
						
						bconds[(lastdigit * 13) + configs.indexOf(c)] = 0;
						
					} else {
						
						for (int nn = 0; nn < 13; nn++) {
							
							if (bconds[(lastdigit * 13) + nn] == 2) {
								
								bconds[(lastdigit * 13) + nn] = 0;
								
							}
							
							if (nn == configs.indexOf(c)) {
								
								bconds[(lastdigit * 13) + nn] = 1;
								
							}
							
						}
						
					}
					
				}
				
				if (survival) {
					
					if (negating) {
						
						sconds[(lastdigit * 13) + configs.indexOf(c)] = 0;
						
					} else {
						
						for (int nn = 0; nn < 13; nn++) {
							
							if (nn == configs.indexOf(c)) {
								
								sconds[(lastdigit * 13) + nn] = 1;
								
							} else if (sconds[(lastdigit * 13) + nn] == 2) {
								
								sconds[(lastdigit * 13) + nn] = 0;
								
							}
							
						}
						
					}
					
				}
				
			}
			
			if (c == '-') {
				
				negating = true;
				
			}
			
		}
		
		int[][] conds = {bconds, sconds};
		
		return conds;
		
	}
	
	void parse() {
		
		rparse();
		
	}
	
	// File functions
	
	int getcurrentid() throws FileNotFoundException, IOException {
		
		int c;
		
		int id = 0;
		
		FileInputStream file = new FileInputStream(idpath + "ngliders.txt");
		
		c = file.read();
		
		while (c != -1) {
			
			id *= 10;
			
			id += (c - '0');
			
			c = file.read();
			
		}
		
		file.close();
		
		return id;
		
	}
	
	int eparse_dx, eparse_dy, eparse_period, eparse_minpop, eparse_id;
	
	String eparse_minrule = "", eparse_maxrule = "", eparse_rle = "";
	
	void eparse() throws FileNotFoundException, IOException {
		
		int c;
		
		int linecount = 0;
		
		this.eparse_dx = 0;
		
		this.eparse_dy = 0;
		
		this.eparse_period = 0;
		
		this.eparse_minpop = 0;
		
		this.eparse_id = 0;
		
		this.eparse_minrule = "";
		
		this.eparse_maxrule = "";
		
		this.eparse_rle = "";
		
		// FileInputStream file = new FileInputStream(gliders + "GlidINT.txt");
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_dy *= 10;
			
			this.eparse_dy += (c - '0');
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_dx *= 10;
			
			this.eparse_dx += (c - '0');
			
			c = this.nextg.read();
			
		}
		
		// System.out.println(this.eparse_dx);
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_period *= 10;
			
			this.eparse_period += (c - '0');
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_minpop *= 10;
			
			this.eparse_minpop += (c - '0');
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_minrule += (char) (c);
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_maxrule += (char) (c);
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ' ') {
			
			this.eparse_rle += (char) (c);
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read(); // Gets ':'
		
		c = this.nextg.read(); // Gets ' '
		
		c = this.nextg.read();
		
		while (c != ',') {
			
			this.eparse_id *= 10;
			
			this.eparse_id += (c - '0');
			
			c = this.nextg.read();
			
		}
		
		c = this.nextg.read();
		
		// this.nextg.close();
		
		// System.out.println(this.eparse_dy + ":" + this.eparse_dx + ":" + this.eparse_period + ":" + this.eparse_minrule + ":" + this.eparse_maxrule + ":" + this.eparse_rle);
		
	}
	
	final int ABOVE = 0;
	
	final int BELOW = 0;
	
	final int EQUAL = 1; // The current rule is equal to the one being tested against
	
	final int OTHER = 2; // The current rule is not inside the min/max range
	
	int abovelower(int[] bconds, int[] sconds, int[] lbconds, int[] lsconds) {
		
		int tag = 0;
		
		int status = EQUAL;
		
		int[] limits = {1, 2, 6, 10, 13, 10, 6, 2, 1};
		
		for (int n = 0; n < 117; n++) {
			
			if ((n % 13) >= limits[n / 13]) continue;
			
			if ((bconds[n] != 0) && (lbconds[n] == 0) && (status == EQUAL)) status = ABOVE;
			
			if ((bconds[n] == 0) && (lbconds[n] != 0) && (status != OTHER)) status = OTHER;
			
		}
		
		for (int n = 0; n < 117; n++) {
			
			if ((n % 13) >= limits[n / 13]) continue;
			
			if ((sconds[n] != 0) && (lsconds[n] == 0) && (status == EQUAL)) status = ABOVE;
			
			if ((sconds[n] == 0) && (lsconds[n] != 0) && (status != OTHER)) status = OTHER;
			
		}
		
		return status;
		
	}
	
	int belowupper(int[] bconds, int[] sconds, int[] ubconds, int[] usconds) {
		
		int tag = 0;
		
		int status = EQUAL;
		
		int[] limits = {1, 2, 6, 10, 13, 10, 6, 2, 1};
		
		for (int n = 0; n < 117; n++) {
			
			if ((n % 13) >= limits[n / 13]) continue;
			
			if ((bconds[n] == 0) && (ubconds[n] != 0) && (status == EQUAL)) status = BELOW;
			
			if ((bconds[n] != 0) && (ubconds[n] == 0)) status = OTHER;
			
		}
		
		for (int n = 0; n < 117; n++) {
			
			if ((n % 13) >= limits[n / 13]) continue;
			
			if ((sconds[n] == 0) && (usconds[n] != 0) && (status == EQUAL)) status = BELOW;
			
			if ((sconds[n] != 0) && (usconds[n] == 0)) status = OTHER;
			
		}
		
		return status;
		
	}
	
	int countlines() throws FileNotFoundException, IOException {
		
		int lines = 0;
		
		int c;
		
		FileInputStream file = new FileInputStream(gliders + "/GlidINT.txt");
		
		c = file.read();
		
		while (c != -1) {
			
			if (c == '\n') lines++;
			
			c = file.read();
			
		}
		
		file.close();
		
		return lines;
		
	}
	
	void searchdb() throws FileNotFoundException, IOException {
		
		// int maxid = getcurrentid();
		
		int lines = countlines();
		
		// int processed;
		
		int[] lbconds = new int[117], lsconds = new int[117];
		
		int[] ubconds = new int[117], usconds = new int[117];
		
		int[][] lconds = new int[2][117];
		
		int[][] uconds = new int[2][117];
		
		for (int n = 1; n < (lines + 1); n++) {
			
			// processed = process(n);
				
			// if (processed == -1) continue;
			
			// System.out.println("Processing...");
			
			eparse();
			
			lconds = rparse(this.eparse_minrule);
			
			uconds = rparse(this.eparse_maxrule);
			
			ubconds = uconds[0];
			
			usconds = uconds[1];
			
			lbconds = lconds[0];
			
			lsconds = lconds[1];
			
			if ((abovelower(this.bconds, this.sconds, lbconds, lsconds) == OTHER) || (belowupper(this.bconds, this.sconds, ubconds, usconds) == OTHER)) continue;
			
			System.out.println("#C GlidINT " + this.eparse_id);
			
			System.out.println("#C Works from " + this.eparse_minrule + " to " + this.eparse_maxrule);
			
			System.out.println("#C Systematic name: " + this.eparse_minpop + "P" + this.eparse_period + "H" + this.eparse_dy + "V" + this.eparse_dx);
			
			System.out.println("x = 0, y = 0, rule = " + this.rulestring);
			
			System.out.println(this.eparse_rle);
			
		}
		
	}
	
}

class SearchDB {
	
	public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException {
		
		if (args.length == 0) {
			
			System.out.println("Usage: java SearchDB <rulestring>");
			
			return;
			
		}
		
		var parser = new Parser();
		
		parser.parse(args[0]);
		
		var funcs = new Funcs(parser.rulestring);
		
		System.out.println("Updating local GlidINT database copy...");
		
		Process process1 = new ProcessBuilder("curl", "-o", (funcs.gliders + "GlidINT.txt"), "https://sim.zpsou.eu/interna242/~mamaral/gliders/GlidINT.txt").inheritIO().start();
		
		Process process2 = new ProcessBuilder("curl", "-o", (funcs.idpath + "ngliders.txt"), "https://sim.zpsou.eu/interna242/~mamaral/gliders/ngliders.txt").inheritIO().start();
		
		process1.waitFor();
		
		process2.waitFor();
		
		funcs.parse();
		
		funcs.searchdb();
		
	}
	
}
To use it, make a file called SearchDB.java, then edit the "gliders" and "idpath" variables to the directory where you want "GlidINT.txt" (the database itself) and "ngliders.txt" (the next glider ID to be used) to be saved.

Then, run

Code: Select all

$ javac SearchDB.java
in the directory where you saved the SearchDB file.

After that, run

Code: Select all

$ java SearchDB <rulestring>
where "rulestring" is the rulestring of the rule whose gliders you want to search for.

The output should look something like this:

Code: Select all

$ java SearchDB B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak
Updating local GlidINT database copy...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100     2  100     2    0     0      7      0 --:--:-- --:--:-- --:--:--     7
100 20334  100 20334    0     0  47620      0 --:--:-- --:--:-- --:--:-- 47509
#C GlidINT 7
#C Works from B3-ry4acenqt5eir6acn/S2-a3-a4nq5aknr6cei to B3-ry4acenqt5eir6-ek8/S2-a3-a4cnq5-ijqy6-ak
#C Systematic name: 109P5H2V1
x = 0, y = 0, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak
2bo$o3bo$2o4b2o$o2b4o$2b2obo$4b2o$4bobo6bo$6bob2obob2o$6bo6bo$10b2obo$8b2o3bo$10b5o$10bo2bo2b2o$12b5o$17bo$18bo$16b3o$19b2o$14bo5bo$14b2o2bob2o$14bo3b2o2bo$16b3o3b3o$21bo$21bo3bo$21b3o$23bo$23b2o$24bo6bobo$26b3o4bo$25b2o3bob2o$23bo5bob2o$23bob2o3bo$24b3ob2o$25b3o!
#C GlidINT 8
#C Works from B3aijq4a/S2eik3ijnr to B2cin345-a67e8/S2-a3-a4-akw5-qy6-k78
#C Systematic name: 8P4H2V0
x = 0, y = 0, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak
bo$3bo$3bo$o2bo$b3o!
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

GlidINT now has an attribution system. To use it, here is a Curl-dependent Python script for uploading an attribution to the database (you need to know the GlidINT ID of the spaceship whose attribution you intend to upload):

Code: Select all

from random import randint

from subprocess import run

ident = int(input("Spaceship ID: "))

name = input("Spaceship name: ")

person = input("Discoverer: ")

prog = input("Program used: ")

yearstr = input("Discovery year (hit Enter for unknown): ")

monthstr = ""

daystr = ""

year = 0

month = 0

day = 0

maxdays = [31, 00, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

if yearstr != "":
	
	year = int(yearstr)
	
	monthstr = input("Discovery month (hit Enter for unknown): ")
	
	if monthstr != "":
		
		month = int(monthstr)
		
		daystr = input("Discovery day (hit Enter for unknown): ")
		
		if daystr == "":
			
			day = 0
			
		else:
			
			day = int(daystr)
			
	else:
		
		month = 0
		
else:
	
	year = 0
	
if ident <= 0:
	
	raise ValueError("Nonexistent spaceship ID")
	
if month > 12 or month < 0 or day < 0:
	
	raise ValueError("Invalid date")
	
if month == 2:
	
	if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
		
		if day > 29:
			
			raise ValueError("Invalid date")
			
	else:
		
		if day > 28:
			
			raise ValueError("Invalid date")
			
else:
	
	if (day > maxdays[month]):
		
		raise ValueError("Invalid date")
		
r = randint(0, 100000000000000)

path = "/Users/YOUR USERNAME HERE/tmp"

with open(f"{path}/{r}.attr", "w") as file:
	
	file.write(f"{ident}:{name}:{person}:{prog}:{year}:{month}:{day},\n")
	
run(f"/usr/local/bin/curl -T {path}/{r}.attr https://sim.zpsou.eu/interna242/~mamaral/gliders/uncommitted/{r}.attr", shell = True)
In order to find the ID of the spaceship whose attribution you want to submit, use the database searcher included in the last post.

Spaceship attributions can be overwritten if inaccuracies are present.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
LaundryPizza03
Posts: 2651
Joined: December 15th, 2017, 12:05 am
Location: Unidentified location "https://en.wikipedia.org/wiki/Texas"

Re: INT version of gliderdb

Post by LaundryPizza03 »

The new link is dead as well. Why not host on a private website, like speedydelete's

I'd suggest now scraping Catagolue (via textcensus) for all spaceship speeds that have occurred in results in any of the rules that have been apgsearched. Also, there is Sapin (2010) on finding novel INT guns.

EDIT: Speaking of which, his gun collection seems to be lost to time. Do you own a copy? It might help to convert it to a modern format as well.

EDIT: The complete list, plus alternative reconstructions and reductions. The first 100 entries are the same as on the article.

Code: Select all

5P1H1V0 B1e3a/S2a4ar - B1e2-a3-i45678/S0123-a45678 2o$2o$o! #Speculative correction (the given patern, 2o2$o$bo! moving down, is impossible in INT)
6P1H1V0 B1e4w/S1e - B1e2-ae345678/S012-k345678 b2o$o2bo$o2bo!
6P1H1V0 B1e6a/S1e2a3r - B1e2-a3-in45678/S012-e34-i5678 3o$obo$o!
7P1H1V0 B2a3r4nz/S - B2-ci3-n45-e678/S1c2-i345678 obo2$3o2$2b2o! #I think this is redundant to 3P1H1V0 in B2a3r/S
6P1H1V0 B2a4a/S3j4j - B23-a45678/S012-a3-i4-w5678 2bo$b3o$2o!
4P1H1V0 B2ak3r/S - B2-ci34-y5678/S1c2345678 obo2$2o!
4P1H1V0 B2ak/S - B23-q45678/S1c2345678 o2bo2$b2o! #Also in GliderDB
4P1H1V0 B2a3i4t/S - B23-n45678/S1c2-i345678 bo2$3o!
5P1H1V0 B2a3ir/S - B2-ci345-e678/S1c2-i345678 obo2$3o!
6P1H1V0 B2ae3i/S3e - B2-c34-r5678/S01e23-in45678 obobo$b3o!
6P1H1V0 B2ae3i4t/S - B2-k34-k5678/S1e2-ik345678 2bo$o3bo$b3o! #Speculative correction (the given pattern, o3bo$b3o! moving down, is impossible in INT)
7P1H1V0 B2a3n4ir5r/S3e - B2-ce3-a45678/S02-a34-n5678 2bo$bo$3o2$2o!
4P1H1V0 B2a3i/S3e - B23-a45678/S012-a3-i45678 bo$3o!
7P2H2V0 B2a4jk/S1c2k5i - B2aci3-i4-a5678/S12-ac3-a4-r5-n6-a78 o2bo2$bo$o2bo$b2o!
5P2H2V0 B2ak3nq/S - B2-ci3-ci4-i5-r678/S1c2-i345678 3o2$2o!
6P2H2V0 B1e2ck3a4q/S1e2ae3y4a5n - B1e2-ai3-ij45-y6-k78/S12-ik3-aq45-ij67e8 b2o$2bo$o2$o$o! #Generation 1 is misprinted with a missing last row
6P2H2V0 B2a3n5r/S - B2-c3-ir4-n5678/S1c2-i345678 4o2$b2o!
6P2H2V0 B2ac4i5r/S - B2-k3-inq45678/S1c2-i345678 4o2$b2o!
3P2H2V0 B2a3n/S0 - B2-ce3-r45678/S02345678 bo2$2o!
6P2H2V0 B2a/S1c2k - B2akn3-j45678/S123-a4-q5678 o2bo$b2o$b2o!
3P2H2V0 B2ae/S - B2-ck3-jr4-k5678/S2-k345678 2bo$2o!
3P2H2V0 B2a3n/S - B2-c3-r45678/S1c2345678 o2$2o! #Also in 5S
5P2H2V0 B2ac4i5r/S - B2-k3-nq4-nt5678/S1c2-i345678 o2$b2o2$b2o!
7P2H2V0 B2ae4i/S - B2-ck3-jr4-k5678/S2-k345678 o$b2o2$b2o2$b2o! #Redundant to #21
7P2H2V0 B2a3i4i6i/S2i3i - B2-c3-an4-t5-i678/S1c2-a3-e456-i78 bo2$3o4$3o! #Redundant to a smaller ship
4P2H2V0 B2a3i/S - B2-c3-r4-n5678/S1c2-i345678 2bo2$3o!
5P2H2V0 B2a3n4i/S - B2-c3-r45678/S1c2345678 bo2$2o2$2o! #Redundant to #22
3P2H1V0 B2e3ei/S2ac - B2-ac3-a45678/S01e23-ei45678 obo$bo! #Also in 5S
4P2H1V0 B2c3a5i/S2a3e - B2-a3-i45678/S012-e3-i4-i5678 3o$bo! #Used for all the guns found by Sapin
4P2H1V0 B3ai/S1e2i3i - B2-a3-n4-t5678/S12-a3-e45678 3o$bo!
5P2H1V0 B3ai/S2a3ei6c - B2ekn345678/S123-a4-a5-i678 bo2$bo$3o!
5P2H1V0 B2c3a4t5i/S02a3e4t - B2-a3-n4-a5678/S01c23-ij45-y678 bo2$3o$bo!
6P2H1V0 B2ck3a5i/S1c2a3e - B2-a3-ijq45678/S123-ik4-i5678 o3bo2$b3o$2bo!
9P2H1V0 B2c3an5ir6i/S2a3e4r5i - B2-a3-i4-a5678/S01c2-i3-i45-n67c8 5o2$b3o$2bo!
8P2H1V0 B2c3aq4ik5i/S2a3e - B2-a3-ijr4-t5-e678/S02-i3-ik4-i5678 obo$obo2$3o$bo!
3P2H1V0 B2c3ae/S1c3e - B2-ae3-i45678/S012-ac3-i45678 bo$obo!
4P2H1V0 B3ai/S2ae3i4i - B2-ae3456-c78/S012-c3-en45678 3o$bo!
5P2H1V0 B2ce3j4i5y/S1c - B2-a3-ei45678/S01c2aen3-y45678 bo$bo$bo$obo!
8P2H1V0 B2c3a5i6c/S2a3en4a5i6ci - B2-ae3-i45678/S012-c3-ai4567 bo$obo$3o$obo!
7P2H1V0 B2c3ae4j/S2ack6c - B2-ae3-in45678/S01c23-i4-r5-ai678 o3bo$obobo$bobo!
3P2H1V0 B2ci3ay/S04t - B2-ak34-a5678/S01c23-i4-e5678 bo2$obo!
5P2H1V0 B2c3an4t5i/S2a3e5i - B2-a3-i45678/S123-ai4-r567c8 bo2$3o$bo!
4P2H1V0 B2a3e5e/S1c2i - B2-ci3-ijr45678/S1c23-y45678 bo$bo$obo!
8P2H1V0 B2ce3jk5y/S1c - B2-ak3-ei4-ikt5678/S01c2aen345678 b3o$o3bo$2bo$bobo!
5P2H1V0 B2ce3a5c/S1c2a3jn4k5j - B2-a3-ij4-r5678/S012-c3-a4-r5678 bo$b2o$obo!
3P2H1V0 B2a3e/S1c2c3e - B2-ce3-ai45678/S012-a3-i45678 bo$obo!
3P2H1V0 B2ce3ei/S2ac - B2-a34-a5678/S023-e4-t5678 obo$bo!
5P2H1V0 B2c3a5i/S2ae4ai6c - B2-a3-i45678/S0123-ai45-i678 3o$obo!
4P2H1V0 B2e3ij/S2ak - B2-a3-a45678/S01e234-ar5678 o2bo$b2o!
3P2H1V0 B2ce3e/S1c2a - B2-a3-a45-i678/S012-c3-ij45-y678 obo$bo!
3P2H1V0 B2ce3i/S1e2c - B2-a3-en4-t5678/S1e2-i345678 obo$bo!
8P2H1V0 B2c3a4t5i/S2ac3ae4a6ci - B2-ae3-in456-c78/S123-in45-i678 bo2$3o$3o$bo!
5P2H1V0 B2ck3a5i/S1c2a3e - B2-a3-ijq45678/S12-e3-ik4-i5678 3bo2$3o$bo! #Redundant to #29
6P2H1V0 B2ci3a4k5i/S2a3e - B2-a3-jqr4-t5-e678/S23-ik4-i5678 obo2$3o$bo!
6P2H1V0 B2ck3a5i/S02ak3e - B2-a3-ijq4-w5678/S01c23-ik4-i5678 o3bo2$b3o$2bo!
4P2H1V1 B2ac/S1 - B2-e3-jnr45678/S12-k345678 2bo2$b2o$o! #Also in 5S
3P3H3V0 B2ac3n/S - B2ace3-qr4-y5678/S1c2345678 o2$2o! #Also in 5S; generation 2 has a misplaced cell
3P3H3V0 B2ak3nq4i/S2i - B2-c3-eir4-y5-r678/S234-c5678 o2$b2o!
4P3H3V0 B2ak/S12a3a - B2-c3-ajqr4-n5678/S1234-aqr5678 o2bo2$b2o!
5P3H3V0 B2a4nz5e/S - B2-ci3-inr4-t5678/S1c2-i345678 3o2$2b2o!
3P3H1V0 B2e3ei5i/S12a - B2-ac3-n4-t5678/S12akn34-i5678 obo$bo!
3P3H1V0 B2ci3ai4t/S03i - B2-a3-n45678/S01c2-ai3-e45678 o$o2$o!
4P3H1V0 B2e3ai4a/S2ae3nr4a - B2-ac34-r5678/S023-a4-r5678 obo$2o!
3P3H1V0 B2ci3ay/S02e3i - B2-ak3-i4-a5-i678/S01c2-a34-eit5678 bo2$obo!
4P3H1V0 B3ai5i/S2a3e5y - B2-ac3-e4-r5678/S01e23-ij45-e678 3o$bo!
5P3H1V1 B2e3i4aw/S1e2cik3a5c - B2-a3-ace45678/S01e2-n3-i45-a6-a7e8 2bo$3bo$obo$bo!
3P4H4V0 B2ac/S - B2-k3-nqr45678/S1c2345678 o2$2o! #Also in 5S; generation 3 is misprinted
5P4H4V0 B2aei4j/S - B2-c3-en45678/S2-ck345678 o$bo$o$b2o! #Generation 3 has a misplaced spark
6P4H4V0 B2ai4kr5i/S2e3j4k - B2-ck3-aijr45678/S1e2-a3-k4-i5678 2bo$2o$bo$2o! #Generation 3 has a misplaced spark
5P4H4V0 B2ace/S2ek3eijr4z - B2-k3cknry4-a5678/S1e2-ac3-kq4-j5678 o$bo$bo$b2o! #Generation 3 is misprinted
36P4H4V0 B2an3aeny4t5en6a/S1e2ci3y4aer5i6ac - B2an3aceny4-aejn5-aij678/S1e2-a3-einq4-ity5-anr6-i78 3bobo$2bobobo$4bo2$4bo$bo5bo$b3ob3o$b2obob2o$b2o3b2o$4ob4o$b2o3b2o! #In generation 2 the back spark is 1 cell off from its actual position; possibly redundant to a smaller ship
3P4H2V0 B2ce4ir5y6c/S15e - B2-a3-aei45678/S012ein3-ei4-ein5678 bo$obo!
3P4H2V0 B2c3aei/S13e - B2-ae3-jn4-t5678/S12-ac3-iy45678 bo$obo!
5P4H2V0 B2e3i/S1e2k - B2ein3-r4-jkn5678/S1e2-ci345678 2bo$o2bo$b2o!
7P4H2V0 B3aiq4a5a/S2ek3ir - B2cin3-j45678/S2-a345-acn678 2bo$o$o2bo$3o!
10P4H2V0 B2c3ae5ir6i/S1c2ac3aej4aj6ci - B2-ae3-ijn4-aiw5-q6-c7/S01c2-ik3-iy4-iy5-ik678 obobo$bobo$b3o$bobo! #This one is utterly incoherent
9P4H2V0 B3aij/S2eik3aijnr - B2kn345-a67e8/S1e234-aw5-jy6-kn78 bobo$o$o$o2bo$3o! #The lightweight spaceship
9P4H2V2 B2acn3n4ar/S2a3r - B2-ek3-eiq4-t5-n678/S2aik3-e45-e678 2bo2bo$3bobo$o3b2o$3bobo!
3P4H1V0 B2ce3n4t5y/S1c2k3i4i - B2-ai3-aei4-i5-i678/S1c2ikn3-e45678 bo$obo!
3P4H1V0 B2ack3ey/S1c2i3i - B2-ei3-ain4-t5678/S1c2-ac3-e45678 bo$obo!
4P4H1V0 B3aei4i5y/S12ack6c - B2kn345678/S123-aei4-a5-i678 bo$3o! #Also in Glider.db
4P4H1V1 B2ci3a4w/S1e2ak4w - B2cik3-c4-r5678/S1e23-j45-k678 b2o$o$o!
3P4H1V1 B2ce/S1 - B2-a3-jnr45678/S12-k345678 2bo$2o! #Also in 5S
5P4H1V1 B3aijn/S2ae3jnr - B2ikn34-r5-n678/S0234-k5678 bo$2bo$3o! #The glider in standard Life
4P4H1V1 B2ce3a4r/S1c2e3an4r5n - B2-a3-i4-a5678/S012-a34-a5678 2o$obo!
4P4H1V1 B2ce3a4r/S1c3an4r - B2-a3-i45678/S012-ae34-a5678 2o$obo!
4P4H1V1 B2c3a4r/S1c2e3jn4j - B2-ae34-a5678/S012-a3-i45678 2o$obo!
4P4H1V1 B2e3ir/S1e2k - B2-ac3-n4-jn5678/S1e2-ci345678 2bo$2bo$obo!
5P5H1V0 B2i3ai4cit/S1e2-in3n4i - B2ikn3-en45-y6-c78/S1e23-eij45-y678 bo$obo2$obo!
4P5H1V0 B2c3an5c/S12ace3cein4ain - B2-ae3ackny4-anz5-j6-a78/S0123-ar4-z5-cj678 o2bo$bobo!
4P6H3V0 B2ce3j4c5y6i/S1c - B2-ai3-cei4-i5678/S1c2aen3-y45678 bo2$bo$obo!
7P6H3V0 B2cik3a4ty5eir/S2a3ej4ar5nq6c7e - B2-a3-inr4-an56-i78/S1c2-ei3-ai4-i5-i6-a7 obo2$3o$obo!
7P6H3V0 B2ci3ay4nty5ei/S2ai3ejn4a5iy6c - B2-ak3-ijnr4-i56-ci78/S1c2-e3-aiy4-ir567c8 obo2$3o$obo!
3P6H1V1 B2ce/S12aek - B2-a3-ijnr4-a5678/S123-r45678 2bo$2o! #The Just Friends glider; also in 5S
3P7H2V0 B2ce3ajy4j/S02n3y - B2cen3ajkqy4-ak5678/S02ein3-jr45678 o2bo$bo!
4P7H2V1 B2en3eijq4w5cj/S02ck3ci4nq5j - B2ein3-ar45-q678/S02-an3-aejn4-akr5-i6-ac78 o$bo2bo2$2bo! #There is a wrong cell in generation 2 (with original phase), and generation 6 is misprinted; I have confirmed with EPE that the reconstruction is unique.
5P9H3V1 B2ek3ij4j/S2-ei3aejq4q5q - B2eik3-aer4-anq5-ac6-e78/S2-e3-inr4-akr5-a678 b2o$bo$bo$o! #Generation 6 has a wrong cell
8P10H5V0 B2ck3ae4aijk5i7e/S2a3ejky4aqrt5iy6c - B2ckn3acekn4-ct5-e67/S2akn3-air4-i56-i7c 2bo$2bo$o3bo2$b3o$2bo!
3P10H1V0 B2ce3i4at5ciy6c/S1c2ace3acjn4cinr5acjr6k8 - B2cen3cikqr4-ce5-e68/S1c23-i4-aeq5-ikqy6ekn78 obo$bo!
5P24H3V3 B2k3aikq4it5n6an/S1e2-n3nqr4ijny5cq6k - B2ikn3-jnr4ceikqtz5-qry67e8/S1e23cnqr4-ak5-kn678 o$2bo$bo$2b2o! #Velocity misreported as c/2d
3P1H1V0 B2a3r/S - B2-c3-n45678/S1c2345678 o2$2o! #In 5S; alternative reconstruction of #1
4P1H1V0 B2ae/S - B23-j45678/S01e2-k345678 o2bo$b2o! #The moon; alternative reconstruction of #11
4P2H2V0 B2a3i/S2i3i - B23-an4-t5678/S1c2-a3-e45678 bo$3o! #Reduction of #25
6P4H4V0 B2aik4r5i/S2e3j4k - B2-c3-aijr4-k5678/S1e2-a3-k4-i5678 2bo$2o$bo$2o! #Alternative reconstruction of #69
5P4H4V0 B2ai4r5i/S2e3j4k - B2-ck3-aijr4-k5678/S1e2-a3-k4-i5678 o$b2o$2o! #Alternative reconstruction of #69
5P4H4V0 B2ae3en/S2ek3eijr4z - B2-c3-aijr4-a5678/S1e2-ac3-kq4-j5678 o$bo$bo$b2o! #Alternative reconstruction of #70
5P4H4V0 B2ae3r/S2cek3eijr4z - B2-c3ckqry4-a5678/S1e2-a3-kq4-j5678 o$bo$bo$b2o! #Alternative reconstruction of #70
8P4H4V0 B2a/S1e2i - B2an3aekny4-an5-ai678/S1e2ci3-er45-r678 5bo$5bo$bo3b2o$bo$2o! #Smallest in minrule of #71
19P4H4V0 B2an3a4rw/S1e2i3ajkr4ajr - B2an3-ijqr4-ajn5-j678/S1e2-a3-eiq4-ty5-n678 o2$4bo$bo3bo$bo3b3o$bo3b2o$2obo$2bo$2b2o$b2o! #Smallest in maxrule of #71
10P4H2V0 B2c3ae5ir6i/S1c2ac3ae4aj6ci - B2-ak3-ijnq4-ai5-q6-c7/S1c2-i3-ijy4-iy5-ik678 obobo$bobo$b3o$bobo! #Alternative reconstruction of #76
10P4H2V0 B2ck3ae4at5ir6i/S1c2ac3aej4a6ci - B2-a3-ijnr4-ny5-q6-c7/S1c2-i3-iy4-ijy5-ik678 obobo$bobo$b3o$bobo! #Alternative reconstruction of #76
4P6H3V0 B2ce3j5y6i/S1c - B2cek3-ei4-ci5678/S1c2aen3-y45678 bo2$bo$obo! #Similar to #91

Code: Select all

x = 4, y = 3, rule = B3-q4z5y/S234k5j
2b2o$b2o$2o!
LaundryPizza03 at Wikipedia
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

LaundryPizza03 wrote: Yesterday, 7:31 pm The new link is dead as well. […]
I don’t know what you’re talking about. I just tried it out and it works fine.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
LaundryPizza03
Posts: 2651
Joined: December 15th, 2017, 12:05 am
Location: Unidentified location "https://en.wikipedia.org/wiki/Texas"

Re: INT version of gliderdb

Post by LaundryPizza03 »

MDA wrote: Today, 5:23 am
LaundryPizza03 wrote: Yesterday, 7:31 pm The new link is dead as well. […]
I don’t know what you’re talking about. I just tried it out and it works fine.
My browser refuses to open the website because it is not a private connection.

Code: Select all

x = 4, y = 3, rule = B3-q4z5y/S234k5j
2b2o$b2o$2o!
LaundryPizza03 at Wikipedia
User avatar
MDA
Posts: 350
Joined: June 8th, 2026, 12:18 pm
Location: In Haven (B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-ak)
Contact:

Re: INT version of gliderdb

Post by MDA »

Sapin’s INT gun collection:
Emmanuel_Sapin_15K_alien_guns.zip
(3.23 MiB) Downloaded 1 time
Edit (November 8th, 2026, 9:30 AM):
LaundryPizza03 wrote: Today, 5:24 am
[…]

My browser refuses to open the website because it is not a private connection.
You might have to open the website anyway. I don’t know why that’s happening. By the way, if you’re interested, you can try submitting some spaceships to GlidINT.
My website (a database of Life objects, WIP).
GlidINT has been released!
Currently working on a forum system for my website.

Code: Select all

x = 5, y = 17, rule = B3-ry4acenqt5eir6-ek/S2-a3-a4nq5aeknr6-akHistory
C$2C$.2C$2C11$.3D$3.D$2.3D!
[[ STOP 72 ]]
User avatar
LaundryPizza03
Posts: 2651
Joined: December 15th, 2017, 12:05 am
Location: Unidentified location "https://en.wikipedia.org/wiki/Texas"

Re: INT version of gliderdb

Post by LaundryPizza03 »

MDA wrote: Today, 5:26 am Sapin’s INT gun collection:

Emmanuel_Sapin_15K_alien_guns.zip

Edit (November 8th, 2026, 9:30 AM):
LaundryPizza03 wrote: Today, 5:24 am
[…]

My browser refuses to open the website because it is not a private connection.
You might have to open the website anyway. I don’t know why that’s happening. By the way, if you’re interested, you can try submitting some spaceships to GlidINT.
It was also blocked by my WiFi network's browser filter for the same reason.

Code: Select all

x = 4, y = 3, rule = B3-q4z5y/S234k5j
2b2o$b2o$2o!
LaundryPizza03 at Wikipedia
Post Reply