The game is played on essentially what is a 40 x 24 board. I have always suspected this to be the case if you look at the regularity of how small growth is drawn on the screen. They all line up in rows and columns.

There are (at least) two copies of the game board in memory, one at 0x25500, and one at 0x260B8. Each portal or growth is in one cell of the game board. There are some areas of the game board that are reserved and never used, for example, the central face never has growth covering it, and the first two and last columns are also “out-of-bounds”. I suspect there are also limits on the corners so growth does not cover the stars representing the number of lives (too much). This may mean that the growth is drawn last in the order that elements are drawn to the screen.
The size of growth is stored as a value between 0x01 and 0x0A (modified by +0x90 to represent growth that has been shot) in the board at 0x25500 and modified by +0x00 to represent evil growth, +0x10 to represent good growth, or +0x20 to represent evil growth that has been shot in 0x260B8.
I don’t think this is the whole story yet. Writing data values into these memory locations mid-game to create new portals or growth does not seem to make any difference. There appears to be other memory locations (0x264A0 and 0x0336DE) referenced. I still need to investigate those.


This is how I see memory locations starting at 0x25500 (left) and 0x260B8 (right) are represented as the game board on screen. Looking at the level data, portals are placed at offsets from these starting memory locations.
There is a routine at 2E39A that uses modulus division by 0x28 (40 in denary), and storing the results into variables $400, $402 (and $40A?) which provides evidence for this game board representation.

Playing through Constellation 1, Star 0 (C1S0) and taking a 10kb memory dump at both 0x25500 and 0x260B8, converting the data into the format above gives us some information about how the game board is structured.
There are variables at $506 to represent the number of evil portals remaining, and $508 to represent the number of good portals remaining.

At the very start of the level, you can see the level data has been loaded without any growth. On the left hand side ( 0x25500), the data is mostly 0x00, except for where portals are – these locations contain 0xFF. In the middle (0x260B8), the data is mostly 0xFF. The single evil portal in this level contains 0x00. The five good portals contain 0x10. The memory locations that these values are written into correspond to the screenshot of the level at this point.
$506 (evil portals) = 0x01 (1 in denary), $508 (good portals) = 0x05 (5 in denary)

A frame or two later, we have growth! The size of the growth is represented as a value between 0x01 and 0x0A (1 – 10) and has only happened around the good portals. In the middle picture (0x260B8), these values have been modified by +0x10.

The growth continues. This layout looks pretty convincing. We now have our first size 2 growth in the bottom right patch.

The first evil growth shows on the left, that is just stored as the size of the growth, but in the middle, the size is modified by +0x00 if it is evil, and +0x10 if it is good. Some increase in growth size – some values in the good growth in the left hand picture have increased to 0x02 (and 0x12 in the middle picture).

Some increase in growth size – the bottom right good portal has produced a growth with size 0x04. The evil portal has produced another evil growth. Again, these positions correspond to the game board in the screenshot.

As the level progresses more, the sizes of the growth increase and you see a corresponding increase in the value of the memory location holding that growth on the game board.

Experimenting shooting the evil growth – the left hand side now modifies the values by +0x90, and the middle by +0x20.
I am assuming that the modification on the left hand side prevents the shot growth from growing and allows it to be covered by good growth.

We have now reached the maximum size 10 (0x0A) for the growth in some areas. Shot growth reverts back to their original values (-0x90 on the left and -0x20) in the middle. There must be a counter/timer somewhere for each of this shot growth as it can revert back.
$506 (evil portals) = 0x01, $508 (good portals) = 0x08 (8 in denary)

Placing more good portals. This representation of the data structure for the game board seems to be a good fit for what is shown on the screen shot.
$506 (evil portals) = 0x01, $508 (good portals) = 0x0B (11 in denary)

Shot evil growth reverts back.
$506 (evil portals) = 0x01, $508 (good portals) = 0x0D (13 in denary)

Most of the game board is covered with good growth at this point. It also shows the boundary for growth surrounding the central face.

Letting the timer run out for the level shows the start of the evil portal takeover and rapid evil growth.
Why some double portals, and some single portals? I suspect this is the same pattern on every level that the timer runs out on, rather than procedurally placed. I will need to play more levels and let the timer run out to check.
$506 (evil portals) = 0x23 (35 in denary), $508 (good portals) = 0x11 (17 in denary)
Interestingly, the good growth in the top left hand corner has reached size 5, and slightly covers the star (life) in the top left, so I now suspect the game board is drawn to the screen last, after the score, timer, stars and face. first two columns (0x0 and 0x1) are left out-of bounds for the score and timer to show, the stars (lives icons) are drawn at positions (0x2,0x0), (0x2,0x16), (0x25,0x0) and (0x25,0x16) taking up a 2×2 area. The final column (0x27) is also left out-of bounds.
If the screen resolution for the Amiga and ST versions are 320x200 pixels in 4 bitplanes (16 colours) Amiga NTSC LowRes, (ST LowRes), this may mean that each game square is an 8x8 block of pixels. (320/40 = 8, 200/24 = 8.3). So a playing area of 320×192 pixels?
The lives icon graphics are 16×14 pixels. The timer graphic (bird/snake) is 16×64 pixels. This reinforces the 8×8 pixel grid – if the first two columns were left blank to not cover the timer or score, 2×8 pixel columns would be 16 pixels wide.

Level lost as the time has run out – all the good portals have been covered by evil growth.
$506 (evil portals) = 0x23 (35 in denary), $508 (good portals) = 0x00 (0 in denary)
Playing through Constellation 1, Star 1 (C1S1) reinforces what we’ve learned about how the game board is represented.

I need to find how the portals produce spores and how they are stored in the structure.

Placing a good portal at the bottom right on the sun face helps me find the limits of where the central character boundary for the growth is. You would expect growth to radiate out from a portal, but there are distinct areas of the screen where growth cannot grow.

The level is won.
$506 (evil portals) = 0x00, $508 (good portals) = 0x0B (11 in denary)

That is a huge amount of work, congrats!
LikeLiked by 1 person