Thank you for your donation!   Download the book!   Join the group!   Public source code repository
Showing posts with label reasoning. Show all posts
Showing posts with label reasoning. Show all posts

Status update

Hello, everyone! Here's a (bi)monthly update on things and stuff. I haven't wrote anything for last two months since I didn't have anything intelligent to say, except maybe "I'm still working on stuff". I still do, but now I wanted to share current status and a few thoughts with you.

First of all, as you might have seen it in my Codeberg repository, I'm still working on classical pieces, previously I supported all usual suspects (Bishop, Rook, Queen), then added support for Knight. Now I'm still working on King, I finished support for movement and castling on all variants, and wrote all relevant tests.

Now I'm working on checks if a field (and a piece on it) is under attack; or, should I say, again. Reason for rework is me being "clever" to speed-up development. Code was finished, tests (mostly) passed, everything was fine, except I overlooked pieces positioned between an attacker and a target. Sure, some are transparent to attacker, but not all. And so I had to get back to a drawing board, and the change isn't as simple as one would expect based on previously done code.

After support for King is finished, I'll start working on Pawns. I don't like to try to predict how long it'll take; but I'd like to finish it by early-to-mid October, since I might have some other (family) obligations, and most likely I won't be able to work at all for a week, or so (I hope); period of forced inactivity might be longer. Anyway, when support for Pawns is finished, I'll publish the very first public code release.

Generally, I agree with Drew DeVault that developers should do only code, and administrators should do distribution, but in this day and age that stance isn't very appealing, or convenient. So, I'll take a look at ways to make executables available for different platforms. So far, I have been ignoring CI/CD, or any other builders; on the other hand, application which isn't easily accessible is effectively dead.

After that, I plan on adding support for canonical variants in order of appearance, starting with Mayan Ascendancy; Croatian Ties is already supported. Recently, I started indulging myself again into thinking about changing some pieces and rules. I have already complained that Centaur might be too OP, even as I did significantly cut its reach. I already come up with a solution to straighten its course, but I'll leave this idea to take a proper shape on its own, rather then being forced into existence. You see, I really like its jumpy frolicking movement as-is, and would like to keep it if possible; problem is that at the moment I  really don't see a simple solution. Of course, if this come to pass, Waves activated by Unicorns and Centaurs would also get their straightening treatment.

There are also some other candidates likely to get rules updated, namely Starchild; regular visitors know I  already promised it'll get a proper revision, or at least a polish. Another candidate is Monolith, I don't like its diamond shaped movement pattern, it simply doesn't belong to it; but at that time I couldn't make my mind about simple to visualize, accelerating pattern. Yet another candidate is Serpent, although this change would be very simple; I'll just restrict its movement a bit, this time after I calculate its power compared to other pieces.

For now, this is mostly it. Take care!

The very first move

So far, I was trying to build game engine library which can do all variants and all pieces from the book right out-of-the-box. Recently, it occurred to me that might be a bite too big to chew. So, I decided I'll focus on simple and randomized variants, and support only classical pieces (+ Pegasus) at first. That way, I'll build complete stack, something useful for users, even if it's just a console application. Let me know if you'd prefer GUI application; depending on feedback, I might also do it. Of course, that would  mean more advanced variants won't be supported for quite some time. Currently, I plan to add them one by one, in order of appearance in the book.

Oki-doki, so I added support for all randomized variants, and simple pieces without special movement are all supported; that is Bishop, Knight, Rook, Queen, Pegasus. King can move, but currently castling is not supported. Pawns are also not supported at all, including en passant and promotion. So, only one side-effect is supported, that is capturing. Before I can publish first public version, I'll also have to add test if King is in check, and if a field is under attack (to test for legality of castling). Saving and loading current chessboard is also not planned for the very first release; simple (and randomized) variants can be played in one sitting. The same applies to in-game chess clock, I presume no one will play new variants in tournaments from the get-go.

How does it look like? Well, I took screen-full of texts from console application:

> new cc14u
   a b c d e f g h i j k l m n
   ---------------------------
14|r r n r n n r k b q b b n b|14
13|p p p p p p p p p p p p p p|13
12|. , . , . , . , . , . , . ,|12
11|, . , . , . , . , . , . , .|11
10|. , . , . , . , . , . , . ,|10
 9|, . , . , . , . , . , . , .| 9
 8|. , . , . , . , . , . , . ,| 8
 7|, . , . , . , . , . , . , .| 7
 6|. , . , . , . , . , . , . ,| 6
 5|, . , . , . , . , . , . , .| 5
 4|. , . , . , . , . , . , . ,| 4
 3|, . , . , . , . , . , . , .| 3
 2|P P P P P P P P P P P P P P| 2
 1|N R N B B N R B B K R Q N R| 1
   ---------------------------
   a b c d e f g h i j k l m n

this creates new chessboard for Classical Chess 14 unbalanced variant. As is custom across console chess applications; dark pieces are lowercase, while light ones are uppercase; in notation all pieces are written uppercase, regardless of color. Since Pawns can't be moved, today there won't be much of a game-play, but Knights can jump over them:

> move Nd3
   a b c d e f g h i j k l m n
   ---------------------------
14|r r n r n n r k b q b b n b|14
13|p p p p p p p p p p p p p p|13
12|. , . , . , . , . , . , . ,|12
11|, . , . , . , . , . , . , .|11
10|. , . , . , . , . , . , . ,|10
 9|, . , . , . , . , . , . , .| 9
 8|. , . , . , . , . , . , . ,| 8
 7|, . , . , . , . , . , . , .| 7
 6|. , . , . , . , . , . , . ,| 6
 5|, . , . , . , . , . , . , .| 5
 4|. , . , . , . , . , . , . ,| 4
 3|, . , N , . , . , . , . , .| 3
 2|P P P P P P P P P P P P P P| 2
 1|N R , B B N R B B K R Q N R| 1
   ---------------------------
   a b c d e f g h i j k l m n

and, there it is!

In short, there is still a long way to first release, this is just a peek into progress made so far.

One step back, two forward

So, I moved to new online Git repository, but since then there was no update on project status. Well, this is it; somewhat overdue, I admit, but with a (good?) reason. You see, most of my followers are chess enthusiasts, not programmers; so, I postponed my initial post since it's not that interesting, then got side-tracked, again (as one does).

In the meantime, there has been some progress on generating paths a piece can make, then comparing those generated paths with user notation, and finally executing a move if a unique match has been found. Due to a sheer scale and count of cases, tests has been separated into different executable:


All tests run One variant, since it's the most complex one, and features one of the largest chessboards in the book. One of tests (out of a few dozens!) is this one: "ta 9" command simulates user who typed "Bg3*N", and given the situation on a chessboard bellow, test then tries to establish if there is a full path (step-by-step) and side-effect (capturing), that matches user notation: 


