Skip to main content

Rule Simulation

The rule simulation process is a fundamental phase to verify the correctness of the generated rules 🧪.
This process can be decomposed into four steps:

  • Facts definition: This steps consists of the definition of the facts (through the so-called fact builders) that will be inserted inside the Drools working memory during the simulation phase.
  • Expectations definition: In this step all the expected outcome in terms of game state changes are defined; basically a list of assertion is defined.
  • Scenario definition: This step consists of defining the order the rules and the facts that will be inserted in the Drools production memory and the Drools working memory respectively.
  • Actual simulation: This final step allows to simulate the pre-defined scenarios and verify if the assertions satisfied.

Fact Builders

A GameFactBuilder instance allows to fluently instantiate a fact representing a gamification element. Each gamification element has its corresponding fact builder:

  • Action ➡️ ActionFactBuilderImpl
  • BadgeCollectionConcept ➡️ BadgeCollectionFactBuilderImpl
  • Challenge ➡️ ChallengeFactBuilderImpl
  • Classification ➡️ ClassificationFactBuilderImpl
  • CustomData ➡️ CustomDataFactBuilderImpl
  • Game ➡️ GameFactBuilderImpl
  • InputData ➡️ InputDataFactBuilderImpl
  • Player ➡️ PlayerFactBuilderImpl
  • PointConcept ➡️ PointConceptFactBuilderImpl
  • Propagation ➡️ PropagationFactBuilderImpl
  • Reward ➡️ RewardFactBuilderImpl

The fact builders can be used as follow:

Simulation.java
public static void main(String[] args) {
// The following builder instantiates a PointConcept
// named "green leaves" and associated to a score of 10 points.
final PointFactBuilderImpl pointFact = PointFactBuilderImpl.builder()
.name("green leaves")
.score(10.0)
.build();

// The following builder instantiates a Game with a name of "game1".
final GameFactBuilderImpl gameFact = GameFactBuilderImpl.builder().id("game1").build();

// The following builder instantiates a Player with "player1" as id.
final PlayerFactBuilderImpl playerFact = PlayerFactBuilderImpl.builder().id("player1").build();

// The following builder instantiates a BadgeCollectionConcept named "green_leaves_badge".
final BadgeCollectionFactBuilderImpl badgeCollectionFact = BadgeCollectionFactBuilderImpl.builder()
.name("green_leaves_badge")
.build();

// The following builder instantiates an InputData with an
// associated map containing the key "sustainable" valued as true.
final InputDataFactBuilderImpl inputDataFact = InputDataFactBuilderImpl.builder()
.data(new HashMap<>() {{ put("sustainable", true); }})
.build();
}

Expectations Definition

When a simulation is run we want to be sure that the outcome matches what we expect; the CheckExpectationLambda interface allows to define a callback that permits to verify if the state of the game has evolved as planned during the simulation:

Simulation.java
public static void main(String[] args) {
// Fact builders definition here ...

// The expectation is to have the badge "10-point-green" inside the badgeCollectionFact
CheckExpectationLambda doesContain10PointGreenBadge = () -> Assert.assertTrue(
"The '10-point-green' badge has been assigned",
badgeCollectionFact.getBadgeEarned().contains("10-point-green")
);

// The expectation is to have 70 points associated to the pointFact
CheckExpectationLambda has70Points = () -> Assert.assertEquals(
"Has 70 points",
70.0,
pointFact.getScore(),
0.0
);

// The expectation is to have the badge "50-point-green" inside the badgeCollectionFact
CheckExpectationLambda doesContain50PointGreenBadge = () -> Assert.assertTrue(
"The '50-point-green' badge has been assigned",
badgeCollectionFact.getBadgeEarned().contains("50-point-green")
);
}
tip

Each expectation can be associated to a message (i.e. "The '10-point-green' badge has been assigned") that will be displayed on the graph generated during the simulation.

Scenario Definition

Once the facts and the expectations are defined, the DSL4GaR allows to simulate a scenario through the SimulationBuilder interface:

Simulation.java
import game.rules.GreenBadgeRules;
import game.rules.GreenPointsRules;

public static void main(String[] args) {
// Fact builders definition here ...

// Expectations definition here ...

new SimulationBuilderImpl()
.addFacts(pointFact, gameFact, playerFact, badgeCollectionFact, inputDataFact)
.addRules(
GreenPointsRules.getGreenSustainableBonusRule(),
GreenBadgeRules.getGreenBadge10Rule(),
GreenBadgeRules.getGreenBadge50Rule()
)
.addExpectations(
has70Points,
doesContain10PointGreenBadge,
doesContain50PointGreenBadge
)
.simulateAndClose();
}
info

The addFacts, addRules and addExpectations methods can be called multiple times and in different orders during the same simulation; this allows to verify more complex and dynamic scenarios. Also partial simulations (where the graph is not generated) are allowed through to the simulate method:

Simulation.java
new SimulationBuilderImpl()
.addFacts(pointFact, gameFact, playerFact, badgeCollectionFact, inputDataFact)
.addRules(GreenPointsRules.getGreenSustainableBonusRule(), GreenBadgeRules.getGreenBadge10Rule())
.addExpectations(has70Points, doesContain10PointGreenBadge)
.simulate()
.addRules(GreenBadgeRules.getGreenBadge50Rule())
// All previous expectations are no longer valid
.addExpectations(doesContain50PointGreenBadge)
.simulateAndClose();
caution

Every time the simulate method is called all the expectations are cleared, thus you need to eventually add them again before calling the simulate or simulateAndClose methods.

Graph

The simulateAndClose method produces a filtrable graph where the game state transitions are shown:

graph_success

If during the simulation not all the expectations are successfully verified an error message reporting the assertion message and the related rules is displayed:

graph_success