So do I write, "Rule: repeat3 = illegal" or "repeat3 = illegal"? Currently I have Rule attached, and it still draws upon repetition.
How Can I Create a Variant?

So do I write, "Rule: repeat3 = illegal" or "repeat3 = illegal"? Currently I have Rule attached, and it still draws upon repetition.
The former.
Check if the repetition claim comes from Sjaak II (it will display a score of 0 in the analysis) or whether it comes from XBoard (which should then say something like "xboard adjudication: 3-fold repetition"). You can set that by going to Options->Adjudications.
Note, however, that if the engine thinks repetition is illegal, it should never play them, so that XBoard should never get the chance to adjudicate it, no matter how its setting for this was. Only the human could play a repetition, and be (wrongly) adjudicated.

Note, however, that if the engine thinks repetition is illegal, it should never play them, so that XBoard should never get the chance to adjudicate it, no matter how its setting for this was. Only the human could play a repetition, and be (wrongly) adjudicated.
You know, that's a fair point.
In fact, SjaakII will never claim a loss due to an illegal repetition, it will complain about an illegal chase (I should probably correct that). It's also possible to disable repetition claims by SjaakII from the options dialog, so even if it's caused by SjaakII, you can disable the result claim and SjaakII will just deviate if the other side repeats illegaly.
Where would that be in the options menu? I found the Adjudications section in WinBoard, but it was only claiming draws for 6-fold repetition and the 51 move rule, which meant that it would never be the source of the draw.
So should I turn on "Check Engine Claims"? And should I have an, "ICS," though I'm not sure what that is? (You can tell I'm new to this scene...)
Oh, and here's a bunch of questions that it's very possible don't have an answer:
In the XianQi variant, there is a pattern of light and dark squares on the board that represents the river and the palace. Is it possible to create unique patterns for other variations?
What if I wanted to add a zone that only one type of piece can enter? It would be reasonable to say that every piece is limited to a "palace" of every square other than that zone, except for the one piece that is allowed to traverse it -- but is there a better solution?
WinBoard allows you to use arbitrary bitmap images as background for the board. Just tick the 'Use board textures' checkbox in the View->Board Themes dialog, and select texture files for the light and dark squares. (You could use the same file for both.) These must be Windows bitmaps (.bmp) files.
Note that WinBoard will cut the squares out of the given bitmap, if the size is not exactly equal to the board. So to do what you want would require an image as large as the largest board you ever want to use. For smaller boards WinBoard will then divide the bitmap into virtual squares, and cut the actual squares from the center on those.
This is all just cosmetics, it has no effect on the rules. For variants that are not pre-programmed in WinBoard, the engine is responsible for enforcing the rules. I assume that Sjaak II can be configured to restrict each piece to a zone. It could not play XiangQi if it did not have the capability to do that internally, and most things it can do can be controlled from the config file. I know there are commands to define arbitrary zones.
Sjaak's option settings will be in the Engine #N Settings dialog, (Except for standard settings shared by all engines, such as hash-table size, which are in Common Engine Options.) All other dialogs of WinBoard only show WinBoard settings that the engine will know nothing about.
The 'verify engine claims' option of WinBoard works only when legality testing is on. It would not be of much help anyway, it just corrects the game result to a loss when the engine terminates the game as a win or a draw, while WinBoard knows for a fact that by the rules it isn't.

