Grouping pattern editor

For scripts to aid with computation or simulation in cellular automata.
Post Reply
User avatar
speedydelete
Posts: 113
Joined: October 7th, 2025, 9:44 pm
Contact:

Grouping pattern editor

Post by speedydelete »

This is a new pattern editor I made based on dvgrn's ideas here, it lets you edit patterns as groups of cells (and other groups), as opposed to just cells.

It's accessible here.

This is a very early prototype version; it's missing lots of features (such as running patterns even, turns out that doing this while preserving the grouping is quite hard) and probably has many bugs.

Discord discussion thread: here

Edit: Source code is available here
Last edited by speedydelete on July 10th, 2026, 3:59 pm, edited 1 time in total.
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
hkoenig
Posts: 299
Joined: June 20th, 2009, 11:40 am

Re: Grouping pattern editor

Post by hkoenig »

Don't think of it as a bit editor. It's an object oriented editor of an array of LifeObject elements, that at some point can be converted to a bitarray that can then be used as the source for a cellular automata. Keep the data separate from the presentation.

Your first order of business should probably be to define what that LifeObject is and its data structure. Start with an apgcode (or similar canonical reference) along with the transformation needed to place the object on the bitarray field in the proper location, orientation, and phase. Any bitpattern can and should be generated from that information, and not be a part of the object data structure.

Also need to handle grouping/ungrouping of objects and how to transform a group of objects as a whole. (Rotation, for example) Another separate pair of operations would be the taking of a list objects and combining them into one object, or partitioning an object into smaller, sub-objects. Inserting/deleting from the group, as well as re-ordering, should also be supported.

As for the editor, you need to concentrate on selecting/moving/editing/manipulating objects. Think of them as a bunch of opaque shapes (rectangles most likely) that appear on the screen. Emulate your favorite drawing program.

Bitpatterns should only be generated when you need to display a pattern or actually generate the next generation. If you do want to generate the next generation in parallel, you would need to figure out when they start to overlap. That's going to be a lot of unnecessary work.

If the user does want to edit the indivdual bits, then that is done within the object, in a "biteditor mode", and should only affect the selected object.

You might want to put all that into a library along with unit-tests. Maybe add a second library to handle display, with emphasis on formatting and User Interface elements.

That's what I've done in my Life editor program, and it works fairly well. (Worst case, if I need to do some serious bit-editing, I copy the objects as a bitmap and paste in Golly, then paste the result back and perform a "partition" operation if necessary.)

You can also perform some placement validation. For example, I added a mode where the objects are Period-2 rotor segments, and the editor checks that various parts are in the proper phase and location to ensure that the result is also valid.
User avatar
speedydelete
Posts: 113
Joined: October 7th, 2025, 9:44 pm
Contact:

Re: Grouping pattern editor

Post by speedydelete »

hkoenig wrote: July 10th, 2026, 3:39 pm Don't think of it as a bit editor. It's an object oriented editor of an array of LifeObject elements, that at some point can be converted to a bitarray that can then be used as the source for a cellular automata. Keep the data separate from the presentation.

Your first order of business should probably be to define what that LifeObject is and its data structure. Start with an apgcode (or similar canonical reference) along with the transformation needed to place the object on the bitarray field in the proper location, orientation, and phase. Any bitpattern can and should be generated from that information, and not be a part of the object data structure.

Also need to handle grouping/ungrouping of objects and how to transform a group of objects as a whole. (Rotation, for example) Another separate pair of operations would be the taking of a list objects and combining them into one object, or partitioning an object into smaller, sub-objects. Inserting/deleting from the group, as well as re-ordering, should also be supported.

As for the editor, you need to concentrate on selecting/moving/editing/manipulating objects. Think of them as a bunch of opaque shapes (rectangles most likely) that appear on the screen. Emulate your favorite drawing program.

Bitpatterns should only be generated when you need to display a pattern or actually generate the next generation. If you do want to generate the next generation in parallel, you would need to figure out when they start to overlap. That's going to be a lot of unnecessary work.

If the user does want to edit the indivdual bits, then that is done within the object, in a "biteditor mode", and should only affect the selected object.

