Move generation is a behaviour of scid::core::Position, not a separate aggregate. Position owns the board, side to move, castling rights, en-passant target, piece lists, pin directions, and attack indexes needed to decide which moves are legal. The public result is a MoveList of resolved MoveAction values that can be applied, undone, scored, ordered, or formatted.
The move-generation pipeline starts from the current side to move. Position first recomputes pins and, unless the caller has already ruled check out, counts attacks on the side-to-move king. A checked king takes the evasion path: double check permits only king moves, while single check also allows captures of the checking piece and blocks on the checking ray.
When the side to move is not in check, generation walks the piece list. Pinned pieces are constrained to the pin direction, pinned knights do not move, pawns are checked for promotion and en-passant edge cases, and king moves are tested against enemy attacks before being appended. Castling is generated only when non-captures are requested, the king is not currently in check, the castling right is present, the king and rook path is clear, and the king's transit squares are not attacked.
This diagram expands the generation pipeline into the public types and the important helper families behind them. It is intentionally loose: generation is an algorithm over Position state, so the private helper functions are shown as named method groups rather than as independent classes.
MoveSpec and MoveAction sit on opposite sides of the position resolution step. MoveSpec is the portable request stored in games and accepted by notation parsers. MoveAction is the reversible, position-resolved form produced by generation and Position::resolveMove(). It records captured pieces, captured squares, old castling rights, old en-passant target, old halfmove clock, and piece-list indexes so Position::apply() and Position::undo() can restore state exactly.
The low-level geometry is deliberately split by dependency. knightAttacks and kingAttacks are table lookups for one-piece attacks. square_Move() and square_Last() describe one-step movement and slider ray ends. The move_predicates helpers validate piece geometry against an occupancy predicate, which lets legality code reason about hypothetical board states without first mutating every Position index.