RubyNEAT comprises many interacting modules. While it is not strictly necessary to understand RubyNEAT at this level of detail, it would be beneficial for a number of reasons, especially in understanding how to tweak the parameters to improve performance for your application.
RubyNEAT comprises the following modules: Controller, Expressor, Evaluator, Evolver, Population, and Critter.
The Controller mediates all aspects of RubyNEAT evolution, the various modules involved and their interactions, and also holds the settings the other modules will refer to.
The Controller is singular. There can only be one Controller in the RubyNEAT system. All other objects associated with the Controller shall have embedded in them a reference to their controller.
The Evolver module houses the evolving algorithms for RubyNEAT. It evolves the entire Population of Critters.
The Expressor module is responsible for interpreting the Genotype of the Critters and creating their Phenotypes. The default Expressor generates Ruby code and attaches that code to the Phenotype instances of the Critter.
It is entirely possible to swap in a different Expressor and generate code for a different target language, or create some other construct. There is no limit to what you could have an Expressor do.
The Evaluator is a kind of bridge between the inner "biology" of the RubyNEAT "ecosystem" and the outside world. It has ties to the RubyNEAT DSL where you encode your own fitness functions and data links to some external problem space. It is, in a sense, the "gateway".
The Population is what your intuition tells you. It is a environment that houses a collection of Critters.
The Critter is the embodiment of both the genetics for the neural net and also the expression of the same. It contains, in other words, the Genotype and the Phenotype.
Critters are mated through the Evolver, and have their genes expressed through the Expressor.