This simulation is built using data-oriented design paradigm. All entities are stored in a Map with unique ids(numbers for the sake of simplicity). The entity tables (Maps) store an entity's metadata like it's energy and age (number of ticks since it is alive).
npm installnpm run simulate
Node version 24.15.0+ (hasn't been tested on earlier versions)
The code relies on Node's ability to run Typescript directly - No TS compilation step is included
- The simulation is a square grid
- There are only 3 types of movements: horizontal, vertical and diagonal
- The movement is left to right (assuming it on a graph with x and y axis)
- When an animal moves past the edge, it appears from the opposite end - In case of horizontal movement, the animal will move 1 step up when it moves past the edge
AI has been used to generate the code for creating a data structure allowing 2-way lookups. The functions generated by AI have the following comment above their definition: // AI generated (See ./src/helpers.ts).
See ./src/config.ts for configuration options.
The ./src/data.ts loads initial data manually. This includes placing each individual entity on the grid.
There is no random entity generation. But the design is simple enough to allow adding random data.
The function loadData() first populates the entity tables (plants, herbivores and carnivores) and then
positions each entity on the grid using addEntity() available for each entity type, for example addPlant()
In order to add more data, it is necessary to populate at both places (the entity tables and grid positions).
Note that there isn't a single grid where all entities are placed. Rather, each entity type gets it's own storage which is also a Map (actually 2 Maps for reverse lookups).
The 2 Maps approach allows us to achieve the following with O(1) lookup:
- Get an entity's position based on it's id (Where is plant 14 located on the grid?)
- Check which entity exists on a specific location (Which entity exists at position { x: 4, y: 12 } on the grid?)