Feel free to join the next Helmholtz Hacky Hour #26 on Wednesday, April 21, 2021 from 2PM to 3PM!

Commit df02adfc authored by Martin Lange's avatar Martin Lange

Merge branch 'feature/yarner-migration' into 'master'

Migrate to Yarner 0.3.0, use default Yarner settings

See merge request !12
parents a67c5f5f 086dff65
Pipeline #15626 passed with stage
in 15 seconds
image: openjdk:15-jdk
variables:
YARNER_VERSION: 0.2.2
YARNER_VERSION: 0.3.0
before_script:
- curl -L -o- https://github.com/mlange-42/yarner/releases/download/${YARNER_VERSION}/yarner-${YARNER_VERSION}-linux.tar.gz | tar xz
......@@ -9,7 +9,7 @@ before_script:
build:
script:
- yarner
- yarner --clean
- cd code
- ./gradlew build
- mv build/distributions/*.zip ..
......
......@@ -37,13 +37,13 @@ Model development is an iterative process. For example, submodels are frequently
A design approach that facilitates this style of work is the Entity–Component–System (ECS) pattern, by decoupling the state of the model from the logic. While it is rooted in game design, it has proven to be useful for IBMs.
In ECS terms, *entities* are abstract handles to refer to what we usually consider entities in the IBM world. For example in a predator-prey-model, each predator and each prey could be represented by an entity. In a livestock model, each individual animal, each herd, and each market could be represented by an entity.
In ECS terms, *entities* are abstract handles to refer to what we usually consider entities in the IBM world. For example in a predator-prey-model, each predator and each prey could be represented by an entity. In a livestock model, each individual animal, each herd, and each market could be represented by an entity.
Each entity has one or more *components* which contain the entity's state variables. What can happen with an entity in the model results from the composition of its components. To resume the livestock example, all three types of entities could have a location component, but only animals would have an age. The herds could e.g. have a component holding their trade partners.
What is called a submodel in modelling terms are *systems* in ECS. Systems contain the logic of the model and operate on a certain combination of components. Examples of this kind of logic could be:
* If something has a position and a velocity, it moves (i.e. changes position).
* If something has a position and a velocity, it moves (i.e. changes position).
* If something has a velocity and a mass, is falls due to gravity (i.e. changes velocity).
Because systems are only concerned with certain components relevant for their logic, while further components are ignored, the ECS approach enables independent development of different aspects of a model.
......@@ -67,7 +67,7 @@ In this grassing model, the only entities are grassers. All grassers possess the
Component `Position` contains continuous coordinates in a two-dimensional world.
```java
/// file:src/main/java/grassing/comp/Position.java
//- file:src/main/java/grassing/comp/Position.java
package grassing.comp;
public class Position extends com.artemis.Component {
......@@ -87,7 +87,7 @@ public class Position extends com.artemis.Component {
Component `Energy` contains the entity's current energy budget.
```java
/// file:src/main/java/grassing/comp/Energy.java
//- file:src/main/java/grassing/comp/Energy.java
package grassing.comp;
public class Energy extends com.artemis.Component {
......@@ -105,7 +105,7 @@ Component `Movement` contains the direction the entity is moving, in radians.
Entities have component `Movement` only when searching, but not when grassing. The presence or absence of the component defines an entity's behaviour.
```java
/// file:src/main/java/grassing/comp/Movement.java
//- file:src/main/java/grassing/comp/Movement.java
package grassing.comp;
public class Movement extends com.artemis.Component {
......@@ -125,12 +125,12 @@ public class Movement extends com.artemis.Component {
Grassers live in a two-dimensional world. The world is represented by a grid of grass that grassers can consume.
```java
/// file:src/main/java/grassing/res/Grass.java
//- file:src/main/java/grassing/res/Grass.java
package grassing.res;
import grassing.util.FloatGrid;
public class Grass {
public class Grass {
// Any instance of a Java class can be a resource, but only one instance of each class is possible
final public FloatGrid grass;
......@@ -147,7 +147,7 @@ public class Grass {
A single global pseudo random number generator is used for all processes that include randomness.
```java
/// file:src/main/java/grassing/res/Randomness.java
//- file:src/main/java/grassing/res/Randomness.java
package grassing.res;
import java.util.Random;
......@@ -171,7 +171,7 @@ Processes in the model are grass growth, grasser metabolism, grasser reproductio
> During initialization, systems are added to the world in a certain order, which defines the order of their execution. As systems interact indirectly via components, it is important to understand how the order of execution shapes the resulting dynamics.
```java
/// file:src/main/java/grassing/Main.java
//- file:src/main/java/grassing/Main.java
package grassing;
import com.artemis.World;
......@@ -226,7 +226,7 @@ The model is initialized with `NUM_GRASSERS` grassers. All grassers start with c
Position is initialized randomly. Energy is initialized with 1.0.
```java
/// Create entities
//- Create entities
private static void createEntities(World world, Random rng) {
for (int i = 0; i < NUM_GRASSERS; i++) {
int entity = world.create();
......@@ -245,7 +245,7 @@ Submodels are described in their order of execution.
### Grass growth
Grass growth is logistic. The amount of grass is updated according
Grass growth is logistic. The amount of grass is updated according
```math
p_{t+1} = p_t + r p_t \frac{k - p_t}{k}
......@@ -254,18 +254,18 @@ p_{t+1} = p_t + r p_t \frac{k - p_t}{k}
where $`p_t`$ is the amount in the current step and $`p_{t+1}`$ in the next step. $`r`$ is the growth rate per step and $`k`$ is the capacity. Capacity is always 1.0.
> The grass growth system does not access any entities, and only modifies the `Grass` grid, which is a resource in ECS terms.
>
>
> A system implements what happens in each time step, but scheduling of those steps is done by the ECS, outside the systems.
```java
/// file:src/main/java/grassing/sys/LogisticGrassGrowth.java
//- file:src/main/java/grassing/sys/LogisticGrassGrowth.java
package grassing.sys;
import com.artemis.BaseSystem;
import com.artemis.annotations.Wire;
import grassing.res.Grass;
public class LogisticGrassGrowth extends BaseSystem {
public class LogisticGrassGrowth extends BaseSystem {
// A system must extend BaseSystem or one of its many sub-classes that serve different purposes
// Since this system does not access any entities, we simply extend `BaseSystem`
......@@ -298,7 +298,7 @@ In each iteration, grassers lose `consumption` energy. When it's energy drops to
> Here, we are interested only in the `Energy` component which is modified in-place, thereby influencing the model evolution.
```java
/// file:src/main/java/grassing/sys/Metabolism.java
//- file:src/main/java/grassing/sys/Metabolism.java
package grassing.sys;
import com.artemis.ComponentMapper;
......@@ -335,14 +335,14 @@ public class Metabolism extends IteratingSystem {
The grasser reproduction works on all entities that have the components `Position` and `Energy`.
In each iteration, each grasser reproduces with a fixed probability.
In each iteration, each grasser reproduces with a fixed probability.
When reproducing, energy is split in half between the grasser and it's offspring. The offspring starts with the grassing behaviour (i.e. without `Movement`).
> Here, we are interested only in entities that have components `Position` and `Energy`. Only component `Energy` is modified, while `Position` is required to determine the grasser's grid cell.
```java
/// file:src/main/java/grassing/sys/Reproduction.java
//- file:src/main/java/grassing/sys/Reproduction.java
package grassing.sys;
import com.artemis.ComponentMapper;
......@@ -390,11 +390,11 @@ The grassing behaviour works on all entities that have the components `Position`
If the grasser's energy is 1.0 or above, it does nothing. Otherwise, the grasser decides if there is enough grass in its grid cell. If this is the case, the grasser consumes grass and converts it to energy. Otherwise, the grasser switches to the searching behaviour.
> The behaviour is switched by adding component `Movement`.
>
>
> Here, we want only entities that have components `Position` and `Energy`, but not `Movement`, which is optional according to our model logic. Thus, grassers that are searching instead of grassing will not be processed by this system. When the `Movement` component is added, this implies that the respective entity will not be processed by this system in the next step, but by the `SearchBehaviour`.
```java
/// file:src/main/java/grassing/sys/GrassingBehaviour.java
//- file:src/main/java/grassing/sys/GrassingBehaviour.java
package grassing.sys;
import com.artemis.ComponentMapper;
......@@ -453,7 +453,7 @@ The grasser decides if there is enough grass in it's grid cell. If this is the c
> The behaviour is switched by removing component `Movement`.
```java
/// file:src/main/java/grassing/sys/SearchBehaviour.java
//- file:src/main/java/grassing/sys/SearchBehaviour.java
package grassing.sys;
import com.artemis.ComponentMapper;
......@@ -521,7 +521,7 @@ public class SearchBehaviour extends IteratingSystem {
The world has a size of 100 x 100 cells and starts populated with 1000 grassers.
```java
/// Parameters
//- Parameters
final static int WORLD_WIDTH = 100;
final static int WORLD_HEIGHT = 100;
......@@ -531,14 +531,14 @@ final static int NUM_GRASSERS = 1000;
Grass growth rate is 0.01.
```java
/// Parameters
//- Parameters
final static float GRASS_GROWTH_RATE = 0.01f;
```
Grassers start searching when grass goes below 0.1 units, and resume grassing when finding grass of at least 0.2 units.
```java
/// Parameters
//- Parameters
final static float GRASS_START_SEARCHING = 0.1f;
final static float GRASS_START_GRASSING = 0.2f;
```
......@@ -546,7 +546,7 @@ final static float GRASS_START_GRASSING = 0.2f;
Grassers can consume 0.05 units of grass per step, and need 0.02 units per step for their metabolism.
```java
/// Parameters
//- Parameters
final static float GRASS_CONSUMPTION = 0.05f;
final static float ENERGY_CONSUMPTION = 0.02f;
```
......@@ -554,14 +554,14 @@ final static float ENERGY_CONSUMPTION = 0.02f;
Grassers have a reproduction probability of 5% per step.
```java
/// Parameters
//- Parameters
final static float REPRODUCTION_PROB = 0.05f;
```
Grassers walk with 0.25 units per step, and turn with values from a normal distribution with a mean of 0° and a standard deviation of 30°.
```java
/// Parameters
//- Parameters
final static float RANDOM_WALK_SPEED = 0.25f;
final static float RANDOM_WALK_ANGLE = MathUtil.deg2rad(30);
```
......
[parser]
# The sequence that identifies the start and end of a fenced code block
fence_sequence = "```"
# Alternative sequence that identifies the start and end of a fenced code block.
# Allows for normal Markdown fences in code blocks
fence_sequence_alt = "~~~"
# Parsed comments are stripped from the code and written to an `<aside></aside>` block after the code when printing.
# If false, the comments are just written back into the code.
comments_as_aside = false
# The sequence to identify a comment which should be omitted from the compiled code,
# and may be rendered as an `<aside>` if `comments_as_aside` is set.
# Text after a comment in the first line of a code block gives the block's name
comment_start = "///"
# The sequence to identify the start of a meta variable interpolation.
interpolation_start = "@{"
# The sequence to identify the end of a meta variable interpolation.
interpolation_end = "}"
block_name_prefix = "//-"
# The sequence to identify the start of a macro invocation.
macro_start = "// ==>"
# The sequence to identify the end of a macro invocation.
macro_end = "."
# The sequence to identify the start of a transclusion.
transclusion_start = "@{{"
# The sequence to identify the end of a transclusion.
transclusion_end = "}}"
# Prefix for links that should be followed during processing.
# Should be RegEx-compatible.
link_prefix = "@"
# The sequence to split variables into name and value.
variable_sep = ":"
# Prefix for file-specific entry points.
file_prefix = "file:"
# Name prefix for code blocks not shown in the docs.
hidden_prefix = "hidden:"
## The language to set if there was no automatically detected language. Optional.
# default_language = "java"
[paths]
# Root directory. All paths are relative to this.
root = "."
# Code output path.
code = "code/"
# Docs output path.
docs = "docs/"
# The input source file(s) as glob pattern(s).
files = ["README.md"]
entrypoint = "Main"
# File(s) to include in code output (unprocessed), as glob pattern(s).
code_files = ["gradle/**/*"]
# Allows to modify paths of copied code files. Replaces path components. Optional.
code_paths = ["-"]
## File(s) to include in docs output (unprocessed), as glob pattern(s).
# doc_files = ["**/*.png", "**/*.jpg"]
## Entrypoint block name. Optional. If not supplied, unnamed code blocks are used.
entrypoint = "Main"
[language.java]
clear_blank_lines = true
eof_newline = true
## Language-sprcific settings. Optional. Required for reverse mode.
## The language is determined by the extension of code output files.
## Example language settings for Rust:
# [language.java]
## Start of comments. Can be start of line or block comments.
# comment_start = "//"
### End of comments. Optional, only for block comments
## comment_end = "*/"
## Start of block labels.
# block_start = "<@"
## End of block labels.
# block_end = "@>"
## Replaces lines containing only whitespaces by blank lines, in code output. Defaults to true.
# clear_blank_lines = true
## Enforces code files to always end with a blank line. Defaults to true.
# eof_newline = true
[language.java.block_labels]
comment_start = "//"
block_start = "<@"
block_next = "<@>"
block_end = "@>"
......@@ -14,7 +14,7 @@ This section describes code that is not vital for understanding the model or the
The graphics system draws the amount of grass per cell by shades of green. Further, it draws searching grassers as orange triangles pointing in the direction of their heading, and grassing grassers as white rectangles.
```java
/// file:src/main/java/grassing/sys/Graphics.java
//- file:src/main/java/grassing/sys/Graphics.java
package grassing.sys;
import com.artemis.BaseEntitySystem;
......@@ -118,7 +118,7 @@ public class Graphics extends BaseEntitySystem {
The grid of `float` values for the grass.
```java
/// file:src/main/java/grassing/util/FloatGrid.java
//- file:src/main/java/grassing/util/FloatGrid.java
package grassing.util;
public class FloatGrid {
......@@ -164,7 +164,7 @@ public class FloatGrid {
Utility functions to handle angles.
```java
/// file:src/main/java/grassing/util/MathUtil.java
//- file:src/main/java/grassing/util/MathUtil.java
package grassing.util;
public abstract class MathUtil {
......@@ -181,7 +181,7 @@ public abstract class MathUtil {
Vector for heading calculated from angle.
```java
/// file:src/main/java/grassing/util/Vector.java
//- file:src/main/java/grassing/util/Vector.java
package grassing.util;
public class Vector {
......@@ -200,7 +200,7 @@ public class Vector {
[Gradle](https://gradle.org/) is used as build tool and for dependency management.
```groovy
/// file:build.gradle
//- file:build.gradle
apply plugin: 'application'
sourceCompatibility = 11
......@@ -220,7 +220,7 @@ application {
```
```groovy
/// file:settings.gradle
//- file:settings.gradle
rootProject.name = 'Grassing'
```
......@@ -229,7 +229,7 @@ rootProject.name = 'Grassing'
Regarding VCS/Git, we ignore files generated by Gradle, as well as build output.
```
/// file:.gitignore
//- file:.gitignore
.gradle
build
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment