LIFE(1) LIFE(1) NAME life - run and edit objects in Conway's Game of Life SYNOPSIS life [-v] [-t] [-g] [-f font] [-s scale] [-a algorithm] [-l libdir] ... [-i initfile] ... [filename] ... DESCRIPTION If you do not know what the Game of Life is, then see the appendix at the end. Except in that appendix, the remainder of this document assumes that you know the rules and terms of the game. This program plays the Game of Life on a very large board using sparse matrices or quadcells. The memory requirements depend on the total number of live cells of the object, and not on their locality. Therefore Life objects which cover a very large area can be manipulated. The time needed to compute generations depends on the number of live cells, not on the area covered by an object. The program is normally run under X11 with a view many hundreds of cells wide and high using individual pixels. However, it can also run on normal terminals using text characters, but with much reduced functionality. For terminal use, terms such as 'window' need to be interpreted loosely to make sense for the terminal screen. The program is able to display multiple Life objects in multiple windows. A window can only display one object at a time. However, the same object can be displayed in multiple windows. This allows different views of the object to be seen. Note that this program is designed for its editing and viewing capabilities, not for its raw speed. It contains commands to extract parts of objects, to manipulate multiple objects, and to recombine them again. To simply compute lots of generations quickly, use a program such as xlife or golly. QUICK DEMO Try the following demo to see how the program works. This demo only shows a few of the available features. Start the program by typing 'life'. Notice that there is a text line at the top of the window, and a cursor in the middle of the window. Type the letters 'h', 'j', 'k', and 'l' to move the cursor around. (Under X11, you can also use the arrow keys and can also use the mouse to set the cursor position.) Type the letter 't' to toggle the state of the current cell. Use it - 1 - Formatted: November 14, 2024 LIFE(1) LIFE(1) and the movement commands to build up an object to run. Type the letter 'G' to start running generations. Type the letters 'H', 'J', 'K', and 'L' to shift the view of the object, whether or not it is running. Type the letter 'g' to stop the running of the object, or if it is already stopped, to run it for one more generation. If the object has grown beyond the visible area, type 'S' to automatically scale the view to see the whole object. Type the 's' command to turn off autoscaling, and also to center the view around the current cursor position. Stop the running of the object, position the cursor on a live cell which is part of a large piece of the object, and type the sequence 'dd' to delete that piece. Move the cursor somewhere else and then type 'p' to reinsert the deleted piece at the new location. Type the sequence ';zero' and a return to clear the object. Notice that this only works if generations are not being run. Finally, type the sequence ';quit' and a return to leave the program. VIEWING OBJECTS Each window is divided up into two different areas. The top area of the window contains a line of text which is used for several purposes. The remainder of the window is used for displaying of a Life object. The text normally displayed on the top line is a status message which shows information about the currently displayed Life object along with some state of the program. It is displayed unless a command line or error text is displayed. While a command line is being entered, the text line shows the command line as it is typed and is removed when the command line is completed. If an error occurs, the error message is displayed in the text line and remains until another key is typed. It is possible to disable the text display area, so that the whole window consists of just the view of a Life object. The view of a Life object is a window into an very large Life universe. Each object maintains a cursor which always represents the location of interest. Normally, the view is shifted as necessary to keep the cursor's location visible within the window. If the cursor location is within the window, it is drawn so that the user can see its location. There are many commands which move the cursor, and - 2 - Formatted: November 14, 2024 LIFE(1) LIFE(1) these will implicitly reposition the view when the cursor tries to move out of the view. Besides the Life cells themselves, there are several other things that can be visible in the window. Some cells can be selected for some purpose, and the selected cells are shown differently than the normal cells. Cells which have died or which are newly born can be shown. A grid can be added to help determine distances within the Life object. Outlines can be drawn showing the areas visible within other windows. Finally, some line segments making up a path to be acted on can be displayed. SCALING When an object is large, then not all of it might be seen at once. In this case, the view can be scaled up so that more of the object can be seen at one time. A scale factor of 1 to 100000000 can be applied, which means that each pixel (or character) on the screen represents a square of the given size. Obviously, details of the object are lost when this is done, but scaling is still useful for seeing the overall structure of a large object and to position the cursor within the object. Scale factors which are a power of two are slightly faster to draw. Under X11, representing each cell by individual pixels makes seeing or editing of objects difficult. So the view can be scaled down so that each cell is represented by a square number of pixels. Negative scale factors specify the size of the square representing a cell. If the scale factor is -2, then the cells run into each other. If the scale factor is -3 or smaller, then blank lines separate each cell so that the individual cells can be distinguished easily. Under X11 the default scale factor is -15 for top level windows and -5 for subwindows. When the output is to a terminal and the scale factor is set larger than one, then each position containing live cells is marked with a number from 1 to 9, or an asterisk. A number is the actual count of live cells in the square, while an asterisk means there are 10 or more live cells in the square. Negative scale factors are not allowed for terminals. CHARACTER MODE COMMANDS There are two different kinds of commands to the Life program. These are the character mode commands and the line mode commands. Character mode commands are short sequences of characters which are self-terminating (in the same manner as the commands to the vi editor). They do not echo as they are being entered. Until the character sequence is complete, it can be edited using the normal erase and kill characters. When the sequence is complete, then it is - 3 - Formatted: November 14, 2024 LIFE(1) LIFE(1) immediately executed. Character mode commands can be preceded by zero, one, or two numeric arguments. These arguments are generally used as a count of how many times the command is to be executed. Missing arguments are defaulted to 1 (with the exceptions noted in the tables while appear later). If two arguments are specified, then they are separated by a comma. So a character mode command can take one of the following forms: <cmd> Both arguments defaulted. <a1><cmd> One argument given, second is defaulted. <a1>,<a2><cmd> Both arguments given. A numeric argument is usually an explicit number. But it can also be a numeric expression enclosed within parenthesis, or else one of a set of special values which are described later. For example, the command '(2+3)L' is the same as '5L'. Calculation of generations of an object can still be run while a character mode command is being entered. This allows the repositioning of the view and the changing of scaling factors without having to stop calculations for an object. However, many character mode commands (such as ones which change the object) are illegal while the object is running. LINE MODE COMMANDS Line mode commands begin with either a colon or a semi-colon character, and are terminated by an end of line character. These commands are full words which can be abbreviated, followed by space separated arguments. Line mode commands are echoed at the top of the screen as they are being entered so that editing of them is easy. A tab character can be used in the command name to complete it if the abbreviation is unique or is the start of a preferred command. If generations are currently being run at the time a line mode command is started, the calculations will be suspended until the command is completed. Use the ';help' command to list all of the line mode commands. Some commands are used so often that they can be abbreviated to single characters even when ambiguous. These are marked with an asterisk in the listing. A command you should know before starting the Life program is ';quit' which quits from the program. It can be abbreviated to just ';q'. Aliases can be defined for line mode commands using the ';alias' command. This accepts a non-aliased command name along with possible arguments for that command. - 4 - Formatted: November 14, 2024 LIFE(1) LIFE(1) When a later command is given which exactly matches the alias name then that command is replaced by the one previously defined by the alias. All arguments given to the alias are appended to the arguments that had been defined for the alias. If the ';alias' command is used with no arguments then a list of the currently defined aliases is shown. MOVEMENT AND CHANGING OF THE VIEW Most commands (and the area being viewed) are based on the current cursor location. To change the viewing region, or to point at a location in the object that you wish to modify, you must move the cursor around in the object. To do this, you can use some character mode commands. The directions for movement are based on vi, so that for example, 'h' moves left, 'j' moves down, 'y' moves to the upper left, and so on. You can also use diagonal movement commands which are 'y', 'u', 'b', and 'n'. They accept an optional preceding numeric argument which multiplies their movement by the given amount. The amount of movement is not changed by the scaling factor. The movement commands when capitalized perform a shift of both the cursor and the viewing region together by a fraction of the screen size. This is used to shift the view to see an object on the edge better. The default shift factor is 5, which means to shift by 1/5 of the screen width or height. The default shift factor can be changed by using the ';shift' command. When shifting diagonally, movement is always at 45 degree angles, independent of the relative sizes of the width and height of the screen. The 'C' command moves to the closest cell in the specified set of cells. (Here 'closest' is measured using the taxicab distance.) For example, the 'Ca' command moves to the closest cell of the whole object. This command can be used even while generations are being run. The possible set of cells that can be specified is explained later. If your terminal generates the standard escape sequences for its cursor keys (e.g., <ESC>[A and so on) then you can also use the cursor keys to move left, right, up, or down. This always works for the X11 display. These keys work identically to the 'h', 'l', 'k', and 'j' commands. The 's' command with an argument sets the scale factor for the current object being viewed as desired, and centers the view on the current position of the cursor. Without an argument, 's' simply centers the view without changing the scale factor. The 'S' command does auto-scaling, which selects the smallest positive scale factor which will enabling viewing of the whole object. As the object grows, the scaling factor will be increased automatically to - 5 - Formatted: November 14, 2024 LIFE(1) LIFE(1) keep the complete object in view. Using 's' will disable auto-scaling again. The ';scales' command allows the specification of a list of scale values for an object which can be quickly cycled through. With no arguments, the next scale in a previously specified list is used. This is particularly convenient when a macro for a function key is defined to execute the command. The ';zoom' command changes the view of the current object by changing the scale value slightly to perform a zooming action. It accepts an optional argument which can be 'in' or 'out'. If no argument is given then zooming out is assumed. Zooming out changes the scale value to about 3/2 of its old value. Zooming in changes the scale value to about 2/3 of its old value. EDITING OF AN OBJECT The simplest commands for changing an object are 'o', 'x', and 't'. The 'o' command creates a live cell and moves the cursor to the right. The 'x' command creates a dead cell and moves the cursor to the right. Both of these commands can accept a numeric argument which replicates their action by the given amount. As an example, the command string '25o' creates a row of 25 live cells. The 't' command toggles the current cell from dead to alive (or from alive to dead) without moving the cursor, and is usually the most convenient command to use when editing an object by hand. The ';mode' command sets a mode in which some of the movement commands described earlier automatically insert or delete cells. This makes it easy to create lines of cells in any direction. The argument is either 'insert', 'delete', or 'move', which may be abbreviated. For example, if the mode is insert, then the command '20j' will create a row of 20 cells downwards. ALGORITHMS The Life program can edit, display, and run objects using one of two different algorithms. The algorithms differ in how the cells of the object are stored. Each of these algorithms has its advantages and disadvantages. The 'list' algorithm stores the cells of an object in linked lists. Row objects are linked together, and each row object points to a list of column objects linked together. The 'quadcell' algorithm stores the cells of an object in a tree structure, with each level of the tree linking to four sub-cells, and so on down to the individual cells. Hashing is used so that repeated instances of the same structure share the same cell. This is the - 6 - Formatted: November 14, 2024 LIFE(1) LIFE(1) reason that very large objects having some regularity can be held in memory. The algorithm used for new or zeroed objects can be defaulted by using the -a command line option or the ';default algorithm' command. The algorithm can later be changed for a particular object using the ';algorithm' command. If an object is very large (e.g., containing millions of cells), then the algorithm cannot be changed from the quadcell algorithm since that would use too much memory. There is a bit of overhead in running the quadcell algorithm, so for running single generations of small objects the list algorithm is normally faster. However, when running huge objects or jumping by many generations at a time, the quadcell algorithm becomes superior. RUNNING GENERATIONS To compute generations, use the 'g' or 'G' commands. The 'g' command computes a single generation of the current object, or as many more generations as is specified in its preceding argument. The 'G' command simply means run for an infinite number of generations. If the object dies or becomes stable, computations automatically stop. (However, loops of period 2 or greater are not detected.) While generations are running, and you supply an argument to the 'g' command, then the specified number of generations gets added to the ones already being computed. On the other hand, if generations are running, and you use the 'g' command with NO arguments, then computations are stopped immediately. If a specified number of generations are being run, the status line will display the remaining number of generations to be run next to the generation number. While generations are being computed, you can use the movement and scaling commands to wander around the object. But attempts to change the object while it is running will be rejected. If you wish to wait until the indicated computations are complete before the next command is executed, use the ';wait' command (this is most useful inside of a command macro or loop). Normally each generation will be displayed as it is computed. To speed up the computations when you don't want to see every generation, you can use the ';frequency' or ';jump' commands to set how often the screen is updated. These two commands are incompatible with each other, so that using one of them disables the other. The ';frequency' command still causes generations to be run one at a time, but simply skips the displaying of them except at the specified - 7 - Formatted: November 14, 2024 LIFE(1) LIFE(1) interval. Those actions which depend on the changes of the cells of the object such as stop conditions and tracking work fully. Furthermore, commands are still processed every generation so that commands which can change the viewing area (such as 's') work immediately, causing the current generation of the object to be immediately displayed. The ';jump' command causes multiple generations to be run atomically in one step, without performing screen updates, checking for stop conditions, or command checking except at the specified interval. Its advantage is that when using the quadcell algorithm for running generations, multiple generations can be computed very efficiently and quickly in many situations. For example, a simple glider gun can be run in jumps of 2^20 generations about as quickly as running a single generation. The work involved in jumping depends on the binary representation of the jumping value, with each power of two used in the representation taking time. Therefore jumps which are an exact power of two are the most efficient. The maximum jumping value is 2^30. Normally the Life program displays generations as fast as the processor allows. If your display is too fast to see what is going on, then you can use the ';delay' command to specify a wait time between each displayed generation. The command accepts the number of milliseconds to wait between screen updates, and can range from 0 to 60000 (one minute). If any commands are typed while waiting is in progress, then that wait is aborted so that the commands can be executed quickly. You can enable tracking of dead cells and newly born cells. When tracking is enabled, cells which are born in new locations are colored differently than other live cells, and cells which were once alive but which are dead are also shown. This feature is used to follow the paths of gliders and spaceships, or to determine locations where an evolving object can be perturbed safely. Tracked cells are created only by the running of generations, so that editing of an object does not create any tracks. Tracks are enabled for an object using the ';tracks' command. They can be disabled using the ';tracks off' command. Existing tracks can be cleared using the ';tracks clear' command. Tracks can be forced to be remembered for the current live cells of an object using the ';tracks set' command. Finally, the viewing of tracks can be turned on or off using the ';tracks visible' and 'tracks invisible' commands. (Using tracks but not displaying them can be useful since it is faster.) Tracks are implemented using the quadcell storage algorithm which exploits any regularity in the tracked cells. So there is no problem in tracking objects such as spaceships or puffers which create large number of tracked cells. - 8 - Formatted: November 14, 2024 LIFE(1) LIFE(1) The ';minmax' command enables or disables the tracking of the minimum and maximum cell counts for an object as it runs, and of the first generation number where these extremes occurred. It accepts an argument which is one of 'begin', 'enabled', or 'disabled'. The variables 'mincell', 'maxcell', 'mincellGen', and 'maxcellGen' are used to store the results. The minmax tracking is valid even if the frequency value is set above one. However, if jumping is used then the cell counts are only calculated occasionally and therefore are probably not correct. Turning on minmax tracking can slow down the running of generations. The status line for an object will include the 'minmax' phrase if minmax tracking is currently enabled. A condition can be imposed on an object that will stop the calculation of new generations if the condition is satisfied. This is done using the ';stop' command. It accepts an argument specifying the condition to be met. The argument can be abbreviated. Multiple stop conditions can be specified using separate commands. While a condition is satisfied no new generations can be calculated, and this will be indicated in the status line. Some conditions are expensive to evaluate and so the running of generations can slow down greatly. The "cell" condition stops calculations if the cell at the current location of the cursor (at the time this command was used) changes state, either to ON or to OFF. The "on-path" condition stops calculations if any cell of the object lies exactly on the currently defined path. The "inside-path" condition stops calculations if any cell of the object lies truly inside of the currently defined path. The "outside-path" condition stops calculations if any cell of the object lies truly outside of the currently defined path. The "gap" condition stops calculations if the minimum distance between the set of marked cells and the set of unmarked cells is less than or equal to the specified value. The maximum gap value that can be used is 100. The "expression" condition stops calculations if the specified expression has a nonzero value. The expression is re-evaluated on each generation. The expression can only be 1024 characters in size. There are three stop conditions which have special effects. The condition value of "none" clears all of the stop conditions. The "disabled" condition disables the current stop conditions so that generations can be run, but the conditions are still remembered. The "enabled" condition enables the current stop conditions again. - 9 - Formatted: November 14, 2024 LIFE(1) LIFE(1) (Specifying new stop conditions also enables stopping.) The ';force' command can be used to run the specified number of generations of the current object even if stop conditions are enabled. If no count value is given then one generation is assumed. The ';zero' command clears all cells of an object and resets the scaling factor, cursor position, frequency, and jumping value. It also clears any stop condition and causes the object to use the default algorithm. The ';copymarked name' and ';movemarked name' commands copy or move marked cells to another object. The ';advance' command takes the marked object, removes it, runs the Life rules for the specified number of generations, then reinserts the result back into the current object, marking it. The ';undo' command will undo the most recent change to the current object. This can undo deletions, insertions, marking, paths, and running of generations, among other things. It accepts an optional argument to undo the specified number of changes. There is a limit of 20 changes which can be undone. If any undo has been performed, the current undo depth is displayed in the status line. If an object is edited while an undo change is active, then the undo depth is cleared. The ';redo' command re-applies the changes that were removed by a previous undo. It accepts an optional argument to redo the specified number of changes. A very large argument re-applies all changes, resulting in the most recent version of an object. USING MULTIPLE OBJECTS The life program can simultaneously handle more than one Life object. Each object is distinct and has its own name. The initial object when you start the program is called 'main'. You can switch between objects to select the one that you wish to edit or display. The object currently being edited is the one which is shown in the window. If the object being edited is not 'main', then the object's name is shown in the window's status line. The ';edit' command switches between objects (defaulting to the previously edited object if no name is given). If the object does not yet exist, then a new object with that name is created. The special name of "." means the currently edited object, and the special name of ".." means the last object previously edited. The ';objects' command will display data about all objects. Normally, special objects having names beginning with a period will not be shown. These will also be displayed if the ';objects -a' command is used. The ';next' command switches to the next non-reserved buffer that - 10 - Formatted: November 14, 2024 LIFE(1) LIFE(1) exists. This is very useful when many files have been read in from the command line so that the objects can be easily examined in sequence. Cells can be copied or moved between objects. This allows you to make backups of an object, or split up and edit the parts of a single object. The ';copy' command copies the current object to another object. This copies everything about the object, including the marks, paths, and the tracked cells. The ';backup' command copies the current object to a new object whose name is the concatenation of a base object name, a dash, and a small integer (as in the example 'fred-123'). The smallest positive integer is used which results in a new object name. The command accepts an optional base name to be used for the new object name. If no base name is specified, then the most recent base name is used again. The initial base name is the single letter 'b'. A second copy of the current buffer is made to the buffer whose name is the base name with '-last' appended to it (as in the example 'fred-last'). This command is useful when a series of complicated modifications is made to an object and you wish to save a copy of each of the modifications for error recovery without worrying about the names of the objects. The ';get' command clears the current object and then copies the specified object into the current object. Everything is copied from the old object, including the marks, paths, tracked cells, and algorithm. The ';insert' command inserts another object into the current object. This only copies the cells from the old object, and does not clear the current object first. The newly inserted cells are positioned based on the locations of the two object's cursors. The source object is shifted in order to put the two cursors in the same location, and then the cells are copied relative to the cursor position. When a new object is created or an old object is zeroed, its algorithm, its scaling factor, its display frequency, and its tracking flags are initialized to useful default values. You can use the ';default' command to change these default values. Use ';default algorithm' to change the algorithm used for storing and manipulating the cells. Use ';default scale' to change the default scaling factor. Use ';default frequency' to change the default display frequency. Use ';default tracks' with 'on' or 'off' to turn on or off automatic tracking. These parameter names can be abbreviated. In those commands which accept object names, a tab character can be typed to perform object name recognition. This will examine the object names and try to complete as much of the partial object name as is possible. If a unique object name is matches, it will be completed - 11 - Formatted: November 14, 2024 LIFE(1) LIFE(1) and a space added after the name. If multiple object names match, as much as is common to all the matching object names is completed and a list of matching object names is displayed. If no object names match, a beep will be sounded. The ';overlay' command can be used to draw another object into the same window as the current object. It accepts an object name to be overlayed. If no name is given, then the display of the previously set overlayed object is toggled on or off. The overlayed object is always positioned according to the relative cursor positions of the two objects. The cells of the overlayed object will not overwrite the live cells of the current object in the view. This command lets you see where an object will be inserted by a later ';insert' command, or where a deleted object will be inserted by the 'p' command. For the latter case, the overlay object would be '..delete'. WINDOW BEHAVIOR AND APPEARANCE A window tracks a particular location to keep it visible. By default, the cursor location of the window's current object is what is tracked. The ';view' command sets the location which is being tracked. It accepts a single (possibly abbreviated) parameter. The parameters 'cursor', 'origin', 'mouse', and 'self', or a single 'where' location letter sets the location which is tracked. The 'cursor', 'origin' and where location parameters track the specified locations of the current object. The 'mouse' parameter tracks the mouse's location while a button is pressed. The 'self' parameter tracks the window contents itself, and is thus another way of tracking nothing. Note: If the window view is shifted manually (e.g., using 'H', 'J', 'K', 'L', etc.), then the tracking is temporarily disabled (except when tracking the cursor). In this state, the status line displays the phrase 'shifted'. This lets you move the view around in the window without interference. Typing the 's' command to recenter the view will let tracking occur again. There are several ways that a window's view can be repositioned in order to make a tracked location viewable. By default, the view is shifted to make the location visible. The ';positioning' command sets the manner in which the positioning is done. It accepts a (possibly abbreviated) parameter. The parameters 'shift', 'center', and 'shift' set the method by which the location's view is maintained. The 'center' parameter keeps the location centered in the window. The 'scale' parameter will increase the scale in order to make the location visible. When a window is shifted to make a tracked location viewable, a margin around the tracked location can be applied. Using a margin means that when the cursor is moved cell by cell off the edge of the window, then the view won't be redrawn every movement. Instead, the view shifts when needed so that the cursor is away from the edge by the margin - 12 - Formatted: November 14, 2024 LIFE(1) LIFE(1) size, thus reducing the number of redraws. The default margin size is 0. The ';margin' command is used to set the margin. It accepts a value from 0 to 100. This value is a percentage of the radius of the window (that is, the percentage of the distance from the center of the window to each edge). Normally, there is a status line at the top of a window. The status can be disabled or redirected to the parent window of a sub-window. In either of these two cases, the status line in this window is removed leaving more room for the object's view. The ';status' command is used to set the location of the status line. It can accept one of the (possibly abbreviated) arguments of 'visible, 'invisible', or 'parent'. If no argument is given then 'visible' is assumed. When you are trying to count the number of cells between two parts of an object, then the ';grid' command can be used to turn a grid on and off and to set its size. When a grid is shown, cells are marked (where possible) in one of two ways according to the position of the cell relative to the object's origin. The differing marking repeats at row and column intervals set by the grid size. This allows you to easily count large distances in the object. Since the grid is based on the object's origin, the alignment of cells with respect to the grid does not change as the view is changed. The default grid size is 10 cells. If used without any arguments, the ';grid' command toggles whether or not a grid is being displayed. Otherwise it accepts one of the commands 'on', 'off', 'size', 'characters', 'dots', 'lines' or 'checkerboard' to perform a specific action. Abbreviations can be used. The ';grid on' command turns on the grid. The ';grid off' command turns off the grid. The ';grid size' command sets the size of the grid to the specified size. The ';grid characters' sets the grid characters to the indicated values, and is only used for terminal output. For X11 output, the 'dots' grid is drawn using small dots in the corners of all the visible cells, whether alive or dead. The colors of the dots varies according to the grid size boundaries. The grid will not be displayed unless the scale factor is -3 or less, otherwise it would be difficult to distinguish the grid from the cells. For terminal output, the grid is only shown for empty cells. The default grid characters are a period and a colon. These can be changed using the ';grid characters' command which accepts zero, one, or two characters as an argument. If no characters are specified, then periods and colons are used. If only one character is specified, then that character is used for both cases. - 13 - Formatted: November 14, 2024 LIFE(1) LIFE(1) By default the cells are drawn as solid squares. The ';shape' command can be used to draw cells in alternate ways. It accepts an (possibly abbreviated) argument of 'squares', 'circles', 'diamonds', 'large' or 'small' to determine the method used to display cells. Circles are only actually displayed if the scale factor is -5 or less since very small circles are indistinguishable from squares. Diamonds are only actually displayed if the scale factor is -3 or less. The ';color' command sets the color of one part of the Life window. It accepts a type argument indicating the part of the window to be affected followed by the desired color. The type argument can be abbreviated. It is one of 'background', 'cell', marks, 'tracks', 'old', or 'text'. These are for the window background, normal cells, marked cells, tracks of dead cells, tracks of live cells, or the text in the view subwindow. The color is either a name (possibly multi-word as in 'dark green'), or a hex RGB value in either of the formats '#rgb'or '#rrggbb. For example, '#0c0' is a very light green. The ';border' command sets the size of the window border for sub- windows. The default border size is 3. The border size can be from 0 to 20. A border size of 0 is useful if the background color of the sub-window is different from its parent window. USING MULTIPLE WINDOWS When the Life program is first started it only has one window. New windows can be created which will show objects in the same way as the first window. (Note that this cannot be done for terminal output.) There are two types of windows: the top-level windows and the sub- windows. There are two different commands for creating these two window types. Top-level windows are seen by the window manager and treated as just another application window. They can be moved, resized, raised, lowered, and iconified using the same actions as for other application windows. This has its conveniences, but has the disadvantage that if two top-level windows overlap then typing or clicking on them can cause unwanted raising of windows. Furthermore, the window manager applies its title bars on all the top-level windows, wasting some display area. Sub-windows are not seen directly by the window manager since they are contained entirely within top-level Life windows. They do not have a window manager border, but instead have a very thin border created by the Life program. They can be moved, resized, raised, lowered, or hidden. These actions are performed by the Life program using special mouse actions. The disadvantage of sub-windows is that they are - 14 - Formatted: November 14, 2024 LIFE(1) LIFE(1) clipped by the top-level window that contains them. The ';window' command creates a new top-level window. The ';subwindow command creates a new sub-window of the window where the command was invoked from. In either case, the window is created showing the same object as the window where the command was invoked from. Both commands accept an optional settings name which is used to initialize and share the window's settings (explained later). These settings can be changed later. The size of a new window is based on a percentage of the width and height of either the main display or of the owning parent window. This size percentage can be set using the ';size' command. The command accepts either 'toplevel' or 'subwindow' (which may be abbreviated) followed by the size percentage from 1 to 100. The default values are 90 percent for top level windows and 25 percent for sub-windows. The position of a new top-level window is up to the window manager. The position of a new sub-window is found by trying to find an empty area in the owning window which doesn't cover other sub-windows. There is the concept of the 'current window'. This is the window in which keyboard commands and mouse clicks affect. Actions occur to the current window, and in particular to the current object within the current window. Note that each window has its own idea of the current object, and also of the previous object. The current window is determined by the combination of the top-level window which is activiated by the window manager, and by that top- level's sub-window that the mouse is within at the time of the action. To type a command to a sub-window, you only have to position the mouse within it, and it will become the current window on the next keystroke or mouse click. The status background changes color to show whether or not the window is the current window. A light grey background identifies the current window, whereas a dark grey background identifies the non-current windows. For sub-windows, the window border also shows these colors. Sub-windows can be moved by dragging them using the mouse on their status line or on their grey borders. They can also be moved by clicking them anywhere while holding down an ALT key and dragging them. Sub-windows can be resized by dragging the light green bottom right corner of the border. Clicking on the status line or border using the left mouse button raises the sub-window with respect to the other sub-windows. Clicking on the status line or border using the right mouse button lowers the sub-window with respect to the other sub- windows. - 15 - Formatted: November 14, 2024 LIFE(1) LIFE(1) The ';hide' command can be used to hide and unhide the sub-windows of a top-level window. It has no effect on top-level windows (which you can use window manager actions for). It accepts one of the parameters 'self', 'all', or 'none'. If no parameter is given, then 'self' is assumed. The ';close' command will close the window that the command was exected in. If a top level window is closed, then all of its sub- windows are also closed. The last top level window cannot be closed. It is possible to see rectangular outlines showing the areas of an object which other windows are also displaying. By default, all outlines are disabled. The ';outlines on' and ';outlines off' commands turn on and off the displaying of outlines for the window. It is possible for a window to disable the showing of its own outline in other windows. By default, its outlines are displayable. The ';outlines visible' and ';outlines invisible' commands turn on and off the visiblity of the window's outline in other windows. The ';fullscreen' command sets whether or not the current window is in full screen mode. It accepts an optional parameter of 'off' or 'on'. If no parameter is given then the full screen mode is toggled. While in full screen mode the Life window covers the entire screen, making the usual desktop icons, side panels, and window borders inaccessible. Besides being slightly larger than a maximum resized window, the graphics might be slightly faster since compositing might be avoided by the window manager. Note that this command works by sending a special request to the window manager, and so a modern window manager is required for it to be effective. This command does nothing when running on a terminal. WINDOW SETTINGS Each window has a set of parameters (called settings) which determine the appearance of the window. The parameters affect such things as the border size, whether a grid is displayed, the background color of the window, the shape of the cells within the window, and so on. There are different commands used to set the various types of settings values. For example, the ';shape' command is used to change the cell shape setting. Each window has two different sets of settings values. They are the private settings and the shared settings. The private settings are those whose values only belong to that window. If other windows have a similar settings value, they must have been set independently. Changing of a private settings value only affects that window. The shared settings are those values which can potentially be shared - 16 - Formatted: November 14, 2024 LIFE(1) LIFE(1) with other windows. Such settings have the same value for all windows which share them. Changing of a shared settings value affects all the windows which share it. Whether a particular type of setting is private or shared for a window is individually settable for each type of setting. For example, a window may have a private background color and yet share the cell shape with other windows. There are multiple sets of shared settings. Each set of shared settings has a unique name. There are two pre-defined shared settings, called '.top' and '.sub'. Other sets of shared settings can be created as needed. By default, top-level windows initially use the '.top' shared settings, and sub-windows initially use the '.sub' shared settings. This allows the two types of windows to be initialized with different settings values. If an argument is given to the ';window' or ';subwindow' commands, than that argument is the name of the set of shared settings to be used instead of the default settings. The current settings values for a window can be displayed using the ';show' command. This gives the name of each setting (used for other commands), a description of the setting, and its current value. An asterisk is also present or absent at the front of each setting indicating whether that setting value is currently private or shared. The display also gives the name of the set of shared settings being used by the window. The ';private' command makes the specified list of settings values private to the window. The values of the shared settings are copied to become the private values so that the settings values of the window are not changed. The ';shared' command makes the specified list of settings values shared with the current set of shared settings defined by the window. The window will lose the private values of the specified parameters and take on the values of the shared settings. The settings parameter names can be abbreviated. Besides individual settings parameter names, the special values of 'all', 'default', 'color', and 'grid' can be used to specify useful groups of parameters. The ';settings' command is used to perform a number of special actions on the settings values. Its first argument is action to be performed. The action can be abbreviated. The 'default' action copies the settings from the '.top' or '.sub' set - 17 - Formatted: November 14, 2024 LIFE(1) LIFE(1) of settings to the window's settings, as appropriate to the type of window. The copy updates both the private and shared settings values, so this will affect other windows which share the same settings. The 'initialize' action sets the window's settings to the initial values for the type of window. This will update both the private and the shared settings values. Note: This action is not the same as the 'default' action since the '.top' and '.sub' sets of settings may have been changed since the program was started. The 'load' action requires the name of an existing set set of shared settings, and copies the settings from that set into the window's settings. This will update both the private and shared settings values. The 'merge' action requires the name of an existing set of shared settings, and copies only those settings values from the specified shared settings which are private to the window. The 'store' action requires the name of a new or existing set of shared settings, and copies all of the window's settings into that set of shared settings. The 'use' requires the name of a new or existing set of shared settings, and changes the window's shared settings to that set. The ';defaults sharedSettings' command sets the settings parameters which are to be shared when a new window is created. MARKS A very useful feature is the use of marks. You can select any group of cells of an object, and handle them specially, leaving the rest of the cells unchanged. For example, you can save the marked cells as a different object, or can move them around, or can delete them. Marked cells appear differently in the display so that you can recognize which cells are marked. Each time you mark some cells, the new cells get added to the set of cells which were already marked. This lets you build up the set of marked cells using multiple marking commands, and then act on the final marked set. When you want to unmark all the cells to begin a new set, use the ';unmark' command. Marked cells are 'sticky' in that if generations are being run, then cells which had been marked remain marked in the new generation. Furthermore, new cells whose life depends on a marked cell are also marked in the new generation. Marks are set using the 'm' command, followed by a set specifier letter. For example, the command 'mv' marks all of the cells which - 18 - Formatted: November 14, 2024 LIFE(1) LIFE(1) are currently visible in the window. The full list of set specifiers is described in detail later. PATHS A very advanced editing feature is the use of paths. A path is composed of one or more closed loops of line segments. The line segments join the centers of the cells, NOT the edges or corners of the cells. Each closed loop encloses an area containing a number of cells. The live cells within those areas can be operated on as a unit, with the usual operations being deletion or marking. Cells exactly on the path are also considered to be within the area. The boundary of a path can be arbitrarily complex. The only limits on a path are the memory used to store it and the speed of processing it. If two loops overlap each other, or if one loop crosses itself, then the definition of what is inside the path becomes complicated. The basic rule is that a cell is inside if and only if a typical line segment drawn from that cell out to infinity crosses the path an odd number of times. This means that for two loops which have no points in common, then both loops enclose an area to be acted on. But if one loop is enclosed by another one, then the inner loop excludes its own area from being acted on. To begin defining a path, use the 'a' command. It adds a point to the path at the current cursor location, and draws a line segment from that point back to the previous ending point of the path (if any). The path being drawn is shown in green under X11. You use the 'A' command to close off the current loop of the path so that you can begin to make another disjoint loop. This draws the final line segment from the first point of the loop to the last point of the loop. The 'A' command has no effect if the path is already closed so that multiple 'A' commands in a row are harmless. Notice that the 'A' command is not required before using a path, since there is always an implied closure of a loop even if the implied last segment isn't visible on the screen. You can use the ';shorten' command to remove one or more of the final segments of the currently defined path. This is useful if you have made an error in defining the path. The command accepts an optional numeric argument giving the number of line segments to remove from the path. To remove the path completely, use the ';clearpath' command. The defined path is used by using the letter 'p' in any of the commands which act on sets of cells, as described in the following section. As a side effect of using the path, it is cleared to enable a new path to be conveniently started. The ';restorepath' command will restore a path that has been - 19 - Formatted: November 14, 2024 LIFE(1) LIFE(1) explicitly or implicitly cleared so that you can use it again. Starting a new path prevents the restoration of the previous path. Paths can still be used when running on a terminal, but the segments making up the paths are not visible on the screen. When using paths for an object using the quadcell algorithm, there is a limit of 1000000 on the number of cells possibly selected by the path. ACTING ON SETS OF CELLS A few commands act on a set of cells specified as part of the command. There many possible sets that can be specified. Many of these sets are determined based on the cursor's current location. Here are the commands which act on a specified set of cells: d<set> delete cells fr<set> flip cells around the cursor's row fc<set> flip cells around the cursor's column r<set> rotate cells 90 degrees clockwise around the cursor m<set> mark cells C<set> move to closest live cell in the set The '<set>' in the above commands are one of the following letters: h cells to left of cursor l cells to right of cursor k cells above cursor j cells below cursor b cells below and left of cursor n cells below and right of cursor u cells above and right of cursor y cells above and left of cursor c cell at location of cursor o cells in the king-wise connected object at the cursor (same as '0') e cells in the king-wise extended connected object (same as '1') <digit> cells connected by gaps no larger than the specified value p cells inside or on the currently drawn path g<ch> cells which are in group <ch> r<ch> cells in rectangle determined by the cursor and another location (here <ch> is either '@' for the origin or a 'where' variable) s cells within a selected rectangle (i.e., dragged by mouse) v cells visible in window i cells invisible in window (outside) m cells which are marked a all cells Here are some examples of commands used with sets. The command 'dk' deletes all of the cells which are on or above the current row. The - 20 - Formatted: November 14, 2024 LIFE(1) LIFE(1) command 'fra' flips the whole object around the current row. The command 'mp' marks all of the cells inside the current path, As an special case, repetition of the initial command letter specifies a set which is the same as the 'o' set specifier, which means all of the cells which are connected to the cell which is at the cursor's location. As examples, 'dd' is the same as 'do', and 'frf' is the same as 'fro'. THE ORIGIN A few commands make use of a location within an object called the origin. The origin is a location that is remembered in an object, independent of the current cursor location. You can think of it as the location whose coordinates are (0,0). When an object is created or zeroed, the cursor is positioned at the origin. If a grid is being displayed for an object, the grid markings for the cells are based on their relative distances from the origin. Several commands act relative to the position of the origin. The '\n' command moves to the next row and back to the column of the origin. The '\t' command moves to the next column which is a multiple of eight cells away from the origin's column. The 'c' command moves to a specified row and column offset from the origin's position. This lets you specify the cells of an object given their coordinate values. Finally, the origin is used by the 'r' set selector character, and determines the far corner of a rectangular region to be acted on. The origin does not have to remain at a fixed location in an object. The '@' command sets the origin to the current cursor location, so you can move it as required. The ';center' command can be used to set the actual origin of the object. The object is centered within the coordinate system, and the values of coordinates within the object are adjusted to match. Centering of an object is probably a good thing to do before writing files out in the quadcell format. WHERE LOCATIONS Besides the cursor and the origin, there are 26 other saved locations within an object which you can refer to. These are the 'where' locations, named for the lower case letters. To remember a location in an object, use the 'W' command followed by a lower case letter. This associates the current coordinates of the cursor with the specified letter. To return back to the remembered location, use the 'w' command followed by the same letter to move the cursor back to the remembered location. If any arguments are given, then the cursor is offset by - 21 - Formatted: November 14, 2024 LIFE(1) LIFE(1) those values. The 'where' locations are preserved across the running of generations so that you can still position back to areas of interest. The ';locations' command can be given to specify a set of where locations which are displayed on top of the cells of the view to show their locations, or additional data to be shown in the status line. In addition to the 26 lower case 'where' letters, the '@' character can be used so that the origin's location is shown, and the '.' character can be used so that the current location is shown. If no arguments are given then the showing of all locations is toggled on or off, as if the appropriate 'on' or 'off' action was specified. Otherwise the command accepts an action keyword (possibly abbreviated), possibly followed by a list of locations specified by one string (for example, 'abc@'), and then possibly followed by a list of items specified in one string. The actions 'on', 'off' and 'clear' take no arguments and act on the whole set of where locations. The 'on' and 'off' actions turn on or off the showing of all where locations, without modifying the set of items that had been specified. The 'clear' action turns off the showing of all where locations and in addition removes all items that had been set. The actions 'enable' and 'disable' enable or disable the showing of where locations for the following list of where locations. If any where locations are enabled, then the showing of where locations is turned on. The items that had been specified to be shown are not changed. The 'add' and 'subtract' actions add or subtract the specified set of items to be shown for all of the specified where locations. If an item is added, then the where location is also enabled, and also the showing of where locations is turned on. The items which can added or subtracted are specified by a string made up of one or more letters from the set 'ircfbd'. Here 'i' shows the where character at its location, 'r' shows a horizontal line through its location, 'c' shows a vertical line through its location, 'f' shows a forward diagonal line through its location, 'b' shows a backward diagonal line through its location, and 'd' shows the distance from the cursor to its location in the status line. The distance shown in the status is the absolute value of the differences of the rows and columns, and the number of cells to the forward and backward diagonal lines. If the current location is not an exact number of diagonal cells away, then the distance value shows - 22 - Formatted: November 14, 2024 LIFE(1) LIFE(1) '.5' as part of the number. For example, the command ';locations add ab ifb' causes the 'a' and 'b' where locations to show their id character and both diagonal lines through their locations. Locations are only shown for the X11 display. LOOPS AND MACROS Command loops and macros can be defined using the '<' and '>' commands. If a numeric argument is specified before the '<', then a loop is being defined. If no argument is given, then a macro is being defined. While defining a macro or loop, the commands you type are executed normally so that you can see how the definition will execute. This is useful when you define a macro to create an object, since you can easily see how to create the object. Loops and macros can contain both line mode and character mode commands. While you are defining a loop or macro, the status line will indicate this and give the current depth of loop or macro nesting. If a loop is being defined, the loop is executed the number of times specified by the argument to the '<'. If two arguments are specified, the loop runs from the first to the second argument (backwards if the second argument is less than the first argument). The value of the loop counter is available in the loop itself by using '%' as you would a number. As an example of a loop, the command string '3,7<%o.>' inserts five strings of cells spaced apart by one cell, where the first string contains three cells, and the last string contains seven cells. When nesting loops, supplying an argument to '%' can obtain the loop counter values for the outside loops while in the inner loop. Thus, '2%' obtains the loop value for the next-to-innermost loop level. When defining a macro, the next character after the '<' is the macro name to define (which must be a lower case letter, upper case letter, or a digit). All of the commands between the '<' and the '>' (except for the macro name character) are saved. Once a macro has been defined, it is used by typing the ESCAPE character followed by the macro letter. As an example, the command string '<gththtuktntj>' defines a macro named 'g' which causes a glider to be inserted at the current cursor position every time you type '<ESC>g'. The macros for the digits 1 to 9 are automatically bound to the function keys under X11. For example, hitting the F5 key will execute - 23 - Formatted: November 14, 2024 LIFE(1) LIFE(1) macro 5. While defining a loop or macro, you can request user intervention by using the ';ttyinput' command. This will suspend the execution of the loop or macro and notify the user that input is desired by displaying 'tty-input' in the status line. The user can then execute any commands of his choice. When he is ready to proceed, he uses the ';endinput' (or a control-D) command to continue execution where it had paused. Different commands can be given by the user each time the loop or macro asks for terminal input. If the command ;ttyinput -c' is used, terminal commands will only be asked for if there is any terminal input available to be read. Normally, the screen is not updated while a macro or loop is executing. Thus a complicated command sequence can be executed without letting the user see what is occurring until it is finished. However, if you wish to update the screen in the middle of execution, then use the ';update' command. Commands given by the user automatically do an update whenever no more user input is available. The ';dump' command writes out the definitions of all macros and button assignments so that you can read them back in later. USING THE MOUSE When running under X11, the mouse can be used to move the cursor to any position within the view in a window, and can also optionally execute a command macro of your choice or mark the cells within an area dragged by the mouse. Mouse positioning can be reasonably used within a macro or loop definition since mouse events are always translated to the appropriate 'l' and 'j' relative movement commands and executed in that form. When a mouse button is pressed down (without any modifier keys) a rectangular dragging area is started at the cell specified by the mouse. While the mouse is moved with the button held down, a dragging rectangle is shown on the screen from the starting cell to the cell at the current mouse position. When the mouse button is finally released, the dragging rectangle disappears and the dragging coordinates are saved into the current object. If the mouse was not moved, then a dragging area of one cell is assumed. If a key is typed while a drag is in progress, then the dragging is aborted and that key is ignored. If no command macro is assigned to the mouse button that was pressed, then some default actions are performed on the object when the button is released. Firstly, the cursor is moved to the cell where the button was released. In addition, if the drag area is larger than one cell and no generations are being run, then the cells within the dragged area are added to the current set of marks. - 24 - Formatted: November 14, 2024 LIFE(1) LIFE(1) If a command macro is assigned to the mouse button, then when the button is released the cursor is moved to the specified cell and then the command macro is executed. The cells in the dragged area are NOT marked in this case. The macro can refer to the dragged area using the 's' set specifier, or the variables 'dminx', 'dmaxx', 'dminy', and 'dmaxy'. The ';assign' command assigns a mouse button number to a command macro. It accepts two arguments. The first argument is a button number, and the second argument is a macro name. The normal three mouse buttons are numbered 1 to 3. If configured properly, the mouse scroll wheel will generate buttons 4 and 5. Using a modifier key (such as SHIFT) with a button or scroll wheel adds five more possibilities numbered 6 to 10. With the proper command macros being defined and assigned, this lets you use the mouse buttons for many useful operations like toggling cells, deleting pieces of objects, or repositioning the view, A button can be unassigned using the ';assign' command without any macro name. This restores the button's default action which just moves the cursor to the specified cell and marks dragged areas. The mouse's scroll wheel can be used to zoom the view of the current object in or out. Each click of the scroll wheel is has the same effect as using the ';zoom' line mode command. VARIABLES The program provides numeric variables which you can use to control your commands. Variables are used as numeric arguments to commands. Variables come in two kinds. These are the user-defined single character variables, and a set of predefined multi-character variables. There are 52 single-character variables, whose names are the lower and upper case letters. All of their values are initially zero. When used for a character mode command (and without the use of parenthesis), variable names must be preceded by a dollar sign to distinguish them from commands. For example, the command '$mo' inserts as many live cells in a row as is contained in the value of variable 'm'. When used within an expression for a line mode command, or within a set of parenthesis in a character mode command, the dollar sign can be dropped since the parser knows to expect a variable name in these cases. For example, the command ';type m' will display the value of variable 'm'. Similarly, the command '(m*2)o' will set a number of live cells equal to twice the value of variable 'm'. Single character variables are set by using the ';set' command, which - 25 - Formatted: November 14, 2024 LIFE(1) LIFE(1) takes a variable name followed by an expression. For example, the value of variable 'e' can be tripled by using the command ';set e e * 3'. As a shortcut for a common operation, the '+c' character mode command increments variable c. (A numeric argument can be given to specify an increment value other than than 1.) One common use of variables is inside a macro in order to execute a command string over and over again with only small differences each time (such as to vary the placement of two objects with respect to each other). As an example of this, the command '<q$ao3+a>' will define a macro called 'q' which will insert a number of live cells in a row (as determined by variable 'a'), and the number of cells inserted increases by 3 for each use of the macro. The other kind of variables are the multi-character variables. These are a fixed set of names, and their values represent specific things which are not directly modifiable. These things are values associated with the current object. For example, the 'cx' variable returns the absolute x coordinate of the current cursor position, and 'oy' returns the absolute y coordinate of the origin. The set of variables names 'w<ch>x' and 'w<ch>y' where ch is a lower case letter represent the x and y coordinates of the 'where' variables. You can see the complete set of variables by using the ';variables' command. The variables at the top of the display are always listed no matter what their value is. But the rest of the variables are only listed if their values are nonzero. This applies to both the single character variables and the 'where' variables. If an argument is given to the command then only those variables whose name contains that argument is shown. The ';type' command is useful to perform calculations on the relative positions of cells. For example, to find the number of columns between two positions which are far apart, you can move the cursor to the first position, use the 'Wa' command to set the 'where' variable 'a' to that position, and finally move the cursor to the second position. Then the command ';type cx - wax' will display the number of columns separating the two positions. The lastest value printed by the ';type' command is available for use in later expressions by using the '.' symbol. Since the parser must be able to distinguish multi-character variable names from command letters or single-letter variable names, you cannot use them in character mode commands without surrounding them with a pair of parenthesis. As an example of multi-character variables used as an argument, the command string '((vmaxx-vminx)/2)h' shifts the cursor to the left by an amount equal to half of the screen width. FILE HANDLING The ';read filename' command reads in a command file, or else a - 26 - Formatted: November 14, 2024 LIFE(1) LIFE(1) description of a Life object in either a subset of the xlife format, a rle format, or a quadcell format. The read command automatically distinguishes these different formats depending on the data in the file after skipping leading empty lines or lines beginning with the comment sequences '#C', '#N', or '#O'. The tab character can be used in the ';read' command to try to perform filename completion. Filename completion examines all directory names and all file names matching "*.l", "*.lif", "*.rle", or "*.mc" within the directory indicated by the filename argument, taking into account all of the Life library paths. If there is only one match found, then it will be inserted into the command line, followed by a space if it is a file name, or a slash if it is a directory name. If there are multiple matches, then any common leading characters are inserted into the command line, and a list of the matches is displayed. Directories are indicated by trailing slashes. If no matches are found, then a beep will be sounded. Command files can execute any of the Life program's commands, but normally contain a picture of an object to be inserted. Thus for small objects, you can simply create a picture of an object in an editor, and then the object can be read in by the Life program. Here spaces or periods represent OFF cells, and 'O, 'o', or '*' characters represent ON cells. Lines beginning with '!' are ignored, so that you can comment your objects. Command files must begin with any of the characters which are used to represent OFF or ON cells, or one of the '!', ':', or ';' characters. The xlife format is a list of coordinates of live cells which are generated by the well-known xlife program. (Indirect files are not supported.) Files which begin with a '#' character (after leading blank lines and comment lines are read) are assumed to be in xlife format. The rle format is a "run-length encoded" format which is a very good compact storage format for objects. It is also able to save and restore some of the markings of an object. This is the smallest storage format for large objects, but has the disadvantage that any description of the object in the file must appear at the end of the file. Files which begin with a 'x' character (after leading blank lines and comment lines are read) are assumed to be in rle format. The quadcell format (also known as macro-cell format) is a very good compact format for objects which are extrememly large, particularly if the object has some regularity in its structure. This is the only format which can reasonably handle objects with a huge number of live cells (e.g., billions or even more). Files which begin with '[M' (after leading blank lines and comment lines are read) are assumed to be in MC format. When reading an input file, the program looks for several different - 27 - Formatted: November 14, 2024 LIFE(1) LIFE(1) file names in sequence. It starts by looking for the file name as given. Then it looks for the name with an '.l', '.lif', '.rle', or '.mc' extension appended. Then, if the -l option had been used to specify a one or more personal libraries, then it looks in the specified directories for files. Finally, it looks in /usr/local/games/lib/life for files. Thus there is a standard library of interesting Life objects, and you can create your own Life libraries. When the ';read' command is used from the terminal, and has completed reading of the input file, then the current object is copied to the special "..read" object. This is a convenience since after running or editing an object, it can be restored without having to read it in again. Instead of supplying a file name for the ';read' command to read from, the '-inline' option can be used to read an rle or xlife formatted object which follows the command in the current command file. If an rle object was read, then further commands are read from the current command file starting from the line after the terminating '!' of the rle object. This feature can be used, for example, to read multiple rle encoded objects into several buffers from one input file, or else to define a complicated birth/death rule set before reading of the object. The '-inline' option can only be used within a command file. The ';load' command reads in an object similar to the ';read' command, but the object is read into a new buffer having the same name as the file name, modified slightly if necessary, and the view is changed to show that new buffer. Multiple objects can be read in one command. The ';information' command displays any comments if any that were present in a file that has been loaded. It accepts an object name, defaulting to the current object. The ';list' command will display a list of those files having the known life extensions that can be read in. If given an argument, then only those path names which contain the specified string will be listed. For the library directories, ';list' will show the Life files within several levels of subdirectories. For example, ';list gun/' will list all the Life files within a directory called 'gun'. The '- d' option can be given to the ';list' command to show the files with the life extensions in a specified directory. If no directory is given, then '.' is used. The ';prefix' command sets or displays a path name prefix to be applied when reading or listing files. This feature acts somewhat like a 'cd' command but still provides for the capability of searching through multiple library directories. If an argument is given, then the prefix is set to the specified path, otherwise the current prefix is displayed. The prefix can be either - 28 - Formatted: November 14, 2024 LIFE(1) LIFE(1) an absolute or a relative path name. A relative prefix allows library searches to take place using that path. An absolute prefix disables library searching so that only files in the specified path will be found. Setting the prefix to '.' clears the prefix and restores the default behavior. When the ';read' command is used to read a file using a relative path name, the prefix is inserted at the front of the file name along with a slash. This full file name is then searched for relative to the current directory and the list of library paths. When the ';list' command is used to list Life files, the prefix is appended to the library directories to restrict the listing to the files in the resulting paths. The displayed list of file names does not show the prefix path. The prefix is not applied if the -d option is used for the ';list' command. The command ';write filename' is used to save the current object to a file. The file can be written in any of the pictorial, xlife, rle, or mc formats. The default format is rle. You can specify the desired format using one of the -picture, -xlife, -rle, or -quadcell options within the write command. (These options can also be abbreviated to single letters.) For example, ';write -x it.l' will write the current object to 'it.l' in xlife format. If an option is not used then the extension of the output file determines the file format. The '.mc' extension selects quadcell format, whereas any other extension specifies rle format. If the object contains a large number of cells (i.e., many millions), then the only format which can be used is the quadcell format. The writing of quadcell format is possible even if the object's algorithm is 'list', but it might take some time if the object is complicated. When writing an object to a file in the pictorial format, what is written is a sequence of commands which regenerates the object using the normal commands of the program. The choice of commands is such that for small objects, the commands look like a picture of the object. Thus, the object is written using the commands '.' (to move right), 'o' (to insert cells), and '\n' (to move to the next line). (Periods are used instead of spaces so that you can count the spaces between live cells easily.) When writing out an object, if it is very wide or long, the output will contain repeat counts as necessary in order to compress the resulting file. The ';write' command does not use the ';prefix' path in any way. Files are written using a filename exactly as specified. Confirmation is required if an existing file is being overwritten. ALTERNATE RULES The rules of Life can be changed to some degree. This allows you to - 29 - Formatted: November 14, 2024 LIFE(1) LIFE(1) explore alternative Life universes. You can specify a standard totalistic rule which describes how many live cells are required for a cell to be born, or to stay alive. Alternatively, you can specify a non-totalistic rule which depends on any set of combinations of the nine cells which make up a neighborhood. To change the cells needed for birth or death, use the ';rule B<born>/S<live>' line mode command. The <born> string lists those counts of neighbors which are required for a new cell to be born. The <live> string lists those counts of neighbors which are required for an existing cell to stay alive. The standard rules are thus described by the command ';rule B3/S23'. For convenience, you can omit the B and S characters, and use a comma instead of a slash, and use lower case. You can also swap the born and live rule values, as in ';rule S<live>/B<born>' To set a symmetric non-totalistic rule, any digit can be followed by one or more letters which indicate neighborhood types, and then can be followed by a dash and more letters. The letters preceeding a dash restrict the neighborhoods to the specified set. The letters following a dash remove the neighborhoods for the specified set. The letters and their neighbood meanings were defined by Alan Helsel, and can be seen at his web site. As an example of using a non-totalistic rule, the command ';rule b2-a/s12' specifies the 'Just Friends' rule. Many other Life programs (e.g., Golly) also understand these rules. For non-symmetric rules, you can use the ';rule' command to specify one or more combinations of cells in the nine-cell neighborhood. Each combination defines a condition for which the central cell will be ON in the next generation. The syntax for these rules is specific to this Life program. The combinations use a syntax in which the cells of the nine-cell neighborhood are labeled with lower case letters as follows: abc hid gfe Here the central cell whose next state is being computed is identified by the letter 'i', and the eight neighboring cells are labeled clockwise around the central cell by the letters 'a' through 'h'. A combination consists of one or more conditions concatenated together. Each condition is made up of some digits followed by some letters. The letters specify a subset of the nine neighborhood cells shown above. The digits specify the number of live cells to be found in that subset. If multiple digits are specified, then the set of cells can have any of the specified numbers of live cells. If no digits are specified, then the single digit of 1 is assumed. If there are letters not used in a combination, then they are implicitly added - 30 - Formatted: November 14, 2024 LIFE(1) LIFE(1) with a count of 0, indicating that the missing cells must be OFF. Multiple combinations are separated by commas. A combination can optionally begin with one of the letters 'A' or 'S'. This indicates that the combination is to add to the existing rule, or is to subtract from the existing rule. If these letters are missing, then the combination follows the same adding or subtracting behavior as the previous combination. The complete rule string must start with the 'N' character. If the first combination after the 'N' character does not start with 'A' or 'S', then the existing rule string is cleared and the combination uses the adding behavior. By using 'A' or 'S', multiple ';rule' commands can be used to build up a rule set. For example, the command ';rule N2abc2efg,i12hd' has the same result as the sequence of commands ';rule N2abc2efg' and ';rule NAi12hd'. As an example of using the non-symmetric rule syntax, the normal Life rule can be specified by using the command ';rule N01i3abcdefgh,i2abcdefgh'. This means that there are two combinations for causing a cell to be alive in the next generation. The first combination is that the central cell can be either dead or alive and exactly 3 of the surrounding cells must be alive. The second combination is that the central cell must be alive and exactly 2 of the surrounding cells must be alive. INTERRUPTS While the program is doing something which can take a long time, such as computing generations, defining or executing a macro or loop, or writing out a large Life object, you can type the interrupt key and that action will be aborted at a convenient point and you will be returned to the top command level. When running under X11, remember that the interrupt key must be typed to the xterm which started the Life program, not in the Life window itself. CHARACTER MODE COMMAND SUMMARY The following table lists all the character mode commands, arranged in useful categories. These can be preceeded by one or two numeric arguments. --- MOVEMENT COMMANDS --- SPACE move right <arg1> cells l move right <arg1> cells h move left <arg1> cells l move right <arg1> cells k move up <arg1> cells j move down <arg1> cells y move upper left <arg1> cells - 31 - Formatted: November 14, 2024 LIFE(1) LIFE(1) u move upper right <arg1> cells b move lower left <arg1> cells n move lower right <arg1> cells LF move to next row and to the column of the origin TAB move to next multiple of 8 from the origin column @ remember current location as the origin c move to location <arg1>, <arg2> relative to the origin C<set> move to closest cell in the specified <set> W<ch> remember current location in where variable <ch> (a-z) w<ch> move to location <arg1>, <arg2> relative to where variable <ch> (a-z) / move cursor to the next piece of the object --- SCREEN COMMANDS --- s set viewing scale to <arg1> and center view (default current scale) S turn on auto-scaling and center view H shift view left by width*<arg1>/<arg2> L shift view right by width*<arg1>/<arg2> K shift view up by height*<arg1>/<arg2> J shift view down by height*<arg1>/<arg2> Y shift view left and up U shift view right and up B shift view left and down N shift view right and down <FF> (form feed) refresh the screen --- SINGLE CELL COMMANDS -- t toggle cell at current location o insert <arg1> cells and move cursor right O insert <arg1> cells and move cursor right * insert <arg1> cells and move cursor right x kill <arg1> cells and move cursor right --- MULTIPLE CELL COMMANDS --- d<set> delete cells described by <set> fr<set> flip cells around current row as described by <set> fc<set> flip cells around current column as described by <set> r<set> rotate cells 90 degrees clockwise as described by <set> m<set> mark cells as described by <set> p place last deleted object at current location --- LOOP, VARIABLE, AND MACRO COMMANDS --- < begin loop which executes from <arg1> to <arg2> times (if <arg1> given) <<ch> begin definition of macro named <ch> (if <arg1> not given) - 32 - Formatted: November 14, 2024 LIFE(1) LIFE(1) > end loop or macro definition ESC<ch> execute a macro command named <ch> +<ch> increment the value of the single-character variable <ch> by arg1 --- MISCELLANEOUS COMMANDS --- g compute <arg1> generations (or stop if running) G compute infinite generations a Add line segment to current path A Close current path D Set drag area relative to current cell z set generation number to <arg1> (default zero) ! ignore characters until end of line # ignore character until end of line ;<line> execute a line mode command :<line> execute a line mode command Arguments specified above as <arg1> and <arg2> can be any of the following: <var> value of variable <var>, where <var> is a lower or upper case letter (expr) an arithmetic expression containing constants, variables, operators, and built-in functions % current loop counter value <num> explicit numeric value LINE MODE COMMAND SUMMARY The following lists all of the line mode commands. Each of these commands is started with a colon or semi-colon character, and terminated with a new line character. Words inside of parenthesis are noise words which just help explain the command syntax, and are not actually part of the command. This list can be obtained using the ';help' command. advance (marked cells) expr (gens) algorithm (for object is) type alias (command) name (to) value assign (button) num (to macro) ch backup (current object to base) obj border (width is) width center (object around) location clearpath (from current object) close (current window) color (of) type (is) color copy (current object to) obj copymarked (cells to) obj destroy (object named) obj default param (to) expr - 33 - Formatted: November 14, 2024 LIFE(1) LIFE(1) delay (between updates) expr (msec) dump (initialization data to) file edit (object named) obj endinputlevel factorize (value of) expr force (running) expr (gens) frequency (of typeout is) expr fullscreen (mode is) action get (current object from) obj grid (parameter) name (value) value help hide (sub-window type) type information (about object) obj insert (cells from) obj invert (marks for all cells) jumping (of generations is) expr list (readable life files) load (object from) file ... locations (shown are) action locations items margin (around edges is) value minmax (action is) value mode (for movement) move (current object to) obj movemarked (cells to) obj next (object) objects (are listed) outlines (are) action overlay (object) obj positioning (method is) method prefix (for file paths is) path private (window settings are) list quadcell (statistics are) action quit (program) randomize (live chance) percent read (object from) file redo expr (changes) rename (current object to) obj restorepath (to current object) rule (for life are) born,live set (variable) name (to) expr settings (action) shape (for drawing cells is) shape shared (window settings are) list shift (factor for movement is) expr shortenpath (from current object) show (current window settings) size (for new) type (is) percentage status (line is) action stop (calculations on) condition subwindow (using settings) name ttyinput - 34 - Formatted: November 14, 2024 LIFE(1) LIFE(1) tracks (for dead cells) action type (value of expression) expr undo expr (changes) unmark (all cells) update (view to be current) variables (are listed) phrase view (location is) parameter wait (for computations) window (using settings) name write (current object to) file zero (current object) zoom (view) dir In the above, expr is an arithmetic expression, and obj is an object name. Expressions can use the plus, minus, multiply, divide, modulo arithmetic operators, the raise to power operator, relational operators, arithmetic AND and OR, and parenthesis for grouping. They can use integers, variables, and the built-in functions gcd, lcm, min, max, abs, factor, and sign. OPTIONS The program accepts options both from the command line and from the LIFEOPTS environment variable. If defined, the LIFEOPTS environment variable contains a list of options as used on the command line. The Life program processes these options first, then processes the options given on the command line. If conflicting options are found, then the last ones specified are effective. Here are the possible options when starting the Life program. -h Print a quick summary of the options and exit -v Display the version number of the program and exit -t Use terminal output -g Use graphics output (X11) -a <algorithm> Set the default algorithm for objects -f <font> Use the specified font name for graphics output -s <value> Initialize the default scale to the given value -l <libdir> Set another personal library directory -i <initfile> Reads another file for setting macros and buttons <filename> An initial object to be viewed The -t and -g options specify the output device for the Life program. Using -t uses the current terminal for output using curses. Using -g uses X11, and a new full-screen sized window is opened for output. If neither option is used, then graphics is assumed. Almost all commands work identically between the two different modes of operation. The main differences are simply the differing resolutions of the displays and the optional use of a mouse. The -a option specifies the default algorithm to use for new or zeroed - 35 - Formatted: November 14, 2024 LIFE(1) LIFE(1) objects. The argument can be 'list' or 'quadcell', with abbreviations allowed. The default algorithm can be changed later using the 'default' command. The -f option specifies the font name to be used when graphics is used. The specified font should be a fixed-width font. If this option is not specified then the fixed font is used. This option is ignored if output is to the current terminal. The -s option specifies a scale factor to be used by default for displaying Life objects. This default scale factor can be changed during execution of the program. The -l option specifies an additional library directory to be searched when Life objects are read in. This directory is in addition to the current directory and the system library directory /usr/local/games/lib/life. This option may be used up to 10 times to specify a number of library directories. The -i option specifies the filename of an initialization file which contains commands to configure macros and button assignments. But the file can actually execute any commands and so could automatically load some Life objects, for example. The only restriction is that the initially displayed object is always cleared after this file is read. This option may be used up to 10 times to specify a number of initialization files. A filename without any preceeding option character is a Life object to be read in and initially displayed. It is placed in a buffer whose name is the same as the last component of the file name, or close to that if there is ambiguity. If no filename is given, then the initial object is empty and the buffer is 'main'. Multiple filenames can be given. APPENDIX - THE RULES OF LIFE This is a short introduction to Conway's Game of Life. Life is played on an infinitely large board divided into squares. Each square is called a cell. Each cell can be either dead or alive. Dead cells are seen as blanks, whereas live cells are seen as non- blanks. You begin to play by choosing some arbitrary set of live and dead cells. This configuration is called generation 0. There is a set of rules which transforms this set of cells into another set of cells, called generation 1. These same rules are then reapplied to generation 1 to produce generation 2. This process continues indefinitely. The 'purpose' of the game is to find starting patterns such that 'interesting things' result. - 36 - Formatted: November 14, 2024 LIFE(1) LIFE(1) The rules which are applied are as follows. Take any cell of a generation, and call it the current cell. Consider the eight cells immediately adjacent to the current cell. Count the number of these eight cells which are alive. If the current cell is dead and the count is 3, then the current cell changes to a live cell in the next generation. If the current cell is alive and the count is NOT 2 or 3, then the current cell changes to a dead cell in the next generation. Otherwise the cell remains unchanged in the next generation. This rule is applied to every cell of a generation SIMULTANEOUSLY. Thus to rephrase, 3 live neighbors causes a new cell to be born, whereas 2 or 3 live neighbors keeps a cell alive. To see how these rules work in practice, run the program and start with some number of live cells in some arrangement, and watch the generations change. If you can predict what the changes will be, then you understand the rules. The following are some objects to try, along with some descriptive names. Warning: the last example gets complicated! O O O O OO O OO OO OO O OO O O O O OOO O blinker beehive block traffic lights glider r-pentomino AUTHOR David I. Bell dbell@tip.net.au 21 April 2024 - 37 - Formatted: November 14, 2024