From 4aeede0a397b09f4a131001e7ef467336de617ec Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 13 May 2022 12:30:50 +0100
Subject: [PATCH 1/4] Bump ejs from 3.1.6 to 3.1.7 in /js/jiddly-app (#190)

Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.7.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.7)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 js/jiddly-app/package-lock.json | 101 ++++++++++++++++++++++----------
 1 file changed, 69 insertions(+), 32 deletions(-)

diff --git a/js/jiddly-app/package-lock.json b/js/jiddly-app/package-lock.json
index cd0754594..4046217ee 100644
--- a/js/jiddly-app/package-lock.json
+++ b/js/jiddly-app/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "jiddly-app",
-  "version": "1.3.2",
+  "version": "1.3.6",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "jiddly-app",
-      "version": "1.3.2",
+      "version": "1.3.6",
       "dependencies": {
         "@fortawesome/fontawesome-svg-core": "^6.1.1",
         "@fortawesome/free-solid-svg-icons": "^6.1.1",
@@ -6455,11 +6455,11 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
     "node_modules/ejs": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
-      "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz",
+      "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==",
       "dependencies": {
-        "jake": "^10.6.1"
+        "jake": "^10.8.5"
       },
       "bin": {
         "ejs": "bin/cli.js"
@@ -7534,11 +7534,30 @@
       }
     },
     "node_modules/filelist": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
-      "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz",
+      "integrity": "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==",
       "dependencies": {
-        "minimatch": "^3.0.4"
+        "minimatch": "^5.0.1"
+      }
+    },
+    "node_modules/filelist/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/filelist/node_modules/minimatch": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
+      "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/filesize": {
@@ -8988,11 +9007,11 @@
       }
     },
     "node_modules/jake": {
-      "version": "10.8.4",
-      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz",
-      "integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==",
+      "version": "10.8.5",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+      "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
       "dependencies": {
-        "async": "0.9.x",
+        "async": "^3.2.3",
         "chalk": "^4.0.2",
         "filelist": "^1.0.1",
         "minimatch": "^3.0.4"
@@ -9019,9 +9038,9 @@
       }
     },
     "node_modules/jake/node_modules/async": {
-      "version": "0.9.2",
-      "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-      "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
+      "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
     },
     "node_modules/jake/node_modules/chalk": {
       "version": "4.1.2",
@@ -21142,11 +21161,11 @@
       "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
     },
     "ejs": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
-      "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.7.tgz",
+      "integrity": "sha512-BIar7R6abbUxDA3bfXrO4DSgwo8I+fB5/1zgujl3HLLjwd6+9iOnrT+t3grn2qbk9vOgBubXOFwX2m9axoFaGw==",
       "requires": {
-        "jake": "^10.6.1"
+        "jake": "^10.8.5"
       }
     },
     "electron-to-chromium": {
@@ -21931,11 +21950,29 @@
       }
     },
     "filelist": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
-      "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.3.tgz",
+      "integrity": "sha512-LwjCsruLWQULGYKy7TX0OPtrL9kLpojOFKc5VCTxdFTV7w5zbsgqVKfnkKG7Qgjtq50gKfO56hJv88OfcGb70Q==",
       "requires": {
-        "minimatch": "^3.0.4"
+        "minimatch": "^5.0.1"
+      },
+      "dependencies": {
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
+          "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        }
       }
     },
     "filesize": {
@@ -22945,11 +22982,11 @@
       }
     },
     "jake": {
-      "version": "10.8.4",
-      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.4.tgz",
-      "integrity": "sha512-MtWeTkl1qGsWUtbl/Jsca/8xSoK3x0UmS82sNbjqxxG/de/M/3b1DntdjHgPMC50enlTNwXOCRqPXLLt5cCfZA==",
+      "version": "10.8.5",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
+      "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==",
       "requires": {
-        "async": "0.9.x",
+        "async": "^3.2.3",
         "chalk": "^4.0.2",
         "filelist": "^1.0.1",
         "minimatch": "^3.0.4"
@@ -22964,9 +23001,9 @@
           }
         },
         "async": {
-          "version": "0.9.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
-          "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
+          "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
         },
         "chalk": {
           "version": "4.1.2",

From 358854556252e7896fbca8e88795004b6f4fd303 Mon Sep 17 00:00:00 2001
From: Chris Bamford <chrisbam4d@gmail.com>
Date: Tue, 17 May 2022 17:24:26 +0100
Subject: [PATCH 2/4] Sprite gpu ordering (#194)

* order the sprites on the GPU by alphabetical order so its easy to use them in the shaders

* order sprites consistently across platforms

* fixing history tests for windows

* fixing tests
---
 python/tests/history_test.py                  | 28 +++++++++++++++++--
 src/Griddly/Core/Observers/BlockObserver.cpp  |  2 +-
 src/Griddly/Core/Observers/BlockObserver.hpp  |  6 ++--
 src/Griddly/Core/Observers/SpriteObserver.cpp |  2 +-
 src/Griddly/Core/Observers/SpriteObserver.hpp |  5 ++--
 .../Core/Observers/Vulkan/VulkanDevice.cpp    |  2 +-
 .../Core/Observers/Vulkan/VulkanDevice.hpp    |  3 +-
 .../Core/Observers/BlockObserverTest.cpp      |  4 +--
 .../Observers/IsometricSpriteObserverTest.cpp |  4 +--
 .../Core/Observers/SpriteObserverTest.cpp     |  4 +--
 10 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/python/tests/history_test.py b/python/tests/history_test.py
index f80586ca4..178e61746 100644
--- a/python/tests/history_test.py
+++ b/python/tests/history_test.py
@@ -25,6 +25,23 @@ def build_test_env(test_name, yaml_file, enable_history=True):
     return env
 
 
+def eq_dict(dict1, dict2):
+
+    for key in dict1:
+        if key in dict2:
+            if dict1[key] != dict2[key]:
+                return False
+        else:
+            assert False
+    return True
+
+def in_dict(list_of_dicts, dict):
+    for dict1 in list_of_dicts:
+        if eq_dict(dict1, dict):
+            return True
+    return False
+
+
 def test_history_SinglePlayer_HasHistory(test_name):
     """
     Assuming there is a single avatar
@@ -122,7 +139,9 @@ def test_history_SinglePlayer_MultipleAction(test_name):
         },
     ]
 
-    assert info["History"] == expected_history
+    assert in_dict(info["History"], expected_history[0])
+    assert in_dict(info["History"], expected_history[1])
+
 
 
 def test_history_MultiplePlayer_History(test_name):
@@ -170,7 +189,8 @@ def test_history_MultiplePlayer_History(test_name):
         },
     ]
 
-    assert info["History"] == expected_history
+    assert in_dict(info["History"], expected_history[0])
+    assert in_dict(info["History"], expected_history[1])
 
 
 def test_history_MultiplePlayer_MultipleAction_History(test_name):
@@ -238,4 +258,6 @@ def test_history_MultiplePlayer_MultipleAction_History(test_name):
         },
     ]
 
-    assert info["History"] == expected_history
+    assert in_dict(info["History"], expected_history[0])
+    assert in_dict(info["History"], expected_history[1])
+    assert in_dict(info["History"], expected_history[2])
diff --git a/src/Griddly/Core/Observers/BlockObserver.cpp b/src/Griddly/Core/Observers/BlockObserver.cpp
index b7224a6a9..e721a8422 100644
--- a/src/Griddly/Core/Observers/BlockObserver.cpp
+++ b/src/Griddly/Core/Observers/BlockObserver.cpp
@@ -7,7 +7,7 @@
 
 namespace griddly {
 
-const std::unordered_map<std::string, SpriteDefinition> BlockObserver::blockSpriteDefinitions_ = {
+const std::map<std::string, SpriteDefinition> BlockObserver::blockSpriteDefinitions_ = {
     {"circle", {{"block_shapes/circle.png"}}},
     {"triangle", {{"block_shapes/triangle.png"}}},
     {"square", {{"block_shapes/square.png"}}},
diff --git a/src/Griddly/Core/Observers/BlockObserver.hpp b/src/Griddly/Core/Observers/BlockObserver.hpp
index e06acac52..10bf6662b 100644
--- a/src/Griddly/Core/Observers/BlockObserver.hpp
+++ b/src/Griddly/Core/Observers/BlockObserver.hpp
@@ -16,7 +16,7 @@ struct BlockDefinition {
 };
 
 struct BlockObserverConfig : public SpriteObserverConfig {
-  std::unordered_map<std::string, BlockDefinition> blockDefinitions;
+  std::map<std::string, BlockDefinition> blockDefinitions;
 };
 
 
@@ -32,9 +32,9 @@ class BlockObserver : public SpriteObserver, public ObserverConfigInterface<Bloc
 
  private:
   void updateObjectSSBOs(std::vector<vk::ObjectSSBOs>& objectSSBOCache, std::shared_ptr<Object> object, glm::mat4& globalModelMatrix, DiscreteOrientation& globalOrientation);
-  std::unordered_map<std::string, BlockDefinition> blockDefinitions_;
+  std::map<std::string, BlockDefinition> blockDefinitions_;
 
-  const static std::unordered_map<std::string, SpriteDefinition> blockSpriteDefinitions_;
+  const static std::map<std::string, SpriteDefinition> blockSpriteDefinitions_;
 
 
   BlockObserverConfig config_;
diff --git a/src/Griddly/Core/Observers/SpriteObserver.cpp b/src/Griddly/Core/Observers/SpriteObserver.cpp
index 6815bf7ac..2bfa248ef 100644
--- a/src/Griddly/Core/Observers/SpriteObserver.cpp
+++ b/src/Griddly/Core/Observers/SpriteObserver.cpp
@@ -71,7 +71,7 @@ vk::SpriteData SpriteObserver::loadImage(std::string imageFilename) {
 void SpriteObserver::lazyInit() {
   VulkanObserver::lazyInit();
 
-  std::unordered_map<std::string, vk::SpriteData> spriteData;
+  std::map<std::string, vk::SpriteData> spriteData;
   for (auto spriteDefinitionIt : spriteDefinitions_) {
     auto spriteName = spriteDefinitionIt.first;
     auto spriteDefinition = spriteDefinitionIt.second;
diff --git a/src/Griddly/Core/Observers/SpriteObserver.hpp b/src/Griddly/Core/Observers/SpriteObserver.hpp
index a6c6fd89b..f11cdcac6 100644
--- a/src/Griddly/Core/Observers/SpriteObserver.hpp
+++ b/src/Griddly/Core/Observers/SpriteObserver.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include <memory>
+#include <map>
 
 #include "VulkanGridObserver.hpp"
 
@@ -25,7 +26,7 @@ struct SpriteDefinition {
 };
 
 struct SpriteObserverConfig : public VulkanGridObserverConfig {
-  std::unordered_map<std::string, SpriteDefinition> spriteDefinitions;
+  std::map<std::string, SpriteDefinition> spriteDefinitions;
 };
 
 class SpriteObserver : public VulkanGridObserver, public ObserverConfigInterface<SpriteObserverConfig> {
@@ -40,7 +41,7 @@ class SpriteObserver : public VulkanGridObserver, public ObserverConfigInterface
 
  protected:
   std::string getSpriteName(const std::string& objectName, const std::string& tileName, const glm::ivec2& location, Direction orientation) const;
-  std::unordered_map<std::string, SpriteDefinition> spriteDefinitions_;
+  std::map<std::string, SpriteDefinition> spriteDefinitions_;
 
   void updateObjectSSBOData(PartialObservableGrid& partiallyObservableGrid, glm::mat4& globalModelMatrix, DiscreteOrientation globalOrientation) override;
 
diff --git a/src/Griddly/Core/Observers/Vulkan/VulkanDevice.cpp b/src/Griddly/Core/Observers/Vulkan/VulkanDevice.cpp
index 9330f3fb3..a25e641a2 100644
--- a/src/Griddly/Core/Observers/Vulkan/VulkanDevice.cpp
+++ b/src/Griddly/Core/Observers/Vulkan/VulkanDevice.cpp
@@ -398,7 +398,7 @@ std::vector<uint32_t> VulkanDevice::allocateHostImageData() {
   return {1, 4, (uint32_t)subResourceLayout.rowPitch};
 }
 
-void VulkanDevice::preloadSprites(std::unordered_map<std::string, SpriteData>& spritesData) {
+void VulkanDevice::preloadSprites(std::map<std::string, SpriteData>& spritesData) {
   auto arrayLayers = spritesData.size();
 
   spdlog::debug("Preloading {0} sprites", arrayLayers);
diff --git a/src/Griddly/Core/Observers/Vulkan/VulkanDevice.hpp b/src/Griddly/Core/Observers/Vulkan/VulkanDevice.hpp
index 89f61b397..c6c602a3b 100644
--- a/src/Griddly/Core/Observers/Vulkan/VulkanDevice.hpp
+++ b/src/Griddly/Core/Observers/Vulkan/VulkanDevice.hpp
@@ -8,6 +8,7 @@
 #include <glm/gtx/hash.hpp>
 #include <memory>
 #include <unordered_map>
+#include <map>
 #include <unordered_set>
 #include <vector>
 
@@ -183,7 +184,7 @@ class VulkanDevice {
   std::vector<uint32_t> resetRenderSurface(uint32_t pixelWidth, uint32_t pixelHeight);
 
   // Load the sprites
-  void preloadSprites(std::unordered_map<std::string, SpriteData>& spritesData);
+  void preloadSprites(std::map<std::string, SpriteData>& spritesData);
 
   // Setup variables to be passed to the shaders
   void initializeSSBOs(uint32_t globalVariableCount, uint32_t playerCount, uint32_t objectVariableCount, uint32_t maximumObjects);
diff --git a/tests/src/Griddly/Core/Observers/BlockObserverTest.cpp b/tests/src/Griddly/Core/Observers/BlockObserverTest.cpp
index b441cbcc1..9d2df6e54 100644
--- a/tests/src/Griddly/Core/Observers/BlockObserverTest.cpp
+++ b/tests/src/Griddly/Core/Observers/BlockObserverTest.cpp
@@ -21,7 +21,7 @@ using ::testing::ReturnRef;
 
 namespace griddly {
 
-std::unordered_map<std::string, BlockDefinition> getMockRTSBlockDefinitions() {
+std::map<std::string, BlockDefinition> getMockRTSBlockDefinitions() {
   float red[]{0.5, 0.2, 0.2};
   float green[]{0.2, 0.5, 0.2};
   float blue[]{0.2, 0.2, 0.5};
@@ -70,7 +70,7 @@ std::unordered_map<std::string, BlockDefinition> getMockRTSBlockDefinitions() {
   };
 }
 
-std::unordered_map<std::string, BlockDefinition> getMockBlockDefinitions() {
+std::map<std::string, BlockDefinition> getMockBlockDefinitions() {
   float red[]{1.0, 0.0, 0.0};
   float green[]{0.0, 1.0, 0.0};
   float blue[]{0.0, 0.0, 1.0};
diff --git a/tests/src/Griddly/Core/Observers/IsometricSpriteObserverTest.cpp b/tests/src/Griddly/Core/Observers/IsometricSpriteObserverTest.cpp
index 3592f894c..f84d7d6c6 100644
--- a/tests/src/Griddly/Core/Observers/IsometricSpriteObserverTest.cpp
+++ b/tests/src/Griddly/Core/Observers/IsometricSpriteObserverTest.cpp
@@ -20,7 +20,7 @@ using ::testing::ReturnRef;
 
 namespace griddly {
 
-std::unordered_map<std::string, SpriteDefinition> getMockRTSIsometricSpriteDefinitions() {
+std::map<std::string, SpriteDefinition> getMockRTSIsometricSpriteDefinitions() {
   // mock wall object
   SpriteDefinition mockObject1SpriteDefinition;
   mockObject1SpriteDefinition.tilingMode = TilingMode::ISO_FLOOR;
@@ -111,7 +111,7 @@ void runIsometricSpriteObserverRTSTest(IsometricSpriteObserverConfig observerCon
   testEnvironment.verifyAndClearExpectations();
 }
 
-std::unordered_map<std::string, SpriteDefinition> getMockIsometricSpriteDefinitions() {
+std::map<std::string, SpriteDefinition> getMockIsometricSpriteDefinitions() {
   // mock object 1
   SpriteDefinition mockObject1SpriteDefinition;
   mockObject1SpriteDefinition.tilingMode = TilingMode::ISO_FLOOR;
diff --git a/tests/src/Griddly/Core/Observers/SpriteObserverTest.cpp b/tests/src/Griddly/Core/Observers/SpriteObserverTest.cpp
index 740fe9a3f..8b181e553 100644
--- a/tests/src/Griddly/Core/Observers/SpriteObserverTest.cpp
+++ b/tests/src/Griddly/Core/Observers/SpriteObserverTest.cpp
@@ -20,7 +20,7 @@ using ::testing::ReturnRef;
 
 namespace griddly {
 
-std::unordered_map<std::string, SpriteDefinition> getMockRTSSpriteDefinitions() {
+std::map<std::string, SpriteDefinition> getMockRTSSpriteDefinitions() {
   // mock wall object
   SpriteDefinition mockObjectWallBlockDefinition;
   mockObjectWallBlockDefinition.tilingMode = TilingMode::WALL_16;
@@ -123,7 +123,7 @@ void runSpriteObserverRTSTest(SpriteObserverConfig observerConfig,
   testEnvironment.verifyAndClearExpectations();
 }
 
-std::unordered_map<std::string, SpriteDefinition> getMockSpriteDefinitions() {
+std::map<std::string, SpriteDefinition> getMockSpriteDefinitions() {
   // mock object 1
   SpriteDefinition mockObject1SpriteDefinition;
   mockObject1SpriteDefinition.tilingMode = TilingMode::WALL_16;

From cb9dc763c0523426f8311bbdc39ea6d3db54dc4a Mon Sep 17 00:00:00 2001
From: Chris Bamford <chrisbam4d@gmail.com>
Date: Wed, 18 May 2022 11:50:05 +0100
Subject: [PATCH 3/4] Sprite padding (#195)

* add padding for the edges of the environment so we can still render stuff over it in shaders

* adding some debugging

* if avatar dies then stop rendering anything

* do not use filesystem
---
 bindings/python.cpp                           |  2 +-
 bindings/wrapper/GriddlyLoaderWrapper.cpp     |  4 +-
 python/griddly/__init__.py                    |  2 +-
 src/Griddly/Core/GDY/GDYFactory.cpp           | 40 ++++++++++++++++---
 src/Griddly/Core/GDY/GDYFactory.hpp           |  5 ++-
 src/Griddly/Core/GDY/Objects/Object.cpp       |  5 +++
 src/Griddly/Core/GDY/Objects/Object.hpp       |  3 ++
 src/Griddly/Core/Observers/SpriteObserver.cpp | 29 +++++++++++++-
 src/Griddly/Core/Observers/VectorObserver.cpp |  9 ++++-
 .../Core/Observers/Vulkan/VulkanObserver.hpp  |  1 +
 .../Core/Observers/VulkanGridObserver.cpp     |  4 +-
 11 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/bindings/python.cpp b/bindings/python.cpp
index c659e7c58..5fa2221d7 100644
--- a/bindings/python.cpp
+++ b/bindings/python.cpp
@@ -23,7 +23,7 @@ PYBIND11_MODULE(python_griddly, m) {
   spdlog::debug("Python Griddly module loaded!");
 
   py::class_<Py_GriddlyLoaderWrapper, std::shared_ptr<Py_GriddlyLoaderWrapper>> gdy_reader(m, "GDYReader");
-  gdy_reader.def(py::init<std::string, std::string>());
+  gdy_reader.def(py::init<std::string, std::string, std::string>());
   gdy_reader.def("load", &Py_GriddlyLoaderWrapper::loadGDYFile);
   gdy_reader.def("load_string", &Py_GriddlyLoaderWrapper::loadGDYString);
 
diff --git a/bindings/wrapper/GriddlyLoaderWrapper.cpp b/bindings/wrapper/GriddlyLoaderWrapper.cpp
index 717f785f8..b90afd2c8 100644
--- a/bindings/wrapper/GriddlyLoaderWrapper.cpp
+++ b/bindings/wrapper/GriddlyLoaderWrapper.cpp
@@ -12,8 +12,8 @@ namespace griddly {
 
 class Py_GriddlyLoaderWrapper {
  public:
-  Py_GriddlyLoaderWrapper(std::string imagePath, std::string shaderPath)
-      : resourceConfig_({imagePath, shaderPath}) {
+  Py_GriddlyLoaderWrapper(std::string gdyPath, std::string imagePath, std::string shaderPath)
+      : resourceConfig_({gdyPath, imagePath, shaderPath}) {
   }
 
   std::shared_ptr<Py_GDYWrapper> loadGDYFile(std::string filename) {
diff --git a/python/griddly/__init__.py b/python/griddly/__init__.py
index 09a71bdf3..5d28247ea 100644
--- a/python/griddly/__init__.py
+++ b/python/griddly/__init__.py
@@ -34,7 +34,7 @@ def __init__(self, gdy_path=None, image_path=None, shader_path=None):
             if gdy_path is None
             else gdy_path
         )
-        self._gdy_reader = gd.GDYReader(self._image_path, self._shader_path)
+        self._gdy_reader = gd.GDYReader(self._gdy_path, self._image_path, self._shader_path)
 
     def get_full_path(self, gdy_path):
         # Assume the file is relative first and if not, try to find it in the pre-defined games
diff --git a/src/Griddly/Core/GDY/GDYFactory.cpp b/src/Griddly/Core/GDY/GDYFactory.cpp
index 582cba574..262cc040b 100644
--- a/src/Griddly/Core/GDY/GDYFactory.cpp
+++ b/src/Griddly/Core/GDY/GDYFactory.cpp
@@ -18,10 +18,11 @@
 namespace griddly {
 
 #ifndef WASM
-GDYFactory::GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator, ResourceConfig resourceConfig)
+
+GDYFactory::GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator, ResourceConfig defaultResourceConfig)
     : objectGenerator_(std::move(objectGenerator)),
       terminationGenerator_(std::move(terminationGenerator)),
-      resourceConfig_(std::move(resourceConfig)) {
+      defaultResourceConfig_(std::move(defaultResourceConfig)) {
 #else
 GDYFactory::GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator)
     : objectGenerator_(std::move(objectGenerator)),
@@ -306,6 +307,7 @@ SpriteObserverConfig GDYFactory::parseNamedSpriteObserverConfig(std::string obse
   auto observerConfigNode = observerConfigNodes_.at(observerName);
   parseCommonObserverConfig(config, observerConfigNode, isGlobalObserver);
   parseNamedObserverShaderConfig(config, observerConfigNode);
+  parseNamedObserverResourceConfig(config, observerConfigNode);
 
   config.playerColors = playerColors_;
   config.tileSize = parseTileSize(observerConfigNode);
@@ -313,6 +315,7 @@ SpriteObserverConfig GDYFactory::parseNamedSpriteObserverConfig(std::string obse
   config.rotateAvatarImage = resolveObserverConfigValue<bool>("RotateAvatarImage", observerConfigNode, config.rotateAvatarImage, !isGlobalObserver);
 
   auto backgroundTileNode = observerConfigNode["BackgroundTile"];
+  
   if (backgroundTileNode.IsDefined()) {
     auto backgroundTile = backgroundTileNode.as<std::string>();
     spdlog::debug("Setting background tiling to {0}", backgroundTile);
@@ -321,6 +324,15 @@ SpriteObserverConfig GDYFactory::parseNamedSpriteObserverConfig(std::string obse
     config.spriteDefinitions.insert({"_background_", backgroundTileDefinition});
   }
 
+  auto paddingTileNode = observerConfigNode["PaddingTile"];
+  if (paddingTileNode.IsDefined()) {
+    auto paddingTile = paddingTileNode.as<std::string>();
+    spdlog::debug("Setting padding tiling to {0}", paddingTile);
+    SpriteDefinition paddingTileDefiniton{};
+    paddingTileDefiniton.images = {paddingTile};
+    config.spriteDefinitions.insert({"_padding_", paddingTileDefiniton});
+  }
+
   if (objectNames_.size() == 0) {
     return config;
   }
@@ -350,6 +362,7 @@ BlockObserverConfig GDYFactory::parseNamedBlockObserverConfig(std::string observ
   auto observerConfigNode = observerConfigNodes_.at(observerName);
   parseCommonObserverConfig(config, observerConfigNode, isGlobalObserver);
   parseNamedObserverShaderConfig(config, observerConfigNode);
+  parseNamedObserverResourceConfig(config, observerConfigNode);
 
   config.playerColors = playerColors_;
   config.tileSize = parseTileSize(observerConfigNode);
@@ -385,6 +398,7 @@ IsometricSpriteObserverConfig GDYFactory::parseNamedIsometricObserverConfig(std:
   auto observerConfigNode = observerConfigNodes_.at(observerName);
   parseCommonObserverConfig(config, observerConfigNode, isGlobalObserver);
   parseNamedObserverShaderConfig(config, observerConfigNode);
+  parseNamedObserverResourceConfig(config, observerConfigNode);
 
   config.playerColors = playerColors_;
   config.tileSize = parseTileSize(observerConfigNode);
@@ -422,6 +436,25 @@ IsometricSpriteObserverConfig GDYFactory::parseNamedIsometricObserverConfig(std:
   return config;
 }
 
+void GDYFactory::parseNamedObserverResourceConfig(VulkanObserverConfig& config, YAML::Node observerConfigNode) {
+  auto resourceConfigNode = observerConfigNode["ResourceConfig"];
+  config.resourceConfig = defaultResourceConfig_;
+  
+  if (!resourceConfigNode.IsDefined()) {
+    spdlog::debug("Using default Resource Config");
+    return;
+  }
+
+  if(resourceConfigNode["ImagePath"].IsDefined()) {
+    config.resourceConfig.imagePath = defaultResourceConfig_.gdyPath+"/"+resourceConfigNode["ImagePath"].as<std::string>();
+  }
+
+  if(resourceConfigNode["ShaderPath"].IsDefined()) {
+    config.resourceConfig.shaderPath = defaultResourceConfig_.gdyPath+"/"+resourceConfigNode["ShaderPath"].as<std::string>();
+  }
+};
+
+
 void GDYFactory::parseNamedObserverShaderConfig(VulkanObserverConfig& config, YAML::Node observerConfigNode) {
   auto shaderConfigNode = observerConfigNode["Shader"];
   if (!shaderConfigNode.IsDefined()) {
@@ -1132,7 +1165,6 @@ std::shared_ptr<Observer> GDYFactory::createObserver(std::shared_ptr<Grid> grid,
       auto observerConfig = generateConfigForObserver<IsometricSpriteObserverConfig>(observerName, isGlobalObserver);
       observerConfig.playerCount = playerCount;
       observerConfig.playerId = playerId;
-      observerConfig.resourceConfig = resourceConfig_;
       observer->init(observerConfig);
       return observer;
     } break;
@@ -1143,7 +1175,6 @@ std::shared_ptr<Observer> GDYFactory::createObserver(std::shared_ptr<Grid> grid,
       auto observerConfig = generateConfigForObserver<SpriteObserverConfig>(observerName, isGlobalObserver);
       observerConfig.playerCount = playerCount;
       observerConfig.playerId = playerId;
-      observerConfig.resourceConfig = resourceConfig_;
       observer->init(observerConfig);
       return observer;
     } break;
@@ -1154,7 +1185,6 @@ std::shared_ptr<Observer> GDYFactory::createObserver(std::shared_ptr<Grid> grid,
       auto observerConfig = generateConfigForObserver<BlockObserverConfig>(observerName, isGlobalObserver);
       observerConfig.playerCount = playerCount;
       observerConfig.playerId = playerId;
-      observerConfig.resourceConfig = resourceConfig_;
       observer->init(observerConfig);
       return observer;
     } break;
diff --git a/src/Griddly/Core/GDY/GDYFactory.hpp b/src/Griddly/Core/GDY/GDYFactory.hpp
index 7f081253d..64188d446 100644
--- a/src/Griddly/Core/GDY/GDYFactory.hpp
+++ b/src/Griddly/Core/GDY/GDYFactory.hpp
@@ -27,7 +27,7 @@ namespace griddly {
 class GDYFactory {
  public:
 #ifndef WASM
-  GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator, ResourceConfig resourceConfig);
+  GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator, ResourceConfig defaultResourceConfig);
 #else
   GDYFactory(std::shared_ptr<ObjectGenerator> objectGenerator, std::shared_ptr<TerminationGenerator> terminationGenerator);
 #endif
@@ -148,6 +148,7 @@ class GDYFactory {
 
 #ifndef WASM
   void parseNamedObserverShaderConfig(VulkanObserverConfig& config, YAML::Node observerConfigNode);
+  void parseNamedObserverResourceConfig(VulkanObserverConfig& config, YAML::Node observerConfigNode);
 #endif
 
   const std::string& getPlayerObserverName() const;
@@ -177,7 +178,7 @@ class GDYFactory {
 
   DefaultObserverConfig defaultObserverConfig_;
 #ifndef WASM
-  const ResourceConfig resourceConfig_;
+  const ResourceConfig defaultResourceConfig_;
 #endif
 };
 }  // namespace griddly
diff --git a/src/Griddly/Core/GDY/Objects/Object.cpp b/src/Griddly/Core/GDY/Objects/Object.cpp
index 775e40ce7..587d5d65c 100644
--- a/src/Griddly/Core/GDY/Objects/Object.cpp
+++ b/src/Griddly/Core/GDY/Objects/Object.cpp
@@ -896,6 +896,7 @@ uint32_t Object::getRenderTileId() const {
 }
 
 void Object::removeObject() {
+  removed_ = true;
   grid()->removeObject(shared_from_this());
 }
 
@@ -919,6 +920,10 @@ const std::string &Object::getObjectRenderTileName() const {
   return renderTileName_;
 }
 
+bool Object::isRemoved() const {
+  return removed_;
+}
+
 bool Object::isPlayerAvatar() const {
   return isPlayerAvatar_;
 }
diff --git a/src/Griddly/Core/GDY/Objects/Object.hpp b/src/Griddly/Core/GDY/Objects/Object.hpp
index b2e6ee4d6..dd511e16e 100644
--- a/src/Griddly/Core/GDY/Objects/Object.hpp
+++ b/src/Griddly/Core/GDY/Objects/Object.hpp
@@ -95,6 +95,8 @@ class Object : public std::enable_shared_from_this<Object>, ConditionResolver<Be
 
   virtual bool isPlayerAvatar() const;
 
+  virtual bool isRemoved() const;
+
   virtual void setRenderTileId(uint32_t renderTileId);
 
   virtual uint32_t getRenderTileId() const;
@@ -173,6 +175,7 @@ class Object : public std::enable_shared_from_this<Object>, ConditionResolver<Be
   virtual bool moveObject(glm::ivec2 newLocation);
 
   virtual void removeObject();
+  bool removed_ = false;
 
   SingleInputMapping getInputMapping(const std::string& actionName, uint32_t actionId, bool randomize, InputMapping fallback);
 
diff --git a/src/Griddly/Core/Observers/SpriteObserver.cpp b/src/Griddly/Core/Observers/SpriteObserver.cpp
index 2bfa248ef..46c9a7fdf 100644
--- a/src/Griddly/Core/Observers/SpriteObserver.cpp
+++ b/src/Griddly/Core/Observers/SpriteObserver.cpp
@@ -171,7 +171,8 @@ std::string SpriteObserver::getSpriteName(const std::string& objectName, const s
 }
 
 void SpriteObserver::updateObjectSSBOData(PartialObservableGrid& observableGrid, glm::mat4& globalModelMatrix, DiscreteOrientation globalOrientation) {
-  uint32_t backgroundTileIndex = device_->getSpriteArrayLayer("_background_");
+
+  int32_t backgroundTileIndex = device_->getSpriteArrayLayer("_background_");
   if (backgroundTileIndex != -1) {
     vk::ObjectDataSSBO backgroundTiling;
     backgroundTiling.modelMatrix = glm::translate(backgroundTiling.modelMatrix, glm::vec3(gridWidth_ / 2.0 - config_.gridXOffset, gridHeight_ / 2.0 - config_.gridYOffset, 0.0));
@@ -185,6 +186,30 @@ void SpriteObserver::updateObjectSSBOData(PartialObservableGrid& observableGrid,
   const auto& objects = grid_->getObjects();
   const auto& objectIds = grid_->getObjectIds();
 
+  // Add padding objects
+  int32_t paddingTileIdx = device_->getSpriteArrayLayer("_padding_");
+  if (paddingTileIdx != -1) {
+    for (int32_t xPad = observableGrid.right - gridWidth_; xPad < observableGrid.left + static_cast<int32_t>(gridWidth_); xPad++) {
+      for (int32_t yPad = observableGrid.top - gridHeight_; yPad < observableGrid.bottom + static_cast<int32_t>(gridHeight_); yPad++) {
+        spdlog::debug("xpad,ypad {0},{1}", xPad, yPad);
+        if (xPad < 0 || yPad < 0 || xPad >= gridBoundary_.x || yPad >= gridBoundary_.y) {
+          spdlog::debug("Adding padding tile at {0},{1}", xPad, yPad);
+          vk::ObjectDataSSBO objectData{};
+          objectData.textureIndex = paddingTileIdx;
+          objectData.zIdx = -10;
+          // Translate the locations with respect to global transform
+          glm::vec4 renderLocation = globalModelMatrix * glm::vec4(xPad, yPad, 0.0, 1.0);
+          spdlog::debug("Rendering padding tile at {0},{1}", renderLocation.x, renderLocation.y);
+
+          // Translate
+          objectData.modelMatrix = glm::translate(objectData.modelMatrix, glm::vec3(renderLocation.x, renderLocation.y, 0.0));
+          objectData.modelMatrix = glm::translate(objectData.modelMatrix, glm::vec3(0.5, 0.5, 0.0));  // Offset for the the vertexes as they are between (-0.5, 0.5) and we want them between (0, 1)
+          frameSSBOData_.objectSSBOData.push_back({objectData});
+        }
+      }
+    }
+  }
+
   for (auto& object : objects) {
     vk::ObjectDataSSBO objectData{};
     std::vector<vk::ObjectVariableSSBO> objectVariableData{};
@@ -195,7 +220,7 @@ void SpriteObserver::updateObjectSSBOData(PartialObservableGrid& observableGrid,
 
     spdlog::debug("Updating object {0} at location [{1},{2}]", objectName, location.x, location.y);
 
-    // Check we are within the boundary of the render grid otherwise don't add the object
+    // Check we are within the boundary of the render grid
     if (location.x < observableGrid.left || location.x > observableGrid.right || location.y < observableGrid.bottom || location.y > observableGrid.top) {
       continue;
     }
diff --git a/src/Griddly/Core/Observers/VectorObserver.cpp b/src/Griddly/Core/Observers/VectorObserver.cpp
index 8e7b6699f..32f6e55de 100644
--- a/src/Griddly/Core/Observers/VectorObserver.cpp
+++ b/src/Griddly/Core/Observers/VectorObserver.cpp
@@ -58,8 +58,7 @@ void VectorObserver::resetShape() {
   observationShape_ = {observationChannels_, gridWidth_, gridHeight_};
   observationStrides_ = {1, observationChannels_, observationChannels_ * gridWidth_};
 
-  observation_ = std::shared_ptr<uint8_t>(new uint8_t[observationChannels_ * gridWidth_ * gridHeight_]{}); //NOLINT
-
+  observation_ = std::shared_ptr<uint8_t>(new uint8_t[observationChannels_ * gridWidth_ * gridHeight_]{});  //NOLINT
 }
 
 void VectorObserver::renderLocation(glm::ivec2 objectLocation, glm::ivec2 outputLocation, bool resetLocation) const {
@@ -136,6 +135,12 @@ uint8_t& VectorObserver::update() {
     throw std::runtime_error("Observer not ready, must be initialized and reset before update() can be called.");
   }
 
+  if (avatarObject_ != nullptr && avatarObject_->isRemoved()) {
+    auto size = sizeof(uint8_t) * observationChannels_ * gridWidth_ * gridHeight_;
+    memset(observation_.get(), 0, size);
+    return *observation_.get();
+  }
+
   if (doTrackAvatar_) {
     spdlog::debug("Tracking Avatar.");
 
diff --git a/src/Griddly/Core/Observers/Vulkan/VulkanObserver.hpp b/src/Griddly/Core/Observers/Vulkan/VulkanObserver.hpp
index bd1d17b7f..01e1c1185 100644
--- a/src/Griddly/Core/Observers/Vulkan/VulkanObserver.hpp
+++ b/src/Griddly/Core/Observers/Vulkan/VulkanObserver.hpp
@@ -12,6 +12,7 @@
 namespace griddly {
 
 struct ResourceConfig {
+  std::string gdyPath = "resources/games";
   std::string imagePath = "resources/images";
   std::string shaderPath = "resources/shaders";
 };
diff --git a/src/Griddly/Core/Observers/VulkanGridObserver.cpp b/src/Griddly/Core/Observers/VulkanGridObserver.cpp
index c7cb719a8..15cadb8dd 100644
--- a/src/Griddly/Core/Observers/VulkanGridObserver.cpp
+++ b/src/Griddly/Core/Observers/VulkanGridObserver.cpp
@@ -112,7 +112,9 @@ void VulkanGridObserver::updateFrameShaderBuffers() {
   glm::mat4 globalModelMatrix = getGlobalModelMatrix();
 
   frameSSBOData_.objectSSBOData.clear();
-  updateObjectSSBOData(observableGrid, globalModelMatrix, globalOrientation);
+  if(avatarObject_ == nullptr || !avatarObject_->isRemoved()) {
+    updateObjectSSBOData(observableGrid, globalModelMatrix, globalOrientation);
+  }
 
   if (commandBufferObjectsCount_ != frameSSBOData_.objectSSBOData.size()) {
     commandBufferObjectsCount_ = frameSSBOData_.objectSSBOData.size();

From d61e525e3a202fd153c5ebe257921c6007b92024 Mon Sep 17 00:00:00 2001
From: Bam4d <chrisbam4d@gmail.com>
Date: Wed, 18 May 2022 11:52:15 +0100
Subject: [PATCH 4/4] bumping version numbers

---
 .github/ISSUE_TEMPLATE/bug_report.md | 2 +-
 CMakeLists.txt                       | 2 +-
 bindings/python.cpp                  | 2 +-
 docs/conf.py                         | 2 +-
 js/jiddly-app/package.json           | 2 +-
 python/setup.py                      | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 90c39fa2b..7ffd18841 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -24,7 +24,7 @@ If applicable, add screenshots to help explain your problem.
 
 **Desktop (please complete the following information):**
  - OS: [e.g. mac/linux/windows]
- - Version [e.g. 1.3.7]
+ - Version [e.g. 1.3.8]
 
 **Additional context**
 Add any other context about the problem here.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6a310b9f0..4bf40deac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.10.0)
 set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
-project(Griddly VERSION 1.3.7)
+project(Griddly VERSION 1.3.8)
 
 set(BINARY ${CMAKE_PROJECT_NAME})
 
diff --git a/bindings/python.cpp b/bindings/python.cpp
index 5fa2221d7..d545626f7 100644
--- a/bindings/python.cpp
+++ b/bindings/python.cpp
@@ -12,7 +12,7 @@ namespace griddly {
 
 PYBIND11_MODULE(python_griddly, m) {
   m.doc() = "Griddly python bindings";
-  m.attr("version") = "1.3.7";
+  m.attr("version") = "1.3.8";
 
 #ifndef NDEBUG
   spdlog::set_level(spdlog::level::debug);
diff --git a/docs/conf.py b/docs/conf.py
index 9d4fbe9fe..dd2f1b4f9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -22,7 +22,7 @@
 author = 'Chris Bamford'
 
 # The full version, including alpha/beta/rc tags
-release = '1.3.7'
+release = '1.3.8'
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/js/jiddly-app/package.json b/js/jiddly-app/package.json
index eb964f531..622adde4d 100644
--- a/js/jiddly-app/package.json
+++ b/js/jiddly-app/package.json
@@ -1,6 +1,6 @@
 {
   "name": "jiddly-app",
-  "version": "1.3.7",
+  "version": "1.3.8",
   "private": true,
   "dependencies": {
     "@fortawesome/fontawesome-svg-core": "^6.1.1",
diff --git a/python/setup.py b/python/setup.py
index 55008076d..1e7ee8318 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -71,7 +71,7 @@ def griddly_package_data(config='Debug'):
 
 setup(
     name='griddly',
-    version="1.3.7",
+    version="1.3.8",
     author_email="chrisbam4d@gmail.com",
     description="Griddly Python Libraries",
     long_description=long_description,