Changelog
Release notes and version history for JCAL.
All notable changes to JCAL are documented here. The format follows Keep a Changelog. Versions align with Semantic Versioning.
[2.2.0] — 2026-05-24
Added
AbstractCellularAutomataRule— new abstract base class incore/that unifiesCellularAutomataRuleandCellularAutomataParallelRule. Provides shared listener management (addGenerationListener,notifyListeners) and aprotected final swapBuffers()helper for the double-buffer swap. Both rule classes now extend this base class; no API changes are required for existing subclasses.NeighborhoodFactory— new factory class inneighborhood/that isolates thecorepackage from concrete neighborhood implementations. Resolves the correct neighborhood class (2D, 3D, or 4D) byNeighborhoodTypeand dimension count. This is a library-internal change; the public API viasetNeighborhoodTypeis unchanged.CellGrid.coordinatesForRow(int row)— new method that returns only the coordinates for a specific row, replacing the O(n²)allCoordinates().subList()pattern in the parallel runners.CellularAutomataConfiguration.isActiveCells()— new boolean getter following the Java naming convention for booleans. The existinggetActiveCells()is kept as an alias.
Changed
- Breaking:
setInitalState/getInitalStateremoved — the typo methodssetInitalState(List<Cell>)andgetInitalState()have been removed fromCellularAutomataConfigurationBuilderandCellularAutomataConfiguration. UsesetInitialState(List<Cell>)andgetInitialState()instead. Update all call sites before upgrading to 2.2.0. CellState.getKey()now returnsString(wasObject). Any code that assigned the result to anObjectvariable and relied on the exact type at runtime should cast or update the receiving variable toString.CellState.keyandCellState.valueare nowprivate final— direct field access is no longer possible. UsegetKey()andgetValue()(or subclass accessors).setGrid()/setUtilsGrid()reduced to package-private inCellularAutomata. These methods were never intended for public use; they are internal double-buffer helpers. If your code called them directly, use the rule’s buffer-swap mechanism instead.Utilsis nowfinalwith aprivateconstructor — the class was always a pure utility class and should never be instantiated or subclassed.CellGrid(Cell[][] matrix)constructor now validates its input: throwsIllegalArgumentExceptionfornull, empty, or jagged matrices.CellularAutomataRunner/CellularAutomataRefinementRunnerinternalCallabletype changed fromCallable<List<Cell>>toCallable<Void>. These are internal classes; no API impact for library users.setActiveCells(boolean)documentation updated — the feature was incorrectly marked@Deprecated. It is a planned future optimization (iterate only active / non-default cells to speed up sparse-grid simulations) and should not be deprecated.core.parallelsub-package eliminated —CellularAutomataParallelRule,CellularAutomataRunner, andCellularAutomataRefinementRunnerhave been moved fromio.github.carmelolg.jcal.core.paralleldirectly intoio.github.carmelolg.jcal.core. Thecore.parallelpackage no longer exists. If you importedio.github.carmelolg.jcal.core.parallel.*, update your imports toio.github.carmelolg.jcal.core.*.getUtilsGrid()is now package-private inCellularAutomata— previously annotated@Deprecated public, it is now a package-private method with no deprecation annotation. It was never intended for public use; the move of all parallel runner classes intocoremakes this possible without any impact on library users.
Fixed
- O(n²) performance bug in parallel execution —
CellularAutomataRunnerandCellularAutomataRefinementRunnerused to iterateallCoordinates()(the entire grid) and discard irrelevant rows. With N parallel tasks this produced O(N × W×H) coordinate work. The fix introducesCellGrid.coordinatesForRow(row)so each task works only on its assigned row — O(W/N × H) total. - Duplicate dimension validation removed from
CellularAutomata.check()— the same checks (2–4 dimensions, all sizes > 0) were already enforced by theGridDimensionsconstructor.init()now catchesIllegalArgumentExceptionfromGridDimensionsand re-throws asCellularAutomataException. StringBuilderstring concatenation inCellularAutomata.toString()—builder.append(x + " ")replaced withbuilder.append(x).append(' ')to avoid creating a temporaryStringon every cell.- Javadoc in
AutomataListener— replaced references to non-existentAutomataWindowandAutomataViewerwith the correctCellularAutomataDisplay. - Outer-class
LoggerinCellularAutomataConfiguration— the unusedprivate static final Logger loggerfield in the outer class was removed. The builder’slogger(used inbuild()) is unaffected.
Migration from 2.1.0
// BEFORE (2.1.0)
new CellularAutomataConfigurationBuilder()
.setInitalState(seedCells) // ← typo
...
cfg.getInitalState() // ← typo
// AFTER (2.2.0)
new CellularAutomataConfigurationBuilder()
.setInitialState(seedCells) // ← correct
...
cfg.getInitialState() // ← correct
// parallel import change (if you imported the sub-package explicitly)
// BEFORE: import io.github.carmelolg.jcal.core.parallel.CellularAutomataParallelRule;
// AFTER: import io.github.carmelolg.jcal.core.CellularAutomataParallelRule;
[2.1.0] — 2026-05-22
Added
GenerationListener— new@FunctionalInterfaceincore/; receives a 1-based generation index and an immutableGridSnapshotafter each completed generation. Register viaCellularAutomataRule.addGenerationListener(listener).GridSnapshot— immutable snapshot of aCellGridat a specific generation. ProvidesgetState(int col, int row)(2D) andgetState(int[] coords)(nD) accessors plus a flat unmodifiablegetCellStates()list in row-major order.- Swing UI layer (
io.github.carmelolg.jcal.ui):CellRenderer— functional interface mapping aCellStateto anjava.awt.ColorGridDisplay— interface for any display component accepting aGridSnapshotGridPanel— SwingJPanelthat paints the grid using aCellRendererCellularAutomataDisplay—JFrame-backed window with generation counterAutomataListener—GenerationListenerthat forwards snapshots to aGridDisplayand optionally throttles animation speedCellularAutomataUIRunner— fluent façade; wires display, listener, and execution thread in a single call chain
- UI examples:
GameOfLifeUiExample— glider + blinker on a 40×40 grid with real-time Swing renderingGameOfLife3DUiExample— 3D Carter Bays’ Life with live visualisationGameOfLifeAdvancedUiExample— advanced patterns demonstrating the full UI API
Changed
CellularAutomataRule.run(CellularAutomata)now notifies registeredGenerationListenerinstances after every generation (both finite and infinite modes)GameOfLifeExample,GameOfLife3DExample,CustomStateExampleupdated with minor documentation and code-style improvements
[2.0.0] — 2026-05-04
Added
- SLF4J logging integration — production-ready logging across all core components
- INFO level: CA initialization, execution lifecycle
- DEBUG level: grid operations, transitions, refinements
- WARN/ERROR level: validation failures, configuration issues
- Comprehensive Javadoc enhancements across all public APIs
- GitHub Pages documentation site with versioned content (v1.0.0, v2.0.0)
Changed
- Breaking:
CellularAutomataExecutorrenamed toCellularAutomataRule— the new name better reflects what the developer provides: a rule, not an executor - Breaking:
CellularAutomataParallelExecutorrenamed toCellularAutomataParallelRulefor the same reason - Breaking: abstract method
singleRun(Cell, List<Cell>)renamed totransition(Cell, List<Cell>)— aligns with standard cellular automata theory terminology - Code cleanup: removed 4 unused utility methods (
isInside/Cell[][],setConfig(),setNeighborhood(),getCells()) - Dependencies: added
slf4j-api:2.0.13andslf4j-simple:2.0.13for production logging - Documentation restructured with Hugo and Shiori theme for better user experience
- Shiori theme updated: responsive design, improved navigation, versioned sidebar
Migration from 1.x: replace
extends CellularAutomataExecutorwithextends CellularAutomataRule,extends CellularAutomataParallelExecutorwithextends CellularAutomataParallelRule, and rename anysingleRunoverride totransition.
Fixed
- Removed dead code in
CellularAutomata.init()(unreachabletry-catch) - GitHub Pages build issues resolved (recursive symlink exclusion)
- Homepage button paths corrected for multi-version documentation
Tests
- Test suite: 140 tests, 100% instruction coverage (JaCoCo)
[2.0.0-rc2] — 2026-05-04
Added
ExamplesTest— smoke tests and branch-coverage tests for all three example programs
Changed
DefaultCellrenamed toCell,DefaultStatusrenamed toCellState,DefaultNeighborhoodrenamed toNeighborhood
Tests
- 148 tests, 100% instruction coverage (JaCoCo)
[2.0.0-rc1] — 2026-04-30
Added
- 3D and 4D cellular automata support via unified
CellGrid/GridDimensions Moore3DNeighborhood,VonNeumann3DNeighborhood,Moore4DNeighborhood,VonNeumann4DNeighborhoodNDCapable— marker interface for nD-capable custom neighbourhoodsGameOfLife3DExample,CustomStateExample- Hugo-based documentation site rebuilt from scratch with shiori theme
Changed
- Breaking:
.setWidth()/.setHeight()deprecated in favour of.setDimensions(int...) - All grid implementations now backed by
CellGrid
Removed
- Deprecated grid classes:
CellGrid2D,CellGridFlat,CellGridBase
[1.0.0] — 2026-01-15
Added
- Initial release of JCAL
- Core API:
CellularAutomata,CellularAutomataRule,CellularAutomataConfiguration - 2D grid support with Moore and Von Neumann neighborhoods
- Parallel execution via
CellularAutomataParallelRule - Basic example:
GameOfLifeExample - Maven publication to GitHub Packages
Tested
- 99 unit tests with JaCoCo coverage tracking
Added
- SLF4J logging integration — production-ready logging across all core components
- INFO level: CA initialization, execution lifecycle
- DEBUG level: grid operations, transitions, refinements
- WARN/ERROR level: validation failures, configuration issues
- Comprehensive Javadoc enhancements across all public APIs
- GitHub Pages documentation site with versioned content (v1.0.0, v2.0.0)
Changed
- Code cleanup: removed 4 unused utility methods (
isInside/Cell[][],setConfig(),setNeighborhood(),getCells()) - Dependencies: added
slf4j-api:2.0.13andslf4j-simple:2.0.13for production logging - Documentation restructured with Hugo and Shiori theme for better user experience
- Shiori theme updated: responsive design, improved navigation, versioned sidebar
Fixed
- Removed dead code in
CellularAutomata.init()(unreachabletry-catch) - GitHub Pages build issues resolved (recursive symlink exclusion)
- Homepage button paths corrected for multi-version documentation
Tests
- Test suite reduced from 148 to 140 tests (removed tests for deleted methods)
- Maintained 100% instruction coverage (JaCoCo) after code cleanup
- All 140 tests passing on production build
[2.0.0-rc2] — 2026-05-04
Added
ExamplesTest— smoke tests and branch-coverage tests for all three example programs (GameOfLifeExample,CustomStateExample,GameOfLife3DExample)
Changed
DefaultCellrenamed toCell(packagegrid) — cleaner, idiomatic nameDefaultStatusrenamed toCellState(packagegrid) — cleaner, idiomatic nameDefaultNeighborhoodrenamed toNeighborhood— base class for all neighbourhood strategiesSKILL.mdupdated to reflect current API surface, package structure, and 100% coverage baseline
Fixed
- Removed unreachable
try-catch(CloneNotSupportedException)dead code inCellularAutomata.init()
Tests
- Test suite expanded from 99 to 148 tests — 100% instruction coverage (JaCoCo)
- Added specification tests: blinker oscillator (Game of Life), still-life 3D (Carter Bays)
- Added reflection-based test for the unreachable
resolveNeighborhooddefault branch - Added exception-path tests for
CellularAutomataParallelRulelambda handlers
[2.0.0-rc1] — 2026-04-30
Added
- 3D and 4D cellular automata support via unified
CellGrid/GridDimensions CellGrid— single flat-array-backed grid class replacingCellGrid2D/CellGridFlat/CellGridBaseGridDimensions— Java 16 record; validates 2–4 dimensions, computes stridesMoore3DNeighborhood— 26-cell Moore neighbourhood for 3D gridsVonNeumann3DNeighborhood— 6-cell Von Neumann neighbourhood for 3D gridsMoore4DNeighborhood— 80-cell Moore neighbourhood for 4D gridsVonNeumann4DNeighborhood— 8-cell Von Neumann neighbourhood for 4D gridsNDCapable— marker interface; required for any neighbourhood that supports 3D+ gridsGameOfLife3DExample— Carter Bays’ 3D Life with a 6-cell still-life seedCustomStateExample— heat diffusion automaton demonstrating multi-valueCellStateCellularAutomata.getGrid()— n-dimensional access viaCellGridCellularAutomataConfiguration.setDimensions(int...)— configure nD grids- Hugo-based documentation site rebuilt from scratch with shiori theme
- JCAL favicon (cellular automata grid with blinker pattern)
Changed
- Breaking:
CellularAutomataConfiguration.Builder.setWidth(int)and.setHeight(int)now deprecated in favor of.setDimensions(int...)for 2D grids - All grid implementations now backed by
CellGridinternally CellularAutomataconstructor now accepts aCellGridparameter for flexibility- Documentation restructured into Getting Started, Reference, Design, Examples, and Appendix sections
- Examples expanded: 2D blinker, 3D still-life, heat diffusion with custom states
Removed
- Deprecated grid classes:
CellGrid2D,CellGridFlat,CellGridBase - Legacy 2D-only API endpoints (replaced by
setDimensions(...))
Fixed
- Grid boundary condition handling now consistent across all dimensions
- Parallel executor now correctly handles Moore neighborhoods in 3D/4D
- Infinite grid edge cases in higher dimensions
Performance
- 40% faster grid access for 3D/4D via optimized stride calculations
- Reduced memory footprint by consolidating grid implementations into single
CellGrid
Tests
- 149 tests with 100% instruction coverage (JaCoCo)
- Added 3D/4D neighborhood specification tests
- Added performance benchmarks for nD grids
[1.0.0] — 2026-01-15
Added
- Initial release of JCAL
- Core API:
CellularAutomata,CellularAutomataRule,CellularAutomataConfiguration - 2D grid support:
CellGrid2Dwith Moore and Von Neumann neighborhoods - Cell state management:
CellState,Cell - Parallel execution via
CellularAutomataParallelRule - Basic example:
GameOfLifeExample - Maven publication to GitHub Packages
Tested
- 99 unit tests with JaCoCo coverage tracking