The first thing to do is to find moving piece and its starting position. This isn't as straight-forward as one might think: there might be multiple pieces of the same kind, some with or without a tag, and sometimes opponent's pieces qualify as well, e.g. if activated in a cascade.


After finding a moving piece, all possible paths were generated; in the printout those are indented since they're all connected to each other, in one big, branching tree. The first line shows starting position ("d6"), then piece found at that position ("B", that is light Bishop) and its tag ("!", that is no tag found)., then activator (empty, since this is the first piece in a move), then momentum ("0"), which is still being accumulated ("+"). Lines starting with "<" are forking paths, i.e. all paths connected to it would inherit previous path segment(s), while lines starting with "^" are alternative paths, i.e. would replace other previous segments. Forking paths are used after the starting position, and after divergence. Alternative paths are used if there are multiple possible side-effects (interactions) between moving and stationary pieces; or, as an alternative path segment to a fork in a path. Note, alternative paths do not include displacements since there are too many possible destinations; those are handled differently (as a list of tentative (i.e. all possible) displacements, for each step).

All possible steps a piece can make are enumerated in a list, separated for each piece; enumeration starts from x-axis (3 o'clock) and then goes anti-clockwise. This is why here the first segment after the starting position goes all the way to "x26", then to "a9", then "a3", and finally to "g3". At that last path segment, application found dark Knight ("n"), with no tag ("!"), and established it can be captured ("*N" as a side-effect to the last step of a generated path segment). Momentum of a light Bishop at this moment is "3+", meaning that Bishop had already made 3 steps, and is still accumulating momentum.

Now all paths has to be generated by traversing path tree, and stitching together path segments from starting position to the very last step; each leaf node in a tree ends one path. Those generated paths are then compared to user notation, to see if there is a unique match. Except, that's not entirely correct; due to the need to maximize accumulated and minimize spent momentum, paths are searched for the shortest possible path, and then for the longest, if different. So, the longest path is preferred for the first piece in a cascade, otherwise the shortest path is used. Here, there is only one path possible, so it's saved as the shortest one, e.g. "d6.e5.f4.g3*N".

After unique path has been found, it's time to apply it to the chessboard:


As one might imagine, light Bishop left its starting position, and replaced dark Knight on a chessboard. Except, that is how it would have been done in a physical world. In virtual, digital world light Bishop on its starting position was replaced with None piece, i.e. the one used when there is no piece on a particular position; and then dark Knight on a destination field has been replaced by light Bishop after it has been stripped of its tag, even if it didn't had any. After movement all pieces lose their tag; but, tag stripping is such a simple operation that I didn't bother to check if a piece doesn't have any.

As you can see from a very cursory glance into game engine, it's not that simple to explain it, and it's even worse to implement. In the meantime, I was also trying to think of a simpler, more elegant solution to the problem, and it seems that I have found one. This is why I'll be ditching all this generating of a path tree, extracting each full path from that tree, then comparing it to user notation; and replacing all of this with functions for each piece specifically. That way, a lot of guesswork (but, what if a piece can diverge? is it transparent? to what?) can be eliminated, because in a specific function one has to handle only one piece (e.g. a Bishop) and can safely ignore interactions that are not relevant.

Why I didn't made such a transition earlier? Well, it took me quite some time to figure out that in a cascade I could use intermediary chessboards to communicate all the changes made in a previous ply, and then accumulate all those changes into the final chessboard for a move. The one thing I don't like about piece-specific functions is that can easily lead to a lot of code duplication, since similar code can be embedded in many piece-specific blocks; usually a lot of variables are shared between the two, making it difficult to refactor similar code into a function of its own. The other thing I don't like is that algorithm replaces data, and so no intermediary data is generated, and so the only way to check correctness of such a function is to debug. Oh, well ... nothing is perfect.

Even more variants!

I'm updating the book, even though only two months have passed since the last update, and not that much has changed since. In fact, the only real change is that I added 6 new, unbalanced randomized variants. As you might have guessed, those new variants are unbalanced because initial setup for each player is being randomized independently from each other. Also, there are no additional checks-and-balances, except a standard one for Bishops, so that half of them starts from light fields, and other half from dark ones. And all of this despite wisdom of the commons voting unfavorably against said unbalanced variants. Why did I add them, then?

Well, as I already wrote in the comment on LinkedIn, when sufficient number of elements are randomized, extremes tend to cancel each other out, so it's highly unlikely that one player will have too much advantage over the other. Second reason is because players should be able to choose which randomized variants (and flavors) they'd like to play. Additionally, players should also have an option to vote against a particularly unbalanced setup, if it's deemed unplayable; generating new setup is easy and fast. So, in the end, unbalanced variants might not be up everyone's alley, but they certainly don't hurt.

The book was compiled on February 12, 2026, version is 20260212.063826, and can be found behind that red button above, or in other usual places.

No guessing, only counting

Newly introduced randomized variants also pose a good question: how much there are different initial setups? Let's calculate!

Note that randomized Classical Chess variants and randomized Croatian Ties variants of the same size has the same number of possible initial setups. In Croatian Ties variants Knights are replaced by Pegasuses, but otherwise number of different pieces and their count is the same. Pawns in all variants are irrelevant, since they can be arranged in only one way. So, the only difference is the order of figures arranged in the first and last rank. Both mirrored and symmetrical flavors of randomized variants has the same number of combinations, so it's enough to calculate only once, then double the result.

First, a very brief introduction to binomial coefficients:

c = ( n k ) = n ! k ! ⋅ ( n - k ) !

where n≥k≥0, and n!=n⋅(n-1)⋅(n-2)⋅...⋅2⋅1.

Our factor c is number of combinations when placing k pieces of the same kind (e.g. 4 Rooks) onto n available fields (e.g. 10 empty fields).

So, we'll start with randomized Classical Chess 14, and with Bishops, since we have to make sure we have the same number of Bishops on light and dark fields. There are 4 Bishops in this variant, so that would be 2 Bishops on light and other 2 Bishops on dark fields. In these variants there are 14 fields at each rank (surprising, I know!), so that gives us 7 light and 7 dark fields. Obviously, each set of light and dark fields is completely separated from each other, and so numbers of possible arrangements of Bishops on different fields are the same:

c light = c dark = ( 7 2 ) = 7 ! 2 ! ⋅ 5 ! = 21

where 7 is the number of either light or dark fields; and 2 is count of Bishops on those fields. So, our factor clight is number of combinations of 2 Bishops arranged over 7 light fields; and cdark is the same over dark fields.

Next, we have to arrange 4 Rooks over 14-4=10 fields, where 14 is size of a variant, and 4 is number of fields already occupied by Bishops:

c Rooks = ( 10 4 ) = 10 ! 4 ! ⋅ 6 ! = 210

Next, we have to arrange 4 Knights over 14-8=6 fields, where 14 is still size of a variant, and 8 is number of fields already occupied by Bishops and Rooks:

c Knights = ( 6 4 ) = 6 ! 4 ! ⋅ 2 ! = 15

Queen can now pick between two remaining fields (ladies are choosers! 😎):

c Queen = 2

King will have to be satisfied with whatever field is left empty:

c King = 1

So, our number of combinations for randomized Classical Chess 14 variants is:

c 14 = c light ⋅ c dark ⋅ c Rooks ⋅ c Knights ⋅ c Queen ⋅ c King = 2,778,300

that is for either mirrored or symmetrical flavor. If flavor is also randomized choice, total number of initial setups is doubled:

c ∑ 14 = c 14 ⋅ 2 = 2,778,300 ⋅ 2 = 5,556,600

both those numbers also apply to randomized Croatian Ties 14 variant(s).

Calculation of number of different initial setups for randomized Classical Chess 20 variant(s) -and, by extension, Croatian Ties 20 variant(s)- is the same as above, but numbers are slightly bigger. Size of a chessboard is now 20, there are 10 light fields, and 10 dark fields, there are 6 Rooks, 6 Knights and 6 Bishops (of which 3 are on light fields, and other 3 on dark ones). Taking all into account gives the number of initial setups as:

c 20 = 2,421,619,200

that is for either mirrored or symmetrical flavor. If flavor is also randomized choice, total number of initial setups is doubled:

c ∑ 20 = c 20 ⋅ 2 = 2,421,619,200 ⋅ 2 = 4,843,238,400

both those numbers also apply to randomized Croatian Ties 20 variant(s).

Number of different initial setups for randomized Classical Chess 26 variant(s) is calculated the same as above, but numbers are bigger still. Size of a chessboard is now 26, there are 13 light fields, and 13 dark fields, there are 8 Rooks, 8 Knights and 8 Bishops (of which 4 are on light fields, and other 4 on dark ones). So, number of initial setups is:

c 26 = 2,013,316,519,500

that is for either mirrored or symmetrical flavor. If flavor is also randomized choice, total number of initial setups is doubled:

c ∑ 26 = c 26 ⋅ 2 = 2,013,316,519,500 ⋅ 2 = 4,026,633,039,000

both those numbers also apply to randomized Croatian Ties 26 variant(s).

As an interesting tidbit, if we try to calculate number of initial setups for randomized Classical Chess, we get:

c 8 = 2,880

that is for either mirrored or symmetrical flavor. If flavor is also randomized choice, total number of initial setups is doubled:

c ∑ 8 = c 8 ⋅ 2 = 2,880 ⋅ 2 = 5,760

Obviously, these numbers are somewhat bigger than Fischer Random Chess would have it (i.e. 960), since it also imposes an additional constraint on how initial setups are generated; namely, "the King must be placed on a square between the Rooks", and does not support symmetrical flavor, only mirrored.

New variants galore!

While adding new, simple variants I also thought at the time about adding randomized variants of those, since that is a natural and easy way of improving ones chess variants appeal, without introducing even more complexity; it's what chess designers are inclined to do. Especially if said chess designers have played Fischer Random Chess recently and liked it, because everybody likes randomized Classical Chess, even if they're casual potato just like me, and lost every single game within minutes.

Jokes aside, that's how it played out; I postponed adding randomized variants, since I thought that soon I might be able to finally implement rudimentary support for simple variants in my console application. When it became apparent that I won't be able to pull it off in time, and due to randomized variants being relatively simple, I decided to take the plunge, and do it now. Other reason for adding randomized variants now is they do increase scope of the project somewhat, and it's always better to have scope clear before any real work commences, which is now on the table again.

Why new, randomized Croatian Ties variants all have two ranks of Pawns for each player, while originating, simple Croatian Ties variants have only one(?), I hear you asking. Well, simple variants have fixed positions, and it so just happens that Pawns attacked from the very first move by Pegasuses are also the ones protected by at least 3 different pieces; Rook behind said Pawn, Bishop from the side, and Pegasus beside it. Better, no Queen or King is attacked by Pegasus on its very first move, even if it does capture a Pawn.

In randomized Croatian Ties variants there is no such a guarantee, it's possible to end up with initial setup with undefended Pawns; worse, figures attacked by Pegasus after capturing Pawn might be Rooks, or even Queen, with no escape hatch; worse still, they might be undefended, too. And an unfair situation would be if King itself is exposed in such a way; dark player would be checkmated even before his/hers first move. Fact that initial setup is fair (as in, mirrored or -at least- symmetrical) is of no consequence here, this is not acceptable. So, to prevent Pegasuses from gaining unrecoverable advantage to light player, and give dark player a fighting chance to defend himself, rank of light and dark Pawns had to be added to initial setups.

Sure, at least in theory, it's possible to filter out unfair initial setups, and allow only playable ones; but, it would require more complex randomization algorithm, which has to be very carefully reviewed to ensure unfair setups can't slip through. Then, there is a question where filtering ends, how much of an advantage light player should be allowed? If not much (to keep game fair), then such an algorithm would also kill randomness by severely restricting number of available setups. Also, I'm not really fond of complex designs if it can be avoided, in this case by adding a simple safety net. 

And so, here we are; with only 12 new, randomized variants added to the mix; that makes it 28 variants in total: 10 canonical variants, 6 simple variants, and 12 randomized variants (of which 6 are in mirrored and other 6 are in symmetrical flavor). Since this is quite a change, I'm also updating the book; changes from the last update include:

  • clarifying grammar 
  • clarified syzygy
  • clarified activation momentum
  • clarified Starchild's summary, activations
  • added piece steps table
  • clarified displacement steps
  • Pyramid cannot be uplifted anymore
  • new, randomized Classical Chess 14, 20, 26 variants, in mirrored and symmetrical flavor
  • new, randomized Croatian Ties 14, 20, 26 variants, in mirrored and symmetrical flavor
  • tiny fixes, and more ...
The book was compiled on December 12, 2025, version is 20251212.020837, and can be found behind that red button above, or in other usual places.

Last edit: 2025-12-12 17:32 UTC

Updating the book!

As promised, I'm updating the book since I finished planned changes; most notably, Wave cannot activate Pyramid anymore. Reason I removed such an activation is because it complicates things significantly when Pawn, Shaman gets involved (i.e. any piece that has step- and capture-fields separated), for no real gain.

Other changes include simplifying some (visually) complicated examples, rewriting and clarifying some explanations, grammar + some small changes, fixes. While editing it struck me that examples having chessboards cut exactly at fields edge (e.g. chessboard sized exactly 9 x 6) looks unsettling, and kind-a awkward; so I also added partial fields (hints at where rest of chessboard is) to all of those.

Since two months has already passed since the previous update, I'm updating the book; the book was compiled on November 10, 2025, version is 20251110.003215, and can be found behind that red button above, or in other usual places.

Even more guessing!

Previously, I wrote down my guesstimates how much One variant is more complex than Classical Chess, turns out a lot. Now, it's time to do the same for new, simplified variants. I'll do just Classical Chess 26, smaller variants are of lesser interest here. As for Croatian Ties variants, I haven't yet got around how to calculate complexity factor due to increased mobility; so, using previous method Croatian Ties variants would have exactly the same complexity as their Classical Chess counterparts, which doesn't feel right, but it is what it is.

If you haven't already, read blog post linked above; it explains how complexity factors are calculated, and why. So, let's start with size:

cf size = 1 + ln ( 26 2 8 2 ) = 1 + ln ( 676 64 ) = 3.357310

Next, it's total number of pieces on the chessboards:

cf pieces = 1 + ln ( 104 32 ) = 2.178654996

There are no new pieces, so complexity factor for different types of pieces is one:

cf types = 1 + ln ( 6 6 ) = 1.0

The same applies to Croatian Ties variants, since every Knight is replaced by Pegasus, so there are the same number of different types of pieces.

There are also no new interactions, so complexity factor also goes to one (this one too applies to Croatian Ties variants):

cf interactions = 1 + ln ( 3 3 ) = 1.0

Our complexity c is then defined as a product of all factors calculated above:

c regular = cf size ⋅ cf pieces ⋅ cf types ⋅ cf interactions = 7.314420189

This is complexity scaling factor of regular games from Classical Chess into Classical Chess 26 variant, i.e. all games should be 7.314 times longer. For instance, the longest recorded tournament game was 538 moves (269 FIDE moves, aka cycles), which turns into 3835 moves (1968 cycles) for Classical Chess 26 variant. Average on-line match lasts about 80 moves (40 cycles), in Classical Chess 26 variant that would become 585 moves (292.5 cycles). Average tournament match lasts about 88 moves (44 cycles), which becomes 644 moves (322 cycles).

The same, however, does not apply when calculating maximal possible game length, because players will try to maximize each and every metrics available to prolong the game. So, for maximum game length we have to calculate linear scaling factors; for chessboard sizes factor becomes:

cf size = 26 2 8 2 = 676 64 = 10.562500

Next, for total number of pieces on the chessboards we have:

cf pieces = 104 32 = 3.25

Complexity number for different types of pieces is still one:

cf types = 6 6 = 1.0

Finally, complexity factor for number of different interactions is also one:

cf interactions = 3 3 = 1.0

Taken together, our complexity c becomes:

c longest = cf size ⋅ cf pieces ⋅ cf types ⋅ cf interactions = 34.328125

This is scaling factor for the longest possible games, i.e. the longest games should be 34.33 times longer in Classical Chess 26 variant compared to Classical Chess. For instance, previously mentioned 11797 moves (5898.5 cycles) game as the longest possible with 50-cycle rule in Classical Chess 26 variant becomes 404,968 moves (202,484 cycles) game. Even longer 17697 moves (8848.5 cycles) game with 75-cycle rule in Classical Chess 26 variant turns into 607,505 moves (303,752.5 cycles) game.

These doesn't appear to be large numbers, if you recall estimates for One variant, but should not be underestimated; even "just" 7.314 times increase in complexity results in some prolonged games, especially if increase in complexity is allowed to also translate into longer time allowance per turn. So, 15 seconds per player's turn in bullet game now becomes approx. 110 seconds per turn; given that average Classical Chess 26 game length would be 585 turns, it would last for approx. 17.834 hours of gameplay time; or, 2.23 days if we assume 8-hour gameplay in a day. If we don't increase time allowance per turn, 15 second per turn bullet game would take approx. 2.438 hours of gameplay time.

In short, new Classical Chess variants does pose a challange, even if only just by scaling up. Croatian Ties variants builds more on top of that challenge, by replacing Knights with more mobile siblings, and also allowing Pawns to move sideways, which throws off known gameplay patterns, tactics.

New variants!

Quite some time ago I wrote that I'd like to add some enlarged, but otherwise Classical Chess variants, but dismiss them as not belonging to the book, and requiring their own, separate book which would also discuss mobility. In the meantime, I kinda warmed-up to the idea that enlarged Classical Chess variants do belong to the book presenting new variants, especially since their objective is to make playing on large chessboards more approachable to average, casual player.

Currently, I plan on adding enlarged Classical Chess and Croatian Ties variants as remarks at the very end of the book; those variants won't be fully featured, but will include images. I'm not entirely happy with this design choice, since it will disrupt the flow of the book; but it should be worth it, given that this new book on mobility and such is still very far away, if it will be written at all.

I plan on adding 3 new Classical Chess variants, those will feature only pieces found in Classical Chess, with exactly the same rules, except longer rushes and castlings. I'll also add 3 new Croatian Ties variants, those would be nearly identical to their Classical Chess counterparts, but all Knights would be upgraded to Pegasuses (Pegasi?), and all Pawns will be of side-ways variety; this is to compensate somewhat for decreased mobility of Pawns, Knights on a larger chessboards. New variants will be played on 14 x 14, 20 x 20 and finally 26 x 26 chessboards.

New variants won't bring neither any new pieces, nor any new interactions. Still, I'll have to expand Python application which generates images for the book to support all new variants; later, library will have to be expanded as well. This will take some time, given my usual tempo of writing (which is very slowly) I hope I'll have the book finished by the end of this year.

One step at a time

I changed how Pawn-sacrifice is initiated, by limiting Serpent to its neighboring fields. As a consequence, Pyramid is now activated with only one momentum, so sacrificing Pawn is also limited to only one step. While change itself is rather small, and it applies to only one special movement, there are a few design choices worth pointing out.

The issue with Pawn-sacrifice was that one could lose quite a few Pawns, and in turn have promotion opportunities severely limited or completely gone, all in only one move. Also, in its original form, Serpent could initiate Pawn-sacrifice by activating Pyramid from across a chessboard. It was also possible for a Serpent to slither around pieces and still find a way to its own Pyramid. Similarly, Pyramid activated with a lot of momentum could sacrifice Pawn at the other side of a chessboard.

In my defense, when Pawn-sacrifice was originally conceived, Serpent's movement was much more limited, up to 9 fields in the largest variant, 8 otherwise. In the mean time, I extended Serpent's reach, but failed to notice its impact on Pawn-sacrifice. By limiting Serpent to its neighboring fields, one now has at least some warning signs (Serpent, Pyramid and Pawn placed close to each other) what is about to happen, and an opportunity to counteract that kind of a move.

I'm also updating the book, Pawn-sacrifice is the only meaningful change. The book was compiled on July 29, 2025, version is 20250729.034138, and can be found in other usual places.

Remove the rule, update the book

I have removed the rule which stated that the first piece in a move cannot return to its initial position, regardless if it was the only piece in a move, the first in a cascade, or in divergence. Since this is a major change I'm also updating the book, the other changes include:

  • clarified double checkmate, added notation and status grammar,
  • reworded Starchild intro,
  • clarified castling notation, fixed grammar,
  • clarified optional notation, fixed outro,
  • reorganized sections, 
  • fixed formatting in tables, 
  • other tiny fixes.

If the rule stayed, it would actually mean that all pieces would have to be uniquely tracked, which would mean that each piece would have to be assigned unique number at a start of a match, and then for everything else it's type and tag would have to be fetched from look-up-table. This would lead to a major  shift of underlying API in a library; but more concerning, also in paradigm shift, where chessboard wouldn't host pieces anymore, but their unique identifiers. This change would be even more of a tectonic shift than the previous one; doable, but got me thinking; is it really worth it, why did I impose such a rule, and such.

For one, it wasn't a movement rule per se (belonging to any particular piece), but it was a restriction imposed on a movement rules of all pieces. As such, it doesn't belong in the book, but among other FIDE or tournament rules. More specifically, any piece starting a move cannot do anything more than just to initiate a permutation of Waves, if that starting piece is about to return onto its initial position in the same move. What I overlooked is that permutation necessary leads to repetition of positions, and that has already being handled by FIDE; for instance, see FIDE 9.2 point in FIDE Handbook.

Another reason for the removal of the rule is physicality; all pieces of the same color and type look the same; this is especially true if displayed on-screen, on a web site, or in a computer game. And yet, the rule called for recognizing (and accounting for) that one specific e.g. dark Rook which started a cascade vs. the other(s) which did not. Of course, computers can be programmed to distinguish those easily; however, a player would have hard time tracking which dark Rook is which, especially in a long-winded cascade.

In short, the above rule would be difficult to implement, goes against a physical reality of a game it tries to regulate, and there is already available better, easier alternative; so, no wonder it has been removed.

Anyway, the book was compiled on June 6, 2025, version is 20250620.014531, and can be found behind that juicy red button above, or in other usual places.

Guessing game

Merging pieces and tags mentioned in a previous post have gone much smoother than I expected, and it's finished now. I also wrote in that post my estimates how long a game in the largest variant could take. In the meantime I have revised my estimates, and so I present you with bigger, better numbers. Again, these are very rough guesstimates, it's difficult to even assess how much numbers presented here could deviate from real-world matches; in short, those shouldn't be taken too seriously.

Estimates here are based on the fact that most large, complex systems settle its metrics somewhat in the middle, since most extremes tend to cancel each other out. For this analysis we'll be comparing easy to calculate metrics such as:

  • size of a chessboards,
  • count of all pieces in a variant,
  • number of different types of pieces,
  • number of possible interactions,
and will be comparing One variant against Classical Chess. For each metrics we'll calculate its contribution to overall complexity, then multiply them all together, since they are all (mostly) independent; although, total number of pieces is always larger than number of different piece types.

All complexity factors have the same form, so let's define generic complexity factor cf as a simple ratio between new (n) and old (m) metrics, like so:

cf = n m

Edit: with provision that n≥m.

This definition is all well and good, but applies only if corresponding metrics contribute to system's complexity directly, in a linear fashion. Most of the time, this is not the case. For instance, adding two ranks and files to a classical chessboard is a much larger change (as a percentage) then adding the same to the second largest variant, Discovery. So, each increase in metrics yields diminishing increase in complexity; for such a non-linear increase there is a function which sets limits to growth, and that's natural logarithm (ln):

cf = ln ( n m )

There is still a small issue to solve here, before calculations can take place. Observe what happens if we compare e.g. Classical Chess with its own self:

cf = ln ( m m ) = ln ( 1 ) = 0

Our complexity factor cf gets to 0. This is actually fine, all that calculation is showing us is that there is no additional complexity when comparing a variant to itself. Still, we'd like to multiply our complexity factors, as independent variables should be. So, we'll add 1 to formulae, like so:

cf = 1 + ln ( n m )

Now that we have generic formulae for complexity factors sorted out, we can actually calculate something; lets start by comparing sizes of chessboards:

cf size = 1 + ln ( 26 2 8 2 ) = 1 + ln ( 676 64 ) = 3.357310

Next, we can compare total number of pieces on the chessboards:

cf pieces = 1 + ln ( 190 32 ) = 2.781288

Another comparison is between number of different types of pieces:

cf types = 1 + ln ( 18 6 ) = 2.098612

Finally, we can compare number of different interactions:

cf interactions = 1 + ln ( 19 3 ) = 2.845827

Our complexity c is then defined as a product of all factors calculated above:

c regular = cf size ⋅ cf pieces ⋅ cf types ⋅ cf interactions = 55.767104

This is actual length scaling factor of regular games from Classical Chess into One variant, i.e. all games should be 55.767 times longer. For instance, the longest recorded tournament game was 538 moves (269 FIDE moves, aka cycles), which turns into 30002 moves (15001 cycles) for One variant. Average on-line match lasts about 80 moves (40 cycles), in One variant that would become 4461 moves (2230.5 cycles). Average tournament match lasts about 88 moves (44 cycles), which becomes 4907 moves (2453.5 cycles).

The same, however, does not apply when calculating maximal possible game length, because players will try to maximize each and every metrics available to prolong the game. This can be seen in Classical Chess games alone; the longest possible game with 50-cycle rule is 11797 moves (5898.5 cycles), while with 75-cycle rule it's 17697 moves (8848.5 cycles). If we calculate ratio between the two rules:

75 50 = 1.5

and game lengths, we can see that contribution to game length by rules extension was almost perfectly linear (50% increase in movement rule resulted in 50% longer game):

17697 11797 = 1.500127151

So, for maximum game length we have to calculate linear scaling factors; for chessboard sizes factor becomes:

cf size = 26 2 8 2 = 676 64 = 10.562500

Next, for total number of pieces on the chessboards we have:

cf pieces = 190 32 = 5.937500

For number of different types of pieces we get:

cf types = 18 6 = 3.000000

Finally, we can calculate factor for number of different interactions:

cf interactions = 19 3 = 6.333333

Taken together, our complexity c becomes:

c longest = cf size ⋅ cf pieces ⋅ cf types ⋅ cf interactions = 1191.582031

This is scaling factor for the longest possible games, i.e. the longest games should be 1191.58 times longer in One variant compared to Classical Chess. For instance, previously mentioned 11797 moves (5898.5 cycles) game as the longest possible with 50-cycle rule in One variant becomes 14,057,093 moves (7,028,546.5 cycles) game. Even longer 17697 moves (8848.5 cycles) game with 75-cycle rule in One variant turns into 21,087,427 moves (10,543,713.5 cycles) game.
Edit: all this without resurrections, with those used it's -for all we know- infinite.

These are all very large numbers, even "just" 55.767 times increase in complexity results in some ludicrous (as in, almost completely impractical) estimates. For instance, increase in complexity should also translate into longer time allowance per turn, simply because there is so much more stuff a player has to handle. So, 15 seconds per player's turn in bullet game (10 minutes, spread over average of 40 turns per match, see https://en.wikipedia.org/wiki/Time_control#Classification) now becomes approx. 13.941776 minutes per turn; given that average One game length would be 4461 turns, it would last for approx. 1036.5710456 hours of gameplay time; or, 129.5713807 days if we assume 8-hour gameplay in a day. If we don't increase time allowance per turn, 15 second per turn bullet game would take on average 18.5875 hours of gameplay time, or 2.3234375 days with the same 8 hours of gameplay per day.

And that's just bullet, lets not talk about classical time controls here, those numbers would be depressingly huge. One thing that is sorely missing from complexity estimate is mobility, and associated with it, piece powers. These are not easily estimated; also, increase in mobility alone does not add to complexity, rather it's ratio between mobility and available space (i.e. chessboard size), and I'm not sure that ratio has been increased by much. Anyway, this post is already too long, so I'll leave it for some future post.

Tectonic shift

It's unusual to have very base data model change this late in a project; any yet, here we are. Currently, I was implementing generators of all legal paths every piece can make in a ply. Since this change will disrupt development for quite some time, let me try to explain it.

The issue I'm talking about is that currently piece and tag enumerations are separated; which would be fine in almost all designs, since most of the time one data entity is indeed independent from any other, e.g. one person's year of birth is very separated from their phone number. This is not the case here, Bishop can never get "can rush" tag, nor Knight can ever castle.
Edit: Tags and pieces have very few, and very intimate relationships; usually tag can be attached to a few pieces (e.g. rush and en passant tags for privates). Technically, tag is a link between a piece and a field at which that piece is located. Once that link is broken (e.g. a Pawn has been activated and moved away), there is no more tag present (e.g. activated Pawn has lost its promotion tag) even if both a piece and its originating field are still present in a game. Most of the time the best data model is the one designed after real-life; this is why original design featured tags separated from pieces. 

Another issue with separated piece and tag enumerations is that, well, they are separated. So, every function working with pieces (and in a chess game that means all of them) has to have two separate parameters. Yes, you can combine then in a neat struct, together with some other bits (e.g. a position) to bring number of parameters down; but, they both are now present in every struct you have to pass around.

Plus, they still take too much space, in fact, twice as much as needed; and that's after a change has been made quite some time ago, so that only 1 byte (char) is stored per enumeration instead of default 4 (enums are just fancy ints). You might think that we have moved past storage issues since like forever, but that is true only for local apps. For libraries, one has to consider possibility that it might serve many users at once, also it might need to do it on a restricted hardware (e.g. micro-controllers).

There is another issue with enumeration storage, and that's space it takes in a chessboard struct; again, currently it's double the amount it actually needs. Parsing user notation and applying it to a current chessboard is not an easy task; if undo is supported then one has to apply all moves performed until that point. To speed things up (and avoid doing the same job twice) position after performed move can be stored, and later retrieved. Only problem is, the largest variant has 676 fields, 190 pieces and 14 different interactions (losing tags are not counted, as they're result of interactions), which means it can last much longer than classical chess game. The longest recorded classical chess match in tournament was 269 moves, but legal match can stretch up to 5898.5 moves with 50-moves draw rule, or up to 8848.5 moves if 75-move draw rule is used instead.

For the record, move to me always means all actions performed by one player in one turn; this is different from FIDEs definition used above which define a move as white player action followed by black player action; for FIDE definition I use term cycle. Reason why I refer to move as such is because each player moves their pieces independently to each other (current chessboard position notwithstanding), there is a meaningful choice to be made; in fact, making a choice is the whole point of a game.

So, how long can chess game go in the latest and greatest variant of them all, the One? Honest answer, I don't know. I tried to guess-timate the thing, but it's probably wildly inaccurate. My guess is that tournament games won't last much longer than 18.000 moves, and technically legal games could probably go for 10.000.000+ moves; both with 50-cycle draw rule. This post is already too long, if you're interested to hear my reasoning, let me know in comments below.

As you can see, if undo is supported by storing chessboards, just having variant enumeration as an int in a chessboard struct can easily eat up to 40+ MB of space, just for that one enum. Undo chessboards could currently use 13+ GB of RAM in total; with changes proposed here implemented, that could drop down to 6.5+ GB. This is why I'll merge piece and tag enums, and also change variant enum storage to byte. Such a change will affect everything in the project; for the time, there will be development without (much) progress.

New book update

I'm updating the book even though less than a month has passed since the previous update; the newest changes include:

  • rewrote checking opponent's King by Serpent,
  • tiny clarification, cascading en passant,
  • filled-in, clarified piece activations table,
  • removed activations on miracle-fields by Starchild, Wave,
  • removed Wave divergence on miracle-fields,
  • a bunch of tiny fixes, clarifications.

In a previous update I planned on making an exception to Wave's transparency, so that King behind it is not in check anymore. That has been revised, and so Wave transparency stays the same, and King behind it is still in check. Due to Shaman being able to capture multiple pieces in a single ply, I had to put forward rule that King is in check if it could be captured, if it was opponent's turn. Then everything else followed from there: if a Wave can be passed over by a piece due to its transparency, then attacker already have direct access to a King; and hence, King is already in check.

I also removed all activations on miracle-fields, except Starchild can still activate a Star. This is due to miracle- and uplifting-fields being the same, so it was hard to determine on-the-spot (when parsing user notation, building legal path, ...) if interaction is just an ordinary activation (on miracle-field), or it's uplifting a piece; because uplifting is a two-stage process, and so activation context has to be passed between plies, before anything conclusive can be known.

The book was compiled on April 2, 2025, version is 20250402.230028, and can be found in usual places.

En passant finally described! And checking opponent's King! More news at 11! Also, the book has been updated ...

I'm updating the book after only two months, since there has been some significant changes, including en passant being thoroughly described, for real. More detailed list of changes follows:

  • fixed side-effects table, added footnote
  • clarified displacement
  • described checking opponent's King
  • clarified static Serpent
  • clarified castling blocked
  • clarified piece actions
  • clarified Scout can be rerouted around any non-empty field
  • described en passant blocked, denied, turned into capture, divergence, ...
  • described activation after en passant
  • described multiple rushes, en passants in a cascade
  • described en passant in close quarters
  • described en passant affected by a Star, Starchild
  • switched to non-shifted tilde
  • and many more tiny edits, fixes, ...

While I was reviewing changes I made to the book since the last update, it also occurred to me that I gave too much leverage to pieces attacking opponent's King. Most pieces grew significantly more powerful, especially in late variants, while King remained the same it ever was, in effect making it much weaker against any opposing force. This is fine, and as it should be; the tricky part here is finding the right balance. This is why I already started changes to limit checks only to pieces directly "in line of sight" of opponent's King, meaning that King is in check only if all capture-fields between an attacker and a King are empty. In hindsight, what happened here is just me always leaning towards giving a player more choices, a piece more mobility; in short, more power for all; sometimes more power is just too much.

I also lean towards doing the same with Wave. Currently, due to its transparency, Wave cannot be hard-pinned to its King. With upcoming changes, Wave on a capture-field would nullify any check to a King behind it. The reason is the same one used to make Pyramid incapable of checking opponent's King, while at the same time that very same Pyramid can capture any other opponent's piece; it is to ensure all checks, checkmates are direct, simple to see, and reason about. It also helps that in doing so, it makes rules (and code implementing them) less fiddly.

It could be argued that transparency of Wave is hard principle, i.e. it should always work like that, without exceptions (which is true), and also that King would be sufficiently protected just by aforementioned changes, without changing Waves (also true). Counter-argument might be that directness of checks and checkmates is also hard design principle, i.e. no pieces between checking piece and checked King. Good game design promotes, and sticks to its own design principle hierarchy. To me, directness of checks, checkmates have precedence over any other rule; which means, transparency of a Wave will have to have an addendum.

I plan finishing changes mentioned here, then continue working on the code; book update will follow its own (give, or take) quarterly schedule. In the meantime, I'm also starting to think about revising One variant, namely Starchild could be reverted to its initial design, where any piece could activate it. Still, this is very low priority, and in very early stage; so, it most likely won't make it in time for next book update.

The book was compiled on March 9, 2025, version is 20250309.071052, and can be found in usual places.

Updating the book!

I'm updating the book, since previous update was three months ago, and there were some meaningful changes, which include:

  • changed reposition symbol to backslash,
  • removed unsupported castling notation examples,
  • added delayed column to variants table, description,
  • removed monogamous promotion,
  • changed draw offer cancelled symbol,
  • clarified resurrecting converted pieces,
  • clarified only captured and oblationed pieces can be resurrected,
  • clarified resurrecting Waves, Starchilds,
  • fixed grammar: Starchild can be activated,
  • and many more fixed edits, typos.

Some of changes were made to ease parsing user notation; for instance, repositioning symbol used to be just comma, which is also used for list of captured pieces during (double) trance-journey. Another example, cancelled draw offer was previously written as (-), now minus sign has been removed from brackets, since it's also used to separate destination from any previous step.

For castling notation, previously one could specify for Rook starting, any or all intermediate fields; now it accepts only destinations, either full position or just a file, optionally preceded by Rook symbol. So, Kh1-d1&Re1 is acceptable notation, but Kh1-d1&Ra1-e1 is not anymore; because King is not transparent to Rook, it's just a very special move. Another reason is that it also simplifies parsing user notation, without losing any valuable information.

I also removed monogamous promotion; after some thinking it was obvious to me that promotion does not add anything to the game, but only complicates things for players, and for no good reason. I thought I had one when I was setting promotion rules, but certain choices doesn't make a good story. I prefer freedom of choice over (unnecessary) rules. There is also a moment when one has to consider simplifying design, when possible. 

The book was compiled on Jan 13, 2024, version is 20250113.203449, and can be found in usual places.

A new book update

I just finished the most recent changes, and so I pushed a new book update. There are some slight corrections, clarifications, but also conceptual change, and complete activations overhaul. I was comparing activation and divergence, and especially for a Wave, their differences; and it made me thinking: "why activated Wave can move over only one type of field, while diverged Wave can choose any?", "how is this fair?", ... So, I decided to level the playing fields, so to speak, and make all activator's steps, fields accessible to activated Wave.

Now, Wave does not inherit type of field at which it has been activated anymore, and instead it can choose from any of steps its activator can at the beginning of a ply. For the most part, activation works just like it was before, changes are relevant only for activators which have separated step- and capture-fields, like Pawn, and Shaman. For those two, Wave can now choose any movement or capturing step as its initial direction.

I was a little bit concerned about Wave activated by Shaman being OP. But, it's just one new activator, which is still more restricted than the other one OP already present in the game; namely, Centaur. So, in a way, it's more fair, since Centaur is now less of an outlier.

At the moment, I don't have any planned, or outstanding changes for the book; so, I'll say, it's as good as it gets. Of course, it's quite possible that I missed something, that should be corrected. With so many moving parts it's difficult to stay on top of every new version. In any case, if you notice something that looks like discrepancy between various texts, tables, examples, ...; please, do let me know.

I'll take this time between the book and the code, to take some more side-questing, and invest at least a few days to get to know NeoVim better. While I don't like vi, nor any derivatives, and have never been a fan, there is no denying that Pulsar is getting more and more annoying, the more I use it. I'm not sure what Pulsar devs are using, but I'm kinda appalled by the lack of performance on older, although still middle-of-the-road CPU, with plenty of memory. I also tried disabling tree-sitter, heck, even all of auto-complete stack, restarting Pulsar without plugins; all to no avail. I mean, everything works ok if edited file is well under 1k SLOC, otherwise it's a lot of pain. In a 4k SLOC Python file, every edit takes at least a second (!) before editor shows the change. As it is right now, this is not a proper tool for work, it's a toy. Bright, shiny, fairly extensible, beautiful; yet, ultimately, next to useless. Which is a shame, really; I do like it a lot.

Geany, you ask? Well, I did use it, it was good, I kinda liked it; but, after Pulsar, it's like going back to your first bike. Sure, it works, it can make you go places, but it's not the same anymore. For me, it's plan B, if NeoVim does not work for me. Especially since with the newest Geany version (2.0.0) very little has been changed compared to previous stable version, except devs bumped version number, and introduced C++17 dependency. So, it's painful to get the upgrade if your Linux repo is LTS, and it's simply not worth it. All together paint a bleak picture for future development of the IDE.

Anyway, the book can be found in usual places, it was compiled on November 14, 2024, and the version is 20241114.064539.

Finished once more

Oki, so the book is updated once more, and there are no more planned additions to it, so I'll call it done. That is, if I don't stumble upon a special interaction which was somehow left undocumented. For instance, I only recently stumbled upon rushing Pawn starting a cascade (nothing special here), which blocks capture-field of opponent's Pawn, so that en passant is not possible anymore (whoops!). Missing details like this are always a possibility, the best I can do is update the book as needed.

What I really wanted to write about is what didn't made into the book. First thing is a (semi-)transparency of Unicorn and Shaman. This isn't really a problem, but a nuisance; it adds so much in complexity, without enhancing game-play really.
It also does not make sense. I always tried to have all pieces congruent with their role, their story. And having physical entities suddenly becoming transparent to physical is not it.

Other things that didn't make it into the book are resized and expanded Classical Chess variants. I started doing it as casual remarks at the end of the book, but then realized that (if described in sufficient detail) these variants would significantly overgrow its casual remark status.
Worse, those variants actually do not belong to the book. Just as each piece has its story, so does the book as a whole. You most likely don't want to be reading synopsis for 1984, while finishing Alice's Adventures in Wonderland.

I was thinking for quite some time about a new book, where I'd  discuss mobility and calculated values of pieces in different variants. There is some chance that new book will be written, and  then alternative Classical Chess variants would be described in it. While I'd like to do it, right now is not the right time for it. That new book would be a major undertaking, and there are more important things I have to do.

My current plan is to finish game engine library and console application first. After that, I'll add enhanced PGN and other chess file formats support, and obviously document all enhancements done to adapt them for all Croatian Chess variants. And in a distant future, bot and networking support, then GUI application.

Simplifying

Changes described in the previous post are mostly done. I'll continue working on the book, hence no update just yet. There would be no changes to rules, pieces, designs; I'll be just clarifying descriptions, most notably, movement of Shaman really needs to be simplified. Another issue is that I put a few examples in parallel into just one image. Obviously not ideal, but also not sure if it would really benefit from splitting it up.

As for changes described in the previous post, Starchild has been made transparent to all pieces, Unicorn is now transparent to Shaman, and Shaman is now transparent to all own pieces (i.e. in the same color), and to opponent's Shaman. Sometimes you just have to take the plunge; I'm not really happy with this kind of a blunt design, lumping all pieces into just three categories. On the other hand it does make sense, and can't be really more selective, while also keeping its simplicity.

One planned change that didn't make it, is that Starchild can be activated only on trance- and miracle-fields. While that can be done, both Waves and Starchilds are kinda life-line; if player ever looses all of Waves and Starchilds, (s)he cannot cascade anymore, and cannot resurrect any captured pieces, which is a major setback. To leave opportunity to save at least some of those pieces, I decided to keep activation of Starchilds and Waves on its step-fields.

While castling is special, one-off move, in reality is not that special compared to e.g. resurrection, and so it can stand to a reason that it too should participate in a mundane cascades. So, Wave is now set as not blocking when castling, and Starchild is blocking only destination fields of castling pieces. As a result, castling can now also start a cascade.

With all of those changes made, I do plan on revisiting movement of Starchild, its activation rules, just to check if all of those are sound. In fact, the book as a whole could receive a little reading from me. Yes, really. 

While I did wrote the book, changes are always made to one page, one example, one paragraph at a time. So, keeping track of all rules (and exceptions to those rules) is nigh on impossible. And yet, it's necessary if one is to check that all things are inherently congruent, to themselves, and between each other. So, I'm going to re-read the book to see if rules (and their exceptions) could be simplified while keeping their original spirit intact.

Streamlining

Usually, I would preface talk about the book with an (also, usually overdue) book update, then write something about plans for the future. Not this time. Changes done so far were minimal, and so it didn't make sense to update the book this time around, given that I'm thinking about reversing some of the changes made. Right now, I'm kinda stuck in the middle of a coding session. As soon as I put together minimal implementation for paths, routes, I'll do changes to the book, since it has priority over any code.

For example, one change committed to repository, but not yet in an updated book is clarification that all step-fields must to be empty when castling. This however is one of the carry-overs from classical chess, which doesn't have transparent pieces, and can be reverted back. After the change, Wave could be placed in-between castling Rook and King, and it still wouldn't prevent said castling.

Things do get dicey from here on, since then Wave could also be activated by either King or Rook. Sure, it could be done, and momentum could be calculated by simply counting step-fields traveled over by e.g. Rook. But, I don't like activating Wave while castling, since Rook is sort-of stepping over King, and castling is meant as an one-time super-special move, not a regular one. Maybe solution is to simply state that castling pieces cannot activate Wave, but are not obstructed by it, either; that seems the most reasonable design so far, will see.

Speaking of transparency, I'm also thinking about making Starchild transparent. You see, it kinda makes sense, but not all of the time. One design was to make Starchild transparent to pieces travelling over step-fields, but not over capture-fields. This would mostly just complicate things, but wouldn't do much for gameplay, since almost all pieces have the two kinds of fields lumped together, anyway. I tried to reconcile the two opposing design choices, but so far couldn't really make it work.

A solution (although, kinda cheesing it) could be to have Starchild transparent to some, but not all of pieces. For instance, Starchild could be transparent to e.g. Unicorn, Shaman, Starchild and naturally Wave, but not other pieces. Again, not really happy with this design, so I'll have to take a look into it. Although, past experience thought me not to relay too much on first impressions, sometimes necessary evil is necessary.

I have to admit I made a blunder: currently Starchild cannot be activated, and it's just by a simple decree ("you can't do that"). This is not good. What I should have done is describe interactions, everything else should be derived from that. In this instance, I should have written that Starchild can only be activated on miracle-fields (by other Starchilds), or on trance-fields (by Shamans). While net result is the same, one does not impose arbitrary limitations (and you already know how I feel about those), it just enumerates interactions.

Together with bad no-activation rule will go rule that material pieces gain one momentum from Starchild, by simply diverging from it. I don't know what kind of a brain-fart I had that day, but oh boy, it's still smelly. Solution is simple, if a piece has enough momentum, and Starchild is transparent to it, great; if not, it'll be blocked from moving any further, just like any other piece.

Another design that I'd like to simplify is set of potential destination fields for resurrecting syzygy. Other things that desperately needs simplifying are rules regarding multiple syzygies, be it a piece moving from one into another, or standing on a shared field, or something else.

In short, while the book is finished, some things are still settling, and it will take its time, just like everything else. On the other hand, if you look at classical chess, which is much simpler design, it took roughly a millennia to have rules more-or-less in its current form. As an additional bonus, I'm very, very slow; both in writing, and in coding. If you ask me, I'd say don't prepare your popcorn just yet ...