PHPackages                             mahdyfo/rotifer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. mahdyfo/rotifer

ActiveLibrary[Framework](/categories/framework)

mahdyfo/rotifer
===============

A genetic AI framework that evolves its own neural network architecture through biologically-inspired neuroevolution (AutoML)

v2.0.0(4d ago)25Apache-2.0PHPPHP &gt;=8.2

Since Sep 6Pushed 2d ago1 watchersCompare

[ Source](https://github.com/mahdyfo/rotifer)[ Packagist](https://packagist.org/packages/mahdyfo/rotifer)[ RSS](/packages/mahdyfo-rotifer/feed)WikiDiscussions main Synced yesterday

READMEChangelog (4)Dependencies (3)Versions (5)Used By (0)

Rotifer
=======

[](#rotifer)

**A genetic AI framework that evolves its own neural networks - modelled on how life actually evolves.**

Rotifer doesn't train networks with backpropagation. It *evolves* them: a population of organisms, each a neural network described entirely by its genome, competes and reproduces over generations. Topology, neuron count, and weights are all discovered automatically (AutoML / neuroevolution). On top of plain genetic search, Rotifer models the messy, powerful machinery of real evolution - **geographic islands, epigenetic trauma, self-tuning mutation, and lifetime learning that children inherit.**

Pure PHP. Watch it evolve live in your terminal **or** in a browser dashboard. Reproducible to the bit. Parallel across CPU cores.

```
composer install
php bin/rotifer serve            # start dashboard http://localhost:8080
```

[![Rotifer browser dashboard — weather_forecast at generation 500, 99% match](docs/screenshot.jpg)](docs/screenshot.jpg)

---

Why it's different
------------------

[](#why-its-different)

Traditional deep learningRotiferFixed architecture you designArchitecture is **discovered** by evolutionGradient descent / backpropGenetic operators: crossover + mutationOne global modelA **world of islands**, each its own gene poolWeights are everythingThe **genome is the network** - one array of connection genesA black box**Watch every generation** evolve, in terminal or browserCore ideas
----------

[](#core-ideas)

- **Genome = network.** A genome is just a list of connection genes (`from → to`, weight). There are no separate weight matrices; the genome *is* the network. (`src/Genome/`)
- **Organism.** A genome compiled into a runnable `Brain` plus the things evolution cares about - fitness, age, and an `Epigenome`. (`src/Organism/`)
- **World of islands.** The `World` runs several semi-isolated `Island`s ("villages"). Each evolves on its own and periodically migrates its best individuals to neighbours - spreading breakthroughs while preserving diversity. (`src/Evolution/`)
- **One seeded RNG tree.** Every random choice flows through a seedable `Rng`; the master seed derives an independent stream per island. **Same seed ⇒ identical run**, which makes evolution testable and parallel-safe. (`src/Runtime/Rng.php`)
- **Events, not print statements.** The engine emits events; *reporters* render them - a terminal dashboard, a JSON stream for the web UI, or nothing at all. (`src/Observe/`)

Topology is dynamic by default: hidden neurons are sorted by index and edges flow low→high, so a chain of hidden neurons naturally forms multiple layers - but the same set of neurons can equally well form a single layer with intra-connections, depending on what evolution finds useful.

[![Dynamic topology: the same neurons can form multi-layer or single-layer-with-intra-connections depending on how evolution wires them](docs/neural_layerings.jpg)](docs/neural_layerings.jpg)

The biology
-----------

[](#the-biology)

Every mechanism is independently switchable in a problem's config; turned off, it's a no-op.

- **Epigenetic trauma** - hardship leaves a heritable, *decaying* stress marker that makes a lineage's offspring mutate harder for a few generations, then fades. Inherited trauma that washes out over time.
- **Adaptive mutation** - each island raises mutation when it stalls (explore) and lowers it when improving (exploit).
- **Lifetime learning** - an organism refines its own weights during its life (the Baldwin effect). A configurable fraction of what it learns is written back into its genome and **inherited** (Lamarckian).
- **Islands &amp; migration** - different demes drift toward different solutions and trade their best on a ring.

Getting started
---------------

[](#getting-started)

### 1. Install

[](#1-install)

```
composer install
```

Pure PHP - all you need is PHP ≥ 8.2 and Composer.

### 2. Use the browser dashboard

[](#2-use-the-browser-dashboard)

One persistent server drives every run, so you never need a separate port per experiment.

```
php bin/rotifer serve   # then open http://localhost:8080
```

From the page you can:

1. **Pick a problem** from the dropdown - its recommended defaults load into the control panel.
2. **Tune any option.** The top row has the common knobs; expand **advanced parameters** and **biology parameters** for everything else (see the table below).
3. **Toggle the biology** you want - trauma, adaptive mutation, lifetime learning.
4. Press **Start** and watch the fitness chart, the champion's network graph (hover any connection or neuron for the underlying math), and the island map update live.
5. Press **Stop** any time, or **Continue** to resume the last run from where it left off.
6. When a run ends, read the **champion predictions** table, **feed the champion a custom input** and watch each neuron light up by how strongly it fires, or hit **+ New problem** to author your own from example input → output rows.

Prefer to keep launching from the terminal but still watch in the browser? Run the two side by side - `--web` streams a CLI run to the same dashboard:

```
php bin/rotifer serve                       # terminal 1 - the dashboard
php bin/rotifer run flappy_bird --web       # terminal 2 - streams this run to the page
```

### 3. Evolve a problem in the terminal

[](#3-evolve-a-problem-in-the-terminal)

```
php bin/rotifer list                # see the built-in problems
php bin/rotifer run xor             # evolve XOR with a live terminal dashboard
```

You'll watch fitness climb generation by generation; when it stops (or you press Ctrl+C) it prints the champion's predictions, a success rate, and the best genome as hex. A few variations:

```
php bin/rotifer run xor --seed=42 --quiet        # reproducible, no live output
php bin/rotifer run weather_forecast             # multi-class classification
php bin/rotifer run flappy_bird                  # a game, learned with no training data
php bin/rotifer run auto_encoder --parallel=8    # evaluate across 8 worker processes
php bin/rotifer help                             # the full, annotated option list
```

### 4. Every option, both ways

[](#4-every-option-both-ways)

The command line and the dashboard expose **exactly the same knobs**: anything you can pass as a `--flag` you can set in a field, and the reverse. (They share one schema - `src/Runtime/RunOptions.php` - so they can't drift apart.) A flag or field only overrides what you set; everything else keeps the problem's own `config()`. Run `php bin/rotifer help` for the annotated list, or open the dashboard's **advanced parameters** / **biology parameters** panels.

GroupKnobsCLI flagsCorepopulation, generations, islands, seed, parallel, resume`--population` `--generations` `--islands` `--seed` `--parallel[=N]` `--resume`Structure / selectionsurvive rate, elitism, diversity, init hidden, hidden layers, simplicity, activation`--survive-rate` `--elitism` `--diversity` `--initial-hidden` `--hidden-layers=5,3,5` `--simplicity` `--activation=tanh`Reproductioncrossover, weight-mutation chance, **weight count / adjust / randomize**, add/remove neuron &amp; connection`--crossover` `--weight-mutation` `--weight-count` `--weight-adjust` `--weight-randomize` `--add-neuron` `--add-connection` `--remove-neuron` `--remove-connection`Traumaenable, intensity, decay`--trauma` `--trauma-intensity` `--trauma-decay`Adaptive mutationenable, patience, up/down factor, min/max scale`--adaptive-mutation` `--adaptive-patience` `--adaptive-up` `--adaptive-down` `--adaptive-min` `--adaptive-max`Lifetime learningenable, steps, step size, lamarckian fraction`--lifetime-learning` `--lifetime-steps` `--lifetime-step-size` `--lamarckian`Migrationevery N generations, top K`--migration-every` `--migration-top`For example, the weight-mutation mechanics behind `->weightMutation(count: 2, adjustmentRange: 0.8, randomizeProbability: 0.1)` are the **weight count / weight adjust / weight rnd** fields in the dashboard's advanced panel, or on the command line:

```
php bin/rotifer run xor --weight-count=2 --weight-adjust=0.8 --weight-randomize=0.1
```

Built-in problems
-----------------

[](#built-in-problems)

NameKindShows off`xor`logicevolving topology from scratch`memory_recall`sequencerecurrent memory networks`phone_recall`memoryrecall a phone number from a constant input - pure recurrence`auto_encoder`unsupervisedcompression through a bottleneck`house_price`regressionordinary tabular data`weather_forecast`classificationmulti-class output + islands/migration`flappy_bird`gameemergent control, no training dataTeaching it your own task
-------------------------

[](#teaching-it-your-own-task)

A new task is **one class**. Define the data, the fitness, and the tuning - that's the entire surface.

```
namespace Rotifer\Problems;

use Rotifer\Network\Activation\Sigmoid;
use Rotifer\Network\Shape;
use Rotifer\Organism\Organism;
use Rotifer\Runtime\EvolutionConfig;
use Rotifer\Runtime\Fitness\Problem;

final class XorProblem implements Problem
{
    public function name(): string { return 'xor'; }

    public function shape(): Shape { return new Shape(inputs: 3, outputs: 1); }

    public function data(): array
    {
        return [
            [[1, 0, 0], [0]],
            [[1, 0, 1], [1]],
            [[1, 1, 0], [1]],
            [[1, 1, 1], [0]],
        ];
    }

    public function fitness(Organism $organism, array $row): float
    {
        return 1.0 - abs($organism->outputs()[0] - $row[1][0]);
    }

    public function config(): EvolutionConfig
    {
        return EvolutionConfig::default()
            ->population(150)->islands(2)->generations(80)
            ->activation(new Sigmoid())
            ->mutation(weight: 0.85, addNeuron: 0.05, addConnection: 0.12)
            ->adaptiveMutation(true)
            ->migration(everyGenerations: 8, topK: 2)
            ->seed(1234);
    }
}
```

Drop it in `problems/`, then `php bin/rotifer run xor`. A row of `[]` in `data()` resets network memory between sequences. For episodic tasks (games), run the whole episode inside `fitness()` - see `problems/FlappyBirdProblem.php`.

Testing
-------

[](#testing)

```
composer test                       # all suites
vendor/bin/phpunit --testsuite Unit
```

Because runs are reproducible, evolution itself is unit-tested (same seed ⇒ identical champion), alongside each genetic and biological mechanism.

> On Windows, run the suite from PowerShell - the parallel tests spawn `php.exe` workers.

Project layout
--------------

[](#project-layout)

```
src/
  Genome/        NodeType, NodeRef, Gene, Genome (+distance), Weight
  Network/       Brain (forward pass), GenomePruner, Activation/, Shape, NetworkSpec
  Organism/      Organism, Epigenome
  Evolution/     World, Island, OrganismFactory, IdSequence,
                 Reproduction/ Selection/
                 Adaptation/ Epigenetics/ Learning/ Migration/
  Runtime/       EvolutionConfig, Rng, Fitness/ (Problem, evaluators, Scorer), Parallel/
  Observe/       EventDispatcher, Event/, Reporter/ (terminal + JSON-stream)
  Persistence/   Codec/ (Json, Binary, Hex), SnapshotStore
  Web/           server.php + public/ (vanilla-JS dashboard)
  Cli/           Console, ProblemRegistry
problems/        one class per task
bin/rotifer      the command-line entry point

```

The original (pre-2.0) implementation is preserved in git history under the `v1.0.0`-`v1.1.0` tags.

Requirements
------------

[](#requirements)

- PHP ≥ 8.2
- Composer
- `amphp/parallel` (pulled in automatically) for `--parallel`

License
-------

[](#license)

Apache-2.0

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance100

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~342 days

Total

4

Last Release

4d ago

Major Versions

v1.1.0 → v2.0.02026-06-29

PHP version history (2 changes)v1.0.0PHP &gt;=8.0.0

v2.0.0PHP &gt;=8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/15161574?v=4)[mahdyfo](/maintainers/mahdyfo)[@mahdyfo](https://github.com/mahdyfo)

---

Top Contributors

[![mahdyfo](https://avatars.githubusercontent.com/u/15161574?v=4)](https://github.com/mahdyfo "mahdyfo (168 commits)")

---

Tags

aineatmachine learningDeep learningneural networksgenetic algorithmneuroevolutionAutoML

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mahdyfo-rotifer/health.svg)

```
[![Health](https://phpackages.com/badges/mahdyfo-rotifer/health.svg)](https://phpackages.com/packages/mahdyfo-rotifer)
```

###  Alternatives

[rubix/ml

A high-level machine learning and deep learning library for the PHP language.

2.2k1.5M28](/packages/rubix-ml)[laravel/boost

Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.

3.5k21.5M588](/packages/laravel-boost)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M194](/packages/laravel-ai)[php-mcp/laravel

Laravel SDK for building Model Context Protocol (MCP) servers - Seamlessly integrate MCP tools, resources, and prompts into Laravel applications

473153.0k3](/packages/php-mcp-laravel)[davmixcool/php-sentiment-analyzer

PHP Sentiment Analyzer is a lexicon and rule-based sentiment analysis tool that is used to understand sentiments in a sentence using VADER (Valence Aware Dictionary and sentiment Reasoner).

136173.7k1](/packages/davmixcool-php-sentiment-analyzer)[nlpcloud/nlpcloud-client

NLP Cloud serves high performance pre-trained or custom models for NER, sentiment-analysis, classification, summarization, paraphrasing, grammar and spelling correction, keywords and keyphrases extraction, chatbot, product description and ad generation, intent classification, text generation, image generation, code generation, question answering, automatic speech recognition, machine translation, language detection, semantic search, semantic similarity, tokenization, POS tagging, speech synthesis, embeddings, and dependency parsing. It is ready for production, served through a REST API. This is the PHP client for the API. More details here: https://nlpcloud.com. Documentation: https://docs.nlpcloud.com. Github: https://github.com/nlpcloud/nlpcloud-php

2526.3k1](/packages/nlpcloud-nlpcloud-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
