From 9270bdad2e27d8dfa2d04b8f6c8748c51bfae72b Mon Sep 17 00:00:00 2001 From: mworzala Date: Mon, 5 Sep 2022 15:48:26 -0400 Subject: [PATCH] examples --- .../java/unnamed/mmo/server/dev/Main.java | 65 +++++++++--------- modules/entity/README.md | 66 +++++++++++++++++++ .../unnamed/mmo/entity/UnnamedEntity.java | 6 +- .../src/main/resources/data/behaviors.json | 32 +++++++++ .../src/main/resources/data/entities.json | 6 ++ .../src/main/resources/entity_reference.json5 | 0 6 files changed, 141 insertions(+), 34 deletions(-) create mode 100644 modules/entity/README.md create mode 100644 modules/entity/src/main/resources/data/behaviors.json create mode 100644 modules/entity/src/main/resources/data/entities.json create mode 100644 modules/entity/src/main/resources/entity_reference.json5 diff --git a/modules/development/src/main/java/unnamed/mmo/server/dev/Main.java b/modules/development/src/main/java/unnamed/mmo/server/dev/Main.java index f248bb10..19962488 100644 --- a/modules/development/src/main/java/unnamed/mmo/server/dev/Main.java +++ b/modules/development/src/main/java/unnamed/mmo/server/dev/Main.java @@ -26,6 +26,7 @@ import unnamed.mmo.command.BaseCommandRegister; import unnamed.mmo.damage.DamageProcessor; import unnamed.mmo.entity.UnnamedEntity; +import unnamed.mmo.entity.brain.task.SelectorTask; import unnamed.mmo.entity.brain.task.Task; import unnamed.mmo.item.Item; import unnamed.mmo.item.ItemManager; @@ -82,43 +83,43 @@ public static void main(String[] args) { //todo test entity -// JsonElement json = JsonParser.parseString(""" -// { -// "type": "unnamed:selector", -// "children": { -// "q.has_target": { -// "type": "unnamed:follow_target" -// }, -// "": { -// "type": "unnamed:sequence", -// "children": [ -// { -// "type": "unnamed:wander_in_region" -// }, -// { -// "type": "unnamed:idle", -// "time": 5 -// } -// ], -// -// "canInterrupt": true -// } -// } -// }"""); JsonElement json = JsonParser.parseString(""" { - "type": "unnamed:sequence", - "children": [ - { - "type": "unnamed:wander_in_region" + "type": "unnamed:selector", + "children": { + "q.has_target": { + "type": "unnamed:follow_target" }, - { - "type": "unnamed:idle", - "time": 20 + "": { + "type": "unnamed:sequence", + "children": [ + { + "type": "unnamed:wander_in_region" + }, + { + "type": "unnamed:idle", + "time": 5 + } + ], + + "canInterrupt": true } - ] + } }"""); - Task task = JsonOps.INSTANCE.withDecoder(Task.Spec.CODEC) +// JsonElement json = JsonParser.parseString(""" +// { +// "type": "unnamed:sequence", +// "children": [ +// { +// "type": "unnamed:wander_in_region" +// }, +// { +// "type": "unnamed:idle", +// "time": 20 +// } +// ] +// }"""); + Task task = JsonOps.INSTANCE.withDecoder(SelectorTask.Spec.CODEC) .apply(json).getOrThrow(false, System.err::println).getFirst().create(); UnnamedEntity entity = new UnnamedEntity(task); entity.setInstance(instance, new Pos(0, 40, 0)) diff --git a/modules/entity/README.md b/modules/entity/README.md new file mode 100644 index 00000000..6c0044d9 --- /dev/null +++ b/modules/entity/README.md @@ -0,0 +1,66 @@ +# Entities +Module for defining entities as well as their associated behavior. + +## Entity Definition +```json5 +{ + "namespace": "unnamed:test", + + // The model to use. For now this must be a vanilla entity type. + "model": "minecraft:pig", + // A reference to a behavior file + "behavior": "unnamed:test_behavior", + // (optional) The navigator to use for this entity. If not specified, the land navigator will be used. + "navigator": "minecraft:land", + + // (optional) The loot table to use when the entity dies + "loot_table": "unnamed:test_loot", + + // Stats + //todo need to be able to specify things like walk speed, jump height, etc. These are navigator parameters i suppose +} +``` + +## Behavior Definition +```json5 +{ + "namespace": "test_behavior", + + // Root behavior node + "type": "sequence", + "children": [/* ... */], + // (optional) If true, the task may be interrupted during execution by a parent sequence. Defaults to false. + "canInterrupt": false, +} +``` + +A behavior node is a JSON object with a type and some set of properties defined on the node itself. The basic primitives +are `sequence`s and `selector`s. They are documented below: + +```json5 +{ + // Sequence is a set of tasks to perform in order. If any task fails, the sequence fails. + "type": "unnamed:sequence", + // Each child is executed in order. If the sequence may be interrupted then any child task may be interrupted. + "children": [/* ... */], +} +``` + +```json5 +{ + // Selector is a set of tasks which will be performed based on their order and condition. + "type": "unnamed:selector", + // An array of stimuli definitions which will be active as long as this selector is active. This can be used for + // performance reasons (e.g. do not tick a stimuli source if you do not have to), but should not be used if there + // are two conflicting stimuli sources (e.g. do not have two targeting stimuli nested within each other). + "stimuli": [/* ... */], + // A set of mql expressions and tasks. Each expression is evaluated in order, executing the first task to completion. + // If the selected task may not be interrupted, it is executed to completion. If it may be interrupted, the + // conditions will be continuously evaluated, and the selected task will change if an earlier condition passes. + // An empty mql expression will always evaluate to true. + "children": { + "q.has_target": {/* ... */}, + "": {/* ... */}, + } +} +``` diff --git a/modules/entity/src/main/java/unnamed/mmo/entity/UnnamedEntity.java b/modules/entity/src/main/java/unnamed/mmo/entity/UnnamedEntity.java index 64a0c659..201d3b09 100644 --- a/modules/entity/src/main/java/unnamed/mmo/entity/UnnamedEntity.java +++ b/modules/entity/src/main/java/unnamed/mmo/entity/UnnamedEntity.java @@ -19,8 +19,10 @@ public class UnnamedEntity extends LivingEntity { private final Brain brain; public UnnamedEntity(Task task) { - super(EntityType.SLIME); - ((SlimeMeta) getEntityMeta()).setSize(2); + super(EntityType.ZOMBIE); + if (getEntityMeta() instanceof SlimeMeta slimeMeta) { + slimeMeta.setSize(1); + } brain = new SingleTaskBrain(this, task); } diff --git a/modules/entity/src/main/resources/data/behaviors.json b/modules/entity/src/main/resources/data/behaviors.json new file mode 100644 index 00000000..2f46c2f2 --- /dev/null +++ b/modules/entity/src/main/resources/data/behaviors.json @@ -0,0 +1,32 @@ +[ + { + "namespace": "hostile_generic", + "type": "unnamed:selector", + "stimuli": [ + { + "type": "unnamed:target_entity_in_range", + "entity_type": "player", + "range": 16, + "line_of_sight": true + } + ], + "children": { + "q.has_target": { + "type": "unnamed:follow_target" + }, + "": { + "type": "unnamed:sequence", + "children": [ + { + "type": "unnamed:idle_time", + "time": { "min": 20, "max": 60 } + }, + { + "type": "unnamed:wander_in_region" + } + ], + "can_interrupt": true + } + } + } +] \ No newline at end of file diff --git a/modules/entity/src/main/resources/data/entities.json b/modules/entity/src/main/resources/data/entities.json new file mode 100644 index 00000000..78c0de0e --- /dev/null +++ b/modules/entity/src/main/resources/data/entities.json @@ -0,0 +1,6 @@ +[ + { + "id": "unnamed:slime", + "behavior": "unnamed:slime_generic" + } +] \ No newline at end of file diff --git a/modules/entity/src/main/resources/entity_reference.json5 b/modules/entity/src/main/resources/entity_reference.json5 new file mode 100644 index 00000000..e69de29b