In the XianQi variant, there is a pattern of light and dark squares on the board that represents the river and the palace. Is it possible to create unique patterns for other variations?
What if I wanted to add a zone that only one type of piece can enter? It would be reasonable to say that every piece is limited to a "palace" of every square other than that zone, except for the one piece that is allowed to traverse it -- but is there a better solution?
SjaakII has no control over how XBoard draws the board (it does have some control over how pieces are displayed, through the "XBoard pieces"/PieceToChar string). If you choose Xiangqi as a parent variant, you can get a XiangQi-like board division (which reminds me that this doesn't work for non-standard sizes; I have a patch for that though), otherwise you're stuck with the checkered board. You can mark squares as "non-existent" by putting a '*' on them in the FEN string (you then need to tell SjaakII about this too). You can also replace the board with a texture, but I've never done that myself (I see HGM already explained how).
What you describe is exactly what you would need to do to restrict piece movement. It's a bit cumbersome to do from the config file because the syntax is very verbose; perhaps this is something that should be improved. Suggestions for this are welcome.
Similarly to how the Exclude option limits the movement of all pieces, you could add an option to pieces similar to Prison that would work as the inverse. Maybe it could be called Restrict, like this:
Piece: generic
Move: I don't even care
Restrict: zone
I was also wondering if there was an option for pieces in a prison to not be allowed to jump over "holes" in their prison. What I mean is that currently a piece cannot land outside of their prison, but they can move through a square that isn't in their prison. (River chess shall be a thing! Just you wait! )
Also, re-texturing the entire board could indeed make a pattern on the board, but wouldn't it do it to every variant? And I know that it's just cosmetic, but visualizing the parts of the board that are restricted is difficult for us pathetic humans.
Indeed, the texture would be valid for all variants. But you can define the settings before and after the texture change a 'theme' by defining a theme name for them in the Board Themes dialog before you OK that. You can then simply switch between the themes when you switch between the variants that need them.
Also, what is wrong if White has no legal moves and having two computers play yields in an instant loss for white for the reason, "No white pieces left"? Because this is a super weird issue that just now happened.
It sounds like something that Sjaak would have said. So Evert would have to answer that one. It would help if you post the position, or better yet, the game here. If you discovered a bug in Sjaak it will be virtually impossible to fix based on only a vague bug report like "sometimes it does so and so".
That's true, here's the FEN.
FEN: "eornbqkbnroe/pppppppppppp/12/12/12/12/12/12/PPPPPPPPPPPP/EORNBQKBNROE w --"
It's a 12x10 board. O and E are defined pieces. Upon starting the game, there are no legal moves, and if you go to mode and chose "Two Machines," the game is instantly lost for white because, "White has no pieces left," despite the fact that he obviously does. I have tried insterting, "w KQkq" in the FEN, this has no effect.

I'll need more than just the FEN: I need the whole game description to be able to see what may be wrong. It's correct that not having any valid moves should not produce a "no pieces left" message.
What could cause it is a problem with the piece definitions. If something is wrong there, the pieces could be undefined and the reading of the FEN would fail. This is most obvious if you run SjaakII in a terminal: the displayed board will be empty.
Either way, to figure out the issue I will need to see the full variant definition.
ADDENDUM: I checked the code. SjaakII will only claim "no remaining pieces" if a given side indeed has no pieces. That means it failed to set up the start position correctly, which suggests that there is an error in the piece definitions.
I guess meaningful error messages is something I should add to the variant parser.

Similarly to how the Exclude option limits the movement of all pieces, you could add an option to pieces similar to Prison that would work as the inverse. Maybe it could be called Restrict, like this:
Piece: generic
Move: I don't even care
Restrict: zone
I was also wondering if there was an option for pieces in a prison to not be allowed to jump over "holes" in their prison. What I mean is that currently a piece cannot land outside of their prison, but they can move through a square that isn't in their prison. (River chess shall be a thing! Just you wait! )
I am a little hesitant to introduce a second way to do something (ie, restrict piece movement to a specified region of the board) that does just the opposite of the way the existing mechanism works. At the very least it raises the question how the two terms should interact if both are specified. I was thinking that one or more of the following might be useful:
- Use earlier defined zones inside the definition of new zones. I would probably add "filea - fileo" and "rank1 - rank16" as pre-defined zones.
- Combine zones using logical operators (join, intersect, invert).
The last one can become a bit complicated though (and writing a parser for it is a bit of work).
As for marking squares that a piece cannot move through (or to): this could be done relatively easily by giving each piece a bitmask of squares that it always considers to be "occupied by a friendly piece". Easy in principle, but it needs to be done with some care because it requires adding yet another bitmask [i]and[/i] changing the code in the inner loop of the move generator, which can slow things down a lot. I'll think about it.
Wouldn't it be possible to make exclusion zones work like that in general: like the forbidden squares are occupied? That doesn't really need to drive up the complexity of move generation: instead of ANDing with an 'accessible' mask after generation you would OR the 'occupied' mask with the 'exclude' mask before generation.
For convex zones and unbent trajectories it would not make a difference. And although it is a close call I would say it is slightly more logical that if a piece is not allowed to leave a zone, it should also not be allowed to use squares outside the zone as intermediate steps.
Since you asked for it, here is the whole variant description. Just beware, it's a bit... large, to say the least.
############
# Bridge Chess #
############
Variant: Bridge (12x10)
Board: 12x10
FEN: "eornbqkbnroe/pppppppppppp/12/12/12/12/12/12/PPPPPPPPPPPP/EORNBQKBNROE w --"
XBoard pieces: "PNBRQFEACWMOHIJGDVLSUKpnbrqfeacwmohijgdvlsuk"
Zone: rank10 = a10,b10,c10,d10,e10,f10,g10,h10,i10,j10,k10,l10
Zone: rank9 = a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9
Zone: rank2 = a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2
Zone: rank1 = a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1
Zone: not_river = a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,d4,e4,g4,h4,d5,e5,g5,h5,a6,b6,c6,d6,e6,g6,h6,i6,j6,k6,l6,a7,b7,c7,e7,f7,g7,h7,i7,j7,k7,l7,a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,a10,b10,c10,d10,e10,f10,g10,h10,i10,j10,k10,l10
# This is a REALLY brute force solution; essentially I'm saying that the pieces cannot leave this zone, which means they can't enter the river.
Piece: King
Move: leap ((1,0)|(1,1))
Symbol: "K", "K,k"
Flags: royal, castle
# Prison: not_river, not_river
# Castle: white g1-i1 with j1
# Castle: white g1-e1 with c1
# Castle: black g10-i10 with j10
# Castle: black g10-e10 with c10
Piece: Elephant
Move: leap (2,2)
Symbol: "E", "E,e"
Prison: not_river, not_river
Piece: Rook
Move: slide (H,V)
Symbol: "R", "R,r"
Prison: not_river, not_river
Piece: Knight
Move: leap (2,1)
Symbol: "N", "N,n"
Prison: not_river, not_river
Piece: Trebuchet
Move: leap ((1,0)|(1,1))
Capture: aleap (0,3)
Symbol: "T", "O,o"
Prison: not_river, not_river
Piece: Queen
Move: slide (D,A,H,V)
Symbol: "Q", "Q,q"
Prison: not_river, not_river
Piece: Pawn
Move: step N
Capture: step NE,NW
Special: rank2, rank9, step 2N
Symbol: " ", "P,p"
Flags: set_ep,take_ep
Promotion: rank10, rank1, "QROBNE"
Rule: checkmate = win
Rule: stalemate = draw
Rule: repeat3 = draw
You'll notice that there are a few commented-out sections in the King's description, I'm still trying to get castling working correctly and if I don't comment those out the engine will freeze up when it tries to use them.

Ok, a few things to begin with.
You should probably use "O" for the notation of the "Trebuchet" if you're calling it that in the FEN description. Or call it "T" in both. Doesn't matter (much) for SjaakII, but it may be confusing for yourself (and XBoard).
There should be a space between the castling and en-passant fields in the FEN string ("- -" rather than "--").
Most importantly: you neglected to define the Bishop, so it fails to parse beyond the first black bishop in the FEN string. No pieces are placed after that, so in particular no white pieces at all. SjaakII actually prints an error message for that ("Error: unknown piece type 'b' (bad FEN eornbqkbnroe/pppppppppppp/12/12/12/12/12/12/PPPPPPPPPPPP/EORNBQKBNROE w - -)"), but either XBoard doesn't get it, or it ignores it if you don't see that error.
I'll let you know if there's more, but these stood out to me.
ADDENDUM: "Flags: castle" does nothing. It seems that SjaakII gets confused if you define the King as the first piece. I'm not sure why, but I'll look into that.There is an actual bug that can cause a crash when reading the promotion description (no work-around, but I fixed it locally) and it seems SjaakII fails to properly define the castling move (not sure why).
In the variants.txt file it's possible to change fundamental rules, e.g. repeatN = illegal instead of repeatN = draw, but when I change these rules the computer seems to ignore it, and it will draw the match anyway. Do you know a way around this? Also, is there a way to change the 50-move rule? Ideally I would change its rules (50 moves without check is a draw), but removing entirely would work for me as well.
Disabling repetition draws is definitely possible, but make sure you specify an actual number instead of writing N. For instance "repeat3 = illegal".
The 50-move rule indeed cannot be changed from inside the configuration file, which is something I should change.