Skip to content

Extract GeneGraphProcessor and void nodes unreachable from the last node - #819

Merged
chrxh merged 4 commits into
developfrom
features/ExtractGeneGraphProcessor
Jul 31, 2026
Merged

Extract GeneGraphProcessor and void nodes unreachable from the last node#819
chrxh merged 4 commits into
developfrom
features/ExtractGeneGraphProcessor

Conversation

@chrxh

@chrxh chrxh commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Two commits on top of develop:

1. Extract gene graph passes from MutationProcessor into GeneGraphProcessor

removeUnreachableGenesFromRoot and removeCyclesNotThroughRoot moved into their own class.

2. Void gene nodes unreachable from the last node

A construction stays attached to its constructor at the last constructed node, so every node of a gene that is not connected to that node is lost after the construction. The new pass GeneGraphProcessor::voidNodesUnreachableFromLastNode detects these nodes and sets them to void (with constructorAvailable = false). It runs in ConstructorProcessor::mutateGenome after the mutations and before the two existing gene graph passes.

Per gene (the genes are distributed over the lanes, since the nodes of a gene have to be examined in construction order):

  • The node graph is built while stepping through the ShapeGenerator: an edge to the predecessor plus the requiredNodeId edges. The generator is advanced for void nodes as well, because they occupy a position of the shape during the real construction. An edge only holds if none of its two nodes is void, since a void cell dies right after its construction.
  • The connected components are computed with a union-find structure (one int per node), so no edges have to be stored.
  • Genes with homogeneousCellType, with less than two nodes or without any void node are skipped.

Special case: if the first node of a gene is voided this way, the whole gene is removed from the genome, references to it are dropped (constructor turned off, injector falls back to gene 0) and the remaining references are remapped. The gene compaction previously living in removeUnreachableGenesFromRoot was extracted into the shared helper removeMarkedGenes for that. As in MutationProcessor::applyMutations_deleteGene, at least one gene always survives so the genome never becomes empty.

Tests: new test kernel cudaTestVoidUnreachableNodes plus UnreachableNodeVoidingTests (6 tests: no change without void nodes, voiding a node reachable only via void nodes in a triangle, loss of the constructor, gene removal including reference adjustment, keeping the last gene, homogeneousCellType).

Full EngineTests suite passes (3096 passed, 3 pre-existing skips), as do EngineInterfaceTests, NetworkTests and PersisterTests.

Note on the effect: with shape Segment, any void node in the interior separates all preceding nodes from the last node, so the first node becomes void as well and the gene is always deleted. That follows directly from the specified rule (and is what the special case is for), but it makes the void mutation rather destructive for segment genes.

🤖 Generated with Claude Code

chrxh and others added 4 commits July 30, 2026 21:25
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chrxh
chrxh merged commit 04c5dfd into develop Jul 31, 2026
1 check passed
@chrxh
chrxh deleted the features/ExtractGeneGraphProcessor branch July 31, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant