diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7ffd18841..a2330ff92 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.8] + - Version [e.g. 1.3.9] **Additional context** Add any other context about the problem here. diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf40deac..9536399a0 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.8) +project(Griddly VERSION 1.3.9) set(BINARY ${CMAKE_PROJECT_NAME}) diff --git a/bindings/python.cpp b/bindings/python.cpp index d545626f7..07c6fd88f 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.8"; + m.attr("version") = "1.3.9"; #ifndef NDEBUG spdlog::set_level(spdlog::level::debug); diff --git a/docs/conf.py b/docs/conf.py index dd2f1b4f9..16d830b03 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.8' +release = '1.3.9' # -- General configuration --------------------------------------------------- diff --git a/js/jiddly-app/package.json b/js/jiddly-app/package.json index 622adde4d..7104ea641 100644 --- a/js/jiddly-app/package.json +++ b/js/jiddly-app/package.json @@ -1,6 +1,6 @@ { "name": "jiddly-app", - "version": "1.3.8", + "version": "1.3.9", "private": true, "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.1", diff --git a/python/setup.py b/python/setup.py index 1e7ee8318..1d028cef2 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.8", + version="1.3.9", author_email="chrisbam4d@gmail.com", description="Griddly Python Libraries", long_description=long_description, diff --git a/src/Griddly/Core/GDY/GDYFactory.cpp b/src/Griddly/Core/GDY/GDYFactory.cpp index 262cc040b..019cdfe04 100644 --- a/src/Griddly/Core/GDY/GDYFactory.cpp +++ b/src/Griddly/Core/GDY/GDYFactory.cpp @@ -206,6 +206,22 @@ VectorObserverConfig GDYFactory::parseNamedVectorObserverConfig(std::string obse config.includeRotation = resolveObserverConfigValue("IncludeRotation", observerConfigNode, config.includeRotation, !isGlobalObserver); config.includeVariables = resolveObserverConfigValue("IncludeVariables", observerConfigNode, config.includeVariables, !isGlobalObserver); + auto globalVariableMappingNode = observerConfigNode["GlobalVariableMapping"]; + + if (globalVariableMappingNode.IsDefined()) { + const auto& globalEntityVariables = singleOrListNodeToList(globalVariableMappingNode); + + for (const auto& globalEntityVariable : globalEntityVariables) { + if (globalVariableDefinitions_.find(globalEntityVariable) == globalVariableDefinitions_.end()) { + std::string error = fmt::format("No global variable with name {0} in GlobalVariableMapping feature configuration.", globalEntityVariable); + spdlog::error(error); + throw std::invalid_argument(error); + } + } + + config.globalVariableMapping = globalEntityVariables; + } + return config; } diff --git a/src/Griddly/Core/Observers/VectorObserver.cpp b/src/Griddly/Core/Observers/VectorObserver.cpp index 32f6e55de..6b7e19d59 100644 --- a/src/Griddly/Core/Observers/VectorObserver.cpp +++ b/src/Griddly/Core/Observers/VectorObserver.cpp @@ -55,6 +55,12 @@ void VectorObserver::resetShape() { spdlog::debug("Adding {0} variable channels at: {1}", observationChannels_ - channelsBeforeVariables_, channelsBeforeVariables_); } + if (config_.globalVariableMapping.size() > 0) { + channelsBeforeGlobalVariables_ = observationChannels_; + observationChannels_ += static_cast(config_.globalVariableMapping.size()); + spdlog::debug("Adding {0} global variable channels at: {1}", observationChannels_ - channelsBeforeGlobalVariables_, channelsBeforeGlobalVariables_); + } + observationShape_ = {observationChannels_, gridWidth_, gridHeight_}; observationStrides_ = {1, observationChannels_, observationChannels_ * gridWidth_}; @@ -237,6 +243,27 @@ uint8_t& VectorObserver::update() { } } } + + // Sellotape the chosen global variables onto the obs + if (config_.globalVariableMapping.size() > 0) { + const auto& globalVariables = grid_->getGlobalVariables(); + uint32_t globalVariableIdx = 0; + for (const auto& variableName : config_.globalVariableMapping) { + const auto& variable = globalVariables.at(variableName); + + auto value = variable.size() > 1 ? variable.at(config_.playerId) : variable.at(0); + + for (auto x = 0; x < gridWidth_; x++) { + for (auto y = 0; y < gridHeight_; y++) { + auto memPtr = observation_.get() + observationChannels_ * (gridWidth_ * y + x); + auto globalVariableMemPtr = memPtr + channelsBeforeGlobalVariables_ + globalVariableIdx; + *globalVariableMemPtr = *value; + } + } + globalVariableIdx++; + } + } + } spdlog::debug("Purging update locations."); diff --git a/src/Griddly/Core/Observers/VectorObserver.hpp b/src/Griddly/Core/Observers/VectorObserver.hpp index ea067a2b2..63930405b 100644 --- a/src/Griddly/Core/Observers/VectorObserver.hpp +++ b/src/Griddly/Core/Observers/VectorObserver.hpp @@ -10,6 +10,7 @@ struct VectorObserverConfig : public ObserverConfig { bool includeVariables = false; bool includeRotation = false; bool includePlayerId = false; + std::vector globalVariableMapping{}; }; class VectorObserver : public Observer, public TensorObservationInterface, public ObserverConfigInterface { @@ -34,6 +35,7 @@ class VectorObserver : public Observer, public TensorObservationInterface, publi uint32_t channelsBeforePlayerCount_; uint32_t channelsBeforeRotation_; uint32_t channelsBeforeVariables_; + uint32_t channelsBeforeGlobalVariables_; VectorObserverConfig config_; }; diff --git a/tests/src/Griddly/Core/Observers/VectorObserverTest.cpp b/tests/src/Griddly/Core/Observers/VectorObserverTest.cpp index 7573ed9ca..734ac1ec1 100644 --- a/tests/src/Griddly/Core/Observers/VectorObserverTest.cpp +++ b/tests/src/Griddly/Core/Observers/VectorObserverTest.cpp @@ -478,6 +478,26 @@ TEST(VectorObserverTest, partialObserver_withOffset_trackAvatar_rotateWithAvatar runVectorObserverTest(config, Direction::LEFT, {4, 5, 3}, {1, 4, 20}, expectedData[0][0]); } +TEST(VectorObserverTest, defaultObserver_global_variables) { + VectorObserverConfig config = { + 5, + 5, + 0, + 0, + false, false}; + + config.globalVariableMapping = {"lightingR", "lightingB"}; + + uint8_t expectedData[5][5][6] = { + {{1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}}, + {{1, 0, 0, 0, 50, 100}, {0, 1, 0, 0, 50, 100}, {0, 0, 0, 0, 50, 100}, {0, 0, 1, 0, 50, 100}, {1, 0, 0, 0, 50, 100}}, + {{1, 0, 0, 0, 50, 100}, {0, 1, 0, 0, 50, 100}, {0, 0, 0, 1, 50, 100}, {0, 0, 1, 0, 50, 100}, {1, 0, 0, 0, 50, 100}}, + {{1, 0, 0, 0, 50, 100}, {0, 0, 1, 0, 50, 100}, {0, 0, 0, 0, 50, 100}, {0, 1, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}}, + {{1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}, {1, 0, 0, 0, 50, 100}}}; + + runVectorObserverTest(config, Direction::NONE, {6, 5, 5}, {1, 6, 30}, expectedData[0][0]); +} + TEST(VectorObserverTest, multiPlayer_Outline_Player1) { VectorObserverConfig config = {5, 5, 0, 0}; config.playerId = 1;