diff --git a/README.md b/README.md index 111b489..bd4bfba 100644 --- a/README.md +++ b/README.md @@ -114,18 +114,6 @@ Examples: - a "mouth" block that can communicate wether food is available to eat and can receive eat commands at the same time -### Evaluating a machine's mind's iteration - -for each iteration, the `stored signal` of each block is calculated using its connection with adiacent blocks. - -This `new stored signal` is stored in a special variable without overwriting the `current stored signal` -so that the process can be easily accomplished in multithreading execution environments. - -After all the `new stored signals` have been calculated, their value is applied to the `current stored signal` -and the calculation process is repeated. This is done to encourage parallel computing. - -__Note:__ the bigger a machine, the slower it reacts to signals because they need more time to travel through the body - ### Reproduction and evolution This requires two action blocks: @@ -150,7 +138,6 @@ This requires some new blocks: - the energy drain block - the generator block - the stomach block - - the energy drain block sucks energy from a structure's batteries. - the battery block stores energy and emits the current level to its connections - the generator block uses up a lot of energy, then gives back slightly more @@ -162,7 +149,7 @@ This requires some new blocks: - each action block uses up a moderate amount of energy when activated - each sensor block uses up a small amount of energy when activated -## Fitness of a structure +### Fitness of a structure The fitness is calculated by dividing the creature's total harvested energy by the creature's total consumed energy. @@ -177,6 +164,21 @@ This method to calculate fitness has many problems: The conclusion is that this system is far too complex to consider fitness evaluation. +### Complexity of a structure + +The complexity of a structure is: + +- if the fitness is `> 0`: the sum of the complexity of all its blocks. +- if the fitness is `<= 0`: 0 + +Complexity of a block starts at 0, then: + +- increases by 1 for every not null connection of the block, if the block is an input block +- increases by x for every output block, depending on the specific block + +The point of structure complexity is to try and approximately figure out how computationally expensive it is +to compute an itearation of the simulation for the structure + ## Primordial world The world should be composed of a variety of huge, small and anything in between energy farming or storage @@ -201,14 +203,18 @@ even early in an implementation. We __don't__ want to lose good machines! ## Interface -- navigate world +It is very important to give the user the ability to see the world in motion. + +The interface should be structured akin to the following guidelines: + +- a world navigation screen - lets the user create an empty structure (needs at least 1 block) -- navigate structure +- structure navigation screen - ability to save the structure to file - has a small _selected block_ sidebar with block informaton - lets the user clear cells or set a block to them -- view block - - provides all info about the block and maybe signal activity monitoring +- block navigation screen + - provides all info about the block and signal activity information - lets the user view all connections and edit them - lets the user edit the block type, preserving the connections @@ -217,3 +223,52 @@ A sidebar has controls to handle simulation speed and pausing and other informat - current CPU load. - available energy in the world and amount being generated - population information + +## Implementation + +The rust programming language is the best suited for a variety of reasons, namely: + +- it is a fast language, well suited for performance intensive tasks +- it has a package manager that allows a programmer to focus on writing the code, not + desiging infrastructure, build systems, or coding functions already available in popular libraries +- it produces native, multiplatform binaries +- it obviously supports all the required features for the implementation of the simulation + +But most importantly: + +- it is built with a focus on type safety, concurrency and thread safety +- it's impossible to compile a thread unsafe concurrent program with the rust reference compiler + +### Simulation iteration evaluation algorithm + +- __MT__: main thread, controls the flow, HIGHEST PRIORITY +- __WT__: worker thread, evaluates a simulation iteration for one or more structures +- __AT__: applier threads, applies actions and writes the `new stored signal` into the `current stored signal` + for all blocks + +One tick is evaluated using the following algorithm: + +1. __MT__ + - rebalances the __WTs__ work load, evaluating it based on structure complexity + - assignes newborn structures to the workers + - starts all the workers +1. __WTs__ work, __MT__ waits until they are done +1. __MT__ assigns actions returned by all the __WTs__ to a number of __ATs__ + - tries to balance the __ATs__' work + - groups events from creatures that interact with each other together, keeping it thread safe but as distributed + across threads as possible +1. __ATs__ work, __MT__ waits untile they are done + +It's probably not as fast as it gets, but it should be decent + +#### Structure iteration evaluation algorithm + +1. the `new stored signal` of each block is calculated + - if the block is a neuron block, calculate its `new stored signal` using immutable references to the other blocks + and the connection values. + - if the block is an input block, run its logic to figure out what its output should be + - if the block is an output block, add the action it should perform to the action queue + - This `new stored signal` is stored in a special variable without overwriting the `current stored signal` + so that the process can be easily accomplished in multithreading execution environments. + +__Note:__ the bigger a machine, the slower it reacts to inputs because signals need more time to travel through the body