diff --git a/README.md b/README.md
index b107a1c..31c4d88 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,6 @@
[](https://github.com/sponsors/insality) [](https://ko-fi.com/insality) [](https://www.buymeacoffee.com/insality)
-# Disclaimer
-
-The library in development stage. May be not fully tested and README may be not full. If you have any questions, please, create an issue.
-
-
# Decore
**Decore** - a Defold library for managing ECS game entities and components in a data-driven way. The ECS is based on [tiny ECS](https://github.com/bakpakin/tiny-ecs) library.
@@ -26,7 +21,7 @@ The library in development stage. May be not fully tested and README may be not
Add in your `game.project` dependencies:
```
-https://github.com/Insality/decore/archive/refs/tags/2.zip
+https://github.com/Insality/decore/archive/refs/tags/3.zip
```
### Basic Usage
@@ -52,18 +47,24 @@ function update(self, dt)
self.world:update(dt)
end
-
function on_input(self, action_id, action)
+ -- Systems can be accessed via world, if registered
return self.world.input:on_input(action_id, action)
end
-
function final(self)
self.world:clearEntities()
self.world:clearSystems()
end
```
+## Examples
+Look at next examples to get more information about how to use the library:
+- [System examples](https://github.com/Insality/asset-store/tree/main/system/Insality) - System examples
+- [Entity example](https://github.com/Insality/cosmic-dash-jam-2025/blob/main/entity/player/player_entity.lua) - Entity example
+- [Shooting Circles](https://github.com/Insality/shooting_circles) - Game Example
+- [Cosmic Dash](https://github.com/Insality/cosmic-dash-jam-2025) - Game Example
+
## Quick API Reference
@@ -98,11 +99,14 @@ decore.create_component(component_id, [component_pack_id])
decore.apply_component(entity, component_id, [component_data])
decore.apply_components(entity, [components])
+-- Find entities
decore.find_entities(world, component_id, [component_value])
+-- Debug functions
decore.print_loaded_packs_debug_info()
decore.print_loaded_systems_debug_info(world)
+-- Logging
decore.set_logger([logger_instance])
decore.get_logger([name], [level])
```
@@ -115,6 +119,23 @@ This project is licensed under the MIT License - see the LICENSE file for detail
If you have any issues, questions or suggestions please [create an issue](https://github.com/Insality/decore/issues).
+## Changelog
+
+
+
+### **V1**
+ - Initial release
+
+### **V2**
+ - Reworked API and internal structure
+ - Updated documentation
+
+### **V3**
+ - Updated event bus system for better performance
+ - Update documentation
+
+
+
## ❤️ Support project ❤️
Your donation helps me stay engaged in creating valuable projects for **Defold**. If you appreciate what I'm doing, please consider supporting me!
diff --git a/USE_CASES.md b/USE_CASES.md
new file mode 100644
index 0000000..091addc
--- /dev/null
+++ b/USE_CASES.md
@@ -0,0 +1,35 @@
+# Use Cases
+
+This section illustrates practical examples of how to use the Decore module in your Defold game development projects.
+
+## Global world module
+
+Often for convenience, we can create a Lua module file which will be used as a global world module.
+
+```lua
+-- /game/world.lua
+
+--- Use this module to get the latest created world instance
+---@class world
+local M = {}
+local METATABLE = { __index = nil }
+
+---@param world world
+function M.set_world(world)
+ METATABLE.__index = world
+end
+
+return setmetatable(M, METATABLE)
+```
+
+```lua
+-- Game script
+local decore = require("decore.decore")
+local world = require("game.world")
+
+function init(self)
+ self.world = decore.new_world(...)
+ -- Set a world after creation to have access to it from any script later
+ world.set_world(self.world)
+end
+```
diff --git a/assets/atlases/game.atlas b/assets/atlases/game.atlas
deleted file mode 100644
index a9f3ed1..0000000
--- a/assets/atlases/game.atlas
+++ /dev/null
@@ -1,19 +0,0 @@
-images {
- image: "/assets/images/ui_circle_8.png"
-}
-images {
- image: "/assets/images/ui_circle_16.png"
-}
-images {
- image: "/assets/images/ui_circle_32.png"
-}
-images {
- image: "/assets/images/ui_circle_64.png"
-}
-images {
- image: "/assets/images/empty.png"
-}
-images {
- image: "/assets/images/pixel.png"
-}
-extrude_borders: 2
diff --git a/assets/fonts/text.font b/assets/fonts/text.font
deleted file mode 100644
index 31dd57f..0000000
--- a/assets/fonts/text.font
+++ /dev/null
@@ -1,10 +0,0 @@
-font: "/assets/fonts/troika.otf"
-material: "/builtins/fonts/font-df.material"
-size: 40
-outline_alpha: 1.0
-shadow_alpha: 1.0
-shadow_blur: 1
-shadow_y: -3.0
-output_format: TYPE_DISTANCE_FIELD
-render_mode: MODE_MULTI_LAYER
-characters: " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
diff --git a/assets/fonts/troika.otf b/assets/fonts/troika.otf
deleted file mode 100644
index 60c7c52..0000000
Binary files a/assets/fonts/troika.otf and /dev/null differ
diff --git a/assets/images/empty.png b/assets/images/empty.png
deleted file mode 100755
index 36b4ff1..0000000
Binary files a/assets/images/empty.png and /dev/null differ
diff --git a/assets/images/pixel.png b/assets/images/pixel.png
deleted file mode 100755
index a91437b..0000000
Binary files a/assets/images/pixel.png and /dev/null differ
diff --git a/assets/images/ui_circle_16.png b/assets/images/ui_circle_16.png
deleted file mode 100644
index 559c77c..0000000
Binary files a/assets/images/ui_circle_16.png and /dev/null differ
diff --git a/assets/images/ui_circle_32.png b/assets/images/ui_circle_32.png
deleted file mode 100644
index 82932ca..0000000
Binary files a/assets/images/ui_circle_32.png and /dev/null differ
diff --git a/assets/images/ui_circle_64.png b/assets/images/ui_circle_64.png
deleted file mode 100644
index c74547d..0000000
Binary files a/assets/images/ui_circle_64.png and /dev/null differ
diff --git a/assets/images/ui_circle_8.png b/assets/images/ui_circle_8.png
deleted file mode 100644
index 0d49e70..0000000
Binary files a/assets/images/ui_circle_8.png and /dev/null differ
diff --git a/core/atlas/core.atlas b/core/atlas/core.atlas
deleted file mode 100644
index 3d96bb0..0000000
--- a/core/atlas/core.atlas
+++ /dev/null
@@ -1,19 +0,0 @@
-images {
- image: "/core/images/empty.png"
-}
-images {
- image: "/core/images/pixel.png"
-}
-images {
- image: "/core/images/ui_circle_8.png"
-}
-images {
- image: "/core/images/ui_circle_16.png"
-}
-images {
- image: "/core/images/ui_circle_32.png"
-}
-images {
- image: "/core/images/ui_circle_64.png"
-}
-extrude_borders: 2
diff --git a/core/fonts/text.font b/core/fonts/text.font
deleted file mode 100644
index 178cf66..0000000
--- a/core/fonts/text.font
+++ /dev/null
@@ -1,10 +0,0 @@
-font: "/assets/fonts/troika.otf"
-material: "/builtins/fonts/font-df.material"
-size: 40
-outline_alpha: 1.0
-shadow_alpha: 1.0
-shadow_blur: 1
-shadow_y: -3.0
-output_format: TYPE_DISTANCE_FIELD
-render_mode: MODE_MULTI_LAYER
-characters: " !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\320\260\320\261\320\262\320\263\320\264\320\265\321\221\320\266\320\267\320\270\320\271\320\272\320\273\320\274\320\275\320\276\320\277\321\200\321\201\321\202\321\203\321\204\321\205\321\206\321\207\321\210\321\211\321\212\321\213\321\214\321\215\321\216\321\217\320\220\320\221\320\222\320\223\320\224\320\225\320\201\320\226\320\227\320\230\320\231\320\232\320\233\320\234\320\235\320\236\320\237\320\240\320\241\320\242\320\243\320\244\320\245\320\246\320\247\320\250\320\251\320\252\320\253\320\254\320\255\320\256\320\257\302\247\303\227"
diff --git a/core/fonts/troika.otf b/core/fonts/troika.otf
deleted file mode 100644
index 60c7c52..0000000
Binary files a/core/fonts/troika.otf and /dev/null differ
diff --git a/core/images/empty.png b/core/images/empty.png
deleted file mode 100755
index 36b4ff1..0000000
Binary files a/core/images/empty.png and /dev/null differ
diff --git a/core/images/pixel.png b/core/images/pixel.png
deleted file mode 100755
index a91437b..0000000
Binary files a/core/images/pixel.png and /dev/null differ
diff --git a/core/images/ui_circle_16.png b/core/images/ui_circle_16.png
deleted file mode 100644
index 559c77c..0000000
Binary files a/core/images/ui_circle_16.png and /dev/null differ
diff --git a/core/images/ui_circle_32.png b/core/images/ui_circle_32.png
deleted file mode 100644
index 82932ca..0000000
Binary files a/core/images/ui_circle_32.png and /dev/null differ
diff --git a/core/images/ui_circle_64.png b/core/images/ui_circle_64.png
deleted file mode 100644
index c74547d..0000000
Binary files a/core/images/ui_circle_64.png and /dev/null differ
diff --git a/core/images/ui_circle_8.png b/core/images/ui_circle_8.png
deleted file mode 100644
index 0d49e70..0000000
Binary files a/core/images/ui_circle_8.png and /dev/null differ
diff --git a/core/particles/confetti/fx_confetti.atlas b/core/particles/confetti/fx_confetti.atlas
deleted file mode 100644
index 9ca951d..0000000
--- a/core/particles/confetti/fx_confetti.atlas
+++ /dev/null
@@ -1,4 +0,0 @@
-images {
- image: "/core/particles/confetti/fx_confetti.png"
-}
-extrude_borders: 2
diff --git a/core/particles/confetti/fx_confetti.png b/core/particles/confetti/fx_confetti.png
deleted file mode 100644
index 3712edc..0000000
Binary files a/core/particles/confetti/fx_confetti.png and /dev/null differ
diff --git a/core/particles/confetti/fx_quest_complete.particlefx b/core/particles/confetti/fx_quest_complete.particlefx
deleted file mode 100644
index bf6e2cd..0000000
--- a/core/particles/confetti/fx_quest_complete.particlefx
+++ /dev/null
@@ -1,636 +0,0 @@
-emitters {
- mode: PLAY_MODE_ONCE
- duration: 0.2
- space: EMISSION_SPACE_WORLD
- position {
- x: -200.0
- }
- rotation {
- z: 0.25881904
- w: 0.9659258
- }
- tile_source: "/core/particles/confetti/fx_confetti.atlas"
- animation: "fx_confetti"
- material: "/builtins/materials/particlefx.material"
- max_particle_count: 128
- type: EMITTER_TYPE_CIRCLE
- start_delay: 0.2
- properties {
- key: EMITTER_KEY_SPAWN_RATE
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_X
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_Y
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_LIFE_TIME
- points {
- y: 2.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SPEED
- points {
- y: 900.0
- }
- spread: 200.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SIZE
- points {
- y: 40.0
- }
- spread: 20.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_RED
- points {
- y: 0.9
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_GREEN
- points {
- y: 0.8
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_BLUE
- points {
- y: 0.1
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ALPHA
- points {
- y: 1.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ROTATION
- points {
- y: 0.0
- }
- spread: 360.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_X
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_Y
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ANGULAR_VELOCITY
- points {
- y: 20.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_SCALE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_RED
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_GREEN
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_BLUE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ALPHA
- points {
- y: 0.0
- t_x: 0.07194582
- t_y: 0.99740857
- }
- points {
- x: 0.11320755
- y: 0.99277455
- t_x: 0.99418455
- t_y: 0.10768964
- }
- points {
- x: 0.7112546
- y: 0.555656
- t_x: 0.5694311
- t_y: -0.82203907
- }
- points {
- x: 1.0
- y: 0.0072254334
- t_x: 0.4737472
- t_y: -0.8806609
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ROTATION
- points {
- y: -0.10988372
- t_x: 0.0022114606
- t_y: 0.99999756
- }
- points {
- x: 1.0
- y: 266.89883
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ANGULAR_VELOCITY
- points {
- y: 1.0
- }
- }
- modifiers {
- type: MODIFIER_TYPE_DRAG
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: 1.5
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_ACCELERATION
- rotation {
- z: -0.25881904
- w: 0.9659258
- }
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: -400.0
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_VORTEX
- rotation {
- z: 0.25881904
- w: 0.9659258
- }
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: 100.0
- }
- }
- properties {
- key: MODIFIER_KEY_MAX_DISTANCE
- points {
- y: 400.0
- }
- }
- }
-}
-emitters {
- id: "emitter1"
- mode: PLAY_MODE_ONCE
- duration: 0.2
- space: EMISSION_SPACE_WORLD
- tile_source: "/core/particles/confetti/fx_confetti.atlas"
- animation: "fx_confetti"
- material: "/builtins/materials/particlefx.material"
- max_particle_count: 128
- type: EMITTER_TYPE_CIRCLE
- properties {
- key: EMITTER_KEY_SPAWN_RATE
- points {
- y: 40.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_X
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_Y
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_LIFE_TIME
- points {
- y: 2.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SPEED
- points {
- y: 900.0
- }
- spread: 200.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SIZE
- points {
- y: 40.0
- }
- spread: 20.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_RED
- points {
- y: 0.8
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_GREEN
- points {
- y: 0.15
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_BLUE
- points {
- y: 0.8
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ALPHA
- points {
- y: 1.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ROTATION
- points {
- y: 0.0
- }
- spread: 360.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_X
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_Y
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ANGULAR_VELOCITY
- points {
- y: 20.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_SCALE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_RED
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_GREEN
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_BLUE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ALPHA
- points {
- y: 0.0
- t_x: 0.07194582
- t_y: 0.99740857
- }
- points {
- x: 0.11320755
- y: 0.99277455
- t_x: 0.99418455
- t_y: 0.10768964
- }
- points {
- x: 0.7112546
- y: 0.555656
- t_x: 0.5694311
- t_y: -0.82203907
- }
- points {
- x: 1.0
- y: 0.0072254334
- t_x: 0.4737472
- t_y: -0.8806609
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ROTATION
- points {
- y: -0.10988372
- t_x: 0.0022114606
- t_y: 0.99999756
- }
- points {
- x: 1.0
- y: 266.89883
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ANGULAR_VELOCITY
- points {
- y: 1.0
- }
- }
- modifiers {
- type: MODIFIER_TYPE_ACCELERATION
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: -400.0
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_DRAG
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: 1.5
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_VORTEX
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: -200.0
- }
- }
- properties {
- key: MODIFIER_KEY_MAX_DISTANCE
- points {
- y: 400.0
- }
- }
- }
-}
-emitters {
- id: "emitter2"
- mode: PLAY_MODE_ONCE
- duration: 0.2
- space: EMISSION_SPACE_WORLD
- position {
- x: 200.0
- }
- rotation {
- z: -0.25881904
- w: 0.9659258
- }
- tile_source: "/core/particles/confetti/fx_confetti.atlas"
- animation: "fx_confetti"
- material: "/builtins/materials/particlefx.material"
- max_particle_count: 128
- type: EMITTER_TYPE_CIRCLE
- start_delay: 0.2
- properties {
- key: EMITTER_KEY_SPAWN_RATE
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_X
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_SIZE_Y
- points {
- y: 60.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_LIFE_TIME
- points {
- y: 2.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SPEED
- points {
- y: 900.0
- }
- spread: 200.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_SIZE
- points {
- y: 40.0
- }
- spread: 20.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_RED
- points {
- y: 0.2
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_GREEN
- points {
- y: 0.8
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_BLUE
- points {
- y: 0.9
- }
- spread: 0.1
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ALPHA
- points {
- y: 1.0
- }
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ROTATION
- points {
- y: 0.0
- }
- spread: 360.0
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_X
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_STRETCH_FACTOR_Y
- points {
- y: 0.0
- }
- spread: 0.2
- }
- properties {
- key: EMITTER_KEY_PARTICLE_ANGULAR_VELOCITY
- points {
- y: 20.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_SCALE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_RED
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_GREEN
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_BLUE
- points {
- y: 1.0
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ALPHA
- points {
- y: 0.0
- t_x: 0.07194582
- t_y: 0.99740857
- }
- points {
- x: 0.11320755
- y: 0.99277455
- t_x: 0.99418455
- t_y: 0.10768964
- }
- points {
- x: 0.7112546
- y: 0.555656
- t_x: 0.5694311
- t_y: -0.82203907
- }
- points {
- x: 1.0
- y: 0.0072254334
- t_x: 0.4737472
- t_y: -0.8806609
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ROTATION
- points {
- y: -0.10988372
- t_x: 0.0022114606
- t_y: 0.99999756
- }
- points {
- x: 1.0
- y: 266.89883
- }
- }
- particle_properties {
- key: PARTICLE_KEY_ANGULAR_VELOCITY
- points {
- y: 1.0
- }
- }
- modifiers {
- type: MODIFIER_TYPE_ACCELERATION
- rotation {
- z: 0.25881904
- w: 0.9659258
- }
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: -400.0
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_DRAG
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: 1.5
- }
- }
- }
- modifiers {
- type: MODIFIER_TYPE_VORTEX
- properties {
- key: MODIFIER_KEY_MAGNITUDE
- points {
- y: 100.0
- }
- }
- properties {
- key: MODIFIER_KEY_MAX_DISTANCE
- points {
- y: 400.0
- }
- }
- }
-}
diff --git a/core/utils/editor_only_label-df.material b/core/utils/editor_only_label-df.material
deleted file mode 100644
index 0105560..0000000
--- a/core/utils/editor_only_label-df.material
+++ /dev/null
@@ -1,7 +0,0 @@
-name: "label"
-vertex_program: "/builtins/fonts/font-df.vp"
-fragment_program: "/builtins/fonts/font-df.fp"
-vertex_constants {
- name: "view_proj"
- type: CONSTANT_TYPE_VIEWPROJ
-}
diff --git a/core/utils/editor_only_sprite.material b/core/utils/editor_only_sprite.material
deleted file mode 100644
index a980168..0000000
--- a/core/utils/editor_only_sprite.material
+++ /dev/null
@@ -1,25 +0,0 @@
-name: "sprite"
-tags: "editor"
-vertex_program: "/builtins/materials/sprite.vp"
-fragment_program: "/builtins/materials/sprite.fp"
-vertex_constants {
- name: "view_proj"
- type: CONSTANT_TYPE_VIEWPROJ
-}
-fragment_constants {
- name: "tint"
- type: CONSTANT_TYPE_USER
- value {
- x: 1.0
- y: 1.0
- z: 1.0
- w: 1.0
- }
-}
-samplers {
- name: "texture_sampler"
- wrap_u: WRAP_MODE_CLAMP_TO_EDGE
- wrap_v: WRAP_MODE_CLAMP_TO_EDGE
- filter_min: FILTER_MODE_MIN_DEFAULT
- filter_mag: FILTER_MODE_MAG_DEFAULT
-}
diff --git a/core/utils/play_particle.script b/core/utils/play_particle.script
deleted file mode 100644
index b7f8c58..0000000
--- a/core/utils/play_particle.script
+++ /dev/null
@@ -1,10 +0,0 @@
-go.property("particle", hash(""))
-go.property("lifetime", 5)
-
-function init(self)
- local particle_url = msg.url(nil, nil, self.particle)
- particlefx.play(particle_url)
- timer.delay(self.lifetime, false, function()
- go.delete()
- end)
-end
diff --git a/core/utils/set_sprite.script b/core/utils/set_sprite.script
deleted file mode 100644
index 1ae8c9c..0000000
--- a/core/utils/set_sprite.script
+++ /dev/null
@@ -1,14 +0,0 @@
-local EMPTY_HASH = hash("")
-go.property("image_id", hash(""))
-go.property("sprite_url", msg.url("#sprite"))
-go.property("scale", vmath.vector3(1, 1, 1))
-
-function init(self)
- if self.image_id and self.image_id ~= EMPTY_HASH then
- sprite.play_flipbook(self.sprite_url, self.image_id)
- end
-
- if self.scale.x ~= 1 or self.scale.y ~= 1 then
- go.set(self.sprite_url, "scale", self.scale)
- end
-end
diff --git a/decore/decore.lua b/decore/decore.lua
index 22ed8ff..2442897 100644
--- a/decore/decore.lua
+++ b/decore/decore.lua
@@ -8,7 +8,6 @@ local system_decore = require("decore.internal.system_decore")
local system_event_bus = require("decore.internal.system_event_bus")
local EMPTY_HASH = hash("")
-local TYPE_TABLE = "table"
local NEXT_ENTITY_ID = 0
---@class world
@@ -190,7 +189,7 @@ end
---Register components pack to decore components
----@param components_data decore.components_pack_data
+---@param components_data decore.components_data
---@return boolean
function M.register_components(components_data)
local pack_id = components_data.pack_id
@@ -255,7 +254,7 @@ function M.apply_component(entity, component_id, component_data)
end
if component_data ~= nil then
- if type(component_data) == TYPE_TABLE then
+ if type(component_data) == "table" then
decore_utils.merge_tables(entity[component_id], component_data)
else
entity[component_id] = component_data
diff --git a/decore/editor_scripts/decore.editor_script b/decore/editor_scripts/decore.editor_script
deleted file mode 100644
index 14a5524..0000000
--- a/decore/editor_scripts/decore.editor_script
+++ /dev/null
@@ -1,64 +0,0 @@
-local M = {}
-
-local function ends_with(str, ending)
- return ending == "" or str:sub(-#ending) == ending
-end
-
-
-function M.get_commands()
- return {
- {
- label = "[Decore] Set as Bootstrap Collection",
- locations = { "Assets" },
- query = { selection = { type = "resource", cardinality = "one" } },
- active = function(opts)
- return ends_with(editor.get(opts.selection, "path"), ".collection")
- end,
- run = function(opts)
- local file = opts.selection
- print("Run script for", editor.get(file, "path"))
- local collection_path = editor.get(file, "path")
-
- local project_path = editor.external_file_attributes(".").path
- local game_project_path = project_path .. editor.get("/game.project", "path")
-
- local lines = {}
-
- do -- Open game.project file for reading
- local game_project_file = io.open(game_project_path, "r")
- if not game_project_file then
- print("Error: Could not open game.project file")
- return
- end
-
- -- Read all lines and modify the main_collection line
- for line in game_project_file:lines() do
- if line:match("main_collection%s*=.*") then
- line = "main_collection = " .. collection_path .. "c"
- end
- table.insert(lines, line)
- end
- game_project_file:close()
- end
-
- do -- Write the modified content back to the file
- local game_project_file = io.open(game_project_path, "w")
- if not game_project_file then
- print("Error: Could not open game.project file for writing")
- return
- end
-
- for _, line in ipairs(lines) do
- game_project_file:write(line .. "\n")
- end
- game_project_file:close()
-
- print("Successfully updated main_collection to " .. collection_path .. "c")
- end
- end
- }
- }
-end
-
-
-return M
diff --git a/decore/internal/decore_annotations.lua b/decore/internal/decore_annotations.lua
deleted file mode 100644
index eb69e5f..0000000
--- a/decore/internal/decore_annotations.lua
+++ /dev/null
@@ -1,33 +0,0 @@
----@class action
----@field action_id hash|nil
-
---- JSON file scheme for entities data
----@class decore.entities_pack_data
----@field pack_id string
----@field entities table
-
---- JSON file scheme for components data
----@class decore.components_pack_data
----@field pack_id string
----@field components table
-
---- JSON file scheme for worlds data
----@class decore.worlds_pack_data
----@field pack_id string
----@field worlds table
-
----@class decore.world.instance_id
----@field world_id string|nil
----@field pack_id string|nil
-
----@class decore.entities_pack_data.instance
----@field prefab_id string|nil
----@field pack_id string|nil
----@field components table|nil
-
----@class decore.world.instance
----@field included_worlds decore.world.instance_id[]|nil
----@field entities decore.entities_pack_data.instance[]
-
-
-
diff --git a/decore/internal/decore_data.lua b/decore/internal/decore_data.lua
index 661cb17..62b7bd8 100644
--- a/decore/internal/decore_data.lua
+++ b/decore/internal/decore_data.lua
@@ -116,7 +116,7 @@ function M.get_entity(prefab_id, pack_id)
end
end
- decore_internal.logger:warn("Entity is not registered in Decore to spawn", {
+ logger:warn("Entity is not registered in Decore to spawn", {
prefab_id = prefab_id,
pack_id = pack_id,
})
diff --git a/decore/internal/decore_logger.lua b/decore/internal/decore_logger.lua
index 0b71bbd..3844a7b 100644
--- a/decore/internal/decore_logger.lua
+++ b/decore/internal/decore_logger.lua
@@ -38,10 +38,10 @@ end
---@param t table
---@param depth number?
---@param result string|nil Internal parameter
----@return string, boolean result String representation of table, Is max string length reached
+---@return string result String representation of table
function M.table_to_string(t, depth, result)
if type(t) ~= "table" then
- return tostring(t) or "", false
+ return tostring(t) or ""
end
depth = depth or 0
@@ -71,7 +71,7 @@ function M.table_to_string(t, depth, result)
end
end
- return result .. "}", false
+ return result .. "}"
end
diff --git a/decore/internal/decore_utils.lua b/decore/internal/decore_utils.lua
index d9e1d68..320f5c2 100644
--- a/decore/internal/decore_utils.lua
+++ b/decore/internal/decore_utils.lua
@@ -27,7 +27,7 @@ end
function M.deepcopy(value_to_copy)
local orig_type = type(value_to_copy)
local copy
- if orig_type == 'table' then
+ if orig_type == "table" then
copy = {}
for orig_key, orig_value in next, value_to_copy, nil do
copy[M.deepcopy(orig_key)] = M.deepcopy(orig_value)
diff --git a/decore/internal/event_bus.lua b/decore/internal/event_bus.lua
index 0c50832..d957824 100644
--- a/decore/internal/event_bus.lua
+++ b/decore/internal/event_bus.lua
@@ -1,7 +1,12 @@
+-- Special key for events without entity
+local NO_ENTITY_KEY = "system"
+
---@class decore.event_bus
----@field events table The list of events group by event name. Array part of entities map is the order of entities event's triggers
----@field stash table Events to be processed in PostWrap
----@field merge_callbacks table The merge policy for events. If the merge policy returns true, the events are merged and not will be added as new event
+---@field events table The list of events group by event name. Array part of entities map is the order of entities event's triggers
+---@field events_by_entity table> Maps event_name -> entity -> array of events for fast lookup
+---@field stash table Events to be processed in PostWrap
+---@field stash_by_entity table> Maps event_name -> entity -> array of events for stash (fast lookup)
+---@field merge_callbacks table):boolean> The merge policy for events. If the merge policy returns true, the events are merged and not will be added as new event
local M = {}
---Creates a new event bus.
@@ -9,7 +14,9 @@ local M = {}
function M.create()
local instance = {
events = {},
+ events_by_entity = {},
stash = {},
+ stash_by_entity = {},
merge_callbacks = {},
}
@@ -22,42 +29,54 @@ end
---@param data any The data to pass to the event and its associated callbacks.
function M:trigger(event_name, data)
self.stash[event_name] = self.stash[event_name] or {}
+ self.stash_by_entity[event_name] = self.stash_by_entity[event_name] or {}
local stash = self.stash[event_name]
+ local stash_by_entity = self.stash_by_entity[event_name]
local merge_callback = self.merge_callbacks[event_name]
- local is_merged = merge_callback and merge_callback(data, stash)
+ local entity = data and data.entity
+ local is_merged = false
+
+ if merge_callback then
+ is_merged = merge_callback(data, stash, stash_by_entity)
+ end
if not is_merged then
- table.insert(stash, data or true)
+ local event_data = data or true
+ table.insert(stash, event_data)
+ local entity_key = entity or NO_ENTITY_KEY
+ stash_by_entity[entity_key] = stash_by_entity[entity_key] or {}
+ table.insert(stash_by_entity[entity_key], event_data)
end
end
----Processes a specified event, executing the callback function with the provided context.
+---Processes a specified event, returning the list of events and optionally calling callback with the full list.
---@param event_name hash|string The name of the event to process.
----@param callback fun(...) The callback function to execute.
----@param context any|nil The context in which to execute the callback.
+---@param callback fun(events: any[])|fun(context: any, events: any[])|nil Optional callback function to execute with the full list of events.
+---@param context any|nil Optional context to pass as first argument to callback.
+---@return any[]|nil events The list of events, or nil if no events found.
function M:process(event_name, callback, context)
local events = self.events[event_name]
- if not events then
- return
+ if not events or #events == 0 then
+ return nil
end
- if context then
- for i = 1, #events do
- callback(context, events[i])
- end
- else
- for i = 1, #events do
- callback(events[i])
+ if callback then
+ if context then
+ callback(context, events)
+ else
+ callback(events)
end
end
+
+ return events
end
---You can set the merge policy for an event. This is useful when you want to merge events of the same type.
---@param event_name string The name of the event to set the merge policy for.
----@param merge_callback (fun(events: any[], new_event: any):boolean)|nil The callback function to merge the events. Return true if the events were merged, false otherwise.
+---@param merge_callback (fun(new_event: any, events: any[], entity_map: table):boolean)|nil The callback function to merge the events. Return true if the events were merged, false otherwise.
function M:set_merge_policy(event_name, merge_callback)
self.merge_callbacks[event_name] = merge_callback
end
@@ -65,12 +84,16 @@ end
function M:clear_events()
self.events = {}
+ self.events_by_entity = {}
end
function M:stash_to_events()
self.events = self.stash
self.stash = {}
+
+ self.events_by_entity = self.stash_by_entity
+ self.stash_by_entity = {}
end
diff --git a/decore/internal/system_decore.lua b/decore/internal/system_decore.lua
index 6e451c4..cb37d64 100644
--- a/decore/internal/system_decore.lua
+++ b/decore/internal/system_decore.lua
@@ -3,12 +3,21 @@ local decore_data = require("decore.internal.decore_data")
local ecs = require("decore.internal.ecs")
+---@class decore.entity_prefab_data
+---@field prefab_id string|nil
+---@field pack_id string|nil
+---@field components table|nil
+
+---@class decore.components_data
+---@field pack_id string
+---@field components table
+
---@class entity
---@field id number|nil Unique entity id, autofilled by decore.create_entity
---@field prefab_id string|nil The entity id from decore collections, autofilled by decore.create_entity
---@field pack_id string|nil The entity id from decore collections, autofilled by decore.create_entity
---@field parent_prefab_id string|nil The parent prefab_id, used for prefab inheritance
----@field child_instancies decore.entities_pack_data.instance[]|nil The child instances to spawn on entity creation
+---@field child_instancies decore.entity_prefab_data[]|nil The child instances to spawn on entity creation
---@field parent_id number|nil The parent id
---@field children_ids number[]|nil The children ids
diff --git a/examples/basic_camera_setup/basic_camera_setup.collection b/examples/basic_camera_setup/basic_camera_setup.collection
deleted file mode 100644
index ae74e46..0000000
--- a/examples/basic_camera_setup/basic_camera_setup.collection
+++ /dev/null
@@ -1,47 +0,0 @@
-name: "basic_camera_setup"
-instances {
- id: "player"
- prototype: "/examples/basic_camera_setup/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-instances {
- id: "debug"
- prototype: "/core/system/debug/debug.go"
-}
-instances {
- id: "entity_camera"
- prototype: "/core/system/camera/entity_camera.go"
- position {
- x: 480.0
- y: 320.0
- z: 10.0
- }
- component_properties {
- id: "entity"
- properties {
- id: "size_x"
- value: "960.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "640.0"
- type: PROPERTY_TYPE_NUMBER
- }
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "root"
- children: "debug"
- children: "entity_camera"
- children: "player"
- data: "components {\n"
- " id: \"basic_camera_setup\"\n"
- " component: \"/examples/basic_camera_setup/basic_camera_setup.script\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_camera_setup/basic_camera_setup.script b/examples/basic_camera_setup/basic_camera_setup.script
deleted file mode 100644
index 49ab038..0000000
--- a/examples/basic_camera_setup/basic_camera_setup.script
+++ /dev/null
@@ -1,31 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.world(
- require("system.transform.system_transform").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.game_object.system_game_object").create(),
- require("system.input.system_input").create_system(),
- require("system.movement_controller.system_movement_controller").create(),
-
- -- Debug
- require("system.on_key_released.system_on_key_released").create_system(),
- require("system.debug.system_debug").create_system(),
- require("system.camera.system_camera").create(),
- require("system.window_event.system_window_event").create_system()
- )
-
- decore.register_entity("player", require("examples.basic_camera_setup.entity.player"))
- decore.register_entity("debug", require("system.debug.entity_debug"))
- decore.register_entity("camera", require("system.camera.entity_camera"))
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/basic_camera_setup/entity/player.go b/examples/basic_camera_setup/entity/player.go
deleted file mode 100644
index 1dd0aae..0000000
--- a/examples/basic_camera_setup/entity/player.go
+++ /dev/null
@@ -1,53 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_KINEMATIC\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"player\"\n"
- "mask: \"level\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_SPHERE\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 1\n"
- " }\n"
- " data: 32.0\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_camera_setup/entity/player.lua b/examples/basic_camera_setup/entity/player.lua
deleted file mode 100644
index 81b433a..0000000
--- a/examples/basic_camera_setup/entity/player.lua
+++ /dev/null
@@ -1,10 +0,0 @@
-return {
- transform = {},
- game_object = {},
- transform_border = {
- border = vmath.vector4(0, 640, 960, 0),
- },
- movement_controller = {
- speed = 20
- }
-}
\ No newline at end of file
diff --git a/examples/basic_collision/basic_collision.collection b/examples/basic_collision/basic_collision.collection
deleted file mode 100644
index 6e2c5e2..0000000
--- a/examples/basic_collision/basic_collision.collection
+++ /dev/null
@@ -1,1110 +0,0 @@
-name: "basic_collision"
-instances {
- id: "player"
- prototype: "/examples/basic_collision/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-instances {
- id: "score_counter"
- prototype: "/examples/basic_collision/entity/score_counter.go"
-}
-instances {
- id: "coin21"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 438.0
- y: -70.0
- }
-}
-instances {
- id: "coin1"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -170.0
- }
-}
-instances {
- id: "coin26"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -122.0
- y: 30.0
- }
-}
-instances {
- id: "coin17"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 290.0
- y: 30.0
- }
-}
-instances {
- id: "coin2"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -70.0
- }
-}
-instances {
- id: "coin14"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 290.0
- y: -70.0
- }
-}
-instances {
- id: "coin23"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -122.0
- y: -170.0
- }
-}
-instances {
- id: "coin16"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -270.0
- y: -270.0
- }
-}
-instances {
- id: "coin10"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -270.0
- y: -170.0
- }
-}
-instances {
- id: "coin5"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -270.0
- }
-}
-instances {
- id: "coin4"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: 130.0
- }
-}
-instances {
- id: "coin27"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 438.0
- y: 130.0
- }
-}
-instances {
- id: "coin7"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -70.0
- }
-}
-instances {
- id: "coin9"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: 130.0
- }
-}
-instances {
- id: "coin12"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 290.0
- y: -270.0
- }
-}
-instances {
- id: "coin"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -270.0
- }
-}
-instances {
- id: "coin8"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: 30.0
- }
-}
-instances {
- id: "coin28"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 438.0
- y: -170.0
- }
-}
-instances {
- id: "coin11"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -270.0
- y: -70.0
- }
-}
-instances {
- id: "coin3"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: 30.0
- }
-}
-instances {
- id: "coin18"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -270.0
- y: 30.0
- }
-}
-instances {
- id: "coin20"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 438.0
- y: 30.0
- }
-}
-instances {
- id: "coin25"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -122.0
- y: -70.0
- }
-}
-instances {
- id: "coin15"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 290.0
- y: 130.0
- }
-}
-instances {
- id: "coin29"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -122.0
- y: 130.0
- }
-}
-instances {
- id: "coin22"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -122.0
- y: -270.0
- }
-}
-instances {
- id: "coin19"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 290.0
- y: -170.0
- }
-}
-instances {
- id: "coin6"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -170.0
- }
-}
-instances {
- id: "coin13"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -270.0
- y: 130.0
- }
-}
-instances {
- id: "coin24"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 438.0
- y: -270.0
- }
-}
-instances {
- id: "coin30"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 332.0
- y: -21.0
- }
-}
-instances {
- id: "coin31"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 332.0
- y: -121.0
- }
-}
-instances {
- id: "coin32"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 256.0
- y: -221.0
- }
-}
-instances {
- id: "coin33"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -304.0
- y: 179.0
- }
-}
-instances {
- id: "coin34"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 332.0
- y: 179.0
- }
-}
-instances {
- id: "coin35"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -228.0
- y: 79.0
- }
-}
-instances {
- id: "coin36"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -304.0
- y: -21.0
- }
-}
-instances {
- id: "coin37"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 256.0
- y: -121.0
- }
-}
-instances {
- id: "coin38"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -228.0
- y: -121.0
- }
-}
-instances {
- id: "coin39"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 404.0
- y: -221.0
- }
-}
-instances {
- id: "coin40"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 404.0
- y: 179.0
- }
-}
-instances {
- id: "coin41"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -156.0
- y: -121.0
- }
-}
-instances {
- id: "coin42"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -156.0
- y: -21.0
- }
-}
-instances {
- id: "coin43"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -156.0
- y: 79.0
- }
-}
-instances {
- id: "coin44"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 256.0
- y: 79.0
- }
-}
-instances {
- id: "coin45"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 256.0
- y: 179.0
- }
-}
-instances {
- id: "coin46"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 404.0
- y: -121.0
- }
-}
-instances {
- id: "coin47"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -304.0
- y: 79.0
- }
-}
-instances {
- id: "coin48"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 404.0
- y: -21.0
- }
-}
-instances {
- id: "coin49"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -304.0
- y: -221.0
- }
-}
-instances {
- id: "coin50"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 256.0
- y: -21.0
- }
-}
-instances {
- id: "coin51"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -228.0
- y: -21.0
- }
-}
-instances {
- id: "coin52"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 404.0
- y: 79.0
- }
-}
-instances {
- id: "coin53"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -228.0
- y: -221.0
- }
-}
-instances {
- id: "coin54"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -228.0
- y: 179.0
- }
-}
-instances {
- id: "coin55"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -156.0
- y: -221.0
- }
-}
-instances {
- id: "coin56"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -156.0
- y: 179.0
- }
-}
-instances {
- id: "coin57"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 332.0
- y: -221.0
- }
-}
-instances {
- id: "coin58"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -304.0
- y: -121.0
- }
-}
-instances {
- id: "coin59"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 332.0
- y: 79.0
- }
-}
-instances {
- id: "coin60"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 218.0
- y: -221.0
- }
-}
-instances {
- id: "coin61"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -342.0
- y: 179.0
- }
-}
-instances {
- id: "coin62"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 328.0
- y: -70.0
- }
-}
-instances {
- id: "coin63"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -266.0
- y: 179.0
- }
-}
-instances {
- id: "coin64"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 328.0
- y: -170.0
- }
-}
-instances {
- id: "coin65"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -21.0
- }
-}
-instances {
- id: "coin66"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -221.0
- }
-}
-instances {
- id: "coin67"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 294.0
- y: -21.0
- }
-}
-instances {
- id: "coin68"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -266.0
- y: -121.0
- }
-}
-instances {
- id: "coin69"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 252.0
- y: -270.0
- }
-}
-instances {
- id: "coin70"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -308.0
- y: 130.0
- }
-}
-instances {
- id: "coin71"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 218.0
- y: -21.0
- }
-}
-instances {
- id: "coin72"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 328.0
- y: 130.0
- }
-}
-instances {
- id: "coin73"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -342.0
- y: -121.0
- }
-}
-instances {
- id: "coin74"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -232.0
- y: 30.0
- }
-}
-instances {
- id: "coin75"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 294.0
- y: -121.0
- }
-}
-instances {
- id: "coin76"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -308.0
- y: -70.0
- }
-}
-instances {
- id: "coin77"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 252.0
- y: -170.0
- }
-}
-instances {
- id: "coin78"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -232.0
- y: -170.0
- }
-}
-instances {
- id: "coin79"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 400.0
- y: -270.0
- }
-}
-instances {
- id: "coin80"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 400.0
- y: 130.0
- }
-}
-instances {
- id: "coin81"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -21.0
- }
-}
-instances {
- id: "coin82"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: 79.0
- }
-}
-instances {
- id: "coin83"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -160.0
- y: -170.0
- }
-}
-instances {
- id: "coin84"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -266.0
- y: -221.0
- }
-}
-instances {
- id: "coin85"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -160.0
- y: -70.0
- }
-}
-instances {
- id: "coin86"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 294.0
- y: 179.0
- }
-}
-instances {
- id: "coin87"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 218.0
- y: -121.0
- }
-}
-instances {
- id: "coin88"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 294.0
- y: 79.0
- }
-}
-instances {
- id: "coin89"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: 179.0
- }
-}
-instances {
- id: "coin90"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -342.0
- y: -21.0
- }
-}
-instances {
- id: "coin91"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -160.0
- y: 30.0
- }
-}
-instances {
- id: "coin92"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 252.0
- y: 30.0
- }
-}
-instances {
- id: "coin93"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 252.0
- y: 130.0
- }
-}
-instances {
- id: "coin94"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 218.0
- y: 79.0
- }
-}
-instances {
- id: "coin95"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 400.0
- y: -170.0
- }
-}
-instances {
- id: "coin96"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -308.0
- y: 30.0
- }
-}
-instances {
- id: "coin97"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -121.0
- }
-}
-instances {
- id: "coin98"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 218.0
- y: 179.0
- }
-}
-instances {
- id: "coin99"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 400.0
- y: -70.0
- }
-}
-instances {
- id: "coin100"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -308.0
- y: -270.0
- }
-}
-instances {
- id: "coin101"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 252.0
- y: -70.0
- }
-}
-instances {
- id: "coin102"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: 179.0
- }
-}
-instances {
- id: "coin103"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -232.0
- y: -70.0
- }
-}
-instances {
- id: "coin104"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 400.0
- y: 30.0
- }
-}
-instances {
- id: "coin105"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -232.0
- y: -270.0
- }
-}
-instances {
- id: "coin106"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -232.0
- y: 130.0
- }
-}
-instances {
- id: "coin107"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -194.0
- y: -121.0
- }
-}
-instances {
- id: "coin108"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -266.0
- y: -21.0
- }
-}
-instances {
- id: "coin109"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: 79.0
- }
-}
-instances {
- id: "coin110"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -160.0
- y: -270.0
- }
-}
-instances {
- id: "coin111"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -160.0
- y: 130.0
- }
-}
-instances {
- id: "coin112"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 366.0
- y: -221.0
- }
-}
-instances {
- id: "coin113"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 328.0
- y: -270.0
- }
-}
-instances {
- id: "coin114"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -342.0
- y: -221.0
- }
-}
-instances {
- id: "coin115"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -342.0
- y: 79.0
- }
-}
-instances {
- id: "coin116"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -308.0
- y: -170.0
- }
-}
-instances {
- id: "coin117"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 328.0
- y: 30.0
- }
-}
-instances {
- id: "coin118"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 294.0
- y: -221.0
- }
-}
-instances {
- id: "coin119"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -266.0
- y: 79.0
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "system"
- data: "components {\n"
- " id: \"basic_collision\"\n"
- " component: \"/examples/basic_collision/basic_collision.script\"\n"
- "}\n"
- ""
-}
-embedded_instances {
- id: "coins"
- children: "coin"
- children: "coin1"
- children: "coin10"
- children: "coin100"
- children: "coin101"
- children: "coin102"
- children: "coin103"
- children: "coin104"
- children: "coin105"
- children: "coin106"
- children: "coin107"
- children: "coin108"
- children: "coin109"
- children: "coin11"
- children: "coin110"
- children: "coin111"
- children: "coin112"
- children: "coin113"
- children: "coin114"
- children: "coin115"
- children: "coin116"
- children: "coin117"
- children: "coin118"
- children: "coin119"
- children: "coin12"
- children: "coin13"
- children: "coin14"
- children: "coin15"
- children: "coin16"
- children: "coin17"
- children: "coin18"
- children: "coin19"
- children: "coin2"
- children: "coin20"
- children: "coin21"
- children: "coin22"
- children: "coin23"
- children: "coin24"
- children: "coin25"
- children: "coin26"
- children: "coin27"
- children: "coin28"
- children: "coin29"
- children: "coin3"
- children: "coin30"
- children: "coin31"
- children: "coin32"
- children: "coin33"
- children: "coin34"
- children: "coin35"
- children: "coin36"
- children: "coin37"
- children: "coin38"
- children: "coin39"
- children: "coin4"
- children: "coin40"
- children: "coin41"
- children: "coin42"
- children: "coin43"
- children: "coin44"
- children: "coin45"
- children: "coin46"
- children: "coin47"
- children: "coin48"
- children: "coin49"
- children: "coin5"
- children: "coin50"
- children: "coin51"
- children: "coin52"
- children: "coin53"
- children: "coin54"
- children: "coin55"
- children: "coin56"
- children: "coin57"
- children: "coin58"
- children: "coin59"
- children: "coin6"
- children: "coin60"
- children: "coin61"
- children: "coin62"
- children: "coin63"
- children: "coin64"
- children: "coin65"
- children: "coin66"
- children: "coin67"
- children: "coin68"
- children: "coin69"
- children: "coin7"
- children: "coin70"
- children: "coin71"
- children: "coin72"
- children: "coin73"
- children: "coin74"
- children: "coin75"
- children: "coin76"
- children: "coin77"
- children: "coin78"
- children: "coin79"
- children: "coin8"
- children: "coin80"
- children: "coin81"
- children: "coin82"
- children: "coin83"
- children: "coin84"
- children: "coin85"
- children: "coin86"
- children: "coin87"
- children: "coin88"
- children: "coin89"
- children: "coin9"
- children: "coin90"
- children: "coin91"
- children: "coin92"
- children: "coin93"
- children: "coin94"
- children: "coin95"
- children: "coin96"
- children: "coin97"
- children: "coin98"
- children: "coin99"
- data: ""
- position {
- x: 480.0
- y: 320.0
- }
-}
diff --git a/examples/basic_collision/basic_collision.script b/examples/basic_collision/basic_collision.script
deleted file mode 100644
index 55673ae..0000000
--- a/examples/basic_collision/basic_collision.script
+++ /dev/null
@@ -1,28 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.world(
- require("system.transform.system_transform").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.game_object.system_game_object").create(),
- require("system.input.system_input").create_system(),
- require("system.movement_controller.system_movement_controller").create(),
- require("system.collision.system_collision").create_system(),
-
- require("examples.basic_platformer_controller.system.system_score_counter").create_system()
- )
-
- decore.register_entity("player", require("examples.basic_collision.entity.player"))
- decore.register_entity("coin", require("examples.basic_collision.entity.entity_coin"))
- decore.register_entity("score_counter", require("examples.basic_collision.entity.score_counter"))
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/basic_collision/entity/coin.go b/examples/basic_collision/entity/coin.go
deleted file mode 100644
index 1629ba3..0000000
--- a/examples/basic_collision/entity/coin.go
+++ /dev/null
@@ -1,62 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "coin"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "32.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "32.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_32\"\n"
- "material: \"/panthera/materials/sprite.material\"\n"
- "attributes {\n"
- " name: \"color\"\n"
- " double_values {\n"
- " v: 1.0\n"
- " v: 1.0\n"
- " v: 0.502\n"
- " v: 1.0\n"
- " }\n"
- "}\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_TRIGGER\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"level\"\n"
- "mask: \"player\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_SPHERE\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 1\n"
- " }\n"
- " data: 16.0\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_collision/entity/entity_coin.lua b/examples/basic_collision/entity/entity_coin.lua
deleted file mode 100644
index 442cc57..0000000
--- a/examples/basic_collision/entity/entity_coin.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-return {
- transform = {},
- game_object = {
- factory_url = "/spawner#coin",
- is_factory = true
- },
- collision = {
- is_remove = true,
- send_event = "score_plus",
- },
-}
\ No newline at end of file
diff --git a/examples/basic_collision/entity/player.go b/examples/basic_collision/entity/player.go
deleted file mode 100644
index 1dd0aae..0000000
--- a/examples/basic_collision/entity/player.go
+++ /dev/null
@@ -1,53 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_KINEMATIC\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"player\"\n"
- "mask: \"level\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_SPHERE\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 1\n"
- " }\n"
- " data: 32.0\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_collision/entity/player.lua b/examples/basic_collision/entity/player.lua
deleted file mode 100644
index 5e553bb..0000000
--- a/examples/basic_collision/entity/player.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-return {
- transform = {},
- game_object = {},
- transform_border = {
- border = vmath.vector4(0, 640, 960, 0),
- },
- movement_controller = {
- speed = 20
- },
- collision = {}
-}
\ No newline at end of file
diff --git a/examples/basic_collision/entity/score_counter.go b/examples/basic_collision/entity/score_counter.go
deleted file mode 100644
index c5faf8e..0000000
--- a/examples/basic_collision/entity/score_counter.go
+++ /dev/null
@@ -1,13 +0,0 @@
-components {
- id: "score_counter"
- component: "/examples/basic_collision/entity/score_counter.gui"
-}
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "score_counter"
- type: PROPERTY_TYPE_HASH
- }
-}
diff --git a/examples/basic_collision/entity/score_counter.gui b/examples/basic_collision/entity/score_counter.gui
deleted file mode 100644
index d501c69..0000000
--- a/examples/basic_collision/entity/score_counter.gui
+++ /dev/null
@@ -1,24 +0,0 @@
-script: "/examples/basic_collision/entity/score_counter.gui_script"
-fonts {
- name: "text"
- font: "/assets/fonts/text.font"
-}
-nodes {
- position {
- x: 480.0
- y: 540.0
- }
- size {
- x: 200.0
- y: 100.0
- }
- type: TYPE_TEXT
- text: "Score: 0"
- font: "text"
- id: "text"
- inherit_alpha: true
-}
-material: "/builtins/materials/gui.material"
-adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 1
-max_dynamic_textures: 1
diff --git a/examples/basic_collision/entity/score_counter.gui_script b/examples/basic_collision/entity/score_counter.gui_script
deleted file mode 100644
index 1ed8e2a..0000000
--- a/examples/basic_collision/entity/score_counter.gui_script
+++ /dev/null
@@ -1,12 +0,0 @@
-function init(self)
- self.score = 0
- self.text = gui.get_node("text")
-end
-
-
-function on_message(self, message_id)
- if message_id == hash("score_plus") then
- self.score = self.score + 1
- gui.set_text(self.text, "Score: " .. self.score)
- end
-end
diff --git a/examples/basic_collision/entity/score_counter.lua b/examples/basic_collision/entity/score_counter.lua
deleted file mode 100644
index 8e7c3cc..0000000
--- a/examples/basic_collision/entity/score_counter.lua
+++ /dev/null
@@ -1,3 +0,0 @@
-return {
- score_counter = true,
-}
\ No newline at end of file
diff --git a/examples/basic_movement/basic_movement.collection b/examples/basic_movement/basic_movement.collection
deleted file mode 100644
index 8819562..0000000
--- a/examples/basic_movement/basic_movement.collection
+++ /dev/null
@@ -1,19 +0,0 @@
-name: "basic_movement"
-instances {
- id: "player"
- prototype: "/examples/basic_movement/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "root"
- children: "player"
- data: "components {\n"
- " id: \"basic_movement\"\n"
- " component: \"/examples/basic_movement/basic_movement.script\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_movement/basic_movement.script b/examples/basic_movement/basic_movement.script
deleted file mode 100644
index 40f4635..0000000
--- a/examples/basic_movement/basic_movement.script
+++ /dev/null
@@ -1,23 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.world(
- require("system.transform.system_transform").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.game_object.system_game_object").create(),
- require("system.input.system_input").create_system(),
- require("system.movement_controller.system_movement_controller").create()
- )
-
- decore.register_entity("player", require("examples.basic_movement.entity.player"))
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/basic_movement/entity/player.go b/examples/basic_movement/entity/player.go
deleted file mode 100644
index b537cd5..0000000
--- a/examples/basic_movement/entity/player.go
+++ /dev/null
@@ -1,30 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_movement/entity/player.lua b/examples/basic_movement/entity/player.lua
deleted file mode 100644
index 81b433a..0000000
--- a/examples/basic_movement/entity/player.lua
+++ /dev/null
@@ -1,10 +0,0 @@
-return {
- transform = {},
- game_object = {},
- transform_border = {
- border = vmath.vector4(0, 640, 960, 0),
- },
- movement_controller = {
- speed = 20
- }
-}
\ No newline at end of file
diff --git a/examples/basic_movement_with_walls/basic_movement_with_walls.collection b/examples/basic_movement_with_walls/basic_movement_with_walls.collection
deleted file mode 100644
index 192536b..0000000
--- a/examples/basic_movement_with_walls/basic_movement_with_walls.collection
+++ /dev/null
@@ -1,111 +0,0 @@
-name: "basic_movement_with_walls"
-instances {
- id: "player"
- prototype: "/examples/basic_movement_with_walls/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-instances {
- id: "wall"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 193.0
- y: 153.0
- }
-}
-instances {
- id: "wall1"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 499.0
- y: 153.0
- }
-}
-instances {
- id: "wall2"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 826.0
- y: 142.0
- }
-}
-instances {
- id: "wall3"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 116.0
- y: 271.0
- }
- rotation {
- z: -0.70710677
- w: 0.70710677
- }
-}
-instances {
- id: "entity_camera"
- prototype: "/system/camera/entity_camera.go"
- position {
- x: 480.0
- y: 320.0
- z: 10.0
- }
-}
-instances {
- id: "wall4"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 499.0
- y: 523.0
- }
-}
-instances {
- id: "wall5"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 797.0
- y: 509.0
- }
-}
-instances {
- id: "wall6"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 652.0
- y: 367.0
- }
-}
-instances {
- id: "wall7"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 573.0
- y: 448.0
- }
- rotation {
- z: -0.70710677
- w: 0.70710677
- }
-}
-instances {
- id: "wall8"
- prototype: "/examples/basic_movement_with_walls/entity/wall.go"
- position {
- x: 721.0
- y: 585.0
- }
- rotation {
- z: -0.70710677
- w: 0.70710677
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "root"
- data: "components {\n"
- " id: \"basic_movement_with_walls\"\n"
- " component: \"/examples/basic_movement_with_walls/basic_movement_with_walls.script\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_movement_with_walls/basic_movement_with_walls.script b/examples/basic_movement_with_walls/basic_movement_with_walls.script
deleted file mode 100644
index b3fca77..0000000
--- a/examples/basic_movement_with_walls/basic_movement_with_walls.script
+++ /dev/null
@@ -1,27 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.new_world(
- require("system.transform.system_transform").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.game_object.system_game_object").create(),
- require("system.input.input_system").create(),
- require("system.camera.system_camera").create(),
- require("system.movement_controller.system_movement_controller").create()
- )
-
- decore.register_entities("game", {
- ["player"] = require("examples.basic_movement_with_walls.entity.player"),
- ["camera"] = require("system.camera.camera_entity")
- })
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/basic_movement_with_walls/entity/player.go b/examples/basic_movement_with_walls/entity/player.go
deleted file mode 100644
index b537cd5..0000000
--- a/examples/basic_movement_with_walls/entity/player.go
+++ /dev/null
@@ -1,30 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_movement_with_walls/entity/player.lua b/examples/basic_movement_with_walls/entity/player.lua
deleted file mode 100644
index 44d0914..0000000
--- a/examples/basic_movement_with_walls/entity/player.lua
+++ /dev/null
@@ -1,8 +0,0 @@
----@diagnostic disable: missing-fields
----@type entity
-return {
- transform = {},
- game_object = {},
- transform_border = { border = vmath.vector4(0, 640, 960, 0) },
- movement_controller = { speed = 20 }
-}
diff --git a/examples/basic_movement_with_walls/entity/wall.go b/examples/basic_movement_with_walls/entity/wall.go
deleted file mode 100644
index ad64859..0000000
--- a/examples/basic_movement_with_walls/entity/wall.go
+++ /dev/null
@@ -1,41 +0,0 @@
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_STATIC\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"level\"\n"
- "mask: \"player\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_BOX\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 3\n"
- " }\n"
- " data: 100.0\n"
- " data: 25.0\n"
- " data: 10.0\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"pixel\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "size {\n"
- " x: 200.0\n"
- " y: 50.0\n"
- "}\n"
- "size_mode: SIZE_MODE_MANUAL\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/core/atlas/core.atlas\"\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_platformer_controller/basic_platformer_controller.collection b/examples/basic_platformer_controller/basic_platformer_controller.collection
deleted file mode 100644
index 111eb90..0000000
--- a/examples/basic_platformer_controller/basic_platformer_controller.collection
+++ /dev/null
@@ -1,343 +0,0 @@
-name: "basic_platformer_controller"
-instances {
- id: "player"
- prototype: "/examples/basic_platformer_controller/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-instances {
- id: "score_counter"
- prototype: "/examples/basic_platformer_controller/entity/score_counter.go"
-}
-instances {
- id: "coin16"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -270.0
- y: -270.0
- }
-}
-instances {
- id: "coin5"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 366.0
- y: -270.0
- }
-}
-instances {
- id: "coin12"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 290.0
- y: -270.0
- }
-}
-instances {
- id: "coin"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -194.0
- y: -270.0
- }
-}
-instances {
- id: "coin22"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -122.0
- y: -270.0
- }
-}
-instances {
- id: "coin24"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 438.0
- y: -270.0
- }
-}
-instances {
- id: "coin69"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 252.0
- y: -270.0
- }
-}
-instances {
- id: "coin79"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 400.0
- y: -270.0
- }
-}
-instances {
- id: "coin100"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -308.0
- y: -270.0
- }
-}
-instances {
- id: "coin105"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -232.0
- y: -270.0
- }
-}
-instances {
- id: "coin110"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: -160.0
- y: -270.0
- }
-}
-instances {
- id: "coin113"
- prototype: "/examples/basic_platformer_controller/entity/coin.go"
- position {
- x: 328.0
- y: -270.0
- }
-}
-instances {
- id: "entity_camera"
- prototype: "/core/system/camera/entity_camera.go"
- position {
- x: 480.0
- y: 320.0
- z: 10.0
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "system"
- data: "components {\n"
- " id: \"basic_platformer_controller\"\n"
- " component: \"/examples/basic_platformer_controller/basic_platformer_controller.script\"\n"
- "}\n"
- ""
-}
-embedded_instances {
- id: "coins"
- children: "coin"
- children: "coin100"
- children: "coin105"
- children: "coin110"
- children: "coin113"
- children: "coin12"
- children: "coin16"
- children: "coin22"
- children: "coin24"
- children: "coin5"
- children: "coin69"
- children: "coin79"
- data: ""
- position {
- x: 480.0
- y: 320.0
- }
-}
-embedded_instances {
- id: "floor"
- data: "embedded_components {\n"
- " id: \"collisionobject\"\n"
- " type: \"collisionobject\"\n"
- " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
- "mass: 0.0\\n"
- "friction: 0.1\\n"
- "restitution: 0.5\\n"
- "group: \\\"level\\\"\\n"
- "mask: \\\"player\\\"\\n"
- "embedded_collision_shape {\\n"
- " shapes {\\n"
- " shape_type: TYPE_BOX\\n"
- " position {\\n"
- " }\\n"
- " rotation {\\n"
- " }\\n"
- " index: 0\\n"
- " count: 3\\n"
- " }\\n"
- " data: 960.0\\n"
- " data: 10.0\\n"
- " data: 10.0\\n"
- "}\\n"
- "\"\n"
- "}\n"
- "embedded_components {\n"
- " id: \"sprite\"\n"
- " type: \"sprite\"\n"
- " data: \"default_animation: \\\"pixel\\\"\\n"
- "material: \\\"/builtins/materials/sprite.material\\\"\\n"
- "size {\\n"
- " x: 1920.0\\n"
- " y: 20.0\\n"
- "}\\n"
- "size_mode: SIZE_MODE_MANUAL\\n"
- "textures {\\n"
- " sampler: \\\"texture_sampler\\\"\\n"
- " texture: \\\"/core/atlas/core.atlas\\\"\\n"
- "}\\n"
- "\"\n"
- "}\n"
- ""
- position {
- x: 480.0
- y: 14.0
- }
-}
-embedded_instances {
- id: "floor1"
- data: "embedded_components {\n"
- " id: \"collisionobject\"\n"
- " type: \"collisionobject\"\n"
- " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
- "mass: 0.0\\n"
- "friction: 0.1\\n"
- "restitution: 0.5\\n"
- "group: \\\"level\\\"\\n"
- "mask: \\\"player\\\"\\n"
- "embedded_collision_shape {\\n"
- " shapes {\\n"
- " shape_type: TYPE_BOX\\n"
- " position {\\n"
- " }\\n"
- " rotation {\\n"
- " }\\n"
- " index: 0\\n"
- " count: 3\\n"
- " }\\n"
- " data: 960.0\\n"
- " data: 10.0\\n"
- " data: 10.0\\n"
- "}\\n"
- "\"\n"
- "}\n"
- "embedded_components {\n"
- " id: \"sprite\"\n"
- " type: \"sprite\"\n"
- " data: \"default_animation: \\\"pixel\\\"\\n"
- "material: \\\"/builtins/materials/sprite.material\\\"\\n"
- "size {\\n"
- " x: 1920.0\\n"
- " y: 16.0\\n"
- "}\\n"
- "size_mode: SIZE_MODE_MANUAL\\n"
- "textures {\\n"
- " sampler: \\\"texture_sampler\\\"\\n"
- " texture: \\\"/core/atlas/core.atlas\\\"\\n"
- "}\\n"
- "\"\n"
- "}\n"
- ""
- position {
- x: -553.0
- y: 287.0
- }
-}
-embedded_instances {
- id: "floor2"
- data: "embedded_components {\n"
- " id: \"collisionobject\"\n"
- " type: \"collisionobject\"\n"
- " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
- "mass: 0.0\\n"
- "friction: 0.1\\n"
- "restitution: 0.5\\n"
- "group: \\\"level\\\"\\n"
- "mask: \\\"player\\\"\\n"
- "embedded_collision_shape {\\n"
- " shapes {\\n"
- " shape_type: TYPE_BOX\\n"
- " position {\\n"
- " }\\n"
- " rotation {\\n"
- " }\\n"
- " index: 0\\n"
- " count: 3\\n"
- " }\\n"
- " data: 200.0\\n"
- " data: 50.0\\n"
- " data: 10.0\\n"
- "}\\n"
- "\"\n"
- "}\n"
- "embedded_components {\n"
- " id: \"sprite\"\n"
- " type: \"sprite\"\n"
- " data: \"default_animation: \\\"pixel\\\"\\n"
- "material: \\\"/builtins/materials/sprite.material\\\"\\n"
- "size {\\n"
- " x: 400.0\\n"
- " y: 100.0\\n"
- "}\\n"
- "size_mode: SIZE_MODE_MANUAL\\n"
- "textures {\\n"
- " sampler: \\\"texture_sampler\\\"\\n"
- " texture: \\\"/core/atlas/core.atlas\\\"\\n"
- "}\\n"
- "\"\n"
- "}\n"
- ""
- position {
- x: 809.0
- y: 169.0
- }
-}
-embedded_instances {
- id: "floor3"
- data: "embedded_components {\n"
- " id: \"collisionobject\"\n"
- " type: \"collisionobject\"\n"
- " data: \"type: COLLISION_OBJECT_TYPE_STATIC\\n"
- "mass: 0.0\\n"
- "friction: 0.1\\n"
- "restitution: 0.5\\n"
- "group: \\\"level\\\"\\n"
- "mask: \\\"player\\\"\\n"
- "embedded_collision_shape {\\n"
- " shapes {\\n"
- " shape_type: TYPE_BOX\\n"
- " position {\\n"
- " }\\n"
- " rotation {\\n"
- " }\\n"
- " index: 0\\n"
- " count: 3\\n"
- " }\\n"
- " data: 200.0\\n"
- " data: 50.0\\n"
- " data: 10.0\\n"
- "}\\n"
- "\"\n"
- "}\n"
- "embedded_components {\n"
- " id: \"sprite\"\n"
- " type: \"sprite\"\n"
- " data: \"default_animation: \\\"pixel\\\"\\n"
- "material: \\\"/builtins/materials/sprite.material\\\"\\n"
- "size {\\n"
- " x: 400.0\\n"
- " y: 100.0\\n"
- "}\\n"
- "size_mode: SIZE_MODE_MANUAL\\n"
- "textures {\\n"
- " sampler: \\\"texture_sampler\\\"\\n"
- " texture: \\\"/core/atlas/core.atlas\\\"\\n"
- "}\\n"
- "\"\n"
- "}\n"
- ""
- position {
- x: 894.0
- y: 311.0
- }
-}
diff --git a/examples/basic_platformer_controller/basic_platformer_controller.script b/examples/basic_platformer_controller/basic_platformer_controller.script
deleted file mode 100644
index 709055a..0000000
--- a/examples/basic_platformer_controller/basic_platformer_controller.script
+++ /dev/null
@@ -1,44 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.world(
- require("system.window_event.system_window_event").create_system(),
- require("system.camera.system_camera").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.input.system_input").create_system(),
- require("system.platformer_controller.system_platformer_controller").create_system(),
- require("system.platformer_physics.system_platformer_physics").create_system(),
- require("system.game_object.system_game_object").create(),
- require("system.collision.system_collision").create_system(),
-
- require("examples.basic_platformer_controller.system.system_on_remove_event").create_system(),
- require("examples.basic_platformer_controller.system.system_score_counter").create_system(),
-
- require("system.transform.system_transform").create()
- )
-
- decore.register_entity("player", require("examples.basic_platformer_controller.entity.player"))
- decore.register_entity("coin", require("examples.basic_platformer_controller.entity.coin"))
- decore.register_entity("score_counter", require("examples.basic_platformer_controller.entity.score_counter"))
- decore.register_entity("camera", require("system.camera.entity_camera"))
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function fixed_update(self, dt)
- self.world:fixed_update(dt)
-end
-
-
-function on_message(self, message_id, message, sender)
- decore.on_message(self.world, message_id, message, sender)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/basic_platformer_controller/entity/coin.go b/examples/basic_platformer_controller/entity/coin.go
deleted file mode 100644
index 1629ba3..0000000
--- a/examples/basic_platformer_controller/entity/coin.go
+++ /dev/null
@@ -1,62 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "coin"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "32.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "32.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_32\"\n"
- "material: \"/panthera/materials/sprite.material\"\n"
- "attributes {\n"
- " name: \"color\"\n"
- " double_values {\n"
- " v: 1.0\n"
- " v: 1.0\n"
- " v: 0.502\n"
- " v: 1.0\n"
- " }\n"
- "}\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_TRIGGER\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"level\"\n"
- "mask: \"player\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_SPHERE\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 1\n"
- " }\n"
- " data: 16.0\n"
- "}\n"
- ""
-}
diff --git a/examples/basic_platformer_controller/entity/coin.lua b/examples/basic_platformer_controller/entity/coin.lua
deleted file mode 100644
index e6cd61a..0000000
--- a/examples/basic_platformer_controller/entity/coin.lua
+++ /dev/null
@@ -1,9 +0,0 @@
---@type entity
-return {
- transform = {},
- game_object = {},
- collision = {
- is_remove = true,
- },
- on_remove_event = "score_plus"
-}
diff --git a/examples/basic_platformer_controller/entity/player.go b/examples/basic_platformer_controller/entity/player.go
deleted file mode 100644
index c9dcfd8..0000000
--- a/examples/basic_platformer_controller/entity/player.go
+++ /dev/null
@@ -1,60 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-components {
- id: "component_platformer_physics"
- component: "/core/system/platformer_physics/component_platformer_physics.script"
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "collisionobject"
- type: "collisionobject"
- data: "type: COLLISION_OBJECT_TYPE_KINEMATIC\n"
- "mass: 0.0\n"
- "friction: 0.1\n"
- "restitution: 0.5\n"
- "group: \"player\"\n"
- "mask: \"level\"\n"
- "embedded_collision_shape {\n"
- " shapes {\n"
- " shape_type: TYPE_BOX\n"
- " position {\n"
- " }\n"
- " rotation {\n"
- " }\n"
- " index: 0\n"
- " count: 3\n"
- " }\n"
- " data: 32.0\n"
- " data: 32.0\n"
- " data: 10.0\n"
- "}\n"
- "bullet: true\n"
- ""
-}
diff --git a/examples/basic_platformer_controller/entity/player.lua b/examples/basic_platformer_controller/entity/player.lua
deleted file mode 100644
index de99067..0000000
--- a/examples/basic_platformer_controller/entity/player.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-return {
- transform = {},
- game_object = {},
- platformer_controller = {},
- transform_border = {
- border = vmath.vector4(0, 640, 960, 0),
- },
- collision = {}
-}
\ No newline at end of file
diff --git a/examples/basic_platformer_controller/entity/score_counter.go b/examples/basic_platformer_controller/entity/score_counter.go
deleted file mode 100644
index 06c760c..0000000
--- a/examples/basic_platformer_controller/entity/score_counter.go
+++ /dev/null
@@ -1,13 +0,0 @@
-components {
- id: "score_counter"
- component: "/examples/basic_platformer_controller/entity/score_counter.gui"
-}
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "score_counter"
- type: PROPERTY_TYPE_HASH
- }
-}
diff --git a/examples/basic_platformer_controller/entity/score_counter.gui b/examples/basic_platformer_controller/entity/score_counter.gui
deleted file mode 100644
index cc3a1a6..0000000
--- a/examples/basic_platformer_controller/entity/score_counter.gui
+++ /dev/null
@@ -1,24 +0,0 @@
-script: "/examples/basic_platformer_controller/entity/score_counter.gui_script"
-fonts {
- name: "text"
- font: "/assets/fonts/text.font"
-}
-nodes {
- position {
- x: 480.0
- y: 540.0
- }
- size {
- x: 200.0
- y: 100.0
- }
- type: TYPE_TEXT
- text: "Score: 0"
- font: "text"
- id: "text"
- inherit_alpha: true
-}
-material: "/builtins/materials/gui.material"
-adjust_reference: ADJUST_REFERENCE_PARENT
-max_nodes: 1
-max_dynamic_textures: 1
diff --git a/examples/basic_platformer_controller/entity/score_counter.gui_script b/examples/basic_platformer_controller/entity/score_counter.gui_script
deleted file mode 100644
index 1ed8e2a..0000000
--- a/examples/basic_platformer_controller/entity/score_counter.gui_script
+++ /dev/null
@@ -1,12 +0,0 @@
-function init(self)
- self.score = 0
- self.text = gui.get_node("text")
-end
-
-
-function on_message(self, message_id)
- if message_id == hash("score_plus") then
- self.score = self.score + 1
- gui.set_text(self.text, "Score: " .. self.score)
- end
-end
diff --git a/examples/basic_platformer_controller/entity/score_counter.lua b/examples/basic_platformer_controller/entity/score_counter.lua
deleted file mode 100644
index 8e7c3cc..0000000
--- a/examples/basic_platformer_controller/entity/score_counter.lua
+++ /dev/null
@@ -1,3 +0,0 @@
-return {
- score_counter = true,
-}
\ No newline at end of file
diff --git a/examples/basic_platformer_controller/system/system_on_remove_event.lua b/examples/basic_platformer_controller/system/system_on_remove_event.lua
deleted file mode 100644
index 21999a2..0000000
--- a/examples/basic_platformer_controller/system/system_on_remove_event.lua
+++ /dev/null
@@ -1,26 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field on_remove_event string|nil
-
----@class entity.on_remove_event: entity
----@field on_remove_event string
-decore.register_component("on_remove_event", "")
-
----@class system.on_remove_event: system
----@field entities entity.on_remove_event[]
-local M = {}
-
-
----@return system.on_remove_event
-function M.create_system()
- return decore.system(M, "on_remove_event", "on_remove_event")
-end
-
-
-function M:onRemove(entity)
- self.world.event_bus:trigger(entity.on_remove_event, entity)
-end
-
-
-return M
diff --git a/examples/basic_platformer_controller/system/system_score_counter.lua b/examples/basic_platformer_controller/system/system_score_counter.lua
deleted file mode 100644
index 7f100d5..0000000
--- a/examples/basic_platformer_controller/system/system_score_counter.lua
+++ /dev/null
@@ -1,34 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field score_counter boolean|nil
-
----@class entity.score_counter: entity
----@field score_counter boolean
----@field game_object component.game_object
-decore.register_component("score_counter", false)
-
----@class system.score_counter: system
----@field entities entity.score_counter[]
-local M = {}
-
-
----@return system.score_counter
-function M.create_system()
- return decore.system(M, "score_counter", { "score_counter", "game_object" })
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("score_plus", self.process_score_plus, self)
-end
-
-
-function M:process_score_plus()
- for index = 1, #self.entities do
- msg.post(self.entities[index].game_object.root, "score_plus")
- end
-end
-
-
-return M
diff --git a/examples/boids/boid/boid.go b/examples/boids/boid/boid.go
deleted file mode 100644
index 69f4f9e..0000000
--- a/examples/boids/boid/boid.go
+++ /dev/null
@@ -1,24 +0,0 @@
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"boid\"\n"
- "material: \"/panthera/materials/sprite.material\"\n"
- "size {\n"
- " x: 129.0\n"
- " y: 196.0\n"
- "}\n"
- "size_mode: SIZE_MODE_MANUAL\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/examples/boids/boids.atlas\"\n"
- "}\n"
- ""
- rotation {
- z: -0.70710677
- w: 0.70710677
- }
- scale {
- x: 0.1
- y: 0.1
- }
-}
diff --git a/examples/boids/boid/boid.png b/examples/boids/boid/boid.png
deleted file mode 100644
index 86db9b6..0000000
Binary files a/examples/boids/boid/boid.png and /dev/null differ
diff --git a/examples/boids/boid/boid_panthera.lua b/examples/boids/boid/boid_panthera.lua
deleted file mode 100644
index 1d2130f..0000000
--- a/examples/boids/boid/boid_panthera.lua
+++ /dev/null
@@ -1,66 +0,0 @@
-return {
- type = "animation_editor",
- data = {
- metadata = {
- layers = {
- },
- fps = 60,
- settings = {
- font_size = 30,
- },
- gizmo_steps = {
- },
- gui_path = "/examples/boids/boid/boid.go",
- },
- animations = {
- {
- animation_id = "default",
- duration = 1,
- animation_keys = {
- {
- duration = 0.37,
- property_id = "size_x",
- end_value = 329,
- node_id = "#sprite",
- start_value = 129,
- key_type = "tween",
- easing = "outsine",
- },
- {
- duration = 0.37,
- property_id = "size_y",
- end_value = 499.876,
- node_id = "#sprite",
- start_value = 196,
- key_type = "tween",
- easing = "outsine",
- },
- {
- start_time = 0.37,
- duration = 0.63,
- property_id = "size_x",
- end_value = 129,
- node_id = "#sprite",
- start_value = 329,
- key_type = "tween",
- easing = "outsine",
- },
- {
- start_time = 0.37,
- duration = 0.63,
- property_id = "size_y",
- end_value = 196,
- node_id = "#sprite",
- start_value = 499.876,
- key_type = "tween",
- easing = "outsine",
- },
- },
- },
- },
- nodes = {
- },
- },
- format = "json",
- version = 1,
-}
\ No newline at end of file
diff --git a/examples/boids/boid/boid_sensor.gui b/examples/boids/boid/boid_sensor.gui
deleted file mode 100644
index e884c7d..0000000
--- a/examples/boids/boid/boid_sensor.gui
+++ /dev/null
@@ -1,36 +0,0 @@
-script: "/examples/boids/boid/boid_sensor.gui_script"
-textures {
- name: "druid"
- texture: "/druid/druid.atlas"
-}
-nodes {
- size {
- x: 100.0
- y: 100.0
- }
- type: TYPE_BOX
- id: "root"
- inherit_alpha: true
- size_mode: SIZE_MODE_AUTO
- visible: false
-}
-nodes {
- rotation {
- z: -135.0
- }
- size {
- x: 100.0
- y: 100.0
- }
- type: TYPE_PIE
- texture: "druid/pixel"
- id: "pie"
- parent: "root"
- inherit_alpha: true
- innerRadius: 48.0
- pieFillAngle: 270.0
-}
-material: "/druid/materials/gui_world/gui_world.material"
-adjust_reference: ADJUST_REFERENCE_DISABLED
-max_nodes: 2
-max_dynamic_textures: 1
diff --git a/examples/boids/boid/boid_sensor.gui_script b/examples/boids/boid/boid_sensor.gui_script
deleted file mode 100644
index 04c3c77..0000000
--- a/examples/boids/boid/boid_sensor.gui_script
+++ /dev/null
@@ -1,9 +0,0 @@
-local druid = require("druid.druid")
-local bindings = require("druid.bindings")
-local boid_sensor = require("examples.boids.boid.boid_sensor")
-
-function init(self)
- self.druid = druid.new(self)
- self.boid_sensor = self.druid:new_widget(boid_sensor)
- bindings.set_widget(self.boid_sensor)
-end
\ No newline at end of file
diff --git a/examples/boids/boid/boid_sensor.lua b/examples/boids/boid/boid_sensor.lua
deleted file mode 100644
index b588294..0000000
--- a/examples/boids/boid/boid_sensor.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local panthera = require("panthera.panthera")
-local animation = require("examples.boids.boid.boid_sensor_panthera")
-
----@class gui.boid_sensor: druid.widget
-local M = {}
-
-local HASH_POSITION_X = hash("position.x")
-local HASH_POSITION_Y = hash("position.y")
-local HASH_ROTATION = hash("euler.z")
-
-function M:init()
- self.root = self:get_node("root")
- self.animation = panthera.create_gui(animation, self:get_template(), self:get_nodes())
- panthera.play(self.animation, "default", {
- is_loop = true
- })
-end
-
-
-function M:set_position(x, y)
- gui.set(self.root, HASH_POSITION_X, x)
- gui.set(self.root, HASH_POSITION_Y, y)
-end
-
-
-function M:set_rotation(angle)
- gui.set(self.root, HASH_ROTATION, angle)
-end
-
-
-return M
\ No newline at end of file
diff --git a/examples/boids/boid/boid_sensor_panthera.lua b/examples/boids/boid/boid_sensor_panthera.lua
deleted file mode 100644
index 1ec0ac8..0000000
--- a/examples/boids/boid/boid_sensor_panthera.lua
+++ /dev/null
@@ -1,104 +0,0 @@
-return {
- type = "animation_editor",
- data = {
- metadata = {
- layers = {
- },
- fps = 60,
- settings = {
- font_size = 30,
- },
- gizmo_steps = {
- },
- gui_path = "/examples/boids/boid/boid_sensor.gui",
- },
- animations = {
- {
- animation_id = "default",
- duration = 1,
- animation_keys = {
- {
- duration = 0.5,
- property_id = "rotation_z",
- end_value = -90,
- node_id = "pie",
- start_value = -135,
- key_type = "tween",
- easing = "linear",
- },
- {
- duration = 0.5,
- property_id = "scale_x",
- end_value = 1.5,
- node_id = "pie",
- start_value = 1,
- key_type = "tween",
- easing = "outsine",
- },
- {
- duration = 0.5,
- property_id = "scale_y",
- end_value = 1.5,
- node_id = "pie",
- start_value = 1,
- key_type = "tween",
- easing = "outsine",
- },
- {
- duration = 0.5,
- property_id = "fill_angle",
- end_value = 180,
- node_id = "pie",
- start_value = 270,
- key_type = "tween",
- easing = "linear",
- },
- {
- start_time = 0.5,
- duration = 0.5,
- property_id = "rotation_z",
- end_value = -135,
- node_id = "pie",
- start_value = -90,
- key_type = "tween",
- easing = "linear",
- },
- {
- start_time = 0.5,
- duration = 0.5,
- property_id = "scale_x",
- end_value = 1,
- node_id = "pie",
- start_value = 1.5,
- key_type = "tween",
- easing = "outsine",
- },
- {
- start_time = 0.5,
- duration = 0.5,
- property_id = "scale_y",
- end_value = 1,
- node_id = "pie",
- start_value = 1.5,
- key_type = "tween",
- easing = "outsine",
- },
- {
- start_time = 0.5,
- duration = 0.5,
- property_id = "fill_angle",
- end_value = 270,
- node_id = "pie",
- start_value = 180,
- key_type = "tween",
- easing = "linear",
- },
- },
- },
- },
- nodes = {
- },
- },
- format = "json",
- version = 1,
-}
\ No newline at end of file
diff --git a/examples/boids/boid/entity_boid.lua b/examples/boids/boid/entity_boid.lua
deleted file mode 100644
index 8aa8886..0000000
--- a/examples/boids/boid/entity_boid.lua
+++ /dev/null
@@ -1,42 +0,0 @@
-local color = require("druid.color")
-
-local display_width = sys.get_config_int("display.width")
-local display_height = sys.get_config_int("display.height")
-
----@diagnostic disable: missing-fields
----@class entity.boid: entity
-return {
- quadtree = true,
- debug_draw_transform = false,
- boid = {
- neighbors = {},
- visual_range = 140,
- protected_range = 70,
- centering_factor = 0.6,
- avoid_factor = 0.3,
- matching_factor = 0.5,
- turn_factor = 360, -- When boid around edges it tries to turn around
- },
- color = {
- sprites = "#sprite",
- random_color = { color.hex2vector4("#A1D7F5"), color.hex2vector4("#1890D3") }
- },
- transform = {
- size_x = 10,
- size_y = 10,
- },
- transform_border = {
- border = vmath.vector4(-display_width / 2, display_width / 2, display_height / 2, -display_height / 2),
- is_wrap = false,
- is_limit = false,
- random_position = false
- },
- velocity = {
- min_speed = 150,
- max_speed = 250
- },
- game_object = {
- factory_url = "/spawner#boid",
- is_factory = true
- },
-}
diff --git a/examples/boids/boids.atlas b/examples/boids/boids.atlas
deleted file mode 100644
index 451c889..0000000
--- a/examples/boids/boids.atlas
+++ /dev/null
@@ -1,4 +0,0 @@
-images {
- image: "/examples/boids/boid/boid.png"
-}
-extrude_borders: 2
diff --git a/examples/boids/boids.collection b/examples/boids/boids.collection
deleted file mode 100644
index 8497854..0000000
--- a/examples/boids/boids.collection
+++ /dev/null
@@ -1,69 +0,0 @@
-name: "basic_platformer_controller"
-instances {
- id: "entity_camera"
- prototype: "/system/camera/entity_camera.go"
- position {
- z: 10.0
- }
-}
-instances {
- id: "coin"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 931.0
- y: 504.0
- }
-}
-instances {
- id: "coin1"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -938.0
- y: 504.0
- }
-}
-instances {
- id: "coin2"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: -938.0
- y: -514.0
- }
-}
-instances {
- id: "coin3"
- prototype: "/examples/basic_collision/entity/coin.go"
- position {
- x: 931.0
- y: -518.0
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "system"
- data: "components {\n"
- " id: \"boids\"\n"
- " component: \"/examples/boids/boids.script\"\n"
- "}\n"
- "components {\n"
- " id: \"gui\"\n"
- " component: \"/examples/boids/boids.gui\"\n"
- "}\n"
- ""
-}
-embedded_instances {
- id: "spawner"
- data: "embedded_components {\n"
- " id: \"boid\"\n"
- " type: \"factory\"\n"
- " data: \"prototype: \\\"/examples/boids/boid/boid.go\\\"\\n"
- "\"\n"
- "}\n"
- "embedded_components {\n"
- " id: \"coin\"\n"
- " type: \"factory\"\n"
- " data: \"prototype: \\\"/examples/basic_collision/entity/coin.go\\\"\\n"
- "\"\n"
- "}\n"
- ""
-}
diff --git a/examples/boids/boids.gui b/examples/boids/boids.gui
deleted file mode 100644
index 65fa210..0000000
--- a/examples/boids/boids.gui
+++ /dev/null
@@ -1,759 +0,0 @@
-script: "/examples/boids/boids.gui_script"
-nodes {
- position {
- x: 1610.0
- y: 75.0
- }
- type: TYPE_TEMPLATE
- id: "memory_panel"
- inherit_alpha: true
- template: "/druid/widget/memory_panel/memory_panel.gui"
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/root"
- parent: "memory_panel"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "memory_panel/mini_graph"
- parent: "memory_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/root"
- parent: "memory_panel/mini_graph"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/header"
- parent: "memory_panel/mini_graph/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "memory_panel/mini_graph/text_header"
- parent: "memory_panel/mini_graph/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/icon_drag"
- parent: "memory_panel/mini_graph/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/content"
- parent: "memory_panel/mini_graph/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/prefab_line"
- parent: "memory_panel/mini_graph/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/mini_graph/color_low"
- parent: "memory_panel/mini_graph/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/content"
- parent: "memory_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "memory_panel/text_max_value"
- parent: "memory_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "memory_panel/text_per_second"
- parent: "memory_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/line_second_1"
- parent: "memory_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "memory_panel/line_second_2"
- parent: "memory_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "memory_panel/text_memory"
- parent: "memory_panel/content"
- template_node_child: true
-}
-nodes {
- position {
- x: 1815.0
- y: 75.0
- }
- type: TYPE_TEMPLATE
- id: "fps_panel"
- inherit_alpha: true
- template: "/druid/widget/fps_panel/fps_panel.gui"
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/root"
- parent: "fps_panel"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "fps_panel/mini_graph"
- parent: "fps_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/root"
- parent: "fps_panel/mini_graph"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/header"
- parent: "fps_panel/mini_graph/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "fps_panel/mini_graph/text_header"
- parent: "fps_panel/mini_graph/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/icon_drag"
- parent: "fps_panel/mini_graph/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/content"
- parent: "fps_panel/mini_graph/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/prefab_line"
- parent: "fps_panel/mini_graph/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/mini_graph/color_low"
- parent: "fps_panel/mini_graph/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/content"
- parent: "fps_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "fps_panel/text_min_fps"
- parent: "fps_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "fps_panel/text_fps"
- parent: "fps_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/line_second_1"
- parent: "fps_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "fps_panel/line_second_2"
- parent: "fps_panel/content"
- template_node_child: true
-}
-nodes {
- position {
- x: 1707.0
- y: 950.0
- }
- type: TYPE_TEMPLATE
- id: "properties_panel"
- inherit_alpha: true
- template: "/druid/widget/properties_panel/properties_panel.gui"
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/root"
- parent: "properties_panel"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/header"
- parent: "properties_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/text_header"
- parent: "properties_panel/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/icon_drag"
- parent: "properties_panel/header"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/content"
- parent: "properties_panel/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/scroll_view"
- parent: "properties_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/scroll_content"
- parent: "properties_panel/scroll_view"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/propeties"
- parent: "properties_panel/content"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_slider"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/root"
- parent: "properties_panel/property_slider"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_slider/text_name"
- parent: "properties_panel/property_slider/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/E_Anchor"
- parent: "properties_panel/property_slider/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/slider"
- parent: "properties_panel/property_slider/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/slider_back"
- parent: "properties_panel/property_slider/slider"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/slider_pin"
- parent: "properties_panel/property_slider/slider"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/button"
- parent: "properties_panel/property_slider/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_slider/selected"
- parent: "properties_panel/property_slider/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_slider/text_value"
- parent: "properties_panel/property_slider/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_checkbox"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_checkbox/root"
- parent: "properties_panel/property_checkbox"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_checkbox/text_name"
- parent: "properties_panel/property_checkbox/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_checkbox/E_Anchor"
- parent: "properties_panel/property_checkbox/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_checkbox/button"
- parent: "properties_panel/property_checkbox/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_checkbox/icon"
- parent: "properties_panel/property_checkbox/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_checkbox/selected"
- parent: "properties_panel/property_checkbox/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_button"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_button/root"
- parent: "properties_panel/property_button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_button/text_name"
- parent: "properties_panel/property_button/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_button/E_Anchor"
- parent: "properties_panel/property_button/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_button/button"
- parent: "properties_panel/property_button/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_button/selected"
- parent: "properties_panel/property_button/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_button/text_button"
- parent: "properties_panel/property_button/button"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_input"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/root"
- parent: "properties_panel/property_input"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_input/text_name"
- parent: "properties_panel/property_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/E_Anchor"
- parent: "properties_panel/property_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_input/rich_input"
- parent: "properties_panel/property_input/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/rich_input/root"
- parent: "properties_panel/property_input/rich_input"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/rich_input/button"
- parent: "properties_panel/property_input/rich_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_input/rich_input/placeholder_text"
- parent: "properties_panel/property_input/rich_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_input/rich_input/input_text"
- parent: "properties_panel/property_input/rich_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/rich_input/cursor_node"
- parent: "properties_panel/property_input/rich_input/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_input/rich_input/cursor_text"
- parent: "properties_panel/property_input/rich_input/cursor_node"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_input/selected"
- parent: "properties_panel/property_input/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_text"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_text/root"
- parent: "properties_panel/property_text"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_text/text_name"
- parent: "properties_panel/property_text/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_text/text_right"
- parent: "properties_panel/property_text/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_left_right_selector"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/root"
- parent: "properties_panel/property_left_right_selector"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_left_right_selector/text_name"
- parent: "properties_panel/property_left_right_selector/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/E_Anchor"
- parent: "properties_panel/property_left_right_selector/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/button_left"
- parent: "properties_panel/property_left_right_selector/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/icon_left"
- parent: "properties_panel/property_left_right_selector/button_left"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/button_right"
- parent: "properties_panel/property_left_right_selector/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/icon_right"
- parent: "properties_panel/property_left_right_selector/button_right"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_left_right_selector/selected"
- parent: "properties_panel/property_left_right_selector/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_left_right_selector/text_value"
- parent: "properties_panel/property_left_right_selector/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_vector3"
- parent: "properties_panel/propeties"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/root"
- parent: "properties_panel/property_vector3"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/text_name"
- parent: "properties_panel/property_vector3/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/E_Anchor"
- parent: "properties_panel/property_vector3/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/field_x"
- parent: "properties_panel/property_vector3/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/text_x"
- parent: "properties_panel/property_vector3/field_x"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_vector3/rich_input_x"
- parent: "properties_panel/property_vector3/field_x"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_x/root"
- parent: "properties_panel/property_vector3/rich_input_x"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_x/button"
- parent: "properties_panel/property_vector3/rich_input_x/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_x/placeholder_text"
- parent: "properties_panel/property_vector3/rich_input_x/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_x/input_text"
- parent: "properties_panel/property_vector3/rich_input_x/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_x/cursor_node"
- parent: "properties_panel/property_vector3/rich_input_x/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_x/cursor_text"
- parent: "properties_panel/property_vector3/rich_input_x/cursor_node"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/selected_x"
- parent: "properties_panel/property_vector3/field_x"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/field_y"
- parent: "properties_panel/property_vector3/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/text_y"
- parent: "properties_panel/property_vector3/field_y"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_vector3/rich_input_y"
- parent: "properties_panel/property_vector3/field_y"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_y/root"
- parent: "properties_panel/property_vector3/rich_input_y"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_y/button"
- parent: "properties_panel/property_vector3/rich_input_y/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_y/placeholder_text"
- parent: "properties_panel/property_vector3/rich_input_y/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_y/input_text"
- parent: "properties_panel/property_vector3/rich_input_y/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_y/cursor_node"
- parent: "properties_panel/property_vector3/rich_input_y/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_y/cursor_text"
- parent: "properties_panel/property_vector3/rich_input_y/cursor_node"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/selected_y"
- parent: "properties_panel/property_vector3/field_y"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/field_z"
- parent: "properties_panel/property_vector3/E_Anchor"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/text_z"
- parent: "properties_panel/property_vector3/field_z"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEMPLATE
- id: "properties_panel/property_vector3/rich_input_z"
- parent: "properties_panel/property_vector3/field_z"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_z/root"
- parent: "properties_panel/property_vector3/rich_input_z"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_z/button"
- parent: "properties_panel/property_vector3/rich_input_z/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_z/placeholder_text"
- parent: "properties_panel/property_vector3/rich_input_z/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_z/input_text"
- parent: "properties_panel/property_vector3/rich_input_z/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/rich_input_z/cursor_node"
- parent: "properties_panel/property_vector3/rich_input_z/root"
- template_node_child: true
-}
-nodes {
- type: TYPE_TEXT
- id: "properties_panel/property_vector3/rich_input_z/cursor_text"
- parent: "properties_panel/property_vector3/rich_input_z/cursor_node"
- template_node_child: true
-}
-nodes {
- type: TYPE_BOX
- id: "properties_panel/property_vector3/selected_z"
- parent: "properties_panel/property_vector3/field_z"
- template_node_child: true
-}
-material: "/builtins/materials/gui.material"
-adjust_reference: ADJUST_REFERENCE_PARENT
diff --git a/examples/boids/boids.gui_script b/examples/boids/boids.gui_script
deleted file mode 100644
index 01fefae..0000000
--- a/examples/boids/boids.gui_script
+++ /dev/null
@@ -1,101 +0,0 @@
-local decore = require("decore.decore")
-
-local properties_panel = require("druid.widget.properties_panel.properties_panel")
-local memory_panel = require("druid.widget.memory_panel.memory_panel")
-local fps_panel = require("druid.widget.fps_panel.fps_panel")
-local druid = require("druid.druid")
-
-local boid = require("examples.boids.boid.entity_boid")
-
-function init(self)
- self.druid = druid.new(self)
- self.druid:new_widget(memory_panel, "memory_panel")
- self.druid:new_widget(fps_panel, "fps_panel")
- self.properties_panel = self.druid:new_widget(properties_panel, "properties_panel")
-
- local b = boid.boid
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Visual Range")
- slider:set_value(b.visual_range, true)
- slider:set_number_type(10, 5000, 10)
- slider.on_change_value:subscribe(function(value)
- decore.last_world.command_boid:set_visual_range(value)
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Protected Range")
- slider:set_value(b.protected_range, true)
- slider:set_number_type(10, 500, 10)
- slider.on_change_value:subscribe(function(value)
- decore.last_world.command_boid:set_protected_range(value)
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Centering Factor")
- slider:set_value(b.centering_factor, true)
- slider:set_number_type(0, 1, 0.1)
- slider.on_change_value:subscribe(function(value)
- decore.last_world.command_boid:set_centering_factor(value)
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Avoid Factor")
- slider:set_value(b.avoid_factor, true)
- slider:set_number_type(0, 1, 0.1)
- slider.on_change_value:subscribe(function(value)
- decore.last_world.command_boid:set_avoid_factor(value)
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Matching Factor")
- slider:set_value(b.matching_factor, true)
- slider:set_number_type(0, 1, 0.1)
- slider.on_change_value:subscribe(function(value)
- decore.last_world.command_boid:set_matching_factor(value)
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Min Speed")
- slider:set_value(boid.velocity.min_speed, true)
- slider:set_number_type(0, 500, 10)
- slider.on_change_value:subscribe(function(value)
- local entities = decore.last_world.command_velocity.velocity.entities
- for i = 1, #entities do
- decore.last_world.command_velocity:set_min_speed(entities[i], value)
- end
- end)
- end)
-
- self.properties_panel:add_slider(function(slider)
- slider.text_name:set_text("Max Speed")
- slider:set_value(boid.velocity.max_speed, true)
- slider:set_number_type(0, 500, 10)
- slider.on_change_value:subscribe(function(value)
- local entities = decore.last_world.command_velocity.velocity.entities
- for i = 1, #entities do
- decore.last_world.command_velocity:set_max_speed(entities[i], value)
- end
- end)
- end)
-end
-
-function final(self)
- self.druid:final()
-end
-
-function update(self, dt)
- self.druid:update(dt)
-end
-
-function on_message(self, message_id, message, sender)
- self.druid:on_message(message_id, message, sender)
-end
-
-function on_input(self, action_id, action)
- return self.druid:on_input(action_id, action)
-end
diff --git a/examples/boids/boids.script b/examples/boids/boids.script
deleted file mode 100644
index 48d2f2f..0000000
--- a/examples/boids/boids.script
+++ /dev/null
@@ -1,63 +0,0 @@
-local log = require("log.log")
-local event = require("event.event")
-local decore = require("decore.decore")
-
-function init(self)
- event.set_logger(log.get_logger("event"))
- decore.set_logger(log.get_logger("boids"))
-
- self.world = decore.world(
- require("system.window_event.system_window_event").create_system(),
- require("system.camera_debug_control.camera_debug_control").create_system(),
- require("system.input.system_input").create_system(),
-
- require("system.transform.system_transform").create(),
- require("system.game_object.system_game_object").create(),
- require("system.follow_cursor.system_follow_cursor").create_system(),
-
- require("system.camera.system_camera").create(),
- require("system.panthera.system_panthera").create_system(),
- require("system.transform_border.system_transform_border").create(),
- require("system.collision.system_collision").create_system(),
- require("system.quadtree.system_quadtree").create_system(),
- require("system.velocity.system_velocity").create_system(),
- require("system.color.system_color").create_system(),
-
- require("examples.boids.system_boid.system_boid").create_system(),
-
- require("system.debug_draw_transform.system_debug_draw_transform").create_system(),
-
- require("system.debug_draw.system_debug_draw").create_system()
- )
-
- decore.register_entity("boid", require("examples.boids.boid.entity_boid"))
- decore.register_entity("coin", require("examples.basic_collision.entity.entity_coin"))
-
- --for index = 1, 4000 do
- --for index = 1, 16000 do
- for index = 1, 200 do
- local boid = decore.create_prefab("boid")
- boid.transform_border.random_position = true
- self.world:addEntity(boid)
- end
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function fixed_update(self, dt)
- self.world:fixed_update(dt)
-end
-
-
-function on_message(self, message_id, message, sender)
- decore.on_message(self.world, message_id, message, sender)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/boids/system_boid/command_boid.lua b/examples/boids/system_boid/command_boid.lua
deleted file mode 100644
index 52f76a9..0000000
--- a/examples/boids/system_boid/command_boid.lua
+++ /dev/null
@@ -1,49 +0,0 @@
----@class world
----@field command_boid system.boid.command
-
----@class system.boid.command
----@field boid system.boid
-local M = {}
-
-
----@return system.boid.command
-function M.create(boid)
- return setmetatable({ boid = boid }, { __index = M })
-end
-
-function M:set_visual_range(value)
- for index = 1, #self.boid.entities do
- local entity = self.boid.entities[index]
- entity.boid.visual_range = value
- end
-end
-
-function M:set_protected_range(value)
- for index = 1, #self.boid.entities do
- local entity = self.boid.entities[index]
- entity.boid.protected_range = value
- end
-end
-
-function M:set_centering_factor(value)
- for index = 1, #self.boid.entities do
- local entity = self.boid.entities[index]
- entity.boid.centering_factor = value
- end
-end
-
-function M:set_avoid_factor(value)
- for index = 1, #self.boid.entities do
- local entity = self.boid.entities[index]
- entity.boid.avoid_factor = value
- end
-end
-
-function M:set_matching_factor(value)
- for index = 1, #self.boid.entities do
- local entity = self.boid.entities[index]
- entity.boid.matching_factor = value
- end
-end
-
-return M
diff --git a/examples/boids/system_boid/ext.manifest b/examples/boids/system_boid/ext.manifest
deleted file mode 100644
index 45b827b..0000000
--- a/examples/boids/system_boid/ext.manifest
+++ /dev/null
@@ -1 +0,0 @@
-name: "c_system_boid"
\ No newline at end of file
diff --git a/examples/boids/system_boid/src/c_system_boid.cpp b/examples/boids/system_boid/src/c_system_boid.cpp
deleted file mode 100644
index 1f41a3f..0000000
--- a/examples/boids/system_boid/src/c_system_boid.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include
-#include
-#include
-
-// List of entity references in Lua registry
-static std::vector entities;
-
-
-// Add entity to system
-static int add_entity(lua_State* L) {
- // Stack: { entity }
- DM_LUA_STACK_CHECK(L, 0);
-
- luaL_checktype(L, 1, LUA_TTABLE);
-
- // Create a reference to the entity and store it
- lua_pushvalue(L, 1);
- int ref = luaL_ref(L, LUA_REGISTRYINDEX);
- entities.push_back(ref);
-
- return 0;
-};
-
-
-// Remove entity from system
-static int remove_entity(lua_State* L) {
- // Stack: { entity }
- DM_LUA_STACK_CHECK(L, 0);
-
- luaL_checktype(L, 1, LUA_TTABLE);
-
- // Find and remove the entity reference
- bool found = false;
- for (auto it = entities.begin(); it != entities.end(); ++it) {
- lua_rawgeti(L, LUA_REGISTRYINDEX, *it);
- if (lua_rawequal(L, -1, 1)) {
- luaL_unref(L, LUA_REGISTRYINDEX, *it);
- entities.erase(it);
- found = true;
- lua_pop(L, 1);
- break;
- }
- lua_pop(L, 1);
- }
- if (!found) {
- dmLogWarning("Entity not found in system.");
- }
-
- return 0;
-};
-
-
-// Update entities
-static int update(lua_State* L) {
- // Stack: { dt }
- DM_LUA_STACK_CHECK(L, 0);
-
- // Increase velocity by 1:1 for each entity
- // velocity placed in entity.velocity.x and entity.velocity.y
- for (auto it = entities.begin(); it != entities.end(); ++it) {
- lua_rawgeti(L, LUA_REGISTRYINDEX, *it); // Push entity
- lua_getfield(L, -1, "velocity"); // Push velocity
-
- // Update velocity.x
- lua_getfield(L, -1, "x"); // Push velocity.x
- lua_pushnumber(L, lua_tonumber(L, -1) + 1); // Push x + 1
- lua_setfield(L, -3, "x"); // Set velocity.x
- lua_pop(L, 1); // Pop old x
-
- // Update velocity.y
- lua_getfield(L, -1, "y"); // Push velocity.y
- lua_pushnumber(L, lua_tonumber(L, -1) + 1); // Push y + 1
- lua_setfield(L, -3, "y"); // Set velocity.y
- lua_pop(L, 1); // Pop old y
-
- lua_pop(L, 2); // Pop velocity and entity
- }
-
- return 0;
-}
-
-
-// Functions exposed to Lua
-static const luaL_Reg Module_methods[] = {
- {"add_entity", add_entity},
- {"remove_entity", remove_entity},
- {"update", update},
- {0, 0}
-};
-
-
-static dmExtension::Result Initialize(dmExtension::Params* params) {
- lua_State* L = params->m_L;
- int top = lua_gettop(L);
-
- luaL_register(L, "c_system_boid", Module_methods);
- lua_pop(L, 1);
-
- assert(top == lua_gettop(L));
- return dmExtension::RESULT_OK;
-}
-
-DM_DECLARE_EXTENSION(c_system_boid, "c_system_boid", 0, 0, Initialize, 0, 0, 0)
diff --git a/examples/boids/system_boid/system_boid.lua b/examples/boids/system_boid/system_boid.lua
deleted file mode 100644
index 52b51cd..0000000
--- a/examples/boids/system_boid/system_boid.lua
+++ /dev/null
@@ -1,201 +0,0 @@
-local decore = require("decore.decore")
-local command_boid = require("examples.boids.system_boid.command_boid")
-
----@class entity
----@field boid component.boid|nil
-
----@class entity.boid: entity
----@field boid component.boid
----@field transform component.transform
----@field transform_border component.transform_border|nil
----@field velocity component.velocity
-
----@class component.boid.neighbor
----@field dx number
----@field dy number
----@field dist_sq number
----@field entity entity.boid
-
----@class component.boid
----@field widget gui.boid_sensor
----@field speed number
----@field separation_radius number
----@field alignment_radius number
----@field cohesion_radius number
----@field max_force number
----@field neighbors component.boid.neighbor[]
----@field separation_weight number
----@field alignment_weight number
----@field cohesion_weight number
----@field turn_factor number -- new
----@field visual_range number
----@field protected_range number
----@field centering_factor number
----@field avoid_factor number The force to avoid other boids
----@field matching_factor number
----@field max_bias number
----@field bias_increment number
----@field bias_val number
-decore.register_component("boid", {
- neighbors = {},
- turn_factor = 180,
- visual_range = 40,
- protected_range = 8,
- centering_factor = 0.0005,
- avoid_factor = 0.05,
- matching_factor = 0.05,
-})
-
----@class system.boid: system
----@field entities entity.boid[]
----@field debug_draw_force boolean
-local M = {}
-
-
-local COLOR_FORCE = vmath.vector4(1, 0, 0, 1)
-
-function M.create_system()
- return decore.system(M, "boid", { "boid", "transform", "velocity" })
-end
-
-
-function M:onAddToWorld()
- self.debug_draw_force = false
- self.world.command_boid = command_boid.create(self)
-end
-
-
-function M:onAdd(entity)
- --c_system_boid.add_entity(entity)
- --local widget = bindings.get_widget(entity.game_object.root)
- --entity.boid.widget = widget
-end
-
-function M:onRemove(entity)
- --c_system_boid.remove_entity(entity)
-end
-
-
-function M:update(dt)
- --c_system_boid.update(dt)
-
- --local divider = 60
- --local entities_per_frame = math.ceil(#self.entities / 60 * divider)
- --self.current_index = self.current_index or 1
- --local entities_from = self.current_index
- --local entities_to = math.min(self.current_index + entities_per_frame - 1, #self.entities)
- --self.current_index = entities_to + 1
- --if self.current_index > #self.entities then
- -- self.current_index = 1
- --end
-
- for index = 1, #self.entities do
- local entity = self.entities[index]
- self:process(entity, dt)
-
- --entity.boid.widget:set_position(entity.transform.position_x, entity.transform.position_y)
- --entity.boid.widget:set_rotation(entity.transform.rotation)
- end
-end
-
-
-function M:process(entity, dt)
- local force_x, force_y = self:calculate_forces_new(entity)
- self.world.command_velocity:add_velocity(entity, force_x * dt, force_y * dt)
-
- if self.debug_draw_force and self.world.command_debug_draw then
- self.world.command_debug_draw:draw_line(
- entity.transform.position_x,
- entity.transform.position_y,
- entity.transform.position_x + force_x,
- entity.transform.position_y + force_y,
- COLOR_FORCE
- )
- end
-end
-
-
----@param entity entity.boid
-function M:calculate_forces_new(entity)
- local boid = entity.boid
- local protected_rande_sq = boid.protected_range * boid.protected_range
-
- self._entity = entity
- self._protected_rande_sq = protected_rande_sq
- self._average_position_x = 0
- self._average_position_y = 0
- self._average_velocity_x = 0
- self._average_velocity_y = 0
- self._neighboring_boids = 0
- self._close_dx = 0
- self._close_dy = 0
-
- self.calculate_neighbor = self.calculate_neighbor or function(other_boid)
- if other_boid ~= self._entity then
- local t = other_boid.transform
- local dx = t.position_x - self._entity.transform.position_x
- local dy = t.position_y - self._entity.transform.position_y
- local dist = dx * dx + dy * dy
-
- if dist < self._protected_rande_sq then
- self._close_dx = self._close_dx + dx
- self._close_dy = self._close_dy + dy
- elseif dist < boid.visual_range * boid.visual_range then
- self._average_position_x = self._average_position_x + t.position_x
- self._average_position_y = self._average_position_y + t.position_y
- self._average_velocity_x = self._average_velocity_x + other_boid.velocity.x
- self._average_velocity_y = self._average_velocity_y + other_boid.velocity.y
- self._neighboring_boids = self._neighboring_boids + 1
- end
- end
- end
-
- self.world.command_quadtree:get_neighbors(entity, math.max(boid.visual_range, boid.protected_range), self.calculate_neighbor)
-
- local average_position_x, average_position_y = self._average_position_x, self._average_position_y
- local average_velocity_x, average_velocity_y = self._average_velocity_x, self._average_velocity_y
- local neighboring_boids = self._neighboring_boids
- local close_dx, close_dy = self._close_dx, self._close_dy
- local force_x = 0
- local force_y = 0
-
- if neighboring_boids > 0 then
- average_position_x = average_position_x / neighboring_boids
- average_position_y = average_position_y / neighboring_boids
- average_velocity_x = average_velocity_x / neighboring_boids
- average_velocity_y = average_velocity_y / neighboring_boids
-
- force_x = force_x + (average_position_x - entity.transform.position_x) * boid.centering_factor
- + (average_velocity_x - entity.velocity.x) * boid.matching_factor
-
- force_y = force_y + (average_position_y - entity.transform.position_y) * boid.centering_factor
- end
-
- if close_dx ~= 0 or close_dy ~= 0 then
- force_x = force_x - close_dx * boid.avoid_factor
- force_y = force_y - close_dy * boid.avoid_factor
- end
-
- -- Here can be turn factor around edges
- local border = entity.transform_border and entity.transform_border.border
- local transform = entity.transform
- if border then
- if transform.position_y > border.y then
- force_y = force_y - boid.turn_factor
- end
- if transform.position_y < border.w then
- force_y = force_y + boid.turn_factor
- end
- if transform.position_x > border.z then
- force_x = force_x - boid.turn_factor
- end
- if transform.position_x < border.x then
- force_x = force_x + boid.turn_factor
- end
- end
-
- return force_x, force_y
-end
-
-
-return M
diff --git a/examples/boids/system_game_object/ext.manifest b/examples/boids/system_game_object/ext.manifest
deleted file mode 100644
index 900e5a5..0000000
--- a/examples/boids/system_game_object/ext.manifest
+++ /dev/null
@@ -1 +0,0 @@
-name: "GoPositionSetter"
\ No newline at end of file
diff --git a/examples/boids/system_game_object/src/c_go_setter.cpp b/examples/boids/system_game_object/src/c_go_setter.cpp
deleted file mode 100644
index e08cec6..0000000
--- a/examples/boids/system_game_object/src/c_go_setter.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-#define EXTENSION_NAME GoPositionSetter
-#define LIB_NAME "GoPositionSetter"
-#define MODULE_NAME "go_position_setter"
-
-#include
-
-#define USERDATA_METATABLE "POSITION_SETTER_USERDATA"
-
-struct InstancePositionData {
- dmGameObject::HInstance rootInstance;
- dmVMath::Vector3 *position;
- // rotation quat
- dmVMath::Quat *rotation;
-
-};
-
-class PositionSetterUserdata {
- public:
- dmArray instances;
- explicit PositionSetterUserdata();
- ~PositionSetterUserdata();
- void addInstance(dmGameObject::HInstance rootInstance, dmVMath::Vector3 *position, dmVMath::Quat *rotation);
- void update();
- void removeInstance(dmGameObject::HInstance rootInstance);
-};
-
-PositionSetterUserdata::PositionSetterUserdata() {
-}
-
-PositionSetterUserdata::~PositionSetterUserdata() {
-}
-
-void PositionSetterUserdata::addInstance(dmGameObject::HInstance rootInstance, dmVMath::Vector3 *position, dmVMath::Quat *rotation) {
- InstancePositionData instanceVector;
- instanceVector.rootInstance = rootInstance;
- instanceVector.position = position;
- instanceVector.rotation = rotation;
- if (instances.Full()) {
- instances.OffsetCapacity(32);
- }
- instances.Push(instanceVector);
-}
-
-void PositionSetterUserdata::update() {
- for (int i = 0; i < instances.Size(); ++i) {
- InstancePositionData instancePositionData = instances[i];
- dmGameObject::SetPosition(instancePositionData.rootInstance, dmVMath::Point3(*instancePositionData.position));
- dmGameObject::SetRotation(instancePositionData.rootInstance, *instancePositionData.rotation);
- }
-}
-
-void PositionSetterUserdata::removeInstance(dmGameObject::HInstance rootInstance) {
- for (int i = 0; i < instances.Size(); ++i) {
- InstancePositionData instancePositionData = instances[i];
- if (instancePositionData.rootInstance == rootInstance) {
- instances.EraseSwap(i);
- return;
- }
- }
-}
-
-static PositionSetterUserdata *PositionSetterUserdataCheck(lua_State *L, int index) {
- return *(PositionSetterUserdata **)luaL_checkudata(L, index, USERDATA_METATABLE);
-}
-
-static int LuaPositionSetterUserdataAddInstance(lua_State *L) {
- PositionSetterUserdata *userdata = PositionSetterUserdataCheck(L, 1);
- dmGameObject::HInstance rootInstance = dmScript::CheckGOInstance(L, 2);
- dmVMath::Vector3 *position = dmScript::CheckVector3(L, 3);
- dmVMath::Quat *rotation = dmScript::CheckQuat(L, 4);
- userdata->addInstance(rootInstance, position, rotation);
- return 0;
-}
-
-static int LuaPositionSetterUserdataUpdate(lua_State *L) {
- PositionSetterUserdata *userdata = PositionSetterUserdataCheck(L, 1);
- userdata->update();
- return 0;
-}
-
-static int LuaPositionSetterUserdataRemoveInstance(lua_State *L) {
- PositionSetterUserdata *userdata = PositionSetterUserdataCheck(L, 1);
- dmGameObject::HInstance rootInstance = dmScript::CheckGOInstance(L, 2);
- userdata->removeInstance(rootInstance);
- return 0;
-}
-
-static int LuaPositionSetterUserdataGC(lua_State *L) {
- PositionSetterUserdata *userdata = PositionSetterUserdataCheck(L, 1);
- delete userdata;
- return 0;
-}
-
-static const luaL_Reg LuaPositionSetterUserdataMethods[] = {
- {"__gc", LuaPositionSetterUserdataGC},
- {"add", LuaPositionSetterUserdataAddInstance},
- {"remove", LuaPositionSetterUserdataRemoveInstance},
- {"update", LuaPositionSetterUserdataUpdate},
- {0, 0}};
-
-int NewPositionSetterUserdataLua(lua_State *L) {
- PositionSetterUserdata *userdata = new PositionSetterUserdata();
- PositionSetterUserdata **ud = (PositionSetterUserdata **)lua_newuserdata(L, sizeof(PositionSetterUserdata *));
- *ud = userdata;
- if (luaL_newmetatable(L, USERDATA_METATABLE)) {
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
- luaL_register(L, 0, LuaPositionSetterUserdataMethods);
- }
- lua_setmetatable(L, -2);
- return 1;
-}
-
-// Functions exposed to Lua
-static const luaL_reg Module_methods[] = {
- {"new", NewPositionSetterUserdataLua},
- {0, 0}};
-
-static void LuaInit(lua_State *L) {
- int top = lua_gettop(L);
- luaL_register(L, MODULE_NAME, Module_methods);
- lua_pop(L, 1);
- assert(top == lua_gettop(L));
-}
-
-static dmExtension::Result AppInitializeMyExtension(dmExtension::AppParams *params) { return dmExtension::RESULT_OK; }
-static dmExtension::Result InitializeMyExtension(dmExtension::Params *params) {
- // Init Lua
- LuaInit(params->m_L);
-
- printf("Registered %s Extension\n", MODULE_NAME);
- return dmExtension::RESULT_OK;
-}
-
-static dmExtension::Result AppFinalizeMyExtension(dmExtension::AppParams *params) { return dmExtension::RESULT_OK; }
-
-static dmExtension::Result FinalizeMyExtension(dmExtension::Params *params) { return dmExtension::RESULT_OK; }
-
-DM_DECLARE_EXTENSION(EXTENSION_NAME, LIB_NAME, AppInitializeMyExtension, AppFinalizeMyExtension, InitializeMyExtension, 0, 0, FinalizeMyExtension)
\ No newline at end of file
diff --git a/examples/manifest.appmanifest b/examples/manifest.appmanifest
deleted file mode 100644
index 930e929..0000000
--- a/examples/manifest.appmanifest
+++ /dev/null
@@ -1,106 +0,0 @@
-platforms:
- armv7-ios:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- frameworks: []
- linkFlags: []
- arm64-ios:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- frameworks: []
- linkFlags: []
- x86_64-ios:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- frameworks: []
- linkFlags: []
- armv7-android:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeJars: []
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- linkFlags: []
- jetifier: true
- arm64-android:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeJars: []
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- linkFlags: []
- jetifier: true
- arm64-osx:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- frameworks: []
- linkFlags: []
- x86_64-osx:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- frameworks: []
- linkFlags: []
- x86_64-linux:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- linkFlags: []
- arm64-linux:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeSymbols: [ScriptModelExt]
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- x86-win32:
- context:
- excludeLibs: [libgamesys_rig, librig, libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libgamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [libgamesys_rig_null.lib, librig_null.lib, libphysics_2d_defold.lib, libgamesys_model_null.lib]
- linkFlags: []
- x86_64-win32:
- context:
- excludeLibs: [libgamesys_rig, librig, libphysics, libLinearMath, libBulletDynamics, libBulletCollision, libgamesys_model]
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [libgamesys_rig_null.lib, librig_null.lib, libphysics_2d_defold.lib, libgamesys_model_null.lib]
- linkFlags: []
- js-web:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeJsLibs: []
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- linkFlags: []
- wasm-web:
- context:
- excludeLibs: [gamesys_rig, rig, physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model]
- excludeJsLibs: []
- excludeSymbols: [ScriptModelExt]
- symbols: []
- libs: [gamesys_rig_null, rig_null, physics_2d_defold, gamesys_model_null]
- linkFlags: []
- wasm_pthread-web:
- context:
- excludeLibs: [physics, LinearMath, BulletDynamics, BulletCollision, gamesys_model, gamesys_rig, rig]
- excludeSymbols: [ScriptModelExt]
- libs: [physics_2d_defold, gamesys_rig_null, gamesys_model_null, rig_null]
diff --git a/examples/nested_entities/entity/player.go b/examples/nested_entities/entity/player.go
deleted file mode 100644
index ea87d2c..0000000
--- a/examples/nested_entities/entity/player.go
+++ /dev/null
@@ -1,62 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "player"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "64.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"ui_circle_64\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/assets/atlases/game.atlas\"\n"
- "}\n"
- ""
-}
-embedded_components {
- id: "label"
- type: "label"
- data: "size {\n"
- " x: 80.0\n"
- " y: 40.0\n"
- "}\n"
- "color {\n"
- " x: 0.2\n"
- " y: 0.2\n"
- " z: 0.2\n"
- "}\n"
- "outline {\n"
- " w: 0.0\n"
- "}\n"
- "shadow {\n"
- " w: 0.0\n"
- "}\n"
- "pivot: PIVOT_W\n"
- "text: \"3.52\"\n"
- "font: \"/core/fonts/text.font\"\n"
- "material: \"/builtins/fonts/label-df.material\"\n"
- ""
- position {
- x: -25.0
- z: 0.1
- }
- scale {
- x: 0.7
- y: 0.7
- }
-}
diff --git a/examples/nested_entities/entity/player.lua b/examples/nested_entities/entity/player.lua
deleted file mode 100644
index 4abfe29..0000000
--- a/examples/nested_entities/entity/player.lua
+++ /dev/null
@@ -1,19 +0,0 @@
---@class entity
-return {
- transform = {},
- game_object = {
- object_scheme = {
- ["#label"] = true,
- ["#sprite"] = true,
- },
- },
- transform_border = {
- border = vmath.vector4(-1920/2, 1080/2, 1920/2, -1080/2),
- },
- text_game_timer = {
- label_url = "#label",
- },
- movement_controller = {
- speed = 20
- }
-}
diff --git a/examples/nested_entities/nested_entities.collection b/examples/nested_entities/nested_entities.collection
deleted file mode 100644
index 6d0a0db..0000000
--- a/examples/nested_entities/nested_entities.collection
+++ /dev/null
@@ -1,27 +0,0 @@
-name: "nested_entities"
-instances {
- id: "player"
- prototype: "/examples/nested_entities/entity/player.go"
- position {
- x: 480.0
- y: 320.0
- }
-}
-instances {
- id: "entity_camera"
- prototype: "/core/system/camera/entity_camera.go"
- position {
- z: 15.0
- }
-}
-scale_along_z: 0
-embedded_instances {
- id: "root"
- children: "entity_camera"
- children: "player"
- data: "components {\n"
- " id: \"nested_entities\"\n"
- " component: \"/examples/nested_entities/nested_entities.script\"\n"
- "}\n"
- ""
-}
diff --git a/examples/nested_entities/nested_entities.script b/examples/nested_entities/nested_entities.script
deleted file mode 100644
index 82d5455..0000000
--- a/examples/nested_entities/nested_entities.script
+++ /dev/null
@@ -1,28 +0,0 @@
-local decore = require("decore.decore")
-
-function init(self)
- self.world = decore.world(
- require("system.window_event.system_window_event").create_system(),
- require("system.camera.system_camera").create(),
- require("system.transform.system_transform").create(),
- require("system.transform_border.system_transform_border").create(),
- require("system.game_object.system_game_object").create(),
- require("system.input.system_input").create_system(),
- require("system.movement_controller.system_movement_controller").create(),
-
- require("examples.nested_entities.system_game_timer.system_game_timer").create_system(),
- require("system.camera_debug_control.camera_debug_control").create_system()
- )
-
- decore.register_entity("player", require("examples.nested_entities.entity.player"))
-end
-
-
-function update(self, dt)
- self.world:update(dt)
-end
-
-
-function on_input(self, action_id, action)
- return decore.on_input(self.world, action_id, action)
-end
diff --git a/examples/nested_entities/system_game_timer/system_game_timer.lua b/examples/nested_entities/system_game_timer/system_game_timer.lua
deleted file mode 100644
index 9dafc49..0000000
--- a/examples/nested_entities/system_game_timer/system_game_timer.lua
+++ /dev/null
@@ -1,47 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field text_game_timer component.text_game_timer|nil
-
----@class entity.text_game_timer: entity
----@field text_game_timer component.text_game_timer
----@field game_object component.game_object
-
----@class component.text_game_timer
----@field label_url string
-decore.register_component("text_game_timer", {
- label_url = "#label",
-})
-
----@class system.text_game_timer: system
----@field entities entity.text_game_timer[]
----@field create_time number
-local M = {}
-
-function M.create_system()
- local system = decore.system(M, "text_game_timer", { "text_game_timer", "game_object" })
- system.create_time = socket.gettime()
- return system
-end
-
-
----@param entity entity.text_game_timer
-function M:onAdd(entity)
- entity.text_game_timer.label_url = hash(entity.text_game_timer.label_url) --[[@as string]]
-end
-
-
-function M:update(dt)
- local current_time = socket.gettime()
- local time_diff = current_time - self.create_time
-
- for index = 1, #self.entities do
- local entity = self.entities[index]
- local text_game_timer = entity.text_game_timer
- local root_url = entity.game_object.object[text_game_timer.label_url]
- label.set_text(root_url, string.format("%.2f", time_diff))
- end
-end
-
-
-return M
diff --git a/game.project b/game.project
index f7b228f..4698686 100644
--- a/game.project
+++ b/game.project
@@ -18,7 +18,6 @@ title = Decore
version = 2
publisher = Insality
developer = Maksim Tuprikov, Insality
-custom_resources = /resources
dependencies#0 = https://github.com/britzl/deftest/archive/master.zip
dependencies#1 = https://github.com/Insality/defold-tweener/archive/refs/tags/3.zip
dependencies#2 = https://github.com/subsoap/defos/archive/refs/tags/v2.8.3.zip
@@ -27,6 +26,7 @@ dependencies#4 = https://github.com/AGulev/drawpixels/archive/refs/tags/2.0.1.zi
dependencies#5 = https://github.com/Insality/defold-event/archive/refs/tags/11.zip
dependencies#6 = https://github.com/Insality/druid/archive/refs/heads/develop.zip
dependencies#7 = https://github.com/Insality/panthera/archive/refs/tags/runtime.4.zip
+dependencies#8 = https://github.com/Insality/asset-store/archive/refs/heads/main.zip
[library]
include_dirs = decore
@@ -53,9 +53,6 @@ max_instances = 32000
[gui]
max_count = 2048
-[native_extension]
-app_manifest = /examples/manifest.appmanifest
-
[event]
use_xpcall = 1
diff --git a/resources/components.json b/resources/components.json
deleted file mode 100644
index e0bfd8a..0000000
--- a/resources/components.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "pack_id": "core",
-
- "components": {
- "id": null,
- "pack_id": null,
- "prefab_id": null,
- "name": null,
-
- "movement_controller": {
- "speed": 0,
- "movement_x": 0,
- "movement_y": 0
- }
- }
-}
diff --git a/resources/entities.json b/resources/entities.json
deleted file mode 100644
index c3ffbfa..0000000
--- a/resources/entities.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "pack_id": "core",
- "entities": {
- "player": {
- "transform": {},
- "game_object": {
- "factory_url": "/system/spawner#player"
- },
- "movement_controller": {
- "speed": 100
- }
- },
-
- "camera": {
- "transform": {},
- "camera": {}
- },
-
- "bullet": {
- "transform": {
- "scale_x": 1.25,
- "scale_y": 1.25
- },
- "game_object": {
- "factory_url": "/spawner/spawner#bullet"
- }
- }
- }
-}
diff --git a/system/camera/camera_entity.lua b/system/camera/camera_entity.lua
deleted file mode 100644
index 04e64a8..0000000
--- a/system/camera/camera_entity.lua
+++ /dev/null
@@ -1,5 +0,0 @@
----@return entity
-return {
- camera = {},
- transform = {},
-}
diff --git a/system/camera/command_camera.lua b/system/camera/command_camera.lua
deleted file mode 100644
index ae45527..0000000
--- a/system/camera/command_camera.lua
+++ /dev/null
@@ -1,47 +0,0 @@
----@class world
----@field command_camera system.camera.command
-
----@class system.camera.command
----@field camera system.camera @Current camera system
-local M = {}
-
-
----@return system.camera.command
-function M.create(camera_system)
- return setmetatable({ camera = camera_system }, { __index = M })
-end
-
-
----@param entity entity
----@param time number?
-function M:move_to_entity(entity, time)
- time = time or 0.3
- self.camera:move_to(entity.transform.position_x, entity.transform.position_y, time, go.EASING_OUTSINE)
-end
-
-
----@param power number
----@param time number
-function M:shake(power, time)
- self.camera.shake_power = power or 8
- self.camera.shake_time = time or 0.4
-end
-
-
-function M:world_to_screen(x, y)
- return self.camera:world_to_screen(x, y)
-end
-
-
-function M:screen_to_world(x, y)
- return self.camera:screen_to_world(x, y)
-end
-
-
----@return entity.camera
-function M:get_current_camera()
- return self.camera.camera
-end
-
-
-return M
diff --git a/system/camera/component_camera.script b/system/camera/component_camera.script
deleted file mode 100644
index 5722ba9..0000000
--- a/system/camera/component_camera.script
+++ /dev/null
@@ -1,5 +0,0 @@
-local component = require("decore.component")
-
-function init(self)
- component.init("camera", {})
-end
\ No newline at end of file
diff --git a/system/camera/entity_camera.go b/system/camera/entity_camera.go
deleted file mode 100644
index 144cd6d..0000000
--- a/system/camera/entity_camera.go
+++ /dev/null
@@ -1,48 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "camera"
- type: PROPERTY_TYPE_HASH
- }
- properties {
- id: "size_x"
- value: "1920.0"
- type: PROPERTY_TYPE_NUMBER
- }
- properties {
- id: "size_y"
- value: "1080.0"
- type: PROPERTY_TYPE_NUMBER
- }
-}
-embedded_components {
- id: "camera"
- type: "camera"
- data: "aspect_ratio: 1.0\n"
- "fov: 0.7854\n"
- "near_z: 0.01\n"
- "far_z: 1000.0\n"
- "orthographic_projection: 1\n"
- ""
-}
-embedded_components {
- id: "sprite"
- type: "sprite"
- data: "default_animation: \"empty\"\n"
- "material: \"/builtins/materials/sprite.material\"\n"
- "size {\n"
- " x: 1920.0\n"
- " y: 1080.0\n"
- "}\n"
- "size_mode: SIZE_MODE_MANUAL\n"
- "textures {\n"
- " sampler: \"texture_sampler\"\n"
- " texture: \"/core/atlas/core.atlas\"\n"
- "}\n"
- ""
- position {
- z: -10.0
- }
-}
diff --git a/system/camera/system_camera.lua b/system/camera/system_camera.lua
deleted file mode 100644
index 6720b94..0000000
--- a/system/camera/system_camera.lua
+++ /dev/null
@@ -1,347 +0,0 @@
-local decore = require("decore.decore")
-
-local command_camera = require("system.camera.command_camera")
-
-local TEMP_VECTOR = vmath.vector3()
-local HASH_SIZE_X = hash("size.x")
-local HASH_SIZE_Y = hash("size.y")
-local HASH_SPRITE = hash("sprite")
-
----@class entity
----@field camera component.camera|nil
-
----@class entity.camera: entity
----@field camera component.camera
----@field transform component.transform
-
----Add this component to camera entity, it will manage the camera visible size and position
----@class component.camera
----@field camera_url url
----@field follow_entity entity.transform|nil
----@field position_x number|nil
----@field position_y number|nil
----@field size_x number|nil
----@field size_y number|nil
----@field offset_x number|nil
----@field offset_y number|nil
----@field offset_size number|nil
----@field zoom number|nil
-decore.register_component("camera", {
- camera_url = "",
-})
-
----@class system.camera.event
----@field entity entity.camera
-
----@class system.camera: system
----@field entities (entity.camera)[]
----@field camera entity.camera|nil @Current camera entity
----@field camera_borders vector4|nil @Borders of camera visible area vmath.vector4(left, right, top, bottom). Camera will not move outside of these borders
----@field shake_power number|nil
----@field shake_time number|nil
----@field shake_max_time number|nil
----@field zoom number
-local M = {}
-
-M.DEFAULT_SIZE = math.min(sys.get_config_int("display.width"), sys.get_config_int("display.height"))
-
----@return system.camera
-function M.create()
- local system = decore.system(M, "camera", "camera")
-
- system.interval = 0.03
- system.camera = nil
- system.camera_borders = nil
- system.zoom = 1
- system.shake_power = 0
- system.shake_time = 0
- system.shake_max_time = 0
-
- return system
-end
-
-
-function M:onAddToWorld()
- self.world.command_camera = command_camera.create(self)
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("window_event", self.process_window_event, self)
- self.world.event_bus:process("transform_event", self.process_transform_event, self)
-end
-
-
----@param window_event system.window_event.event
-function M:process_window_event(window_event)
- if not self.camera then
- return
- end
-
- if window_event == window.WINDOW_EVENT_RESIZED then
- self:update_camera_position(self.camera)
- self:update_camera_zoom(self.camera)
- end
-end
-
-
----@param event system.transform.event
-function M:process_transform_event(event)
- if event.entity ~= self.camera then
- return
- end
-
- if event.is_position_changed then
- self:update_camera_position(self.camera, event.animate_time, event.easing)
- end
-
- if event.is_scale_changed or event.is_size_changed then
- self:update_camera_zoom(self.camera, event.animate_time, event.easing)
- end
-end
-
-
----@param entity entity.camera
-function M:onAdd(entity)
- msg.post("@render:", "use_camera_projection")
- self.camera = entity
- self.is_camera_changed = true
-
- local camera_url = msg.url(entity.game_object.root)
- camera_url.fragment = hash("camera")
- entity.camera.camera_url = camera_url
-
- --camera.acquire_focus(entity.camera.camera_url)
-
- self:update_camera_position(self.camera)
- self:update_camera_zoom(self.camera)
-end
-
-
----@param entity entity.camera
-function M:onRemove(entity)
- if self.camera == entity then
- --camera.release_focus(entity.camera.camera_url)
- self.camera = nil
- end
-end
-
-
-function M:update(dt)
- if self.is_camera_changed then
- self.world.event_bus:trigger("camera_event", self.camera)
- self.is_camera_changed = false
- end
-
- if self.shake_time > 0 then
- self.shake_max_time = math.max(self.shake_max_time, self.shake_time)
-
- self.shake_time = self.shake_time - dt
- if self.shake_time <= 0 then
- self.shake_max_time = 0
- self.shake_power = 0
- self:shake(0)
- else
- local power = self.shake_power * (self.shake_time / self.shake_max_time)
- self:shake(power)
- end
- end
-end
-
-
----Move camera to the specified position
----@param position_x number
----@param position_y number
----@param animate_time number|nil
----@param easing userdata|nil
-function M:move_to(position_x, position_y, animate_time, easing)
- local entity = self.camera
- if entity then
- self.world.command_transform:set_position(entity, position_x, position_y)
- if animate_time then
- self.world.command_transform:set_animate_time(entity, animate_time, easing)
- end
- end
-end
-
-
----Move camera to the specified size
----@param size_x number
----@param size_y number
----@param animate_time number|nil
----@param easing userdata|nil
-function M:size_to(size_x, size_y, animate_time, easing)
- local entity = self.camera
- if entity then
- self.world.command_transform:set_size(entity, size_x, size_y)
- if animate_time then
- self.world.command_transform:set_animate_time(entity, animate_time, easing)
- end
- end
-end
-
-
----Move camera to the entity position
----@param entity entity.camera
----@param animate_time number|nil
----@param easing userdata|nil
-function M:update_camera_position(entity, animate_time, easing)
- TEMP_VECTOR.x = entity.transform.position_x
- TEMP_VECTOR.y = entity.transform.position_y
- TEMP_VECTOR.z = entity.transform.position_z
-
- -- Apply borders
- local borders = self.camera_borders
- if borders then
- local size_x = entity.transform.size_x / 2
- local size_y = entity.transform.size_y / 2
- if TEMP_VECTOR.x - size_x < borders.x then
- TEMP_VECTOR.x = borders.x + size_x
- end
- if TEMP_VECTOR.x + size_x > borders.y then
- TEMP_VECTOR.x = borders.y - size_x
- end
- if TEMP_VECTOR.y + size_y > borders.z then
- TEMP_VECTOR.y = borders.z - size_y
- end
- if TEMP_VECTOR.y - size_y < borders.w then
- TEMP_VECTOR.y = borders.w + size_y
- end
- end
-
- if animate_time then
- easing = easing or go.EASING_OUTSINE
- go.animate(entity.game_object.root, "position", go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, animate_time)
- else
- go.set_position(TEMP_VECTOR, entity.game_object.root)
- end
-end
-
-
----Update camera zoom, so that camera fits the entity size
----@param entity entity.camera
----@param animate_time number|nil
----@param easing userdata|nil
-function M:update_camera_zoom(entity, animate_time, easing)
- local _, _, width, height = defos.get_view_size()
- local camera_size_x = entity.transform.size_x * entity.transform.scale_x
- local camera_size_y = entity.transform.size_y * entity.transform.scale_y
-
- local scale_x = width / camera_size_x
- local scale_y = height / camera_size_y
- self.zoom = math.min(scale_x, scale_y)
- --self.zoom = math.max(scale_x, scale_y)
- entity.camera.zoom = self.zoom
-
- if animate_time then
- easing = easing or go.EASING_OUTSINE
- go.animate(entity.camera.camera_url, "orthographic_zoom", go.PLAYBACK_ONCE_FORWARD, self.zoom, easing, animate_time)
- else
- go.set(entity.camera.camera_url, "orthographic_zoom", self.zoom)
- end
-end
-
-
----Convert from screen to world coordinates
----@param sx number Screen x
----@param sy number Screen y
----@param sz number Screen z
----@param window_width number Width of the window (use defos.get_view_size())
----@param window_height number Height of the window (use defos.get_view_size())
----@param projection matrix4 Camera/render projection (use go.get("#camera", "projection"))
----@param view vector4 Camera/render view (use go.get("#camera", "view"))
----@return number World x
----@return number World y
----@return number World z
-local function screen_to_world(sx, sy, sz, window_width, window_height, projection, view)
- local inv = vmath.inv(projection * view)
- sx = (2 * sx / window_width) - 1
- sy = (2 * sy / window_height) - 1
- sz = (2 * sz) - 1
- local wx = sx * inv.m00 + sy * inv.m01 + sz * inv.m02 + inv.m03
- local wy = sx * inv.m10 + sy * inv.m11 + sz * inv.m12 + inv.m13
- local wz = sx * inv.m20 + sy * inv.m21 + sz * inv.m22 + inv.m23
- return wx, wy, wz
-end
-
-
----Convert from world to screen coordinates
----@param wx number World x
----@param wy number World y
----@param wz number World z
----@param window_width number Width of the window (use defos.get_view_size())
----@param window_height number Height of the window (use defos.get_view_size())
----@param projection matrix4 Camera/render projection (use go.get("#camera", "projection"))
----@param view vector4 Camera/render view (use go.get("#camera", "view"))
----@return number Screen x
----@return number Screen y
----@return number Screen z
-local function world_to_screen(wx, wy, wz, window_width, window_height, projection, view)
- local p = vmath.matrix4() * vmath.vector4(wx, wy, wz, 1)
- p = projection * view * p
- p = p / p.w
- local sx = ((p.x + 1) / 2) * window_width
- local sy = ((p.y + 1) / 2) * window_height
- local sz = ((p.z + 1) / 2)
- return sx, sy, sz
-end
-
-
----Convert from screen to world coordinates
----@param screen_x number Screen x
----@param screen_y number Screen y
----@return number, number
-function M:screen_to_world(screen_x, screen_y)
- if not self.camera then
- return screen_x, screen_y
- end
-
- local width, height = window.get_size()
- local projection = go.get(self.camera.camera.camera_url, "projection")
- local view = go.get(self.camera.camera.camera_url, "view")
-
- local x, y, _ = screen_to_world(screen_x, screen_y, 0, width, height, projection, view)
- return x, y
-end
-
-
----Convert from world to screen coordinates
----@param world_x number World x
----@param world_y number World y
----@return number, number
-function M:world_to_screen(world_x, world_y)
- if not self.camera then
- return world_x, world_y
- end
-
- local width, height = window.get_size()
- local projection = go.get(self.camera.camera.camera_url, "projection")
- local view = go.get(self.camera.camera.camera_url, "view")
-
- local x, y, _ = world_to_screen(world_x, world_y, 0, width, height, projection, view)
- return x, y
-end
-
-
-function M:shake(power)
- if not self.camera then
- return
- end
-
- local obj_url = self.camera.game_object.root
-
- local power_sqr = power * power
- local dx = math.random(-power_sqr, power_sqr)
- local dy = math.random(-power_sqr, power_sqr)
- local x = self.camera.transform.position_x + dx
- local y = self.camera.transform.position_y + dy
- TEMP_VECTOR.x = x
- TEMP_VECTOR.y = y
- TEMP_VECTOR.z = self.camera.transform.position_z
- --go.set_position(TEMP_VECTOR, obj_url)
-
- go.animate(obj_url, "position", go.PLAYBACK_ONCE_FORWARD,TEMP_VECTOR, go.EASING_OUTSINE, 0.03)
-end
-
-
-return M
diff --git a/system/camera_debug_control/camera_debug_control.lua b/system/camera_debug_control/camera_debug_control.lua
deleted file mode 100644
index 1f50971..0000000
--- a/system/camera_debug_control/camera_debug_control.lua
+++ /dev/null
@@ -1,91 +0,0 @@
-local decore = require("decore.decore")
-
----@class system.camera_debug_control: system
----@field is_ctrl boolean
-local M = {}
-
-local HASH_CMD = hash("key_lsuper")
-local HASH_CTRL = hash("key_lctrl")
-
-
----@return system.camera_debug_control
-function M.create_system()
- local system = decore.system(M, "camera_debug_control")
- system.is_ctrl = false
- system.is_hold = false
-
- return system
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("input_event", self.process_input_event, self)
-end
-
-
----@param input_event system.input.event
-function M:process_input_event(input_event)
- -- Process mod key
- local action_id = input_event.action_id
- local is_ctrl = (action_id == HASH_CTRL or action_id == HASH_CMD)
- if is_ctrl and input_event.pressed then
- self.is_ctrl = true
- elseif is_ctrl and input_event.released then
- self.is_ctrl = false
- end
-
- -- process drag camera
- if self.is_ctrl then
- self:process_drag_camera(input_event)
- end
-end
-
-
----@param input_event system.input.event
-function M:process_drag_camera(input_event)
- local action_id = input_event.action_id
- if action_id == hash("touch") then
- if input_event.pressed then
- self.is_hold = true
- self.start_x = input_event.x
- self.start_y = input_event.y
- elseif input_event.released then
- self.is_hold = false
- end
- end
-
- if self.is_hold and action_id == nil then
- local entity = self.world.command_camera:get_current_camera()
- local zoom = entity.camera.zoom
- local koef = 1 / zoom
- self.world.command_transform:add_position(entity, -input_event.screen_dx * koef, -input_event.screen_dy * koef)
- end
-
- if self.is_ctrl then
- -- check wheel
- if input_event.action_id == hash("mouse_wheel_down") then
- local entity = self.world.command_camera:get_current_camera()
- --local new_size_x = entity.transform.size_x * 1.1
- --local new_size_y = entity.transform.size_y * 1.1
- --self.world.command_transform:set_size(entity, new_size_x, new_size_y)
-
- local new_scale_x = entity.transform.scale_x * 1.1
- local new_scale_y = entity.transform.scale_y * 1.1
- self.world.command_transform:set_scale(entity, new_scale_x, new_scale_y)
- self.world.command_transform:set_animate_time(entity, 0.2, go.EASING_OUTSINE)
- end
- if input_event.action_id == hash("mouse_wheel_up") then
- local entity = self.world.command_camera:get_current_camera()
- --local new_size_x = entity.transform.size_x * 0.9
- --local new_size_y = entity.transform.size_y * 0.9
- --self.world.command_transform:set_size(entity, new_size_x, new_size_y)
- local new_scale_x = entity.transform.scale_x * 0.9
- local new_scale_y = entity.transform.scale_y * 0.9
- self.world.command_transform:set_scale(entity, new_scale_x, new_scale_y)
- self.world.command_transform:set_animate_time(entity, 0.2, go.EASING_OUTSINE)
- end
- end
-end
-
-
-return M
diff --git a/system/collision/annotations_collision.lua b/system/collision/annotations_collision.lua
deleted file mode 100644
index 2076392..0000000
--- a/system/collision/annotations_collision.lua
+++ /dev/null
@@ -1,32 +0,0 @@
----@class physics.collision.object
----@field id hash @Id of the object
----@field group hash @Group of the object
----@field position vector3|nil @Position of the object
----@field relative_velocity vector3|nil @Relative velocity of the object
----@field mass number|nil @Mass of the object
----@field normal vector3|nil @Normal of the object
-
----@class physics.collision.contact_point_event
----@field a physics.collision.object
----@field b physics.collision.object
----@field applied_impulse number @Applied impulse
----@field distance number @Distance
-
----@class physics.collision.collision_event
----@field a physics.collision.object
----@field b physics.collision.object
-
----@class physics.collision.ray_cast_response
----@field requst_id number @Request id
----@field group hash @Group of the object
----@field position vector3 @Position of the object
----@field normal vector3 @Normal of the object
----@field fraction number @Fraction of the object
-
----@class physics.collision.ray_cast_missed
----@field requst_id number @Request id
-
----@class physics.collision.trigger_event
----@field a physics.collision.object
----@field b physics.collision.object
----@field enter boolean @True if the trigger interaction is entering, false if it is exiting
diff --git a/system/collision/component_collision.script b/system/collision/component_collision.script
deleted file mode 100644
index 31a4d93..0000000
--- a/system/collision/component_collision.script
+++ /dev/null
@@ -1,15 +0,0 @@
-local component = require("decore.component")
-
-local HASH_EMPTY = hash("")
-
-go.property("is_remove", false)
-go.property("trigger_event", hash(""))
-go.property("is_trigger_once", true)
-
-function init(self)
- component.init("collision", {
- is_remove = self.is_remove,
- trigger_event = self.trigger_event ~= HASH_EMPTY and self.trigger_event or nil,
- is_trigger_once = self.is_trigger_once
- })
-end
\ No newline at end of file
diff --git a/system/collision/system_collision.lua b/system/collision/system_collision.lua
deleted file mode 100644
index ccf609f..0000000
--- a/system/collision/system_collision.lua
+++ /dev/null
@@ -1,211 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field collision component.collision|nil
-
----@class entity.collision: entity
----@field collision component.collision
-
----If true, will get collision events.
----@class component.collision
----@field is_remove boolean|nil
----@field trigger_event hash|string|nil
----@field is_trigger_once boolean|nil
-decore.register_component("collision", {})
-
----@class system.collision.event
----@field entity entity
----@field other entity|nil
----@field trigger_event physics.collision.trigger_event|nil
----@field collision_event physics.collision.collision_event|nil
----@field contact_point_event physics.collision.contact_point_event|nil
-
----@class system.collision: system
----@field entities entity.collision[]
----@field root_to_entity table
----@field collided_this_frame table
-local M = {}
-
-
----@return system.collision
-function M.create_system()
- local system = decore.system(M, "collision", { "collision", "game_object" })
-
- system.root_to_entity = {}
- system.collided_this_frame = {}
-
- return system
-end
-
-
-function M:onAddToWorld()
- physics.set_listener(function(_, event_id, event)
- M.physics_world_listener(self, event_id, event)
- end)
-end
-
-
-function M:onRemoveFromWorld()
- physics.set_listener(nil)
-end
-
-
----@param entity entity
-function M:onAdd(entity)
- local root = entity.game_object.root
- if root then
- self.root_to_entity[root] = entity
- end
-end
-
-
----@param entity entity
-function M:onRemove(entity)
- local root = entity.game_object.root
- if root then
- self.root_to_entity[root] = nil
- end
-end
-
-
-function M:preWrap()
- self.collided_this_frame = {}
-end
-
-
-local CONTACT_POINT_EVENT = hash("contact_point_event")
-local COLLISION_EVENT = hash("collision_event")
-local TRIGGER_EVENT = hash("trigger_event")
-local RAY_CAST_RESPONSE = hash("ray_cast_response")
-local RAY_CAST_MISSED = hash("ray_cast_missed")
-
----@param self system.collision
----@param event hash @Event type
----@param data any
-function M.physics_world_listener(self, event, data)
- if event == CONTACT_POINT_EVENT then
- self:handle_contact_point_event(data)
- elseif event == COLLISION_EVENT then
- self:handle_collision_event(data)
- elseif event == TRIGGER_EVENT then
- self:handle_trigger_event(data)
- elseif event == RAY_CAST_RESPONSE then
- -- Handle raycast hit data
- elseif event == RAY_CAST_MISSED then
- -- Handle raycast miss data
- end
-end
-
-
----@param self system.collision
----@param entity_source entity|nil
----@param entity_target entity|nil
----@param event_data physics.collision.contact_point_event|physics.collision.trigger_event|physics.collision.collision_event
----@param event_type string @"contact_point_event"|"trigger_event"|"collision_event"
-local function handle_collision_event(self, entity_source, entity_target, event_data, event_type)
- --pprint("======Handle Collision Event")
- --pprint("Entity Source: ", entity_source)
- --pprint("Entity Target: ", entity_target)
- --pprint("Event Data: ", event_data)
- --pprint("Event Type: ", event_type)
-
- if entity_source and entity_source.collision then
- local collision = entity_source.collision ---@type component.collision
-
- if collision.is_remove then
- self.world:removeEntity(entity_source)
- end
-
- if collision.trigger_event and event_type == "trigger_event" then
- self.world.event_bus:trigger(collision.trigger_event, entity_source)
- if collision.is_trigger_once then
- collision.trigger_event = nil
- end
- end
-
- ---@type system.collision.event
- local collision_event = {
- entity = entity_source,
- other = entity_target,
- [event_type] = event_data
- }
- self.world.event_bus:trigger("collision_event", collision_event)
- end
-
- if entity_target and entity_target.collision then
- local collision = entity_target.collision ---@type component.collision
-
- if collision.is_remove then
- self.world:removeEntity(entity_target)
- end
-
- if collision.trigger_event and event_type == "trigger_event" then
- self.world.event_bus:trigger(collision.trigger_event, entity_target)
- if collision.is_trigger_once then
- collision.trigger_event = nil
- end
- end
-
- ---@type system.collision.event
- local collision_event = {
- entity = entity_target,
- other = entity_source,
- [event_type] = event_data
- }
- self.world.event_bus:trigger("collision_event", collision_event)
- end
-end
-
-
----@param event_data physics.collision.contact_point_event
-function M:handle_contact_point_event(event_data)
- -- Handle contact point data
- local entity_source = self.root_to_entity[event_data.a.id]
- local entity_target = self.root_to_entity[event_data.b.id]
- handle_collision_event(self, entity_source, entity_target, event_data, "contact_point_event")
-end
-
-
----@param event_data physics.collision.trigger_event
-function M:handle_trigger_event(event_data)
- -- Handle trigger interaction data
- local entity_source = self.root_to_entity[event_data.a.id]
- local entity_target = self.root_to_entity[event_data.b.id]
- handle_collision_event(self, entity_source, entity_target, event_data, "trigger_event")
-end
-
-
----@param event_data physics.collision.collision_event
-function M:handle_collision_event(event_data)
- local entity_source = self.root_to_entity[event_data.a.id]
- local entity_target = self.root_to_entity[event_data.b.id]
-
- local is_source_collided = self.collided_this_frame[entity_source] and self.collided_this_frame[entity_source][entity_target]
- if entity_source and entity_source.collision and not is_source_collided then
- handle_collision_event(self, entity_source, entity_target, event_data, "collision_event")
-
- if entity_target then
- self.collided_this_frame[entity_source] = self.collided_this_frame[entity_source] or {}
- self.collided_this_frame[entity_source][entity_target] = true
-
- self.collided_this_frame[entity_target] = self.collided_this_frame[entity_target] or {}
- self.collided_this_frame[entity_target][entity_source] = true
- end
- end
-
- local is_target_collided = self.collided_this_frame[entity_target] and self.collided_this_frame[entity_target][entity_source]
- if entity_target and entity_target.collision and not is_target_collided then
- handle_collision_event(self, entity_target, entity_source, event_data, "collision_event")
-
- if entity_source then
- self.collided_this_frame[entity_target] = self.collided_this_frame[entity_target] or {}
- self.collided_this_frame[entity_target][entity_source] = true
-
- self.collided_this_frame[entity_source] = self.collided_this_frame[entity_source] or {}
- self.collided_this_frame[entity_source][entity_target] = true
- end
- end
-end
-
-
-return M
diff --git a/system/color/system_color.lua b/system/color/system_color.lua
deleted file mode 100644
index 7674e4b..0000000
--- a/system/color/system_color.lua
+++ /dev/null
@@ -1,106 +0,0 @@
-local color = require("druid.color")
-local decore = require("decore.decore")
-
----@class entity
----@field color component.color|nil
-
----@class entity.color: entity
----@field color component.color
----@field game_object component.game_object
-
----@class component.color
----@field color_id string|nil
----@field color vector4 # color of the entity, constructor can be string
----@field sprites string # "/root#sprite,/root#sprite2"
----@field random_color vector4[] # two colors for lerp
-decore.register_component("color", {
- color = vmath.vector4(1),
-})
-
----@class system.color.event
----@field entity entity
----@field color vector4
-
----@class system.color: system
----@field entities entity.color[]
-local M = {}
-
-
----@return system.color
-function M.create_system()
- return decore.system(M, "color", { "color", "game_object" })
-end
-
-
----@param entity entity.color
-function M:onAdd(entity)
- local random_color = entity.color.random_color
- if random_color then
- entity.color.color = color.lerp(math.random(), random_color[1], random_color[2])
- end
-
- local color_data = entity.color.color
- if type(color_data) == "string" then
- entity.color.color = color.hex2vector4(color_data)
- end
-
- if entity.color.color then
- self:apply_color(entity, entity.color.color, entity.color.sprites)
- end
-end
-
-
----@param entity entity.color
----@param color vector4|nil
----@param sprites string|nil "/root#sprite,/root#sprite2"
-function M:apply_color(entity, color, sprites)
- if not color or not sprites then
- return
- end
-
- local splitted_sprites = M.split(sprites, ",")
- for index = 1, #splitted_sprites do
- local target = splitted_sprites[index]
-
- local splitted = M.split(target, "#")
- local object_id, component_id = splitted[1], splitted[2] or "sprite"
-
- -- If target starts with #, then it's a component id
- if string.sub(target, 1, 1) == "#" then
- object_id = nil
- component_id = splitted[1]
- end
-
- local object = entity.game_object.object
- if object_id then
- if object and object[object_id] then
- local sprite_url = msg.url(nil, object[object_id], component_id)
- go.set(sprite_url, "color", color) -- vertex attribute
- end
- else
- local root = entity.game_object.root
- if root then
- local sprite_url = msg.url(nil, root, component_id)
- go.set(sprite_url, "color", color) -- vertex attribute
- end
- end
- end
-end
-
-
----Split string by separator
----@param s string
----@param sep string
-function M.split(s, sep)
- sep = sep or "%s"
- local t = {}
- local i = 1
- for str in string.gmatch(s, "([^" .. sep .. "]+)") do
- t[i] = str
- i = i + 1
- end
- return t
-end
-
-
-return M
diff --git a/system/debug/command_debug.lua b/system/debug/command_debug.lua
deleted file mode 100644
index a708403..0000000
--- a/system/debug/command_debug.lua
+++ /dev/null
@@ -1,52 +0,0 @@
----@class world
----@field command_debug system.debug.command
-
----@class system.debug.command
----@field debug system.debug
-local M = {}
-
-
----@param debug system.debug
----@return system.debug.command
-function M.create(debug)
- return setmetatable({ debug = debug }, { __index = M })
-end
-
-
-function M:toggle_profiler()
- for _, e in ipairs(self.debug.entities) do
- self.debug:toggle_profiler(e)
- end
-end
-
-
-function M:toggle_memory_record()
- for _, e in ipairs(self.debug.entities) do
- self.debug:toggle_memory_record(e)
- end
-end
-
-
-function M:restart()
- if html5 then
- html5.run('document.location.reload();')
- else
- msg.post("@system:", "reboot")
- end
-end
-
-
-function M:reset_game()
- self.debug:reset_game()
-end
-
-function M:load_slot(slot)
- self.debug:load_slot(slot)
-end
-
-function M:save_slot(slot)
- self.debug:save_slot(slot)
-end
-
-
-return M
diff --git a/system/debug/debug.go b/system/debug/debug.go
deleted file mode 100644
index 7781b3f..0000000
--- a/system/debug/debug.go
+++ /dev/null
@@ -1,9 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "debug"
- type: PROPERTY_TYPE_HASH
- }
-}
diff --git a/system/debug/entity_debug.lua b/system/debug/entity_debug.lua
deleted file mode 100644
index 94dad7b..0000000
--- a/system/debug/entity_debug.lua
+++ /dev/null
@@ -1,13 +0,0 @@
----@return entity.debug
-return {
- debug = {},
- on_key_released = {
- key_p = { "command_debug", "toggle_profiler", true },
- key_1 = { "command_debug", "save_slot", "save_debug.json" },
- key_2 = { "command_debug", "load_slot", "save_debug.json" },
- key_r = { "command_debug", "restart", true },
- key_n = { "command_debug", "reset_game", true },
- key_m = { "command_debug", "toggle_memory_record" },
- key_i = { "command_debug", "inspect", true },
- }
-}
diff --git a/system/debug/system_debug.lua b/system/debug/system_debug.lua
deleted file mode 100644
index 216f205..0000000
--- a/system/debug/system_debug.lua
+++ /dev/null
@@ -1,114 +0,0 @@
-local log = require("log.log")
-local saver = require("saver.saver")
-local decore = require("decore.decore")
-
-local logger = log.get_logger("debug")
-
-local command_debug = require("system.debug.command_debug")
-
----@class entity
----@field debug component.debug|nil
-
----@class entity.debug: entity
----@field debug component.debug
-
----@class component.debug
----@field is_profiler_active boolean
----@field profiler_mode userdata|nil
----@field timer_memory_record number|nil
-decore.register_component("debug", {
- is_profiler_active = false,
- profiler_mode = nil,
- timer_memory_record = nil,
-})
-
----@class system.debug: system
----@field entities entity.debug[]
-local M = {}
-
-
----@return system.debug
-function M.create_system()
- return decore.system(M, "debug", "debug")
-end
-
-
-function M:onAddToWorld()
- self.world.command_debug = command_debug.create(self)
-end
-
-
----@param entity entity.debug
-function M:toggle_profiler(entity)
- local d = entity.debug
-
- if not d.profiler_mode then
- d.profiler_mode = profiler.VIEW_MODE_MINIMIZED
- profiler.enable_ui(true)
- profiler.set_ui_view_mode(d.profiler_mode)
- elseif d.profiler_mode == profiler.VIEW_MODE_MINIMIZED then
- d.profiler_mode = profiler.VIEW_MODE_FULL
- profiler.enable_ui(true)
- profiler.set_ui_view_mode(d.profiler_mode)
- else
- profiler.enable_ui(false)
- d.profiler_mode = nil
- end
-
- logger:info("Profiler is active: " .. tostring(d.is_profiler_active))
-end
-
-
----@param entity entity.debug
-function M:toggle_memory_record(entity)
- local d = entity.debug
-
- if d.timer_memory_record then
- timer.cancel(d.timer_memory_record)
- d.timer_memory_record = nil
- logger:info("Memory record stopped")
- collectgarbage("restart")
- collectgarbage("collect")
- else
- collectgarbage("collect")
- collectgarbage("stop")
- local memory = collectgarbage("count")
- d.timer_memory_record = timer.delay(1, true, function()
- local new_memory = collectgarbage("count")
- logger:info("Memory: " .. new_memory - memory)
- memory = new_memory
- end)
- logger:info("Memory record started")
- end
-end
-
-
-function M:reset_game()
- logger:debug("Game reset")
- saver.delete_game_state()
- sys.reboot()
-end
-
-
-function M:load_slot(slot)
- logger:debug("Game loaded from slot: " .. slot)
- sys.reboot("--config=saver.save_name=" .. slot, "--config=saver.autosave_timer=0")
-end
-
-
-function M:save_slot(slot)
- saver.save_game_state(slot)
- logger:debug("Game saved to slot: " .. slot)
-end
-
-
-function M:restart()
- if html5 then
- html5.run('document.location.reload();')
- else
- msg.post("@system:", "reboot")
- end
-end
-
-
-return M
diff --git a/system/debug_draw/command_debug_draw.lua b/system/debug_draw/command_debug_draw.lua
deleted file mode 100644
index fe26b06..0000000
--- a/system/debug_draw/command_debug_draw.lua
+++ /dev/null
@@ -1,29 +0,0 @@
----@class world
----@field command_debug_draw system.debug_draw.command
-
----@class system.debug_draw.command
----@field debug_draw system.debug_draw
-local M = {}
-
-
----@return system.debug_draw.command
-function M.create(debug_draw)
- return setmetatable({ debug_draw = debug_draw }, { __index = M })
-end
-
-
-function M:draw_rectangle(x, y, width, height, color)
- self.debug_draw:draw_rectangle(x, y, width, height, color)
-end
-
-function M:draw_line(x1, y1, x2, y2, color)
- self.debug_draw:draw_line(x1, y1, x2, y2, color)
-end
-
-
-function M:draw_text(x, y, text)
- self.debug_draw:draw_text(x, y, text)
-end
-
-
-return M
diff --git a/system/debug_draw/component_debug_draw.script b/system/debug_draw/component_debug_draw.script
deleted file mode 100644
index e944951..0000000
--- a/system/debug_draw/component_debug_draw.script
+++ /dev/null
@@ -1,8 +0,0 @@
-local component = require("decore.component")
-go.property("sprite_url", hash("#sprite"))
-
-function init(self)
- component.init("debug_draw", {
- sprite_url = self.sprite_url
- })
-end
\ No newline at end of file
diff --git a/system/debug_draw/debug_draw.atlas b/system/debug_draw/debug_draw.atlas
deleted file mode 100644
index 62e17cf..0000000
--- a/system/debug_draw/debug_draw.atlas
+++ /dev/null
@@ -1,4 +0,0 @@
-images {
- image: "/assets/images/empty.png"
-}
-inner_padding: 1018
diff --git a/system/debug_draw/system_debug_draw.lua b/system/debug_draw/system_debug_draw.lua
deleted file mode 100644
index 438628a..0000000
--- a/system/debug_draw/system_debug_draw.lua
+++ /dev/null
@@ -1,163 +0,0 @@
-local palette = require("druid.color")
-local decore = require("decore.decore")
-local command_debug_draw = require("system.debug_draw.command_debug_draw")
-
----@class entity
----@field debug_draw component.debug_draw|nil
-
----@class entity.debug_draw: entity
----@field debug_draw component.debug_draw
----@field game_object component.game_object
-
----@class component.debug_draw
-decore.register_component("debug_draw", {})
-
----@class system.debug_draw: system
----@field buffer table
----@field header table
----@field entities entity.debug_draw[]
----@field is_dirty boolean
-local M = {
- --interval = 0.2
-}
-
-local HASH_DRAW_TEXT = hash("draw_text")
-local MSG_DRAW_TEXT = {
- text = "",
- position = vmath.vector3(),
-}
-local DEFAULT_COLOR = palette.hex2vector4("#FF6430")
-local SIZE = 1024
-
----@return system.debug_draw
-function M.create_system()
- local system = decore.system(M, "debug_draw", { "debug_draw" })
-
- system.buffer = {
- buffer = buffer.create(SIZE * SIZE, {{
- name = hash("my_buffer"),
- type = buffer.VALUE_TYPE_UINT8,
- count = 4 -- same as channels
- }}),
- width = SIZE,
- height = SIZE,
- channels = 4,
- premultiply_alpha = false
- }
-
- system.header = {
- width = SIZE,
- height = SIZE,
- type = graphics.TEXTURE_TYPE_2D,
- format = graphics.TEXTURE_FORMAT_RGBA,
- }
-
- return system
-end
-
-
-function M:onAddToWorld()
- self.is_dirty = false
- self.world.command_debug_draw = command_debug_draw.create(self)
-end
-
-
----@param x number center
----@param y number center
----@param width number
----@param height number
----@param color vector4
-function M:draw_rectangle(x, y, width, height, color)
- local x1, y1 = self:convert_to_texture(x, y)
- color = color or DEFAULT_COLOR
-
- local x2, y2 = self:convert_to_texture(x + width, y + height)
- width = (x2 - x1)
- height = (y2 - y1)
-
- --drawpixels.rect(self.buffer, x1, y1, width, height, color.x * 255, color.y * 255, color.z * 255, color.w * 255)
-
- x1 = x1 - width / 2
- y1 = y1 - height / 2
-
- drawpixels.line(self.buffer, x1, y1, x1 + width, y1, color.x * 255, color.y * 255, color.z * 255, color.w * 255, false, 2)
- drawpixels.line(self.buffer, x1 + width, y1, x1 + width, y1 + height, color.x * 255, color.y * 255, color.z * 255, color.w * 255, false, 2)
- drawpixels.line(self.buffer, x1 + width, y1 + height, x1, y1 + height, color.x * 255, color.y * 255, color.z * 255, color.w * 255, false, 2)
- drawpixels.line(self.buffer, x1, y1 + height, x1, y1, color.x * 255, color.y * 255, color.z * 255, color.w * 255, false, 2)
-
- self.is_dirty = true
-end
-
-
-function M:draw_text(x, y, text, color)
- self.is_dirty = true
-
- local x1, y1 = self.world.command_camera:world_to_screen(x, y)
- MSG_DRAW_TEXT.position.x = x1
- MSG_DRAW_TEXT.position.y = y1
- MSG_DRAW_TEXT.text = text
-
- -- Still are best way to draw text? I can't find any other way, somehow with label factories? or gui?
- -- Probably GUI also can replace draw pixels to use just nodes? sounds good
- msg.post("@render:", HASH_DRAW_TEXT, MSG_DRAW_TEXT)
-end
-
-
-function M:draw_line(x1, y1, x2, y2, color)
- x1, y1 = self:convert_to_texture(x1, y1)
- x2, y2 = self:convert_to_texture(x2, y2)
- color = color or DEFAULT_COLOR
- drawpixels.line(self.buffer, x1, y1, x2, y2, color.x * 255, color.y * 255, color.z * 255, color.w * 255, false, 2)
- self.is_dirty = true
-end
-
-
-function M:update()
- if not self.is_dirty then
- if not self.is_cleared then
- self.is_cleared = true
- else
- return
- end
- end
-
- local camera = self.world.command_camera:get_current_camera()
- if not camera then
- return
- end
-
- local sprite_url = msg.url(nil, camera.game_object.root, "sprite")
- local texture = go.get(sprite_url, "texture0")
-
- resource.set_texture(texture, self.header, self.buffer.buffer)
-
- -- Too slow! how update and clear faster?
- drawpixels.fill(self.buffer, 0, 0, 0, 0)
-
- if self.is_dirty then
- self.is_cleared = false
- self.is_dirty = false
- end
-end
-
-
-function M:convert_to_texture(x, y)
- local camera = self.world.command_camera:get_current_camera()
- local transform = camera.transform
- local scale = transform.scale_x
- local dx = transform.position_x
- local dy = transform.position_y
-
- -- Adjust zoom and move camera
- x = (x - dx) / scale + 960
- y = (y - dy) / scale + 540
-
- -- World to texture
- x = x * SIZE / 1920
- y = y * SIZE / 1080
-
- return x, y
-end
-
-
-return M
diff --git a/system/debug_draw_transform/system_debug_draw_transform.lua b/system/debug_draw_transform/system_debug_draw_transform.lua
deleted file mode 100644
index ab35b44..0000000
--- a/system/debug_draw_transform/system_debug_draw_transform.lua
+++ /dev/null
@@ -1,57 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field debug_draw_transform boolean|nil
-
----@class entity.debug_draw_transform: entity
----@field debug_draw_transform boolean
----@field transform component.transform
-
----@class component.debug_draw_transform: boolean
-decore.register_component("debug_draw_transform", false)
-
----@class system.debug_draw_transform: system
----@field entities entity.debug_draw_transform[]
----@field is_draw_rectangle boolean
-local M = {}
-
-
----@return system.debug_draw_transform
-function M.create_system()
- return decore.system(M, "debug_draw_transform", { "debug_draw_transform", "transform" })
-end
-
-
-function M:onAddToWorld()
- self.is_draw_rectangle = true
-end
-
-
----@param dt number
-function M:update(dt)
- if not self.is_draw_rectangle then
- return
- end
-
- for index = 1, #self.entities do
- local entity = self.entities[index]
- if entity.debug_draw_transform then
- local t = entity.transform
- self.world.command_debug_draw:draw_rectangle(
- t.position_x,
- t.position_y,
- t.size_x * t.scale_x,
- t.size_y * t.scale_y
- )
-
- --self.world.command_debug_draw:draw_text(
- -- t.position_x,
- -- t.position_y + t.size_y,
- -- self.entities[index].prefab_id
- --)
- end
- end
-end
-
-
-return M
diff --git a/system/follow_cursor/system_follow_cursor.lua b/system/follow_cursor/system_follow_cursor.lua
deleted file mode 100644
index b6808d6..0000000
--- a/system/follow_cursor/system_follow_cursor.lua
+++ /dev/null
@@ -1,43 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field follow_cursor boolean|nil
-
----@class entity.follow_cursor: entity
----@field follow_cursor boolean
-
-decore.register_component("follow_cursor", false)
-
----@class system.follow_cursor: system
----@field entities entity.follow_cursor[]
-local M = {}
-
-
----@return system.follow_cursor
-function M.create_system()
- return decore.system(M, "follow_cursor", { "follow_cursor", "transform" })
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("input_event", self.process_input, self)
-end
-
-
----@param action action
-function M:process_input(action)
- if #self.entities == 0 then
- return
- end
-
- local x, y = self.world.command_camera:screen_to_world(action.screen_x, action.screen_y)
- for index = 1, #self.entities do
- local entity = self.entities[index]
- self.world.command_transform:set_position(entity, x, y)
- end
-end
-
-
-
-
-return M
diff --git a/system/fsm/command_fsm.lua b/system/fsm/command_fsm.lua
deleted file mode 100644
index 6261e5b..0000000
--- a/system/fsm/command_fsm.lua
+++ /dev/null
@@ -1,33 +0,0 @@
----@class world
----@field command_fsm system.fsm.command
-
----@class system.fsm.command
----@field fsm system.fsm
-local M = {}
-
-
----@return system.fsm.command
-function M.create(fsm)
- return setmetatable({ fsm = fsm }, { __index = M })
-end
-
-
----@param entity entity
----@param event string
-function M:trigger(entity, event)
- assert(entity.fsm, "Entity does not have a fsm component.")
- ---@cast entity entity.fsm
- self.fsm:trigger(entity, event)
-end
-
-
----@param entity entity.fsm
----@return string state Current state of the entity.
-function M:get_state(entity)
- assert(entity.fsm, "Entity does not have a fsm component.")
- ---@cast entity entity.fsm
- return entity.fsm.state
-end
-
-
-return M
diff --git a/system/fsm/system_fsm.lua b/system/fsm/system_fsm.lua
deleted file mode 100644
index 5320f78..0000000
--- a/system/fsm/system_fsm.lua
+++ /dev/null
@@ -1,78 +0,0 @@
-local decore = require("decore.decore")
-local command_fsm = require("system.fsm.command_fsm")
-
-local logger = decore.get_logger("system.fsm")
-
----@class entity
----@field fsm component.fsm|nil
-
----@class entity.fsm: entity
----@field fsm component.fsm
-
----@class component.fsm
----@field state string|nil
----@field events table>|nil
-decore.register_component("fsm")
-
----@class system.fsm.event
----@field entity entity
----@field event string
----@field state_before string
----@field state_new string
-
----@class system.fsm: system
----@field entities entity.fsm[]
-local M = {}
-
-
----@return system.fsm
-function M.create_system()
- return decore.system(M, "fsm", "fsm")
-end
-
-
-function M:onAddToWorld()
- self.world.command_fsm = command_fsm.create(self)
-end
-
-
----@param entity entity.fsm
----@param event string
-function M:trigger(entity, event)
- local next_state = self:get_next_state(entity, event)
- if next_state then
- local state_before = entity.fsm.state
- entity.fsm.state = next_state
-
- self.world.event_bus:trigger("fsm_event", {
- entity = entity,
- event = event,
- state_before = state_before,
- state_new = next_state,
- })
-
- logger:info("FSM event triggered", {
- entity = entity,
- event = event,
- state_before = state_before,
- state_new = next_state,
- })
- end
-end
-
-
----Return next state if event will be triggered.
----@param entity entity.fsm
----@param event string
----@return string|nil next_state Next state if event will be triggered. Nil if event is not allowed.
-function M:get_next_state(entity, event)
- local events = entity.fsm.events[event]
- if events then
- return events[entity.fsm.state] or events["*"] or nil
- end
-
- return nil
-end
-
-
-return M
diff --git a/system/fsm/test_fsm.lua b/system/fsm/test_fsm.lua
deleted file mode 100644
index 17866a1..0000000
--- a/system/fsm/test_fsm.lua
+++ /dev/null
@@ -1,74 +0,0 @@
-return function()
- describe("System FSM", function()
- local decore ---@type decore
- local system_fsm ---@type system.fsm
- local world ---@type world
-
- before(function()
- decore = require("decore.decore")
- system_fsm = require("system.fsm.system_fsm")
- world = decore.new_world()
- world:add(system_fsm.create_system())
- end)
-
- local get_entity = function()
- return decore.create({ fsm = {
- state = "idle",
- events = {
- ["walk"] = {
- ["idle"] = "walk",
- },
- ["die"] = {
- ["*"] = "dead",
- },
- ["idle"] = {
- ["walk"] = "idle",
- }
- }
- }})
- end
-
- it("Should init system", function()
- local entity = world:add(get_entity())
- world:refresh()
-
- assert(entity.fsm.state == "idle")
- end)
-
- it("Should transit over states", function()
- local entity = world:add(get_entity())
- world:refresh()
-
- world.command_fsm:trigger(entity, "walk")
- assert(entity.fsm.state == "walk")
- end)
-
- it("Should not transit over non existing states", function()
- local entity = world:add(get_entity())
- world:refresh()
-
- world.command_fsm:trigger(entity, "non_exists")
- assert(entity.fsm.state == "idle")
- end)
-
- it("Should trigger fsm event on state change", function()
- local entity = world:add(get_entity())
- world:refresh()
-
- world.command_fsm:trigger(entity, "walk")
- assert(world.event_bus:get_stash("fsm_event"))
- assert(#world.event_bus:get_stash("fsm_event") == 1)
- local event = world.event_bus:get_stash("fsm_event")[1]
- assert(event.entity == entity)
- assert(event.event == "walk")
- end)
-
- it("Should able to use wildcards in transitions", function()
- local entity = world:add(get_entity())
- world:refresh()
-
- world.command_fsm:trigger(entity, "die")
- assert(entity.fsm.state == "dead")
- end)
- end)
-end
diff --git a/system/game_object/game_object.version b/system/game_object/game_object.version
new file mode 100644
index 0000000..c197978
--- /dev/null
+++ b/system/game_object/game_object.version
@@ -0,0 +1 @@
+Insality:game_object@1
\ No newline at end of file
diff --git a/system/game_object/command_game_object.lua b/system/game_object/game_object_command.lua
similarity index 83%
rename from system/game_object/command_game_object.lua
rename to system/game_object/game_object_command.lua
index 1b52443..6be2ae0 100644
--- a/system/game_object/command_game_object.lua
+++ b/system/game_object/game_object_command.lua
@@ -1,5 +1,5 @@
---@class world
----@field command_game_object system.game_object.command
+---@field game_object system.game_object.command
---@class system.game_object.command
---@field game_object system.game_object
@@ -35,4 +35,12 @@ function M:set_enabled(entity, enabled)
end
end
+
+---@param id string|hash
+---@return entity|nil
+function M:get_entity(id)
+ return self.game_object.root_to_entity[id]
+end
+
+
return M
diff --git a/system/game_object/game_object_system.lua b/system/game_object/game_object_system.lua
new file mode 100644
index 0000000..95b26a2
--- /dev/null
+++ b/system/game_object/game_object_system.lua
@@ -0,0 +1,309 @@
+local decore = require("decore.decore")
+local command_game_object = require("system.game_object.game_object_command")
+
+---@class entity
+---@field game_object component.game_object|nil
+---@field hidden boolean|nil
+
+---@class entity.game_object: entity
+---@field game_object component.game_object
+---@field transform component.transform
+---@field hidden boolean|nil
+
+-- { is_factory = true, factory_url = "/entities#window_settings" }
+---@class component.game_object
+---@field root string|hash
+---@field object table
+---@field sprite_url string|nil # "sprite" as default one. Will try be pick up from the root
+---@field factory_url string|nil
+---@field is_slice9 boolean|nil
+---@field slice9_offset vector3|nil
+---@field remove_delay number|nil
+---@field is_factory boolean|nil
+---@field runtime_created boolean|nil
+---@field object_scheme table|nil Ex: { "root", "circle", "cross" }. Required to set a struct of children game objects to fill inside object field. Used only if entity spawned from the collection with entitty.script
+decore.register_component("game_object")
+decore.register_component("hidden", false)
+
+
+---@class system.game_object: system
+---@field entities entity.game_object[]
+---@field root_to_entity table
+local M = {}
+
+M.DEBUG_PANEL_UPDATE_MEMORY_LIMIT = 2048
+M.DEBUG_PANEL_POSTWRAP_MEMORY_LIMIT = 2048
+M.MSG_INIT_ENTITY = hash("init_entity")
+
+local TEMP_VECTOR = vmath.vector3(0, 0, 0)
+local TEMP_QUAT = vmath.quat(0, 0, 0, 1)
+local VECTOR3_ONE = vmath.vector3(1, 1, 1)
+local ROOT_URL = hash("/root")
+local HASH_POSITION = hash("position")
+local HASH_SIZE = hash("size")
+local HASH_SCALE = hash("scale")
+local HASH_EULER_Z = hash("euler.z")
+local sin = math.sin
+local cos = math.cos
+local rad = math.rad
+
+---@return system.game_object
+function M.create()
+ local self = decore.system(M, "game_object")
+ self.filter = decore.ecs.requireAll("game_object", "transform", decore.ecs.rejectAll("hidden"))
+
+ self.root_to_entity = {}
+
+ return self
+end
+
+
+function M:onAddToWorld()
+ self.world.game_object = command_game_object.create(self)
+end
+
+
+function M:postWrap()
+ self.world.event_bus:process("transform_event", self.process_transform_event, self)
+end
+
+
+---@param entity entity.game_object
+function M:onAdd(entity)
+ local is_already_exists = entity.game_object.root or entity.game_object.object
+ if is_already_exists then
+ self:refresh_root(entity)
+ return
+ end
+
+ local object = self:create_object(entity)
+ local root = object[ROOT_URL]
+ entity.game_object.root = root
+ entity.game_object.object = object
+ entity.game_object.runtime_created = true
+ self:refresh_root(entity)
+end
+
+
+---@param entity entity.game_object
+function M:onRemove(entity)
+ local remove_delay = entity.game_object.remove_delay
+
+ if not remove_delay then
+ self:remove_entity(entity)
+ else
+ timer.delay(remove_delay, false, function()
+ self:remove_entity(entity)
+ end)
+ end
+end
+
+
+---@param entity entity.game_object
+function M:remove_entity(entity)
+ local root = entity.game_object.root
+ if root then
+ self.root_to_entity[root] = nil
+
+ if go.exists(root)then
+ go.delete(root, false)
+ entity.game_object.root = nil
+ end
+ end
+
+ local object = entity.game_object.object
+ if object then
+ for key, node in pairs(object) do
+ local related_entity = self.root_to_entity[node]
+ if related_entity then
+ self.world:removeEntity(related_entity)
+ else
+ -- TODO: it removes also a childs of the related entity
+ -- And I can get errors like panthera trying to play on deleted object
+ -- Right before it will be deleted with upper removeEntity
+ if go.exists(node) then
+ go.delete(node, false)
+ object[key] = nil
+ end
+ end
+ end
+ end
+end
+
+
+---@param events system.transform.event[]
+function M:process_transform_event(events)
+ for i = 1, #events do
+ local event = events[i]
+ local entity = event.entity
+ local transform = entity.transform
+ local game_object = entity.game_object
+
+ if not self.indices[entity] or not game_object then
+ -- skip
+ else
+ local root = game_object.root
+ if root then
+ local delay = event.delay or 0
+
+ if event.is_position_changed then
+ TEMP_VECTOR.x = transform.position_x
+ TEMP_VECTOR.y = transform.position_y
+ --TEMP_VECTOR.z = transform.position_z
+ TEMP_VECTOR.z = self:get_position_z(transform)
+ if event.animate_time then
+ local easing = event.easing or go.EASING_OUTSINE
+ go.animate(root, HASH_POSITION, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time, delay)
+ else
+ go.set_position(TEMP_VECTOR, root)
+ end
+ end
+
+ if event.is_rotation_changed then
+ if event.animate_time then
+ local easing = event.easing or go.EASING_OUTSINE
+ go.animate(root, HASH_EULER_Z, go.PLAYBACK_ONCE_FORWARD, transform.rotation, easing, event.animate_time, delay)
+ else
+ go.set(root, HASH_EULER_Z, transform.rotation)
+ end
+ end
+
+ if event.is_scale_changed then
+ TEMP_VECTOR.x = transform.scale_x
+ TEMP_VECTOR.y = transform.scale_y
+ TEMP_VECTOR.z = transform.scale_z
+ if event.animate_time then
+ local easing = event.easing or go.EASING_OUTSINE
+ go.animate(root, HASH_SCALE, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time, delay)
+ else
+ go.set_scale(TEMP_VECTOR, root)
+ end
+ end
+
+ if game_object.is_slice9 then
+ local component_url = M.get_component_url(entity, game_object.sprite_url or "/root#sprite")
+
+ TEMP_VECTOR.x = transform.size_x
+ TEMP_VECTOR.y = transform.size_y
+ if event.animate_time then
+ local easing = event.easing or go.EASING_OUTSINE
+ go.animate(component_url, HASH_SIZE, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time, delay)
+ else
+ go.set(component_url, HASH_SIZE, TEMP_VECTOR)
+ end
+ end
+ end
+ end
+ end
+end
+
+
+function M:refresh_transform(entity)
+ local root = entity.game_object.root
+ if not root then
+ return
+ end
+
+ go.set_position(entity.transform.position, root)
+ go.set_scale(entity.transform.scale, root)
+
+ TEMP_QUAT.z = sin(rad(entity.transform.rotation) * 0.5)
+ TEMP_QUAT.w = cos(rad(entity.transform.rotation) * 0.5)
+ go.set_rotation(TEMP_QUAT, root)
+end
+
+
+local PROPERTIES = { [ROOT_URL] = { is_spawn_by_entity = true } }
+---@param entity entity.game_object
+---@return table
+function M:create_object(entity)
+ TEMP_VECTOR.x = entity.transform.position_x
+ TEMP_VECTOR.y = entity.transform.position_y
+ TEMP_VECTOR.z = self:get_position_z(entity.transform)
+
+ if entity.game_object.is_factory then
+ local object = factory.create(entity.game_object.factory_url, TEMP_VECTOR, nil, PROPERTIES[ROOT_URL], entity.transform.scale_x)
+ return { [ROOT_URL] = object }
+ else
+ return collectionfactory.create(entity.game_object.factory_url, TEMP_VECTOR, nil, PROPERTIES, entity.transform.scale_x)
+ end
+end
+
+
+---@param t component.transform
+---@return number
+function M:get_position_z(t)
+ return -t.position_y / 10000 + t.position_x / 100000 + t.position_z / 10
+end
+
+
+---@param entity entity.game_object
+function M:refresh_root(entity)
+ local root = entity.game_object.root
+ if not root then
+ return
+ end
+
+ if entity.game_object.is_slice9 then
+ local sprite_id = entity.game_object.sprite_url or "sprite"
+ local component_url = M.get_component_url(entity, sprite_id)
+ local slice9_offset = entity.game_object.slice9_offset
+ TEMP_VECTOR.x = entity.transform.size_x + (slice9_offset and slice9_offset.x or 0)
+ TEMP_VECTOR.y = entity.transform.size_y + (slice9_offset and slice9_offset.y or 0)
+ go.set(component_url, HASH_SIZE, TEMP_VECTOR)
+ go.set(root, HASH_SCALE, VECTOR3_ONE)
+ else
+ TEMP_VECTOR.x = entity.transform.scale_x
+ TEMP_VECTOR.y = entity.transform.scale_y
+ TEMP_VECTOR.z = entity.transform.scale_z
+ go.set(root, HASH_SCALE, TEMP_VECTOR)
+ end
+
+ go.set(root, HASH_EULER_Z, entity.transform.rotation)
+
+ TEMP_VECTOR.x = entity.transform.position_x
+ TEMP_VECTOR.y = entity.transform.position_y
+ TEMP_VECTOR.z = self:get_position_z(entity.transform)
+ go.set(root, HASH_POSITION, TEMP_VECTOR)
+
+ self.root_to_entity[root] = entity
+end
+
+
+---Split string by separator
+---@param s string
+---@param sep string
+function M.split(s, sep)
+ sep = sep or "%s"
+ local t = {}
+ local i = 1
+ for str in string.gmatch(s, "([^" .. sep .. "]+)") do
+ t[i] = str
+ i = i + 1
+ end
+ return t
+end
+
+
+---@param entity entity
+---@param sprite_url string
+function M.get_component_url(entity, sprite_url)
+ local splitted = M.split(sprite_url, "#")
+ local object_id, component_id = splitted[1], splitted[2] or "sprite"
+ -- If target starts with #, then it's a component id
+ if string.sub(sprite_url, 1, 1) == "#" then
+ object_id = nil
+ component_id = splitted[1]
+ end
+
+ local target_url = msg.url(nil, object_id, component_id)
+ if entity.game_object and entity.game_object.object then
+ local object_url = entity.game_object.object[object_id]
+ target_url = msg.url(nil, object_url, component_id)
+ end
+
+ return target_url
+end
+
+
+return M
diff --git a/system/game_object/system_game_object.lua b/system/game_object/system_game_object.lua
deleted file mode 100644
index 0a77962..0000000
--- a/system/game_object/system_game_object.lua
+++ /dev/null
@@ -1,264 +0,0 @@
-local decore = require("decore.decore")
-local command_game_object = require("system.game_object.command_game_object")
-
----@class entity
----@field game_object component.game_object|nil
----@field hidden boolean|nil
-
----@class entity.game_object: entity
----@field game_object component.game_object
----@field transform component.transform
----@field hidden boolean|nil
-
----@class component.game_object
----@field root string|hash
----@field object table
----@field factory_url string|nil
----@field is_slice9 boolean|nil
----@field remove_delay number|nil
----@field is_factory boolean|nil
----@field object_scheme table @For example: {["root"] = true}, used for find objects from already placed game object (not spawned by game object system)
----@field position vector3|nil
----@field rotation quaternion|nil
-decore.register_component("game_object")
-decore.register_component("hidden", false)
-
-
----@class go_position_setter
----@field add fun(self, entity, position, rotation)
----@field remove fun(self, entity)
----@field update fun(self)
-
----@class system.game_object: system
----@field entities entity.game_object[]
----@field root_to_entity table
-local M = {}
-
-M.DEBUG_PANEL_UPDATE_MEMORY_LIMIT = 2048
-M.DEBUG_PANEL_POSTWRAP_MEMORY_LIMIT = 2048
-
-local TEMP_VECTOR = vmath.vector3(0, 0, 0)
-local TEMP_QUAT = vmath.quat(0, 0, 0, 1)
-local VECTOR3_ONE = vmath.vector3(1, 1, 1)
-local ROOT_URL = hash("/root")
-local HASH_POSITION = hash("position")
-local HASH_SIZE = hash("size")
-local HASH_SCALE = hash("scale")
-local HASH_EULER_Z = hash("euler.z")
-local sin = math.sin
-local cos = math.cos
-local rad = math.rad
-
----@return system.game_object
-function M.create()
- local system = setmetatable(decore.ecs.system(), { __index = M })
- system.filter = decore.ecs.requireAll("game_object", "transform", decore.ecs.rejectAll("hidden"))
- system.id = "game_object"
- system.root_to_entity = {}
-
- return system
-end
-
-
-function M:onAddToWorld()
- self.world.command_game_object = command_game_object.create(self)
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("transform_event", self.process_transform_event, self)
-end
-
-
-
----@param entity entity.game_object
-function M:onAdd(entity)
- local is_already_exists = entity.game_object.root or entity.game_object.object
- if is_already_exists then
- self.root_to_entity[entity.game_object.root] = entity
- return
- end
-
-
- local object = self:create_object(entity)
- local root = object[ROOT_URL]
- entity.game_object.root = root
- entity.game_object.object = object
-
- if root then
- if entity.game_object.is_slice9 then
- local sprite_url = msg.url(nil, root, "sprite")
- TEMP_VECTOR.x = entity.transform.size_x
- TEMP_VECTOR.y = entity.transform.size_y
- go.set(sprite_url, HASH_SIZE, TEMP_VECTOR)
- go.set(root, HASH_SCALE, VECTOR3_ONE)
- else
- TEMP_VECTOR.x = entity.transform.scale_x
- TEMP_VECTOR.y = entity.transform.scale_y
- TEMP_VECTOR.z = entity.transform.scale_z
- go.set(root, HASH_SCALE, TEMP_VECTOR)
- end
-
- go.set(root, HASH_EULER_Z, entity.transform.rotation)
-
- self.root_to_entity[root] = entity
- end
-end
-
-
----@param entity entity.game_object
-function M:onRemove(entity)
- local remove_delay = entity.game_object.remove_delay
-
- if not remove_delay then
- self:remove_entity(entity)
- else
- timer.delay(remove_delay, false, function()
- self:remove_entity(entity)
- end)
- end
-end
-
-
----@param entity entity.game_object
-function M:remove_entity(entity)
- local root = entity.game_object.root
- if root then
- self.root_to_entity[root] = nil
-
- if go.exists(root) then
- go.delete(root, false)
- entity.game_object.root = nil
- end
- end
-
- local object = entity.game_object.object
- if object then
- for key, node in pairs(object) do
- local related_entity = self.root_to_entity[node]
- if related_entity then
- self.world:removeEntity(related_entity)
- else
- -- TODO: it removes also a childs of the related entity
- -- And I can get errors like panthera trying to play on deleted object
- -- Right before it will be deleted with upper removeEntity
- if go.exists(node) then
- go.delete(node, false)
- object[key] = nil
- end
- end
- end
- end
-end
-
-
----@param event system.transform.event
-function M:process_transform_event(event)
- local entity = event.entity
- local transform = entity.transform
- local game_object = entity.game_object
-
- if not decore.is_alive(self, entity) then
- return
- end
-
- if not game_object or entity.physics then
- return
- end
-
- local root = game_object.root
- if not root then
- return
- end
-
- if event.is_position_changed then
- TEMP_VECTOR.x = transform.position_x
- TEMP_VECTOR.y = transform.position_y
- TEMP_VECTOR.z = transform.position_z
- if event.animate_time then
- local easing = event.easing or go.EASING_OUTSINE
- go.animate(root, HASH_POSITION, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time)
- else
- go.set_position(TEMP_VECTOR, root)
- end
- end
-
- if event.is_rotation_changed then
- if event.animate_time then
- local easing = event.easing or go.EASING_OUTSINE
- go.animate(root, HASH_EULER_Z, go.PLAYBACK_ONCE_FORWARD, transform.rotation, easing, event.animate_time)
- else
- go.set(root, HASH_EULER_Z, transform.rotation)
- end
- end
-
- if event.is_scale_changed then
- TEMP_VECTOR.x = transform.scale_x
- TEMP_VECTOR.y = transform.scale_y
- TEMP_VECTOR.z = transform.scale_z
- if event.animate_time then
- local easing = event.easing or go.EASING_OUTSINE
- go.animate(root, HASH_SCALE, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time)
- else
- go.set_scale(TEMP_VECTOR, root)
- end
- end
-
- if game_object.is_slice9 then
- local sprite_url = msg.url(nil, root, "sprite")
- TEMP_VECTOR.x = transform.size_x
- TEMP_VECTOR.y = transform.size_y
- if event.animate_time then
- local easing = event.easing or go.EASING_OUTSINE
- go.animate(sprite_url, HASH_SIZE, go.PLAYBACK_ONCE_FORWARD, TEMP_VECTOR, easing, event.animate_time)
- else
- go.set(sprite_url, HASH_SIZE, TEMP_VECTOR)
- end
- end
-end
-
-
-function M:refresh_transform(entity)
- local root = entity.game_object.root
- if not root then
- return
- end
-
- go.set_position(entity.transform.position, root)
- go.set_scale(entity.transform.scale, root)
-
- TEMP_QUAT.z = sin(rad(entity.transform.rotation) * 0.5)
- TEMP_QUAT.w = cos(rad(entity.transform.rotation) * 0.5)
- go.set_rotation(TEMP_QUAT, root)
-end
-
-
-local PROPERTIES = {
- [ROOT_URL] = {
- is_factory_object = true
- }
-}
----@param entity entity.game_object
----@return table
-function M:create_object(entity)
- TEMP_VECTOR.x = entity.transform.position_x
- TEMP_VECTOR.y = entity.transform.position_y
- TEMP_VECTOR.z = self:get_position_z(entity.transform)
-
- if entity.game_object.is_factory then
- local object = factory.create(entity.game_object.factory_url, TEMP_VECTOR, nil, PROPERTIES[ROOT_URL], entity.transform.scale_x)
- return { [ROOT_URL] = object }
- else
- return collectionfactory.create(entity.game_object.factory_url, TEMP_VECTOR, nil, PROPERTIES, entity.transform.scale_x)
- end
-end
-
-
----@param t component.transform
----@return number
-function M:get_position_z(t)
- return -t.position_y / 10000 + t.position_x / 100000 + t.position_z / 10
-end
-
-
-return M
diff --git a/system/health/command_health.lua b/system/health/command_health.lua
deleted file mode 100644
index c1bd50b..0000000
--- a/system/health/command_health.lua
+++ /dev/null
@@ -1,25 +0,0 @@
----@class world
----@field command_health system.health.command
-
----@class system.health.command
----@field health system.health
-local M = {}
-
-
----@param health system.health
----@return system.health.command
-function M.create(health)
- return setmetatable({ health = health }, { __index = M })
-end
-
-
----@param entity entity
----@param damage number
-function M:apply_damage(entity, damage)
- assert(entity.health, "Entity does not have a health component.")
- ---@cast entity entity.health
- self.health:apply_damage(entity, damage)
-end
-
-
-return M
diff --git a/system/health/component_health.script b/system/health/component_health.script
deleted file mode 100644
index d55d3f4..0000000
--- a/system/health/component_health.script
+++ /dev/null
@@ -1,9 +0,0 @@
-go.property("health", 100)
-
-local component = require("decore.component")
-
-function init(self)
- component.init("health", {
- health = self.health
- })
-end
\ No newline at end of file
diff --git a/system/health/system_health.lua b/system/health/system_health.lua
deleted file mode 100644
index c333484..0000000
--- a/system/health/system_health.lua
+++ /dev/null
@@ -1,77 +0,0 @@
-local decore = require("decore.decore")
-local command_health = require("system.health.command_health")
-
----@class entity
----@field health component.health|nil
-
----@class entity.health: entity
----@field health component.health
-
----@class component.health
----@field max_health number
----@field current_health number|nil
----@field remove_on_death boolean|nil
-decore.register_component("health", {
- max_health = 1,
-})
-
----@class system.health.event
----@field entity entity
----@field damage number
-
----@class system.health: system
----@field entities entity.health[]
-local M = {}
-
-
----@return system.health
-function M.create_system()
- return decore.system(M, "health", "health")
-end
-
-
-function M:onAddToWorld()
- self.world.command_health = command_health.create(self)
- self.world.event_bus:set_merge_policy("health_event", M.event_merge_policy)
-end
-
-
----@param entity entity.health
-function M:onAdd(entity)
- local health = entity.health
- health.current_health = health.max_health
-end
-
-
----@param entity entity.health
-function M:apply_damage(entity, damage)
- local health = entity.health
- health.current_health = math.max(0, health.current_health - damage)
- self.world.event_bus:trigger("health_event", {
- entity = entity,
- damage = damage,
- })
-
- if health.current_health == 0 and health.remove_on_death then
- self.world:removeEntity(entity)
- end
-end
-
-
----@param event system.health.event
----@param events system.health.event[]
----@return boolean
-function M.event_merge_policy(event, events)
- for index = #events, 1, -1 do
- local compare_event = events[index]
- if compare_event.entity == event.entity then
- compare_event.damage = compare_event.damage + event.damage
- return true
- end
- end
-
- return false
-end
-
-
-return M
diff --git a/system/health/test_health.lua b/system/health/test_health.lua
deleted file mode 100644
index a170220..0000000
--- a/system/health/test_health.lua
+++ /dev/null
@@ -1,46 +0,0 @@
-return function()
- describe("System Health", function()
- local decore --- @type decore
- local world ---@type world
- local system_health ---@type system.health
-
- before(function()
- decore = require("decore.decore")
- system_health = require("system.health.system_health")
-
- world = decore.new_world()
- world:add(system_health.create_system())
- end)
-
- it("Should set current health", function()
- local entity = decore.create({ health = { max_health = 100 } })
- world:add(entity)
- world:refresh()
-
- assert(entity.health.current_health == 100)
- end)
-
- it("Should catch health command", function()
- local entity = decore.create({ health = { max_health = 100 } })
- world:add(entity)
- world:refresh()
-
- world.command_health:apply_damage(entity, 10)
- assert(entity.health.current_health == 90)
- end)
-
- it("Should produce health_event", function()
- local entity = decore.create({ health = { max_health = 100 } })
- world:add(entity)
- world:refresh()
-
- world.command_health:apply_damage(entity, 10)
-
- assert(world.event_bus:get_stash("health_event"))
- assert(#world.event_bus:get_stash("health_event") == 1)
- local event = world.event_bus:get_stash("health_event")[1]
- assert(event.entity == entity)
- assert(event.damage == 10)
- end)
- end)
-end
diff --git a/system/input/input_system.lua b/system/input/input_system.lua
deleted file mode 100644
index f02f55b..0000000
--- a/system/input/input_system.lua
+++ /dev/null
@@ -1,36 +0,0 @@
-local decore = require("decore.decore")
-
----@class world
----@field input system.input
-
----@class system.input.event: action
-
----@class system.input: system
-local M = {}
-
-
----@return system.input
-function M.create()
- return decore.system(M, "input")
-end
-
-
----@protected
-function M:onAddToWorld()
- msg.post(".", "acquire_input_focus")
- self.world.input = self
-end
-
-
----@public
----@param action_id hash
----@param action action
----@return boolean
-function M:on_input(action_id, action)
- action.action_id = action_id
- self.world.event_bus:trigger("input_event", action)
- return false
-end
-
-
-return M
diff --git a/system/movement_controller/system_movement_controller.lua b/system/movement_controller/system_movement_controller.lua
deleted file mode 100644
index 2833fde..0000000
--- a/system/movement_controller/system_movement_controller.lua
+++ /dev/null
@@ -1,115 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field movement_controller component.movement_controller|nil
-
----@class entity.movement_controller: entity
----@field movement_controller component.movement_controller
-
----@class component.movement_controller
----@field speed number
----@field movement_x number @Runtime
----@field movement_y number @Runtime
-decore.register_component("movement_controller", {
- speed = 1,
- movement_x = 0,
- movement_y = 0,
-})
-
----@class system.movement_controller: system
----@field entities entity.movement_controller[]
----@field input_keys table
-local M = {}
-
-local ACTION_ID_TO_SIDE = {
- [hash("key_w")] = { y = 1, id = "up" },
- [hash("key_s")] = { y = -1, id = "down" },
- [hash("key_a")] = { x = -1, id = "left" },
- [hash("key_d")] = { x = 1, id = "right" },
- [hash("key_up")] = { y = 1, id = "up" },
- [hash("key_down")] = { y = -1, id = "down" },
- [hash("key_left")] = { x = -1, id = "left" },
- [hash("key_right")] = { x = 1, id = "right" },
-}
-
----@static
----@return system.movement_controller
-function M.create()
- local self = decore.processing_system(M, "movement_controller", { "movement_controller", "transform" })
- self.input_keys = {}
- return self
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("input_event", self.process_input_event, self)
-end
-
-
----@param input_event system.input.event
-function M:process_input_event(input_event)
- local action_id = input_event.action_id
- local side = ACTION_ID_TO_SIDE[action_id]
- if not side then
- return
- end
-
- for index = 1, #self.entities do
- self:apply_input_event(self.entities[index], input_event)
- end
-end
-
-
----@param entity entity.movement_controller
----@param input_event system.input.event
-function M:apply_input_event(entity, input_event)
- local action_id = input_event.action_id
- local action = input_event
- local movement_controller = entity.movement_controller
-
- local side = ACTION_ID_TO_SIDE[action_id]
- if action.pressed then
- self.input_keys[side.id] = true
- end
- if action.released then
- self.input_keys[side.id] = nil
- end
-
- do -- direction_x
- movement_controller.movement_x = 0
- if self.input_keys["left"] then
- movement_controller.movement_x = movement_controller.movement_x - 1
- end
- if self.input_keys["right"] then
- movement_controller.movement_x = movement_controller.movement_x + 1
- end
- end
-
- do -- direction_y
- movement_controller.movement_y = 0
- if self.input_keys["up"] then
- movement_controller.movement_y = movement_controller.movement_y + 1
- end
- if self.input_keys["down"] then
- movement_controller.movement_y = movement_controller.movement_y - 1
- end
- end
-end
-
-
-function M:process(entity, dt)
- local movement_controller = entity.movement_controller
-
- local speed = movement_controller.speed
- local movement_x = movement_controller.movement_x
- local movement_y = movement_controller.movement_y
-
- if movement_x ~= 0 or movement_y ~= 0 then
- local force_x = movement_x * speed * dt * 60
- local force_y = movement_y * speed * dt * 60
- self.world.command_transform:add_position(entity, force_x, force_y)
- end
-end
-
-
-return M
diff --git a/system/nakama/command_nakama.lua b/system/nakama/command_nakama.lua
deleted file mode 100644
index 242179a..0000000
--- a/system/nakama/command_nakama.lua
+++ /dev/null
@@ -1,16 +0,0 @@
----@class world
----@field command_nakama command.nakama
-
----@class command.nakama
----@field nakama system.nakama
-local M = {}
-
-
----@param nakama system.nakama
----@return command.nakama
-function M.create(nakama)
- return setmetatable({ nakama = nakama }, { __index = M })
-end
-
-
-return M
diff --git a/system/nakama/nakama_core.lua b/system/nakama/nakama_core.lua
deleted file mode 100644
index 5aa8841..0000000
--- a/system/nakama/nakama_core.lua
+++ /dev/null
@@ -1,309 +0,0 @@
-local defold = require("nakama.engine.defold")
-local nakama = require("nakama.nakama")
-local nakama_session = require("nakama.session")
-local log = require("log.log")
-local uuid = require("libs.uuid")
-
-local logger = log.get_logger("nakama")
-
-local M = {}
-
-local SESSION_FILE_PATH = sys.get_save_file(sys.get_config_string("project.title", "nakama"), "nakama_session")
-
----@class nakama.client
-
----@class nakama.session
----@field expires number
----@field token string
-
----@class nakama.socket_result.match
----@field match nakama.match
----@field error string|nil
-
----@class nakama.socket
----@field create fun(client)
----@field connect fun(callback)
----@field send fun(message, callback)
----@field on_disconnect fun(fn)
----@field channel_join fun(target, type, persistence, hidden, callback)
----@field channel_leave fun(channel_id, callback)
----@field channel_message_send fun(channel_id, content, callback)
----@field channel_message_remove fun(channel_id, message_id, callback)
----@field channel_message_update fun(channel_id, message_id, content, callback)
----@field match_data_send fun(match_id, op_code, data, presences, reliable, callback)
----@field match_create fun(name, callback): nakama.socket_result.match
----@field match_join fun(match_id, token, metadata, callback)
----@field match_leave fun(match_id, callback)
----@field matchmaker_add fun(min_count, max_count, query, string_properties, numeric_properties, count_multiple, callback)
----@field matchmaker_remove fun(ticket, callback)
----@field party_create fun(open, max_size, callback)
----@field party_join fun(party_id, callback)
----@field party_leave fun(party_id, callback)
----@field party_promote fun(party_id, presence, callback)
----@field party_accept fun(party_id, presence, callback)
----@field party_remove fun(party_id, presence, callback)
----@field party_close fun(party_id, callback)
----@field party_join_request_list fun(party_id, callback)
----@field party_matchmaker_add fun(party_id, min_count, max_count, query, string_properties, numeric_properties, count_multiple, callback)
----@field party_matchmaker_remove fun(party_id, ticket, callback)
----@field party_data_send fun(party_id, op_code, data, callback)
----@field status_follow fun(user_ids, usernames, callback)
----@field status_unfollow fun(user_ids, callback)
----@field status_update fun(status, callback)
----@field on_channel_presence_event fun(fn)
----@field on_match_presence_event fun(callback: fun(message: nakama.socket_result.on_match_presence.event))
----@field on_match_data fun(callback: fun(message: nakama.socket_result.match_data.event))
----@field on_match fun(fn)
----@field on_matchmaker_matched fun(fn)
----@field on_notifications fun(fn)
----@field on_party_presence_event fun(fn)
----@field on_party fun(fn)
----@field on_party_data fun(fn)
----@field on_party_join_request fun(fn)
----@field on_party_leader fun(fn)
----@field on_status_presence_event fun(fn)
----@field on_status fun(fn)
----@field on_stream_data fun(fn)
----@field on_error fun(fn)
----@field on_channel_message fun(fn)
-
----@class nakama.socket_result.on_match_presence.event
----@field match_presence_event nakama.socket_result.on_match_presence
-
----@class nakama.socket_result.on_match_presence
----@field match_id string
----@field joins nakama.presence[]
----@field leaves nakama.presence[]
-
----@class nakama.socket_result.match_data.event
----@field match_data nakama.socket_result.match_data
-
----@class nakama.socket_result.match_data
----@field match_id string
----@field op_code number
----@field data string
----@field presence nakama.presence
-
----@class nakama.presence
----@field username string
----@field session_id string
----@field user_id string
-
----@class nakama.match
----@field match_id string
----@field self nakama.presence
----@field presences nakama.presence[]
----@field size number
-
----@class nakama.session_file
----@field token string|nil
----@field player_id string|nil
-local SESSION = sys.load(SESSION_FILE_PATH) or {
- token = nil,
- player_id = nil
-}
-
-
----@param str string
----@param ending string
-local function string_ends(str, ending)
- return ending == "" or str:sub(-#ending) == ending
-end
-
-
----@param entity entity.nakama
----@param callback function|nil
-function M.connect(entity, callback)
- local token = SESSION.token
- local n = entity.nakama
- n.client = n.client or M.create_nakama_client(n.server_key, n.server_host, n.server_port, n.use_ssl)
- n.socket = n.socket or M.create_nakama_socket(n.client)
-
- if n.is_connected then
- logger:error("Call server connect while already connected")
- return
- end
-
- n.is_connecting = true
- nakama.sync(function()
- token = M.check_new_user(entity, token)
-
- if M.is_token_empty(token) then
- logger:warn("Can't auth on server")
- n.is_connecting = false
- return nil
- end
-
- token = M.check_session(entity, token)
-
- if M.is_token_empty(token) then
- logger:warn("Can't auth on server, drop the connection flow")
- n.is_connecting = false
- return nil
- end
-
- M.socket_connect(entity, callback)
- end)
-end
-
----Return nakama client config
----@param server_key string
----@param host string
----@param port number
----@param is_ssl boolean
----@return table nakama client config
-function M.create_nakama_client(server_key, host, port, is_ssl)
- local config = {
- host = host,
- port = port,
- use_ssl = is_ssl,
- username = server_key,
- password = "",
- engine = defold,
- timeout = 10, -- connection timeout in seconds
- }
- return nakama.create_client(config)
-end
-
-
----Return nakama socket client
----@param client nakama.client
----@return nakama.socket
-function M.create_nakama_socket(client)
- return nakama.create_socket(client)
-end
-
-
----Check and update if required the nakama session
----@param entity entity.nakama
-function M.refresh_session(entity)
- local n = entity.nakama
- local session = n.session
- if not session or M.is_session_expire_soon(session) then
- logger:debug("Session token will expire soon, refresh")
- nakama.sync(function()
- M.auth(entity)
- end)
- end
-end
-
-
----Check and update if required the nakama session
----@param entity entity.nakama
----@param token string|nil
-function M.check_session(entity, token)
- local session = nakama_session.create({ token = token })
- if M.is_session_expire_soon(session) then
- logger:info("Session has expired, call reauth")
- token = M.auth(entity)
- else
- logger:debug("Session token is valid")
- M.set_session_token(entity, session)
- end
- return token
-end
-
-
----@param entity entity.nakama
----@param callback function|nil
-function M.socket_connect(entity, callback)
- local n = entity.nakama
- local socket_connected, socket_error = n.socket.connect()
- n.is_connecting = false
-
- if socket_connected then
- logger:info("Socket connected")
- n.is_connected = true
-
- if callback then
- callback()
- end
- else
- logger:error("Socket error", { error = socket_error })
- M.set_session_token(entity, nil)
-
- if string_ends(socket_error, "401") then
- logger:info("Token expired, reset")
- M.connect(entity, callback)
- end
- end
-end
-
-
----@param entity entity.nakama
----@param session nakama.session|nil
-function M.set_session_token(entity, session)
- local n = entity.nakama
-
- if session and session.token then
- SESSION.token = session.token
- sys.save(SESSION_FILE_PATH, SESSION)
-
- nakama.set_bearer_token(n.client, session.token)
- n.session = session
- else
- SESSION.token = ""
- sys.save(SESSION_FILE_PATH, SESSION)
-
- n.session = nil
- end
-end
-
-
----@param token string|nil
-function M.is_token_empty(token)
- return not token or token == ""
-end
-
-
----@param session nakama.session
-function M.is_session_expire_soon(session)
- local time_to_expire = (session.expires - os.time())
- return time_to_expire < 300 -- 5 minutes
-end
-
-
----@param entity entity.nakama
-function M.auth(entity)
- local player_id = M.get_player_id()
- logger:debug("Auth started", { id = player_id })
-
- local client = entity.nakama.client
- local session = nakama.authenticate_device(client, player_id, nil, true, player_id)
- if not session.token then
- logger:info("Auth failed, no session")
- return nil
- end
-
- M.set_session_token(entity, session)
-
- logger:debug("Authenticated", { token = session.token, user_id = session.user_id })
- return session.token
-end
-
-
----@param entity entity.nakama
-function M.check_new_user(entity, token)
- if M.is_token_empty(token) then
- logger:debug("Auth for new user")
- token = M.auth(entity)
- end
-
- return token
-end
-
-
-function M.get_player_id()
- -- TODO Test
- SESSION.player_id = uuid()
-
- if not SESSION.player_id then
- SESSION.player_id = uuid()
- sys.save(SESSION_FILE_PATH, SESSION)
- end
-
- return SESSION.player_id
-end
-
-
-return M
diff --git a/system/nakama/system_nakama.lua b/system/nakama/system_nakama.lua
deleted file mode 100644
index fe2ee91..0000000
--- a/system/nakama/system_nakama.lua
+++ /dev/null
@@ -1,54 +0,0 @@
-local log = require("log.log")
-local nakama_core = require("system.nakama.nakama_core")
-local decore = require("decore.decore")
-
-local logger = log.get_logger("system.nakama")
-
----@class entity
----@field nakama component.nakama|nil
-
----@class entity.nakama: entity
----@field nakama component.nakama
-
----@class component.nakama
----@field server_host string
----@field server_port number
----@field check_connection_timer number
----@field reconnect_attempts_time number[]
----@field server_key string
----@field http_key string
----@field encryption_key string
----@field refresh_encryption_key string
----@field debug_log boolean
----@field use_ssl boolean
----@field client nakama.client|nil
----@field socket nakama.socket|nil
----@field session nakama.session|nil
----@field is_connected boolean
----@field is_connecting boolean
-
----@class system.nakama: system
-local M = {}
-
-
----@static
----@return system.nakama
-function M.create_system()
- return decore.system(M, "nakama", "nakama")
-end
-
-
----@param entity entity.nakama
-function M:onAdd(entity)
- nakama_core.connect(entity, function()
- self:on_connected()
- end)
-end
-
-
-function M:on_connected()
- logger:trace("on_connected")
-end
-
-
-return M
diff --git a/system/on_key_released/system_on_key_released.lua b/system/on_key_released/system_on_key_released.lua
deleted file mode 100644
index 04681b9..0000000
--- a/system/on_key_released/system_on_key_released.lua
+++ /dev/null
@@ -1,77 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field on_key_released component.on_key_released|nil
-
----@class entity.on_key_released: entity
----@field on_key_released component.on_key_released
-
----@class component.on_key_released
----@field key_to_command_json string|nil @JSON string table>. Will override key_to_command if exists
----@field key_to_command table>|nil @ table>.
-decore.register_component("on_key_released")
-
----@class system.on_key_released: system
----@field entities entity.on_key_released[]
----@field hash_to_string table
-local M = {}
-
-
----@return system.on_key_released
-function M.create_system()
- local system = decore.system(M, "on_key_released", "on_key_released")
- system.hash_to_string = {}
-
- return system
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("input_event", self.process_input_event, self)
-end
-
-
----@param entity entity.on_key_released
-function M:onAdd(entity)
- local on_key_released = entity.on_key_released
-
- for key_id, key_command in pairs(on_key_released) do
- local hash_id = hash(key_id)
- if not self.hash_to_string[hash_id] then
- self.hash_to_string[hash_id] = key_id
- end
- end
-end
-
-
----@param input_event system.input.event
-function M:process_input_event(input_event)
- if not input_event.released then
- return
- end
-
- local key_id = self.hash_to_string[input_event.action_id]
- if not key_id then
- return
- end
-
- local entities = self.entities
- for index = 1, #entities do
- local entity = entities[index]
- self:on_input_released(entity, input_event.action_id, input_event)
- end
-end
-
-
----@param entity entity.on_key_released
-function M:on_input_released(entity, action_id, action)
- local on_key_released = entity.on_key_released
-
- local key_id = self.hash_to_string[action_id]
- if on_key_released[key_id] then
- decore.call_command(self.world, on_key_released[key_id])
- end
-end
-
-
-return M
diff --git a/system/on_spawn_command/component_on_spawn_command.script b/system/on_spawn_command/component_on_spawn_command.script
deleted file mode 100644
index 8e1a4d0..0000000
--- a/system/on_spawn_command/component_on_spawn_command.script
+++ /dev/null
@@ -1,9 +0,0 @@
-go.property("command_label", true)
-
-local component = require("decore.component")
-
-function init(self)
- component.init("on_spawn_command", {
- command_label = self.command_label
- })
-end
\ No newline at end of file
diff --git a/system/on_spawn_command/entity_on_spawn_command.go b/system/on_spawn_command/entity_on_spawn_command.go
deleted file mode 100644
index a93d8e4..0000000
--- a/system/on_spawn_command/entity_on_spawn_command.go
+++ /dev/null
@@ -1,38 +0,0 @@
-components {
- id: "entity"
- component: "/decore/entity.script"
- properties {
- id: "prefab_id"
- value: "on_spawn_command"
- type: PROPERTY_TYPE_HASH
- }
-}
-components {
- id: "component_on_spawn_command"
- component: "/system/on_spawn_command/component_on_spawn_command.script"
-}
-embedded_components {
- id: "command"
- type: "label"
- data: "size {\n"
- " x: 900.0\n"
- " y: 100.0\n"
- "}\n"
- "outline {\n"
- " w: 0.0\n"
- "}\n"
- "shadow {\n"
- " w: 0.0\n"
- "}\n"
- "pivot: PIVOT_W\n"
- "text: \"command_game_gui, set_text, rocket\\n"
- "\"\n"
- " \"\"\n"
- "font: \"/druid/fonts/text_regular.font\"\n"
- "material: \"/core/utils/editor_only_label-df.material\"\n"
- ""
- scale {
- x: 2.0
- y: 2.0
- }
-}
diff --git a/system/on_spawn_command/entity_on_spawn_command.lua b/system/on_spawn_command/entity_on_spawn_command.lua
deleted file mode 100644
index 5d18d5b..0000000
--- a/system/on_spawn_command/entity_on_spawn_command.lua
+++ /dev/null
@@ -1,7 +0,0 @@
----@return entity.on_spawn_command
-return {
- game_object = {},
- on_spawn_command = {
- command_label = true
- }
-}
\ No newline at end of file
diff --git a/system/on_spawn_command/system_on_spawn_command.lua b/system/on_spawn_command/system_on_spawn_command.lua
deleted file mode 100644
index 7c5c1a2..0000000
--- a/system/on_spawn_command/system_on_spawn_command.lua
+++ /dev/null
@@ -1,44 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field on_spawn_command component.on_spawn_command|nil
-
----@class entity.on_spawn_command: entity
----@field on_spawn_command component.on_spawn_command
-decore.register_component("on_spawn_command")
-
----@class component.on_spawn_command
----@field command any[]
----@field command_label boolean
-
----@class system.on_spawn_command: system
----@field entities entity.on_spawn_command[]
-local M = {}
-
-
----@static
----@return system.on_spawn_command
-function M.create_system()
- return decore.system(M, "on_spawn_command", { "on_spawn_command" })
-end
-
-
----@param entity entity.on_spawn_command
-function M:onAdd(entity)
- if entity.on_spawn_command.command then
- decore.call_command(self.world, entity.on_spawn_command.command)
- end
-
- if entity.on_spawn_command.command_label and entity.game_object then
- local root = entity.game_object.root
- local label_url = msg.url(nil, root, "command")
- local command = decore.parse_command(label.get_text(label_url))
- if command then
- decore.call_command(self.world, command)
- end
- end
-end
-
-
-
-return M
diff --git a/system/panthera/command_panthera.lua b/system/panthera/command_panthera.lua
deleted file mode 100644
index 718847a..0000000
--- a/system/panthera/command_panthera.lua
+++ /dev/null
@@ -1,74 +0,0 @@
-local decore = require("decore.decore")
-local panthera = require("panthera.panthera")
-
----@class world
----@field command_panthera system.panthera.command
-
----@class system.panthera.command
----@field panthera system.panthera
-local M = {}
-
-
----@return system.panthera.command
-function M.create(panthera_decore)
- return setmetatable({ panthera = panthera_decore }, { __index = M })
-end
-
-
----@param entity entity
----@param animation_state panthera.animation
----@param animation_id string
-function M:play_state(entity, animation_state, animation_id)
- if not decore.is_alive(self.panthera, entity) then
- return
- end
-
- panthera.play(animation_state, animation_id)
-end
-
-
----@param entity entity
----@param animation_id string
----@param speed number|nil
----@param is_loop boolean|nil
-function M:play(entity, animation_id, speed, is_loop)
- local p = entity.panthera
- assert(p, "Entity doesn't have panthera component")
-
- if not decore.is_alive(self.panthera, entity) then
- return
- end
-
- panthera.play(p.animation_state, animation_id, {
- is_loop = is_loop or false,
- speed = speed or 1,
- callback = function(animation_path)
- -- If default animation, run it after the current animation
- if p.default_animation then
- panthera.play(p.animation_state, p.default_animation, {
- is_loop = p.is_loop or false,
- speed = p.speed or 1,
- })
- end
- end
- })
-end
-
-
----@param entity entity
----@param animation_id string
----@param progress number
-function M:set_progress(entity, animation_id, progress)
- local p = entity.panthera
- assert(p, "Entity doesn't have panthera component")
-
- if not decore.is_alive(self.panthera, entity) then
- return
- end
-
- local time = panthera.get_duration(p.animation_state, animation_id)
- panthera.set_time(p.animation_state, animation_id, time * progress)
-end
-
-
-return M
diff --git a/system/panthera/component_panthera.script b/system/panthera/component_panthera.script
deleted file mode 100644
index bcd7ed0..0000000
--- a/system/panthera/component_panthera.script
+++ /dev/null
@@ -1,23 +0,0 @@
-local component = require("decore.component")
-go.property("default_animation", hash(""))
-go.property("speed", 1)
-go.property("is_loop", true)
-go.property("play_on_start", true)
-
-
-
-function init(self)
- local EMPTY_HASH = hash("")
-
- local animation = self.default_animation
- if animation == EMPTY_HASH then
- animation = nil
- end
-
- component.init("panthera", {
- default_animation = animation,
- speed = self.speed,
- play_on_start = self.play_on_start,
- is_loop = self.is_loop,
- })
-end
\ No newline at end of file
diff --git a/system/panthera/system_panthera.lua b/system/panthera/system_panthera.lua
deleted file mode 100644
index 91c9457..0000000
--- a/system/panthera/system_panthera.lua
+++ /dev/null
@@ -1,97 +0,0 @@
-local decore = require("decore.decore")
-local panthera = require("panthera.panthera")
-
-local command_panthera = require("system.panthera.command_panthera")
-
----@class entity
----@field panthera component.panthera|nil
-
----@class entity.panthera: entity
----@field panthera component.panthera
----@field game_object component.game_object
----@field transform component.transform
-
----@class component.panthera
----@field animation_path string|table
----@field animation_state panthera.animation|nil
----@field default_animation string
----@field speed number
----@field is_loop boolean|nil
----@field play_on_start boolean|nil
----@field play_on_remove string|nil Play animation on entity remove
-decore.register_component("panthera", {
- default_animation = "default",
-})
-
----@class system.panthera: system
----@field entities entity.panthera[]
-local M = {}
-
-
----@return system.panthera
-function M.create_system()
- local system = decore.system(M, "panthera")
- system.filter = decore.ecs.requireAll("panthera", "game_object", decore.ecs.rejectAll("hidden"))
-
- return system
-end
-
-
----@private
-function M:postWrap()
- self.world.event_bus:process("window_event", self.process_window_event, self)
-end
-
-
-function M:onAddToWorld()
- self.world.command_panthera = command_panthera.create(self)
-end
-
-
----@param entity entity.panthera
-function M:onAdd(entity)
- local p = entity.panthera
-
- local animation_state
- if entity.game_object.object then
- animation_state = panthera.create_go(p.animation_path, nil, entity.game_object.object)
- else
- animation_state = panthera.create_go(p.animation_path, nil, { ["/"] = entity.game_object.root })
- end
-
- if animation_state then
- p.animation_state = animation_state
- p.animation_path = animation_state.animation_path
-
- -- TODO: This one should be in update?
- if p.play_on_start then
- panthera.play(p.animation_state, p.default_animation, {
- is_loop = p.is_loop or false,
- speed = p.speed or 1
- })
- end
- end
-end
-
-
----@param entity entity.panthera
-function M:onRemove(entity)
- local p = entity.panthera
- panthera.stop(p.animation_state)
-
- if p.play_on_remove then
- panthera.play(p.animation_state, p.play_on_remove)
- end
-end
-
-
----@private
----@param window_event system.window_event.event
-function M:process_window_event(window_event)
- if window_event == window.WINDOW_EVENT_FOCUS_GAINED then
- panthera.reload_animation()
- end
-end
-
-
-return M
diff --git a/system/physics/command_physics.lua b/system/physics/command_physics.lua
deleted file mode 100644
index 6e2ec25..0000000
--- a/system/physics/command_physics.lua
+++ /dev/null
@@ -1,27 +0,0 @@
----@class world
----@field command_physics system.physics.command
-
----@class system.physics.command
----@field physics system.physics
-local M = {}
-
-
----@param physics system.physics
----@return system.physics.command
-function M.create(physics)
- return setmetatable({ physics = physics }, { __index = M })
-end
-
-
----@param entity entity
----@param force_x number|nil
----@param force_y number|nil
-function M:add_force(entity, force_x, force_y)
- assert(entity.physics, "entity must have physics component")
- ---@cast entity entity.physics
-
- self.physics:add_force(entity, force_x, force_y)
-end
-
-
-return M
diff --git a/system/physics/component_physics.script b/system/physics/component_physics.script
deleted file mode 100644
index 8c20d2c..0000000
--- a/system/physics/component_physics.script
+++ /dev/null
@@ -1,10 +0,0 @@
-go.property("velocity", vmath.vector3(0, 0, 0))
-
-local component = require("decore.component")
-
-function init(self)
- component.init("physics", {
- velocity_x = self.velocity.x,
- velocity_y = self.velocity.y,
- })
-end
\ No newline at end of file
diff --git a/system/physics/system_physics.lua b/system/physics/system_physics.lua
deleted file mode 100644
index d2364f3..0000000
--- a/system/physics/system_physics.lua
+++ /dev/null
@@ -1,99 +0,0 @@
-local decore = require("decore.decore")
-local command_physics = require("system.physics.command_physics")
-
----@class entity
----@field physics component.physics|nil
-
----@class entity.physics: entity
----@field physics component.physics
----@field game_object component.game_object
----@field transform component.transform
-
----@class component.physics
----@field box2d_body b2Body
----@field collisionobject_url url
----@field velocity_x number
----@field velocity_y number
-decore.register_component("physics", {
- velocity_x = 0,
- velocity_y = 0,
- gravity_y = 0,
-})
-
----@class system.physics: system
----@field entities entity.physics[]
-local M = {}
-
-local TEMP_VECTOR = vmath.vector3()
-
----@return system.physics
-function M.create_system()
- return decore.processing_system(M, "physics", { "physics", "game_object", "transform" })
-end
-
-
-function M:onAddToWorld()
- self.world.command_physics = command_physics.create(self)
-end
-
-
----@param entity entity.physics
-function M:onAdd(entity)
- local collisionobject_url = msg.url(nil, entity.game_object.root, "collisionobject")
- entity.physics.collisionobject_url = collisionobject_url
- entity.physics.box2d_body = b2d.get_body(collisionobject_url)
-
- local body = entity.physics.box2d_body
- TEMP_VECTOR.x = entity.physics.velocity_x
- TEMP_VECTOR.y = entity.physics.velocity_y
- b2d.body.set_linear_velocity(body, TEMP_VECTOR)
-end
-
-
-function M:onRemove(entity)
- entity.physics.box2d_body = nil
- entity.physics.collisionobject_url = nil
-end
-
-
----@param entity entity.physics
----@param dt number
-function M:process(entity, dt)
- local body = entity.physics.box2d_body
- local is_awake = b2d.body.is_awake(body)
- if not is_awake then
- return
- end
-
- -- Is it faster?
- local position = b2d.body.get_position(body)
- local position_x = position.x
- local position_y = position.y
-
- local transform = entity.transform
- if position_x ~= transform.position_x or position_y ~= transform.position_y then
- self.world.command_transform:set_position(entity, position_x, position_y, transform.position_z)
- end
-
- local velocity = b2d.body.get_linear_velocity(body)
- entity.physics.velocity_x = velocity.x
- entity.physics.velocity_y = velocity.y
-end
-
-
----@param entity entity.physics
----@param force_x number|nil
----@param force_y number|nil
-function M:add_force(entity, force_x, force_y)
- if not decore.is_alive(self, entity) then
- return
- end
-
- local body = entity.physics.box2d_body
- TEMP_VECTOR.x = force_x or 0
- TEMP_VECTOR.y = force_y or 0
- b2d.body.apply_force_to_center(body, TEMP_VECTOR)
-end
-
-
-return M
diff --git a/system/platformer_controller/system_platformer_controller.lua b/system/platformer_controller/system_platformer_controller.lua
deleted file mode 100644
index ac7d390..0000000
--- a/system/platformer_controller/system_platformer_controller.lua
+++ /dev/null
@@ -1,104 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field platformer_controller component.platformer_controller|nil
-
----@class entity.platformer_controller: entity
----@field platformer_controller component.platformer_controller
----@field physics component.physics
-
----@class component.platformer_controller
----@field direction_x number
----@field direction_y number
-decore.register_component("platformer_controller", {
- direction_x = 0,
- direction_y = 0,
-})
-
----@class system.platformer_controller: system
----@field entities entity.platformer_controller[]
----@field input_keys table
-local M = {}
-
-local KEY_A = hash("key_a")
-local KEY_D = hash("key_d")
-local KEY_LEFT = hash("key_left")
-local KEY_RIGHT = hash("key_right")
-local ACTION_ID_TO_SIDE = {
- [KEY_A] = { x = -1 },
- [KEY_D] = { x = 1 },
- [KEY_LEFT] = { x = -1 },
- [KEY_RIGHT] = { x = 1 },
-}
-local ACTION_JUMP = hash("key_space")
-
----@static
----@return system.platformer_controller
-function M.create_system()
- local system = decore.processing_system(M, "platformer_controller", { "platformer_controller", "platformer_physics" })
- system.input_keys = {}
- return system
-end
-
-function M:postWrap()
- self.world.event_bus:process("input_event", self.process_input_event, self)
-end
-
-
----@param input_event system.input.event
-function M:process_input_event(input_event)
- local action_id = input_event.action_id
- local side = ACTION_ID_TO_SIDE[action_id]
- if side or action_id == ACTION_JUMP then
- for index = 1, #self.entities do
- self:apply_input_event(self.entities[index], input_event)
- end
- end
-end
-
-
----@param entity entity.platformer_controller
----@param input_event system.input.event
-function M:apply_input_event(entity, input_event)
- local action_id = input_event.action_id
- if not action_id then
- return
- end
-
- local action = input_event
- local platformer_controller = entity.platformer_controller
-
- local side = ACTION_ID_TO_SIDE[action_id]
- if action.pressed and side then
- self.input_keys[action_id] = true
- end
- if action.released and side then
- self.input_keys[action_id] = nil
- end
-
- do -- direction_x
- platformer_controller.direction_x = 0
- if self.input_keys[KEY_A] or self.input_keys[KEY_LEFT] then
- platformer_controller.direction_x = platformer_controller.direction_x - 1
- end
- if self.input_keys[KEY_D] or self.input_keys[KEY_RIGHT] then
- platformer_controller.direction_x = platformer_controller.direction_x + 1
- end
- end
-
- if action_id == ACTION_JUMP and action.pressed then
- self.world.command_platformer_physics:jump(entity)
- end
-end
-
-
----@param entity entity.platformer_controller
----@param dt number
-function M:process(entity, dt)
- local platformer_controller = entity.platformer_controller
- self.world.command_platformer_physics:move_vertical(entity, platformer_controller.direction_x)
- self.world.command_platformer_physics:move_horizontal(entity, platformer_controller.direction_y)
-end
-
-
-return M
diff --git a/system/platformer_physics/command_platformer_physics.lua b/system/platformer_physics/command_platformer_physics.lua
deleted file mode 100644
index 0528967..0000000
--- a/system/platformer_physics/command_platformer_physics.lua
+++ /dev/null
@@ -1,49 +0,0 @@
----@class world
----@field command_platformer_physics system.platformer_physics.command
-
----@class system.platformer_physics.command
----@field platformer_physics system.platformer_physics
-local M = {}
-
-
----@static
----@return system.platformer_physics.command
-function M.create(platformer_physics)
- return setmetatable({ platformer_physics = platformer_physics }, { __index = M })
-end
-
-
----@param entity entity
----@param power number Can be zero, means no input
-function M:move_vertical(entity, power)
- assert(entity.platformer_physics, "entity must have platformer_physics component")
- ---@cast entity entity.platformer_physics
-
- local pf = entity.platformer_physics
- pf.target_velocity_x = power * pf.speed
-
- if self.platformer_physics:sign(pf.target_velocity_x) > 0 and pf.contact_timers[3] > 0 then
- pf.target_velocity_x = 0
- end
- if self.platformer_physics:sign(pf.target_velocity_x) < 0 and pf.contact_timers[1] > 0 then
- pf.target_velocity_x = 0
- end
-end
-
-
-function M:move_horizontal(entity, power)
- assert(entity.platformer_physics, "entity must have platformer_physics component")
- ---@cast entity entity.platformer_physics
-
- local pf = entity.platformer_physics
- pf.target_velocity_y = power * pf.speed
-end
-
-
----@param entity entity
-function M:jump(entity)
- entity.platformer_physics.desired_jump = true
-end
-
-
-return M
diff --git a/system/platformer_physics/component_platformer_physics.script b/system/platformer_physics/component_platformer_physics.script
deleted file mode 100644
index 205915e..0000000
--- a/system/platformer_physics/component_platformer_physics.script
+++ /dev/null
@@ -1,52 +0,0 @@
-go.property("gravity_x", 0)
-go.property("gravity_y", -5000)
-go.property("gravity_multiplier", 1)
-go.property("speed", 1000)
-go.property("acceleration", 2000)
-go.property("deceleration", 5000)
-go.property("air_acceleration", 5000)
-go.property("air_deceleration", 1000)
-go.property("turn_speed", 8000)
-go.property("air_turn_speed", 8000)
-go.property("air_control", 8000)
-go.property("air_brake", 8000)
-
-go.property("time_to_jump_apex", 0.3)
-go.property("jump_height", 280)
-go.property("jump_duration", 3)
-go.property("downward_movement_multiplier", 1)
-go.property("is_instant_movement", false)
-go.property("is_double_jump", true)
-go.property("coyote_time", 0)
-go.property("jump_buffer", 0)
-go.property("terminal_velocity", 0)
-go.property("jump_cutoff", 2.3) -- 1 is no cutoff
-
-local component = require("decore.component")
-
-function init(self)
- component.init("platformer_physics", {
- gravity_x = self.gravity_x,
- gravity_y = self.gravity_y,
- gravity_multiplier = self.gravity_multiplier,
- speed = self.speed,
- acceleration = self.acceleration,
- deceleration = self.deceleration,
- air_acceleration = self.air_acceleration,
- air_deceleration = self.air_deceleration,
- turn_speed = self.turn_speed,
- air_turn_speed = self.air_turn_speed,
- time_to_jump_apex = self.time_to_jump_apex,
- jump_height = self.jump_height,
- downward_movement_multiplier = self.downward_movement_multiplier,
- is_instant_movement = self.is_instant_movement,
- jump_duration = self.jump_duration,
- is_double_jump = self.is_double_jump,
- coyote_time = self.coyote_time,
- jump_buffer = self.jump_buffer,
- terminal_velocity = self.terminal_velocity,
- air_control = self.air_control,
- air_brake = self.air_brake,
- jump_cutoff = self.jump_cutoff
- })
-end
\ No newline at end of file
diff --git a/system/platformer_physics/system_platformer_physics.lua b/system/platformer_physics/system_platformer_physics.lua
deleted file mode 100644
index e7153f9..0000000
--- a/system/platformer_physics/system_platformer_physics.lua
+++ /dev/null
@@ -1,304 +0,0 @@
-local decore = require("decore.decore")
-
-local command_platformer_physics = require("system.platformer_physics.command_platformer_physics")
-
----@class entity
----@field platformer_physics component.platformer_physics|nil
-
----@class entity.platformer_physics: entity
----@field platformer_physics component.platformer_physics
----@field transform component.transform
-
----@class component.platformer_physics
----@field gravity_x number
----@field gravity_y number
----@field gravity_multiplier number
----@field gravity_scale number
----@field ground_timer number
----@field contact_timers number[]
----@field velocity_x number
----@field velocity_y number
----@field target_velocity_x number
----@field target_velocity_y number
----@field speed number
----@field acceleration number
----@field deceleration number
----@field air_acceleration number
----@field air_deceleration number
----@field turn_speed number
----@field air_turn_speed number
----@field desired_jump boolean
----@field time_to_jump_apex number
----@field jump_height number
----@field jump_speed number
----@field downward_movement_multiplier number
----@field is_instant_movement boolean
----@field jump_duration number
----@field is_double_jump boolean
----@field coyote_time number
----@field jump_buffer number
----@field terminal_velocity number
----@field air_control number
----@field air_brake number
----@field jump_cutoff boolean
----@field correction vector3
-decore.register_component("platformer_physics", {
- gravity_x = 0,
- gravity_y = 0,
- gravity_multiplier = 1,
- gravity_scale = 1,
- ground_timer = 0,
- contact_timers = { 0, 0, 0, 0 },
-
- velocity_x = 0,
- velocity_y = 0,
- target_velocity_x = 0,
- target_velocity_y = 0,
-
- speed = 10,
- acceleration = 52,
- deceleration = 52,
- air_acceleration = 52,
- air_deceleration = 52,
- turn_speed = 80,
- air_turn_speed = 80,
-
- desired_jump = false,
- time_to_jump_apex = 0.3,
- jump_height = 7.3,
- jump_speed = 0,
- upward_movement_multiplier = 1,
- downward_movement_multiplier = 6.17,
-
- jump_buffer_counter = 0,
- coyote_time_counter = 0,
-
- jump_cutoff = false,
- jump_duration = 0,
- is_double_jump = false,
- coyote_time = 0,
- jump_buffer = 0,
- terminal_velocity = 0,
- air_control = 0,
- air_brake = 0,
-
- correction = vmath.vector3(),
-})
-
----@class system.platformer_physics: system
----@field entities entity.platformer_physics[]
-local M = {}
-
-local RAYCAST_GROUPS = { hash("level") }
-local FROM, TO = vmath.vector3(), vmath.vector3()
-
----@static
----@return system.platformer_physics
-function M.create_system()
- return decore.system(M, "platformer_physics", { "platformer_physics", "transform" })
-end
-
-
-function M:onAddToWorld()
- self.world.command_platformer_physics = command_platformer_physics.create(self)
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("collision_event", self.process_collision_event, self)
-end
-
-
-function M:fixed_update(dt)
- for index = 1, #self.entities do
- local entity = self.entities[index]
- local pf = entity.platformer_physics
-
- if pf.desired_jump then
- self:jump(entity)
- return
- end
-
- if pf.velocity_y == 0 then
- pf.gravity_multiplier = 1
- end
- if pf.velocity_y < -0.01 then
- pf.gravity_multiplier = pf.downward_movement_multiplier
- end
-
- pf.ground_timer = math.max(0, pf.ground_timer - dt)
- for i = 1, #pf.contact_timers do
- pf.contact_timers[i] = math.max(0, pf.contact_timers[i] - dt)
- end
-
- -- apply the compensation to the player character
- local corr = pf.correction
- self.world.command_transform:add_position(entity, corr.x, corr.y, corr.z)
- pf.correction.x = 0
- pf.correction.y = 0
- pf.correction.z = 0
-
- -- update velocity
- self:update_velocity(entity, dt)
- end
-end
-
-
----@param entity entity.platformer_physics
-function M:update_velocity(entity, dt)
- local t = entity.transform
- local pf = entity.platformer_physics
-
- local is_on_ground = pf.contact_timers[4] > 0
- local is_on_left_wall = pf.contact_timers[1] > 0
- local is_on_ceiling = pf.contact_timers[2] > 0
- local is_on_right_wall = pf.contact_timers[3] > 0
-
- -- Acceleration
- local acceleration = is_on_ground and pf.acceleration or pf.air_acceleration
- local deceleration = is_on_ground and pf.deceleration or pf.air_deceleration
- local turn_speed = is_on_ground and pf.turn_speed or pf.air_turn_speed
-
- local max_speed_change = deceleration * dt
- if pf.target_velocity_x ~= 0 then
- if self:sign(pf.target_velocity_x) ~= self:sign(pf.velocity_x) then
- max_speed_change = turn_speed * dt
- else
- max_speed_change = acceleration * dt
- end
- end
-
- pf.velocity_x = self:step(pf.velocity_x, pf.target_velocity_x, max_speed_change)
-
- local gravity_y = (-2 * pf.jump_height) / (pf.time_to_jump_apex * pf.time_to_jump_apex)
- pf.gravity_scale = (gravity_y / pf.gravity_y) * pf.gravity_multiplier
-
- pf.velocity_y = pf.velocity_y + pf.gravity_y * dt
-
- if is_on_ground then
- pf.velocity_y = math.max(pf.velocity_y, 0)
- end
- if is_on_ceiling then
- pf.velocity_y = math.min(pf.velocity_y, 0)
- end
- if is_on_left_wall then
- pf.velocity_x = math.max(pf.velocity_x, 0)
- end
- if is_on_right_wall then
- pf.velocity_x = math.min(pf.velocity_x, 0)
- end
-
- local velocity_x = pf.velocity_x
- local velocity_y = pf.velocity_y
- if velocity_x ~= 0 or velocity_y ~= 0 then
- local target_x = t.position_x + velocity_x * dt
- local target_y = t.position_y + velocity_y * dt
- self.world.command_transform:set_position(entity, target_x, target_y)
-
- if entity.game_object then
- self.world.command_game_object:refresh_transform(entity)
- end
- end
-end
-
-
----@param entity entity.platformer_physics
-function M:jump(entity)
- local pf = entity.platformer_physics
-
- if pf.contact_timers[4] > 0 then
- pf.desired_jump = false
- pf.jump_speed = math.sqrt(-2 * pf.gravity_y * pf.jump_height * pf.gravity_scale)
-
- if pf.velocity_y > 0 then
- pf.jump_speed = math.max(pf.jump_speed - pf.velocity_y, 0)
- elseif pf.velocity_y < 0 then
- pf.jump_speed = pf.jump_speed + math.abs(pf.velocity_y)
- end
-
- pf.velocity_y = pf.velocity_y + pf.jump_speed
- end
-
- pf.desired_jump = false
-end
-
-
-function M:sign(x)
- if x > 0 then
- return 1
- elseif x < 0 then
- return -1
- else
- return 0
- end
-end
-
-
----Move value from current to target value with step amount
----@param current number Current value
----@param target number Target value
----@param step number Step amount
----@return number New value
-function M:step(current, target, step)
- if current < target then
- return math.min(current + step, target)
- else
- return math.max(target, current - step)
- end
-end
-
-
----@param collision_event system.collision.event
----@param entity entity.platformer_physics
-function M:process_collision_event(collision_event, entity)
- local contact_point_event = collision_event.contact_point_event
-
- if contact_point_event then
- -- project the correction vector onto the contact normal
- -- (the correction vector is the 0-vector for the first contact point)
- local pf = entity.platformer_physics
- local normal = collision_event.contact_point_event.b.normal
- if not normal then
- normal = collision_event.contact_point_event.a.normal
- end
-
- if not normal or not pf then
- return
- end
-
- local distance = collision_event.contact_point_event.distance
-
- local proj = vmath.dot(pf.correction, normal)
- -- calculate the compensation we need to make for this contact point
- local comp = (distance - proj) * normal
- -- add it to the correction vector
- pf.correction = pf.correction + comp
-
- -- check if the normal points enough up to consider the player standing on the ground
- -- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
- pf.ground_timer = normal.y > 0.7 and 0.06 or 0
-
- pf.contact_timers[1] = normal.x > 0.7 and 0.06 or pf.contact_timers[1]
- pf.contact_timers[2] = normal.y < -0.7 and 0.06 or pf.contact_timers[2]
- pf.contact_timers[3] = normal.x < -0.7 and 0.06 or pf.contact_timers[3]
- pf.contact_timers[4] = normal.y > 0.7 and 0.06 or pf.contact_timers[4]
-
- local velocity = vmath.vector3(0)
- -- project the velocity onto the normal
- proj = vmath.dot(velocity, normal)
- -- if the projection is negative, it means that some of the velocity points towards the contact point
- if proj < 0 then
- -- remove that component in that case
- local c = proj * normal
- pf.velocity_x = pf.velocity_x - c.x
- pf.velocity_y = pf.velocity_y - c.y
- end
-
- if pf.contact_timers[4] > 0 then
- pf.velocity_y = math.max(0, pf.velocity_y)
- end
- end
-end
-
-
-return M
diff --git a/system/quadtree/command_quadtree.lua b/system/quadtree/command_quadtree.lua
deleted file mode 100644
index 63f0ad8..0000000
--- a/system/quadtree/command_quadtree.lua
+++ /dev/null
@@ -1,24 +0,0 @@
----@class world
----@field command_quadtree system.quadtree.command
-
----@class system.quadtree.command
----@field quadtree system.quadtree
-local M = {}
-
-
----@return system.quadtree.command
-function M.create(quadtree)
- return setmetatable({ quadtree = quadtree }, { __index = M })
-end
-
-
----@param entity entity
----@param radius number
-function M:get_neighbors(entity, radius, callback)
- assert(entity.transform, "entity must have transform component")
- ---@cast entity entity.transform
- return self.quadtree:get_neighbors(entity, radius, callback)
-end
-
-
-return M
diff --git a/system/quadtree/quadtree.lua b/system/quadtree/quadtree.lua
deleted file mode 100644
index 82ec313..0000000
--- a/system/quadtree/quadtree.lua
+++ /dev/null
@@ -1,367 +0,0 @@
----@class quadtree_state
----@field x number
----@field y number
----@field width number
----@field height number
----@field data any
----@field quadtree quadtree
-
----@class quadtree
----@field split_threshold_count number
----@field max_levels number
----@field level number
----@field x number
----@field y number
----@field width number
----@field height number
----@field objects table -- Dictionary for O(1) access
----@field objects_count number -- Number of objects in this node
----@field len number -- Total number of objects in the quadtree
----@field sectors quadtree[] -- The 4 child nodes, [1] = bottom left, [2] = top left, [3] = top right, [4] = bottom right
----@field parent quadtree|nil -- The parent node
-local M = {}
-
----Create new quadtree object. Inner objects are also quadtrees
----@param split_threshold_count number
----@param max_levels number
----@param level number|nil
----@param x number|nil
----@param y number|nil
----@param width number|nil
----@param height number|nil
----@return quadtree
-function M.create(split_threshold_count, max_levels, level, x, y, width, height)
- local self = setmetatable({
- split_threshold_count = split_threshold_count or 4,
- max_levels = max_levels or 5,
- level = level or 0,
- x = x or 0,
- y = y or 0,
- width = width or 0,
- height = height or 0,
- objects = nil,
- objects_count = 0,
- len = 0, -- Total number of objects
- sectors = nil,
- }, { __index = M })
- return self
-end
-
----Insert entity into quadtree
----@param data any
----@param x number
----@param y number
----@param width number
----@param height number
----@return quadtree_state
-function M:insert(data, x, y, width, height)
- local quadtree_state = { x = x, y = y, width = width, height = height, data = data }
- self:insert_state(quadtree_state)
- return quadtree_state
-end
-
-
----Insert a quadtree_state into the quadtree
----@param quadtree_state quadtree_state
----@return boolean success
-function M:insert_state(quadtree_state)
- quadtree_state.quadtree = self
- self.objects = self.objects or {}
-
- -- If sectors exist, insert into sector
- if self.sectors then
- local x, y = quadtree_state.x, quadtree_state.y
- local width, height = quadtree_state.width, quadtree_state.height
- local index = self:get_index(x, y, width, height)
- if index ~= 0 then
- return self.sectors[index]:insert_state(quadtree_state)
- end
- end
-
- local is_inserted = false
- if not self.objects[quadtree_state] then
- is_inserted = true
- self.objects[quadtree_state] = true
- self.objects_count = self.objects_count + 1
-
- if not self.sectors then
- if self.objects_count > self.split_threshold_count and self.level < self.max_levels then
- self:subdivide()
- end
- end
- end
-
- return is_inserted
-end
-
-
-function M:union()
- if self.sectors and self:count_objects() - self.objects_count == 0 then
- self.sectors = nil
- end
-end
-
-
----Remove entity from quadtree
----@param quadtree_state quadtree_state
----@return boolean success
-function M:remove(quadtree_state)
- -- If no sector or object is not in sector
- if self.objects and self.objects[quadtree_state] then
- self.objects[quadtree_state] = nil
- self.objects_count = self.objects_count - 1
- --if self.parent then
- -- self.parent:remove_empty_sectors()
- --end
- return true
- end
-
- if self.sectors then
- local index = self:get_index(quadtree_state.x, quadtree_state.y, quadtree_state.width, quadtree_state.height)
- if index ~= 0 then
- return self.sectors[index]:remove(quadtree_state)
- end
- end
-
- return false
-end
-
----Subdivide the node into four child nodes
-function M:subdivide()
- local half_width = self.width / 2
- local half_height = self.height / 2
- local x = self.x
- local y = self.y
- local level = self.level + 1
-
- -- Bottom left
- self.sectors = {}
-
- self.sectors[1] = M.create(self.split_threshold_count, self.max_levels, level, x, y, half_width, half_height)
- self.sectors[1].parent = self
- -- Top left
- self.sectors[2] = M.create(self.split_threshold_count, self.max_levels, level, x, y + half_height, half_width, half_height)
- self.sectors[2].parent = self
- -- Top right
- self.sectors[3] = M.create(self.split_threshold_count, self.max_levels, level, x + half_width, y + half_height, half_width, half_height)
- self.sectors[3].parent = self
- -- Bottom right
- self.sectors[4] = M.create(self.split_threshold_count, self.max_levels, level, x + half_width, y, half_width, half_height)
- self.sectors[4].parent = self
-
- -- Split objects into sectors
- for obj in pairs(self.objects) do
- local index = self:get_index(obj.x, obj.y, obj.width, obj.height)
- if index ~= 0 then
- self.objects[obj] = nil
- self.objects_count = self.objects_count - 1
- obj.quadtree = nil
-
- self.sectors[index]:insert_state(obj)
- end
- end
-end
-
----Determine which node the object belongs to
----@param x number
----@param y number
----@param width number
----@param height number
----@return number index The 1 is bottom left, 2 is top left, 3 is top right, 4 is bottom right. 0 if object cannot completely fit within a child node
-function M:get_index(x, y, width, height)
- local mid_x = self.x + (self.width / 2)
- local mid_y = self.y + (self.height / 2)
-
- local is_left = x + width <= mid_x
- local is_right = x >= mid_x
- local is_bottom = y + height <= mid_y
- local is_top = y >= mid_y
-
- if is_left then
- if is_bottom then
- return 1
- elseif is_top then
- return 2
- end
- elseif is_right then
- if is_top then
- return 3
- elseif is_bottom then
- return 4
- end
- end
-
- return 0
-end
-
----Update entity in quadtree
----@param quadtree_state quadtree_state
----@param x number
----@param y number
----@param width number
----@param height number
-function M:update(quadtree_state, x, y, width, height)
- local parent_quadtree = self:get_state_to_put(x, y, width, height)
- local is_quadtree_state_changed = quadtree_state.quadtree ~= parent_quadtree
-
- if not is_quadtree_state_changed then
- quadtree_state.x = x
- quadtree_state.y = y
- quadtree_state.width = width
- quadtree_state.height = height
- return
- end
-
- local prev_quadtree = quadtree_state.quadtree
- prev_quadtree:remove(quadtree_state)
-
- quadtree_state.x = x
- quadtree_state.y = y
- quadtree_state.width = width
- quadtree_state.height = height
- parent_quadtree:insert_state(quadtree_state)
-end
-
-
-function M:remove_empty_sectors()
- if not self.sectors then
- return
- end
-
- local is_sectors_empty = true
- for i = 1, 4 do
- if self.sectors[i] and self.sectors[i]:count_objects() > 0 then
- is_sectors_empty = false
- break
- end
- end
-
- if is_sectors_empty then
- self.sectors = nil
- end
-end
-
----Get the appropriate node to place the object
----@param x number
----@param y number
----@param width number
----@param height number
----@return quadtree
-function M:get_state_to_put(x, y, width, height)
- if self.sectors then
- local index = self:get_index(x, y, width, height)
- if index ~= 0 then
- return self.sectors[index]:get_state_to_put(x, y, width, height)
- end
- end
- return self
-end
-
----Retrieve all entities within a given rectangular area
----@param callback fun(quadtree_state: quadtree_state)
----@param x number
----@param y number
----@param w number
----@param h number
-function M:retrieve(callback, x, y, w, h)
- if self.sectors then
- local index = self:get_index_area(x, y, w, h)
- if index ~= 0 then
- self.sectors[index]:retrieve(callback, x, y, w, h)
- end
- end
-
- if self.objects then
- for obj in pairs(self.objects) do
- callback(obj.data)
- end
- end
-end
-
----Get index for area
----@param x number
----@param y number
----@param w number
----@param h number
----@return number
-function M:get_index_area(x, y, w, h)
- local index = 0
- local mid_x = self.x + (self.width / 2)
- local mid_y = self.y + (self.height / 2)
-
- local is_bottom = y + h <= mid_y
- local is_top = y >= mid_y
-
- local is_left = x + w <= mid_x
- local is_right = x >= mid_x
-
- if is_left then
- if is_bottom then
- index = 1
- elseif is_top then
- index = 2
- end
- elseif is_right then
- if is_top then
- index = 3
- elseif is_bottom then
- index = 4
- end
- end
-
- return index
-end
-
----Get all entities in radius
----@param x number X position
----@param y number Y position
----@param radius number Circle radius
-function M:get_in_radius(x, y, radius, callback)
- local x_area = x - radius
- local y_area = y - radius
- local w_area = radius * 2
- local h_area = radius * 2
- self:retrieve(callback, x_area, y_area, w_area, h_area)
-end
-
----Get all entities in a rectangle
----@param x number
----@param y number
----@param width number
----@param height number
----@param callback fun(quadtree_state: quadtree_state)
-function M:get_in_rect(x, y, width, height, callback)
- return self:retrieve(callback, x, y, width, height)
-end
-
----Get all entities in the quadtree
----@param callback fun(quadtree_state: quadtree_state)
-function M:get_all(callback)
- return self:retrieve(callback, self.x, self.y, self.width, self.height)
-end
-
----Count the total number of objects in the quadtree
----@return number
-function M:count_objects()
- local objects = self.objects_count
- if self.sectors then
- for i = 1, #self.sectors do
- objects = objects + self.sectors[i]:count_objects()
- end
- end
- return objects
-end
-
-function M:print_scheme(ident)
- ident = ident or ""
- print(ident .. "Level: " .. self.level)
- print(ident .. "Objects: " .. self.objects_count, "Total: " .. self:count_objects())
- print(ident .. "Sectors: " .. self.sectors and #self.sectors)
- if self.sectors then
- for i = 1, #self.sectors do
- self.sectors[i]:print_scheme(ident .. " ")
- end
- end
-end
-
-return M
diff --git a/system/quadtree/system_quadtree.lua b/system/quadtree/system_quadtree.lua
deleted file mode 100644
index 08fe9ae..0000000
--- a/system/quadtree/system_quadtree.lua
+++ /dev/null
@@ -1,126 +0,0 @@
-local decore = require("decore.decore")
-local quadtree = require("system.quadtree.quadtree")
-
-local command_quadtree = require("system.quadtree.command_quadtree")
-
-local logger = decore.get_logger("system_quadtree")
-
----@class entity
----@field quadtree boolean|nil
-
----@class entity.quadtree: entity
----@field quadtree component.quadtree
----@field transform component.transform
-
----@class component.quadtree: boolean
-decore.register_component("quadtree", false)
-
----@class system.quadtree: system
----@field quadtree quadtree
----@field debug_is_draw_quadtree boolean
----@field entity_to_state table
----@field entity_to_update table
-local M = {}
-
-local width = sys.get_config_int("display.width")
-local height = sys.get_config_int("display.height")
-
----@return system.quadtree
-function M.create_system()
- local system = decore.system(M, "quadtree", { "transform", "quadtree" })
- system.quadtree = quadtree.create(5, 6, 0, -width/2, -height/2, width, height)
- system.debug_is_draw_quadtree = false
- system.entity_to_state = {}
- system.entity_to_update = {}
-
- return system
-end
-
-
-function M:onAddToWorld()
- self.world.command_quadtree = command_quadtree.create(self)
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("transform_event", self.process_transform_event, self)
-
- for entity, quadtree_state in pairs(self.entity_to_update) do
- local t = entity.transform
- self.quadtree:update(quadtree_state, t.position_x, t.position_y, t.size_x, t.size_y)
- end
-end
-
-
----@param entity entity.transform
-function M:onAdd(entity)
- local t = entity.transform
- local x = t.position_x
- local y = t.position_y
- local w = t.size_x
- local h = t.size_y
-
- local quadtree_state = self.quadtree:insert(entity, x, y, w, h)
- self.entity_to_state[entity] = quadtree_state
-end
-
-
-function M:onRemove(entity)
- local quadtree_state = self.entity_to_state[entity]
- self.quadtree:remove(quadtree_state)
- self.entity_to_state[entity] = nil
-end
-
-
-function M:update(dt)
- if self.debug_is_draw_quadtree then
- self:debug_draw_quadtree(self.quadtree)
- end
-end
-
-
----@param quadtree quadtree
-function M:debug_draw_quadtree(quadtree)
- if not self.world.command_debug_draw then
- return
- end
-
- if quadtree.objects_count > 0 then
- local x, y, w, h = quadtree.x, quadtree.y, quadtree.width, quadtree.height
- self.world.command_debug_draw:draw_rectangle(x + w/2, y + h/2, w, h)
- --self.world.command_debug_draw:draw_text(x, y, #quadtree.objects)
- end
-
- if quadtree.sectors then
- for index = 1, #quadtree.sectors do
- self:debug_draw_quadtree(quadtree.sectors[index])
- end
- end
-end
-
-
----@param event system.transform.event
-function M:process_transform_event(event)
- local entity = event.entity
- local quadtree_state = self.entity_to_state[entity]
- if not quadtree_state then
- return
- end
-
- if event.is_position_changed or event.is_size_changed then
- self.entity_to_update[entity] = quadtree_state
- end
-end
-
-
----@param entity entity.transform
----@param radius number
----@param callback fun(entity: entity)
-function M:get_neighbors(entity, radius, callback)
- local position_x = entity.transform.position_x
- local position_y = entity.transform.position_y
- self.quadtree:get_in_radius(position_x, position_y, radius, callback)
-end
-
-
-return M
diff --git a/system/quadtree/test_quadtree.lua b/system/quadtree/test_quadtree.lua
deleted file mode 100644
index 6f4c5c1..0000000
--- a/system/quadtree/test_quadtree.lua
+++ /dev/null
@@ -1,50 +0,0 @@
-return function()
- describe("System Quadtree", function()
- local decore --- @type decore
- local world ---@type world
- local system_quadtree ---@type system.quadtree
- local quadtree ---@type quadtree
-
- before(function()
- decore = require("decore.decore")
- system_quadtree = require("system.quadtree.system_quadtree")
- quadtree = require("system.quadtree.quadtree")
-
- world = decore.new_world()
- world:add(system_quadtree.create_system())
- end)
-
- it("Quadtree can be created and requested", function()
- local q = quadtree.create(3, 3)
- assert(q)
-
- local entity = {
- transform = {
- position_x = 10,
- position_y = 20,
- size_x = 10,
- size_y = 10,
- }
- }
- local t = entity.transform
- q:insert(entity, t.position_x, t.position_y, t.size_x, t.size_y)
-
- local counter = 0
- q:get_in_rect(0, 0, 0, 0, function() counter = counter + 1 end)
- -- TODO: it's wrong
- assert(counter == 1)
-
- counter = 0
- q:get_in_rect(0, 0, 10, 10, function() counter = counter + 1 end)
- assert(counter == 1)
-
- counter = 0
- q:get_in_rect(0, 0, 20, 20, function() counter = counter + 1 end)
- assert(counter == 1)
-
- counter = 0
- q:get_in_rect(0, 0, 30, 30, function() counter = counter + 1 end)
- assert(counter == 1)
- end)
- end)
-end
diff --git a/system/remove_with_delay/component_remove_with_delay.script b/system/remove_with_delay/component_remove_with_delay.script
deleted file mode 100644
index 95f0d10..0000000
--- a/system/remove_with_delay/component_remove_with_delay.script
+++ /dev/null
@@ -1,7 +0,0 @@
-go.property("delay", 1)
-
-local component = require("decore.component")
-
-function init(self)
- component.init("remove_with_delay", self.delay)
-end
\ No newline at end of file
diff --git a/system/remove_with_delay/system_remove_with_delay.lua b/system/remove_with_delay/system_remove_with_delay.lua
deleted file mode 100644
index feb04d4..0000000
--- a/system/remove_with_delay/system_remove_with_delay.lua
+++ /dev/null
@@ -1,33 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field remove_with_delay number|nil
-
----@class entity.remove_with_delay: entity
----@field remove_with_delay number
-
----@class component.remove_with_delay
-decore.register_component("remove_with_delay", 0)
-
----@class system.remove_with_delay: system
----@field entities entity.remove_with_delay[]
-local M = {}
-
-
----@return system.remove_with_delay
-function M.create_system()
- return decore.processing_system(M, "remove_with_delay", "remove_with_delay")
-end
-
-
----@param entity entity.remove_with_delay
----@param dt number
-function M:process(entity, dt)
- entity.remove_with_delay = entity.remove_with_delay - dt
- if entity.remove_with_delay <= 0 then
- self.world:removeEntity(entity)
- end
-end
-
-
-return M
diff --git a/system/transform/test_transform.lua b/system/transform/test_transform.lua
deleted file mode 100644
index 0793bb9..0000000
--- a/system/transform/test_transform.lua
+++ /dev/null
@@ -1,94 +0,0 @@
-return function()
- describe("System transform", function()
- local decore ---@type decore
- local world ---@type world
- local system_transform ---@type system.transform
-
- before(function()
- decore = require("decore.decore")
- system_transform = require("system.transform.system_transform")
-
- world = decore.new_world()
- world:add(system_transform.create())
- end)
-
- it("Should init correctly", function()
- local entity = decore.create({ transform = {
- position_x = 10,
- position_y = 20,
- }})
- world:add(entity)
- world:refresh()
-
- assert(entity.transform.position_x == 10)
- assert(entity.transform.position_y == 20)
-
- -- Now it works only if we create an entity with decore
- -- How or should we update it?
- --assert(entity.transform.position_z == 0)
- end)
-
- it("Should trigger transform_event on position change", function()
- local entity = decore.create({ transform = {
- position_x = 10,
- position_y = 20,
- }})
- world:add(entity)
- world:refresh()
-
- world.command_transform:set_position(entity, 20, 30)
- assert(world.event_bus:get_stash("transform_event"))
- assert(#world.event_bus:get_stash("transform_event") == 1)
- local event = world.event_bus:get_stash("transform_event")[1]
- assert(event.entity == entity)
- assert(event.is_position_changed)
- end)
-
- it("Should trigger transform_event on scale change", function()
- local entity = decore.create({ transform = {
- scale_x = 1,
- scale_y = 1,
- }})
- world:add(entity)
- world:refresh()
-
- world.command_transform:set_scale(entity, 2, 2)
- assert(world.event_bus:get_stash("transform_event"))
- assert(#world.event_bus:get_stash("transform_event") == 1)
- local event = world.event_bus:get_stash("transform_event")[1]
- assert(event.entity == entity)
- assert(event.is_scale_changed)
- end)
-
- it("Should trigger transform_event on size change", function()
- local entity = decore.create({ transform = {
- size_x = 1,
- size_y = 1,
- }})
- world:add(entity)
- world:refresh()
-
- world.command_transform:set_size(entity, 2, 2)
- assert(world.event_bus:get_stash("transform_event"))
- assert(#world.event_bus:get_stash("transform_event") == 1)
- local event = world.event_bus:get_stash("transform_event")[1]
- assert(event.entity == entity)
- assert(event.is_size_changed)
- end)
-
- it("Should trigger transform_event on rotation change", function()
- local entity = decore.create({ transform = {
- rotation = 0,
- }})
- world:add(entity)
- world:refresh()
-
- world.command_transform:set_rotation(entity, 90)
- assert(world.event_bus:get_stash("transform_event"))
- assert(#world.event_bus:get_stash("transform_event") == 1)
- local event = world.event_bus:get_stash("transform_event")[1]
- assert(event.entity == entity)
- assert(event.is_rotation_changed)
- end)
- end)
-end
diff --git a/system/transform/transform.version b/system/transform/transform.version
new file mode 100644
index 0000000..f99521e
--- /dev/null
+++ b/system/transform/transform.version
@@ -0,0 +1 @@
+Insality:transform@1
\ No newline at end of file
diff --git a/system/transform/command_transform.lua b/system/transform/transform_command.lua
similarity index 83%
rename from system/transform/command_transform.lua
rename to system/transform/transform_command.lua
index 8f027cd..88e7616 100644
--- a/system/transform/command_transform.lua
+++ b/system/transform/transform_command.lua
@@ -1,8 +1,8 @@
---@class world
----@field command_transform system.transform.command
+---@field transform system.transform.command
---@class system.transform.command
----@field transform system.transform
+---@field private transform system.transform
local M = {}
@@ -72,10 +72,12 @@ end
---@param entity entity
---@param animate_time number|nil
---@param easing userdata|nil
-function M:set_animate_time(entity, animate_time, easing)
+---@param delay number|nil
+---@param callback function|nil
+function M:set_animate_time(entity, animate_time, easing, delay, callback)
assert(entity.transform, "Entity does not have a transform component.")
---@cast entity entity.transform
- self.transform:set_animate_time(entity, animate_time, easing)
+ self.transform:set_animate_time(entity, animate_time, easing, delay, callback)
end
@@ -106,5 +108,14 @@ function M:is_overlap(entity1, entity2)
end
+---@param entity entity
+---@param x number
+---@param y number
+---@return boolean
+function M:pick_entity(entity, x, y)
+ local left, top, right, bottom = self:get_transform_borders(entity)
+ return x > left and x < right and y > bottom and y < top
+end
+
return M
diff --git a/system/transform/system_transform.lua b/system/transform/transform_system.lua
similarity index 68%
rename from system/transform/system_transform.lua
rename to system/transform/transform_system.lua
index a87741d..c9ff966 100644
--- a/system/transform/system_transform.lua
+++ b/system/transform/transform_system.lua
@@ -1,15 +1,12 @@
local decore = require("decore.decore")
-local command_transform = require("system.transform.command_transform")
+local transform_command = require("system.transform.transform_command")
---@class entity
----@field transform component.transform|nil
+---@field transform component.transform?
---@class entity.transform: entity
---@field transform component.transform
----@class entity.command_transform: entity
----@field transform component.transform
-
---@class component.transform
---@field position_x number The position x
---@field position_y number The position y
@@ -21,6 +18,7 @@ local command_transform = require("system.transform.command_transform")
---@field scale_y number The scale y
---@field scale_z number The scale z
---@field rotation number The rotation
+---@field is_animated boolean Whether the transform is animated
decore.register_component("transform", {
position_x = 0,
position_y = 0,
@@ -42,6 +40,8 @@ decore.register_component("transform", {
---@field is_size_changed boolean|nil If true, the size was changed.
---@field animate_time number|nil If true, the time it took to animate the transform.
---@field easing userdata|nil The easing function used for the animation.
+---@field delay number|nil The delay before the animation starts.
+---@field callback function|nil The callback function to call when the animation is complete.
---@class system.transform: system
---@field entities entity.transform[]
@@ -55,7 +55,7 @@ end
function M:onAddToWorld()
- self.world.command_transform = command_transform.create(self)
+ self.world.transform = transform_command.create(self)
self.world.event_bus:set_merge_policy("transform_event", self.event_merge_policy)
end
@@ -142,31 +142,42 @@ end
---@param entity entity.transform
---@param animate_time number|nil
---@param easing userdata|nil
-function M:set_animate_time(entity, animate_time, easing)
+---@param delay number|nil
+---@param callback function|nil
+function M:set_animate_time(entity, animate_time, easing, delay, callback)
self.world.event_bus:trigger("transform_event", {
entity = entity,
animate_time = animate_time,
easing = easing,
+ delay = delay,
+ callback = callback
})
end
+---@param new_event system.transform.event
---@param events system.transform.event[]
----@param event system.transform.event
+---@param entity_map table
---@return boolean is_merged
-function M.event_merge_policy(event, events)
- local entity = event.entity
- for i = 1, #events do
- local e = events[i]
- if e.entity == entity then
- e.is_position_changed = event.is_position_changed or e.is_position_changed
- e.is_scale_changed = event.is_scale_changed or e.is_scale_changed
- e.is_rotation_changed = event.is_rotation_changed or e.is_rotation_changed
- e.is_size_changed = event.is_size_changed or e.is_size_changed
- e.animate_time = event.animate_time or e.animate_time
- e.easing = event.easing or e.easing
- return true
- end
+function M.event_merge_policy(new_event, events, entity_map)
+ local entity = new_event.entity
+ if not entity then
+ return false
+ end
+
+ local existing_events = entity_map[entity]
+ if existing_events and #existing_events > 0 then
+ -- Merge with the last event for this entity
+ local existing_event = existing_events[#existing_events]
+ existing_event.is_position_changed = new_event.is_position_changed or existing_event.is_position_changed
+ existing_event.is_scale_changed = new_event.is_scale_changed or existing_event.is_scale_changed
+ existing_event.is_rotation_changed = new_event.is_rotation_changed or existing_event.is_rotation_changed
+ existing_event.is_size_changed = new_event.is_size_changed or existing_event.is_size_changed
+ existing_event.animate_time = new_event.animate_time or existing_event.animate_time
+ existing_event.easing = new_event.easing or existing_event.easing
+ existing_event.delay = new_event.delay or existing_event.delay
+ existing_event.callback = new_event.callback or existing_event.callback
+ return true
end
return false
diff --git a/system/transform_animate_on_event/system_transform_animate_on_event.lua b/system/transform_animate_on_event/system_transform_animate_on_event.lua
deleted file mode 100644
index 2960e94..0000000
--- a/system/transform_animate_on_event/system_transform_animate_on_event.lua
+++ /dev/null
@@ -1,155 +0,0 @@
-local decore = require("decore.decore")
-
-local HASH_EMPTY = hash("")
-
----@class entity
----@field transform_animate_on_event component.transform_animate_on_event|nil
-
----@class entity.transform_animate_on_event: entity
----@field transform_animate_on_event component.transform_animate_on_event
----@field transform component.transform
-
----@class component.transform_animate_on_event
----@field event_id hash|nil
----@field easing constant
----@field time number
----@field trigger_on_add boolean
----@field is_position_relative boolean
----@field position vector3 x, y, z
----@field is_rotation_relative boolean
----@field rotation vector3 x, y, z
----@field is_scale_relative boolean
----@field scale vector3 x, y, z
----@field is_size_relative boolean
----@field size vector3 x, y, z
-decore.register_component("transform_animate_on_event", {
- event_id = nil,
- easing = nil,
- time = 0,
-
- trigger_on_add = false,
-
- is_position_relative = false,
- position = nil,
-
- is_rotation_relative = false,
- rotation = nil,
-
- is_scale_relative = false,
- scale = nil,
-
- is_size_relative = false,
- size = nil,
-})
-
----@class system.transform_animate_on_event: system
----@field entities entity.transform_animate_on_event[]
----@field event_to_entities table
----@field event_to_trigger_on_add entity.transform_animate_on_event[]
-local M = {}
-
----@return system.transform_animate_on_event
-function M.create_system()
- local system = decore.system(M, "transform_animate_on_event", { "transform_animate_on_event", "transform" })
- system.event_to_entities = {}
- system.event_to_trigger_on_add = {}
- return system
-end
-
-
-function M:postWrap()
- for event_id, entities in pairs(self.event_to_entities) do
- self.world.event_bus:process(event_id, function(event, entity)
- for index = 1, #entities do
- self:process_event(entities[index])
- end
- end)
- end
-end
-
-
-function M:onAdd(entity)
- local event_id = entity.transform_animate_on_event.event_id
- if event_id and event_id ~= HASH_EMPTY then
- self.event_to_entities[event_id] = self.event_to_entities[event_id] or {}
- table.insert(self.event_to_entities[event_id], entity)
- end
-
- if entity.transform_animate_on_event.trigger_on_add then
- table.insert(self.event_to_trigger_on_add, entity)
- end
-end
-
-
-function M:onRemove(entity)
- local event_id = entity.transform_animate_on_event.event_id
- if event_id and event_id ~= HASH_EMPTY then
- local entities = self.event_to_entities[event_id]
- if not entities then
- return
- end
-
- for index = #entities, 1, -1 do
- if entities[index] == entity then
- table.remove(entities, index)
- break
- end
- end
- end
-end
-
-
-function M:update()
- for index = #self.event_to_trigger_on_add, 1, -1 do
- self:process_event(self.event_to_trigger_on_add[index])
- self.event_to_trigger_on_add[index] = nil
- end
-end
-
-
----@param entity entity.transform_animate_on_event
-function M:process_event(entity)
- local transform = entity.transform
- local animate_transform = entity.transform_animate_on_event
-
- local position = animate_transform.position
- if position then
- local x, y, z = position.x, position.y, position.z
- if animate_transform.is_position_relative then
- x, y, z = x + transform.position_x, y + transform.position_y, z + transform.position_z
- end
- self.world.command_transform:set_position(entity, x, y, z)
- end
-
- local rotation = animate_transform.rotation
- if rotation then
- local euler_z = rotation.z
- if animate_transform.is_rotation_relative then
- euler_z = euler_z + transform.rotation
- end
- self.world.command_transform:set_rotation(entity, euler_z)
- end
-
- local scale = animate_transform.scale
- if scale then
- local x, y, z = scale.x, scale.y, scale.z
- if animate_transform.is_scale_relative then
- x, y, z = x + transform.scale_x, y + transform.scale_y, z + transform.scale_z
- end
- self.world.command_transform:set_scale(entity, x, y, z)
- end
-
- local size = animate_transform.size
- if size then
- local x, y, z = size.x, size.y, size.z
- if animate_transform.is_size_relative then
- x, y, z = x + transform.size_x, y + transform.size_y, z + transform.size_z
- end
- self.world.command_transform:set_size(entity, x, y, z)
- end
-
- self.world.command_transform:set_animate_time(entity, animate_transform.time, animate_transform.easing)
-end
-
-
-return M
diff --git a/system/transform_border/system_transform_border.lua b/system/transform_border/system_transform_border.lua
deleted file mode 100644
index 7b7b797..0000000
--- a/system/transform_border/system_transform_border.lua
+++ /dev/null
@@ -1,91 +0,0 @@
-local decore = require("decore.decore")
-
----@class entity
----@field transform_border component.transform_border|nil
-
----@class entity.transform_border: entity
----@field transform_border component.transform_border
----@field transform component.transform
-
----@class component.transform_border
----@field border vector4
----@field is_wrap boolean
----@field is_limit boolean
----@field random_position boolean If true, the entity will be placed randomly within the border
-decore.register_component("transform_border", {
- is_wrap = false,
- is_limit = true,
- random_position = false,
-})
-
----@class system.transform_border: system
----@field entities entity.transform_border[]
-local M = {}
-
-
----@return system.transform_border
-function M.create()
- return decore.system(M, "transform_border", { "transform_border", "transform" })
-end
-
-
----@param entity entity.transform_border
-function M:onAdd(entity)
- if entity.transform_border.random_position then
- local border = entity.transform_border.border
- local x = math.random(border.x, border.z)
- local y = math.random(border.w, border.y)
- self.world.command_transform:set_position(entity, x, y)
- end
-end
-
-
-function M:postWrap()
- self.world.event_bus:process("transform_event", self.process_transform_event, self)
-end
-
-
----@param event system.transform.event
-function M:process_transform_event(event)
- local entity = event.entity
- local transform_border = entity.transform_border
-
- if transform_border then
- local border = transform_border.border
- local left, top, right, bottom = self.world.command_transform:get_transform_borders(entity)
-
- if left < border.x or top > border.y or right > border.z or bottom < border.w then
- local t = entity.transform
-
- if transform_border.is_wrap then
- local x = t.position_x
- local y = t.position_y
- local size_x_half = t.size_x/2
- local size_y_half = t.size_y/2
-
- -- Wrap horizontally
- if x - size_x_half > border.z then
- x = border.x + size_x_half
- elseif x + size_x_half < border.x then
- x = border.z - size_x_half
- end
-
- -- Wrap vertically
- if y - size_y_half > border.y then
- y = border.w + size_y_half
- elseif y + size_y_half < border.w then
- y = border.y - size_y_half
- end
-
- self.world.command_transform:set_position(entity, x, y)
- elseif transform_border.is_limit then
- local x = decore.clamp(t.position_x, border.x + t.size_x/2, border.z - t.size_x/2)
- local y = decore.clamp(t.position_y, border.w + t.size_y/2, border.y - t.size_y/2)
- self.world.command_transform:set_position(entity, x, y)
- end
- end
- end
-end
-
-
-return M
diff --git a/system/velocity/command_velocity.lua b/system/velocity/command_velocity.lua
deleted file mode 100644
index 9135c2c..0000000
--- a/system/velocity/command_velocity.lua
+++ /dev/null
@@ -1,65 +0,0 @@
--- command_velocity.lua
----@class world
----@field command_velocity system.velocity.command
-
----@class system.velocity.command
----@field velocity system.velocity
-local M = {}
-
-
----@param velocity system.velocity
----@return system.velocity.command
-function M.create(velocity)
- return setmetatable({ velocity = velocity }, { __index = M })
-end
-
-
-function M:set_velocity(entity, x, y)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_velocity(entity, x, y)
-end
-
-
-function M:add_velocity(entity, x, y)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_velocity(entity, entity.velocity.x + x, entity.velocity.y + y)
-end
-
-
----Set entity velocity angle
----@param entity entity
----@param angle number Angle in degrees
-function M:set_angle(entity, angle)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_angle(entity, angle)
-end
-
-
----Set entity velocity speed
----@param entity entity
----@param speed number Speed value
-function M:set_speed(entity, speed)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_speed(entity, speed)
-end
-
-
-function M:set_min_speed(entity, min_speed)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_min_speed(entity, min_speed)
-end
-
-
-function M:set_max_speed(entity, max_speed)
- assert(entity.velocity, "Entity does not have a velocity component.")
- ---@cast entity entity.velocity
- self.velocity:set_max_speed(entity, max_speed)
-end
-
-
-return M
diff --git a/system/velocity/component_velocity.script b/system/velocity/component_velocity.script
deleted file mode 100644
index fb65717..0000000
--- a/system/velocity/component_velocity.script
+++ /dev/null
@@ -1,10 +0,0 @@
-go.property("velocity", vmath.vector3(0, 0, 0))
-
-local component = require("decore.component")
-
-function init(self)
- component.init("velocity", {
- x = self.velocity.x,
- y = self.velocity.y,
- })
-end
\ No newline at end of file
diff --git a/system/velocity/system_velocity.lua b/system/velocity/system_velocity.lua
deleted file mode 100644
index ae9fd06..0000000
--- a/system/velocity/system_velocity.lua
+++ /dev/null
@@ -1,118 +0,0 @@
-local decore = require("decore.decore")
-local command_velocity = require("system.velocity.command_velocity")
-
----@class entity
----@field velocity component.velocity|nil
-
----@class entity.velocity: entity
----@field transform component.transform
----@field velocity component.velocity
-
----@class component.velocity
----@field angle number
----@field speed number
----@field max_speed number
----@field min_speed number
----@field x number
----@field y number
-decore.register_component("velocity", {
- speed = 0,
- angle = 0,
- max_speed = 0,
- min_speed = 0,
- x = 0,
- y = 0,
-})
-
----@class system.velocity: system
----@field entities entity.velocity[]
----@field debug_draw boolean
-local M = {}
-
-
----@return system.velocity
-function M.create_system()
- return decore.processing_system(M, "velocity", { "velocity", "transform" })
-end
-
-
-function M:onAddToWorld()
- self.debug_draw = false
- self.world.command_velocity = command_velocity.create(self)
-end
-
-
-function M:onAdd(entity)
- local velocity = entity.velocity
- if velocity.speed > 0 then
- self:set_angle(entity, velocity.angle)
- end
-end
-
-
-function M:set_angle(entity, angle)
- local velocity = entity.velocity
- velocity.angle = angle
-
- -- Update velocity components
- local rad = math.rad(angle)
- velocity.x = math.cos(rad) * velocity.speed
- velocity.y = math.sin(rad) * velocity.speed
-end
-
-
-function M:set_speed(entity, speed)
- local velocity = entity.velocity
- velocity.speed = speed
-
- -- Update velocity components
- local rad = math.rad(velocity.angle)
- velocity.x = math.cos(rad) * speed
- velocity.y = math.sin(rad) * speed
-end
-
-
-function M:set_velocity(entity, x, y)
- local velocity = entity.velocity
-
- local speed = math.sqrt(x * x + y * y)
- velocity.speed = decore.clamp(speed, velocity.min_speed, velocity.max_speed)
- velocity.angle = math.deg(math.atan2(y, x))
-
- -- Adjust x and y
- local rad = math.rad(velocity.angle)
- velocity.x = math.cos(rad) * velocity.speed
- velocity.y = math.sin(rad) * velocity.speed
-end
-
-
----@param entity entity.velocity
-function M:process(entity, dt)
- local velocity = entity.velocity
-
- self.world.command_transform:add_position(entity, velocity.x * dt, velocity.y * dt)
- self.world.command_transform:set_rotation(entity, velocity.angle)
-
- if self.debug_draw and self.world.command_debug_draw then
- local t = entity.transform
- self.world.command_debug_draw:draw_line(
- t.position_x,
- t.position_y,
- t.position_x + velocity.x,
- t.position_y + velocity.y
- )
- end
-end
-
-
-function M:set_min_speed(entity, min_speed)
- entity.velocity.min_speed = min_speed
-end
-
-
-function M:set_max_speed(entity, max_speed)
- entity.velocity.max_speed = max_speed
-end
-
-
-return M
diff --git a/system/window_event/system_window_event.lua b/system/window_event/system_window_event.lua
deleted file mode 100644
index f01f8eb..0000000
--- a/system/window_event/system_window_event.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-local events = require("event.events")
-local decore = require("decore.decore")
-
----window.WINDOW_EVENT_FOCUS_GAINED | window.WINDOW_EVENT_FOCUS_LOST | window.WINDOW_EVENT_RESIZED
----@class system.window_event.event
-
----System that listens to window events and triggers events on the event bus
----@class system.window_event: system
-local M = {}
-
-
----@return system.window_event
-function M.create_system()
- return decore.system(M, "window_event")
-end
-
-
-function M:onAddToWorld()
- window.set_listener(function(_, window_event)
- events.trigger("decore.window_event", window_event)
- end)
-
- events.subscribe("decore.window_event", self.on_window_event, self)
-end
-
-
-function M:onRemoveFromWorld()
- events.unsubscribe("decore.window_event", self.on_window_event, self)
-end
-
-
-function M:on_window_event(event)
- self.world.event_bus:trigger("window_event", event)
-end
-
-
-return M
diff --git a/test/test.script b/test/test.script
index 640b864..4b72191 100644
--- a/test/test.script
+++ b/test/test.script
@@ -1,11 +1,6 @@
local deftest = require("deftest.deftest")
function init(self)
- deftest.add(require("system.health.test_health"))
- deftest.add(require("system.fsm.test_fsm"))
- deftest.add(require("system.transform.test_transform"))
- deftest.add(require("system.quadtree.test_quadtree"))
-
local is_report = (sys.get_config_int("test.report", 0) == 1)
deftest.run({ coverage = { enabled = is_report } })
end
diff --git a/wiki/FLOW.md b/wiki/FLOW.md
deleted file mode 100644
index b971c01..0000000
--- a/wiki/FLOW.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# ECS
-
-## Entities
-
-## Systems
-
-### Add new system
-
-- Create a folder with system name in yout systems folder
-- Copy a one of the system type ("template_system", "template_system..command or "template_system_event") to your folder
-- Replace all TEMPLATE with your system name
-- Register your system in game.script
-
-### I want to add new entity
-
-# Tiled
-
-## Add new entity
-- Prepare image for tiled placement, add in /tileset/images folder
-- Open tiled tileset
-- Press "plus", select icon, select image
-- Add required components (`game_object`), transform is not required (autofilled)
-- Add entity_id (prefab_id) in tileset class field
-- Save project (export should me done automatically)
-
-## My entity image have a offset
-If your defold image matches not in center, you can adjust the offset in the tiled tilesets
-- Open corresponding entity in tileset
-- Open Tile Collision Editor
-- Place Point object at new center of the image
--- Detiled uses first point object to calculate offset
-
-## I want change the Z position of Tiled Layer
-- Select layer
-- Add custom number property "position_z" to layer
-- This property will be used as Z position of the layer
-
-# Hints & Solutions
-
-## Tiled
-
-### I want to draw pixel at object area
-- Add entity add tiled with pixel image
-- Place in level and resize as required
-- Add this pixel.collection image as game object in assets
-- Add this pixel.collection to spawner.collection
-- Use factory_url of this pixel
-
-## Game
-
-### I want to add main game input system
-- Add something like "system" tiled layer
-- Add object (point) with name (only visual thing) and class name (prefab_id), ex "game_input"
-- Open game entities.json, add new entity with prefab_id "game_input"
-- Add "input" component and "game_input" component
-- Make "game_input" system
-
-### I want to add some logic to game
-- Think about which system can make it and which data it requires
-- Add component in tiled with default data
-- Add components to objects or on new object
-- Add new system
-
-### I want to animate my object with panthera
-- Add panthera component to the entity with animation path
-
-## GUI
-
-### I want to add new gui
-- Create gui, gui_script, collection
-- Add this collection to spawner as object
-- Add entity in entities.json, add component to components.json
-- Add new object element with class with name of prefab_id
-
-
-### Create GUI
-To pass data and callbacks between system and GUI we need to make a "gui bindings"
-
-```lua
-local bindings = require("gui.bindings")
-
--- GUI
-function init(self)
- -- Store at game object key
- self.bindings = bindings.set({
- on_play_button = event.create(),
- set_color = event.create(),
- })
-end
-
--- System
-local bindings = require("gui.bindings")
-
----@param entity entity.gui
-function M:onAdd(entity)
- -- Get bindings for current game object
- local bindings = bindings.get(entity.game_object.root)
- bindings.on_play_button:subscribe(self.on_play_button, self)
-
- bindings.set_color:trigger("red")
-end
-```
diff --git a/wiki/FLOW_TILED.md b/wiki/FLOW_TILED.md
deleted file mode 100644
index eb18705..0000000
--- a/wiki/FLOW_TILED.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Flow Tiled
-
-## Setup
-
-Open Tiled
-New Project
-Create `/tiled` folder (can use other folder name)
-Name project with the project name to easier find it inside Tiled (it uses filename as a project name)
-
-### Create First Map
-
-Create new map, any settings
-Save at /tiled/maps folder
-Select Export as JSON (/tiled/exported_maps/level_name.json)
-I keep other folder to separate include in game project, but seems more convinient to keep it in the same folder.
-
-### Create first tileset
-
-New Tileset (collection of images)
-Press Plus -> Select image to add first entity
-Seems better to create the folder with all images inside tiled.
-Select Export as JSON (/resources/tilesets/tileset_name.json)
-
diff --git a/wiki/decore_components.md b/wiki/decore_components.md
deleted file mode 100644
index e69de29..0000000
diff --git a/wiki/decore_entities.md b/wiki/decore_entities.md
deleted file mode 100644
index e69de29..0000000
diff --git a/wiki/decore_systems.md b/wiki/decore_systems.md
deleted file mode 100644
index e69de29..0000000
diff --git a/wiki/decore_worlds.md b/wiki/decore_worlds.md
deleted file mode 100644
index e69de29..0000000
diff --git a/wiki/tech_solutions.md b/wiki/tech_solutions.md
deleted file mode 100644
index c6ba207..0000000
--- a/wiki/tech_solutions.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Using vector or just fields in transform
-Pros:
-- Easier to use with game objects
-- A bit faster and a bit less memory usage
-
-Cons:
-- Not POD
-- Need conversions from JSON to vector