You might want to put all that into a library along with unit-tests. Maybe add a second library to handle display, with emphasis on formatting and User Interface elements.
We appear to have reinvented similar ways of doing this. Well, my structure is slightly different, I have "RPFPattern" objects which represent individual patterns (such as Snarks), then "RPFReference" objects which represent "There is a Snark at (x, y) with the given rotation."

I've already implemented grouping/ungrouping and pattern manipulation (you can click on objects to select them):
Screenshot 2026-07-10 155133.png
Screenshot 2026-07-10 155133.png (8.67 KiB) Viewed 243 times
Generation running is going to be extremely optimized. It does not compute bit patterns unless it is truly needed, and it can even be set to warn if this happens, because in a pattern consisting of only circuitry this will often happen when circuitry breaks.

For instance, let's say you want to run a L156 with a Herschel in it:

Code: Select all

x = 29, y = 47, rule = B3/S23
19b2o$19bo$17b3o16$17b2o$17b2o2$8b2obo$8bob2o$26b2o$26bo$24bobo$24b2o
2$9bo$9b3o$o11bo$3o8b2o14bo$3bo22bobo$2b2o23bo7$bo$bobo$b3o$3bo11b2o$
15bo$16b3o$18bo!
Instead of running the pattern itself, it recognizes that the Herschel is "expected" and treats it as a signal, this is added to the RPFReference, so it becomes like "L156 at (x, y) with rotation F and a Herschel in it at generation 0", then all the possible states it can be in are precomputed (they're really saved when the object was created) and then it simply runs it by incrementing it, retrieving the desired state from the cache, and displaying it.

Now, let's say you for some reason didn't want to compute everything for the L156. You could instead precompute for the HLx69R, RF28B, and BFx59H, then the renderer would extract those and put them together to form the complete pattern image.
hkoenig wrote: July 10th, 2026, 3:39 pm You can also perform some placement validation. For example, I added a mode where the objects are Period-2 rotor segments, and the editor checks that various parts are in the proper phase and location to ensure that the result is also valid.
I don't really understand how this can be generalized, do you mind explaining some more?
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
User avatar
Anivec
Posts: 1981
Joined: January 28th, 2022, 7:18 pm
Location: In 4.3 miles, take a right onto Exit 54

Re: Grouping pattern editor

Post by Anivec »

speedydelete wrote: July 10th, 2026, 3:57 pm
Instead of running the pattern itself, it recognizes that the Herschel is "expected" and treats it as a signal, this is added to the RPFReference, so it becomes like "L156 at (x, y) with rotation F and a Herschel in it at generation 0"
Is this a good time to elaborate on my proposed conduit naming scheme or no?
User avatar
speedydelete
Posts: 113
Joined: October 7th, 2025, 9:44 pm
Contact:

Re: Grouping pattern editor

Post by speedydelete »

Anivec wrote: August 13th, 2026, 2:09 pm
speedydelete wrote: July 10th, 2026, 3:57 pm
Instead of running the pattern itself, it recognizes that the Herschel is "expected" and treats it as a signal, this is added to the RPFReference, so it becomes like "L156 at (x, y) with rotation F and a Herschel in it at generation 0"
Is this a good time to elaborate on my proposed conduit naming scheme or no?
Yes, perhaps it is.

My current system looks something like (look at the #conduit's):

Code: Select all

snark:
#conduit 29 43+ input glider 9 6 F output glider 14 8 Fx 24
#envelope 0 0 y5gggsq23zy0ssvvvvvvuusssz8e133011fvvv7711zy2ogku7vmf1u08ozy4643y011
#manualverified speedydelete 2025-07-09
eater_1 0 10 Bx
eater_1 12 0 L
block 9 11
*oggs2uge1u08ozw643y011 6 15

BFx59H:
#conduit 54 53+ input B-heptomino output herschel 21 1 Fx
#envelope -2 -2 0gssvvvvvvvuvuuuususssssoogz33fvvvvvvfff73337733773311zxcn11zx11
#manualverified speedydelete 2025-07-08
block 4 3
snake 1 10 R
But, I'm interested to learn more about yours...
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
User avatar
Anivec
Posts: 1981
Joined: January 28th, 2022, 7:18 pm
Location: In 4.3 miles, take a right onto Exit 54

Re: Grouping pattern editor

Post by Anivec »

speedydelete wrote: August 13th, 2026, 3:37 pm
My current system looks something like (look at the #conduit's):

Code: Select all

snark:
#conduit 29 43+ input glider 9 6 F output glider 14 8 Fx 24
#envelope 0 0 y5gggsq23zy0ssvvvvvvuusssz8e133011fvvv7711zy2ogku7vmf1u08ozy4643y011
#manualverified speedydelete 2025-07-09
eater_1 0 10 Bx
eater_1 12 0 L
block 9 11
*oggs2uge1u08ozw643y011 6 15

BFx59H:
#conduit 54 53+ input B-heptomino output herschel 21 1 Fx
#envelope -2 -2 0gssvvvvvvvuvuuuususssssoogz33fvvvvvvfff73337733773311zxcn11zx11
#manualverified speedydelete 2025-07-08
block 4 3
snake 1 10 R
But, I'm interested to learn more about yours...
First step I took is renaming the orientations, here’s the new orientation renaming:
F -> 0
Fx -> 1
R -> 2
Rx -> 3
L -> 4
Lx -> 5
B -> 6
Bx -> 7

I also have decided to include the symmetry type for each object, that being the Catagolue standard symmetry naming, this also includes new names for glide symmetric spaceships. This makes orientations more specific. The origin of an object is now measured from its origin (bottom left corner) in its standard orientation, which is the orientation Catagolue provides for any given object in rle format. Every object name is provided by the Catagolue naming scheme in its standard orientation.
For the conduit input and output details, we will follow the naming scheme provided, where the strings inside the parentheses will be replaced by a number that is the specified value, excluding the continuous repeat time, which is indicated with a plus before the number.

I(Input object initial, Symmetry type)
O(Output object initial, Symmetry type)
R(Orientation number)
X(Output offset on the x axis)
Y(Output offset on the y-axis)
T(Time of formation of output)
C(Overclock time 1, Overclock time 2,…, Overclock time n, Continuous repeat time)

If any more elaboration on this is needed, I’ll be more than happy to share.
Last edited by Anivec on August 19th, 2026, 7:13 pm, edited 1 time in total.
User avatar
Anivec
Posts: 1981
Joined: January 28th, 2022, 7:18 pm
Location: In 4.3 miles, take a right onto Exit 54

Re: Grouping pattern editor

Post by Anivec »

Anivec wrote: August 14th, 2026, 9:00 am I also have decided to include the symmetry type for each object, that being the Catagolue standard symmetry naming, this also includes new names for glide symmetric spaceships. This makes orientations more specific. The origin of an object is now measured from its origin (bottom left corner) in its standard orientation, which is the orientation Catagolue provides for any given object in rle format.
Updates:
The offset is now measured from the bottom left regardless of symmetry.
The standard orientation is now defined as the following:
The direction the object tends to grow in its first few generations must facing to the top left (simply the top for symmetrical objects) of the grid in order to be considered as the standard orientation. Note that this only applies to methuselahs.
I also decided to move the overclock times to the middle in between the orientation and the output, as well as replace the overclock times with overclocking intervals denoted as
(Overclockstart1-Overclockend1, Overclockstart2-Overclockend2,..., + Continuousoverclock)
When theres an interval of only single overclock generation, it is simply the generation the overclock can happen.
User avatar
speedydelete
Posts: 113
Joined: October 7th, 2025, 9:44 pm
Contact:

Re: Grouping pattern editor

Post by speedydelete »

Anivec wrote: August 14th, 2026, 9:00 am First step I took is renaming the orientations, here’s the new orientation renaming:
F -> 0
Fx -> 1
R -> 2
Rx -> 3
L -> 4
Lx -> 5
B -> 6
Bx -> 7
Why rename the orientations? Aren't they fine as is? (I'm not trying to shut you down, I just want to hear your reasoning.)

Also, what about multi-input and/or multi-output conduits?
I manage the 5S project, which collects all known spaceship speeds in certain rulespaces.
Post Reply