diff --git a/.gitignore b/.gitignore
index ddcbc2f..b5e9975 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ builds/
# Blender
*.blend1
+*.tmp
diff --git a/examples/PushBall/.gitattributes b/examples/PushBall/.gitattributes
new file mode 100644
index 0000000..8ad74f7
--- /dev/null
+++ b/examples/PushBall/.gitattributes
@@ -0,0 +1,2 @@
+# Normalize EOL for all files that Git considers text files.
+* text=auto eol=lf
diff --git a/examples/PushBall/.gitignore b/examples/PushBall/.gitignore
new file mode 100644
index 0000000..7de8ea5
--- /dev/null
+++ b/examples/PushBall/.gitignore
@@ -0,0 +1,3 @@
+# Godot 4+ specific ignores
+.godot/
+android/
diff --git a/examples/PushBall/PushBall.csproj b/examples/PushBall/PushBall.csproj
new file mode 100644
index 0000000..6fa3be0
--- /dev/null
+++ b/examples/PushBall/PushBall.csproj
@@ -0,0 +1,11 @@
+
+
+ net6.0
+ net7.0
+ net8.0
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/PushBall/PushBall.sln b/examples/PushBall/PushBall.sln
new file mode 100644
index 0000000..4d52e29
--- /dev/null
+++ b/examples/PushBall/PushBall.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PushBall", "PushBall.csproj", "{B0EAFC65-EF15-457D-88AA-02DC8422CE19}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ ExportDebug|Any CPU = ExportDebug|Any CPU
+ ExportRelease|Any CPU = ExportRelease|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
+ {B0EAFC65-EF15-457D-88AA-02DC8422CE19}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_2d.gd b/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_2d.gd
new file mode 100644
index 0000000..06d928b
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_2d.gd
@@ -0,0 +1,136 @@
+extends Node2D
+class_name AIController2D
+
+enum ControlModes {
+ INHERIT_FROM_SYNC, ## Inherit setting from sync node
+ HUMAN, ## Test the environment manually
+ TRAINING, ## Train a model
+ ONNX_INFERENCE, ## Load a pretrained model using an .onnx file
+ RECORD_EXPERT_DEMOS ## Record observations and actions for expert demonstrations
+}
+@export var control_mode: ControlModes = ControlModes.INHERIT_FROM_SYNC
+## The path to a trained .onnx model file to use for inference (overrides the path set in sync node).
+@export var onnx_model_path := ""
+## Once the number of steps has passed, the flag 'needs_reset' will be set to 'true' for this instance.
+@export var reset_after := 1000
+
+@export_group("Record expert demos mode options")
+## Path where the demos will be saved. The file can later be used for imitation learning.
+@export var expert_demo_save_path: String
+## The action that erases the last recorded episode from the currently recorded data.
+@export var remove_last_episode_key: InputEvent
+## Action will be repeated for n frames. Will introduce control lag if larger than 1.
+## Can be used to ensure that action_repeat on inference and training matches
+## the recorded demonstrations.
+@export var action_repeat: int = 1
+
+@export_group("Multi-policy mode options")
+## Allows you to set certain agents to use different policies.
+## Changing has no effect with default SB3 training. Works with Rllib example.
+## Tutorial: https://github.com/edbeeching/godot_rl_agents/blob/main/docs/TRAINING_MULTIPLE_POLICIES.md
+@export var policy_name: String = "shared_policy"
+
+var onnx_model: ONNXModel
+
+var heuristic := "human"
+var done := false
+var reward := 0.0
+var n_steps := 0
+var needs_reset := false
+
+var _player: Node2D
+
+
+func _ready():
+ add_to_group("AGENT")
+
+
+func init(player: Node2D):
+ _player = player
+
+
+#region Methods that need implementing using the "extend script" option in Godot
+func get_obs() -> Dictionary:
+ assert(false, "the get_obs method is not implemented when extending from ai_controller")
+ return {"obs": []}
+
+
+func get_reward() -> float:
+ assert(false, "the get_reward method is not implemented when extending from ai_controller")
+ return 0.0
+
+
+func get_action_space() -> Dictionary:
+ assert(
+ false, "the get_action_space method is not implemented when extending from ai_controller"
+ )
+ return {
+ "example_actions_continous": {"size": 2, "action_type": "continuous"},
+ "example_actions_discrete": {"size": 2, "action_type": "discrete"},
+ }
+
+
+func set_action(action) -> void:
+ assert(false, "the set_action method is not implemented when extending from ai_controller")
+
+
+#endregion
+
+
+#region Methods that sometimes need implementing using the "extend script" option in Godot
+# Only needed if you are recording expert demos with this AIController
+func get_action() -> Array:
+ assert(
+ false,
+ "the get_action method is not implemented in extended AIController but demo_recorder is used"
+ )
+ return []
+
+
+# For providing additional info (e.g. `is_success` for SB3 training)
+func get_info() -> Dictionary:
+ return {}
+
+
+#endregion
+
+
+func _physics_process(delta):
+ n_steps += 1
+ if n_steps > reset_after:
+ needs_reset = true
+
+
+func get_obs_space():
+ # may need overriding if the obs space is complex
+ var obs = get_obs()
+ return {
+ "obs": {"size": [len(obs["obs"])], "space": "box"},
+ }
+
+
+func reset():
+ n_steps = 0
+ needs_reset = false
+
+
+func reset_if_done():
+ if done:
+ reset()
+
+
+func set_heuristic(h):
+ # sets the heuristic from "human" or "model" nothing to change here
+ heuristic = h
+
+
+func get_done():
+ return done
+
+
+func set_done_false():
+ done = false
+
+
+func zero_reward():
+ reward = 0.0
diff --git a/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_3d.gd b/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_3d.gd
new file mode 100644
index 0000000..61a0529
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/controller/ai_controller_3d.gd
@@ -0,0 +1,136 @@
+extends Node3D
+class_name AIController3D
+
+enum ControlModes {
+ INHERIT_FROM_SYNC, ## Inherit setting from sync node
+ HUMAN, ## Test the environment manually
+ TRAINING, ## Train a model
+ ONNX_INFERENCE, ## Load a pretrained model using an .onnx file
+ RECORD_EXPERT_DEMOS ## Record observations and actions for expert demonstrations
+}
+@export var control_mode: ControlModes = ControlModes.INHERIT_FROM_SYNC
+## The path to a trained .onnx model file to use for inference (overrides the path set in sync node).
+@export var onnx_model_path := ""
+## Once the number of steps has passed, the flag 'needs_reset' will be set to 'true' for this instance.
+@export var reset_after := 1000
+
+@export_group("Record expert demos mode options")
+## Path where the demos will be saved. The file can later be used for imitation learning.
+@export var expert_demo_save_path: String
+## The action that erases the last recorded episode from the currently recorded data.
+@export var remove_last_episode_key: InputEvent
+## Action will be repeated for n frames. Will introduce control lag if larger than 1.
+## Can be used to ensure that action_repeat on inference and training matches
+## the recorded demonstrations.
+@export var action_repeat: int = 1
+
+@export_group("Multi-policy mode options")
+## Allows you to set certain agents to use different policies.
+## Changing has no effect with default SB3 training. Works with Rllib example.
+## Tutorial: https://github.com/edbeeching/godot_rl_agents/blob/main/docs/TRAINING_MULTIPLE_POLICIES.md
+@export var policy_name: String = "shared_policy"
+
+var onnx_model: ONNXModel
+
+var heuristic := "human"
+var done := false
+var reward := 0.0
+var n_steps := 0
+var needs_reset := false
+
+var _player: Node3D
+
+
+func _ready():
+ add_to_group("AGENT")
+
+
+func init(player: Node3D):
+ _player = player
+
+
+#region Methods that need implementing using the "extend script" option in Godot
+func get_obs() -> Dictionary:
+ assert(false, "the get_obs method is not implemented when extending from ai_controller")
+ return {"obs": []}
+
+
+func get_reward() -> float:
+ assert(false, "the get_reward method is not implemented when extending from ai_controller")
+ return 0.0
+
+
+func get_action_space() -> Dictionary:
+ assert(
+ false, "the get_action_space method is not implemented when extending from ai_controller"
+ )
+ return {
+ "example_actions_continous": {"size": 2, "action_type": "continuous"},
+ "example_actions_discrete": {"size": 2, "action_type": "discrete"},
+ }
+
+
+func set_action(action) -> void:
+ assert(false, "the set_action method is not implemented when extending from ai_controller")
+
+
+#endregion
+
+
+#region Methods that sometimes need implementing using the "extend script" option in Godot
+# Only needed if you are recording expert demos with this AIController
+func get_action() -> Array:
+ assert(
+ false,
+ "the get_action method is not implemented in extended AIController but demo_recorder is used"
+ )
+ return []
+
+
+# For providing additional info (e.g. `is_success` for SB3 training)
+func get_info() -> Dictionary:
+ return {}
+
+
+#endregion
+
+
+func _physics_process(delta):
+ n_steps += 1
+ if n_steps > reset_after:
+ needs_reset = true
+
+
+func get_obs_space():
+ # may need overriding if the obs space is complex
+ var obs = get_obs()
+ return {
+ "obs": {"size": [len(obs["obs"])], "space": "box"},
+ }
+
+
+func reset():
+ n_steps = 0
+ needs_reset = false
+
+
+func reset_if_done():
+ if done:
+ reset()
+
+
+func set_heuristic(h):
+ # sets the heuristic from "human" or "model" nothing to change here
+ heuristic = h
+
+
+func get_done():
+ return done
+
+
+func set_done_false():
+ done = false
+
+
+func zero_reward():
+ reward = 0.0
diff --git a/examples/PushBall/addons/godot_rl_agents/godot_rl_agents.gd b/examples/PushBall/addons/godot_rl_agents/godot_rl_agents.gd
new file mode 100644
index 0000000..e4fe136
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/godot_rl_agents.gd
@@ -0,0 +1,16 @@
+@tool
+extends EditorPlugin
+
+
+func _enter_tree():
+ # Initialization of the plugin goes here.
+ # Add the new type with a name, a parent type, a script and an icon.
+ add_custom_type("Sync", "Node", preload("sync.gd"), preload("icon.png"))
+ #add_custom_type("RaycastSensor2D2", "Node", preload("raycast_sensor_2d.gd"), preload("icon.png"))
+
+
+func _exit_tree():
+ # Clean-up of the plugin goes here.
+ # Always remember to remove it from the engine when deactivated.
+ remove_custom_type("Sync")
+ #remove_custom_type("RaycastSensor2D2")
diff --git a/examples/PushBall/addons/godot_rl_agents/icon.png b/examples/PushBall/addons/godot_rl_agents/icon.png
new file mode 100644
index 0000000..fd8190e
Binary files /dev/null and b/examples/PushBall/addons/godot_rl_agents/icon.png differ
diff --git a/examples/PushBall/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs
new file mode 100644
index 0000000..6dcfa18
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/ONNXInference.cs
@@ -0,0 +1,109 @@
+using Godot;
+using Microsoft.ML.OnnxRuntime;
+using Microsoft.ML.OnnxRuntime.Tensors;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace GodotONNX
+{
+ ///
+ public partial class ONNXInference : GodotObject
+ {
+
+ private InferenceSession session;
+ ///
+ /// Path to the ONNX model. Use Initialize to change it.
+ ///
+ private string modelPath;
+ private int batchSize;
+
+ private SessionOptions SessionOpt;
+
+ ///
+ /// init function
+ ///
+ ///
+ ///
+ /// Returns the output size of the model
+ public int Initialize(string Path, int BatchSize)
+ {
+ modelPath = Path;
+ batchSize = BatchSize;
+ SessionOpt = SessionConfigurator.MakeConfiguredSessionOptions();
+ session = LoadModel(modelPath);
+ return session.OutputMetadata["output"].Dimensions[1];
+ }
+
+
+ ///
+ public Godot.Collections.Dictionary> RunInference(Godot.Collections.Array obs, int state_ins)
+ {
+ //Current model: Any (Godot Rl Agents)
+ //Expects a tensor of shape [batch_size, input_size] type float named obs and a tensor of shape [batch_size] type float named state_ins
+
+ //Fill the input tensors
+ // create span from inputSize
+ var span = new float[obs.Count]; //There's probably a better way to do this
+ for (int i = 0; i < obs.Count; i++)
+ {
+ span[i] = obs[i];
+ }
+
+ IReadOnlyCollection inputs = new List
+ {
+ NamedOnnxValue.CreateFromTensor("obs", new DenseTensor(span, new int[] { batchSize, obs.Count })),
+ NamedOnnxValue.CreateFromTensor("state_ins", new DenseTensor(new float[] { state_ins }, new int[] { batchSize }))
+ };
+ IReadOnlyCollection outputNames = new List { "output", "state_outs" }; //ONNX is sensible to these names, as well as the input names
+
+ IDisposableReadOnlyCollection results;
+ //We do not use "using" here so we get a better exception explaination later
+ try
+ {
+ results = session.Run(inputs, outputNames);
+ }
+ catch (OnnxRuntimeException e)
+ {
+ //This error usually means that the model is not compatible with the input, beacause of the input shape (size)
+ GD.Print("Error at inference: ", e);
+ return null;
+ }
+ //Can't convert IEnumerable to Variant, so we have to convert it to an array or something
+ Godot.Collections.Dictionary> output = new Godot.Collections.Dictionary>();
+ DisposableNamedOnnxValue output1 = results.First();
+ DisposableNamedOnnxValue output2 = results.Last();
+ Godot.Collections.Array output1Array = new Godot.Collections.Array();
+ Godot.Collections.Array output2Array = new Godot.Collections.Array();
+
+ foreach (float f in output1.AsEnumerable())
+ {
+ output1Array.Add(f);
+ }
+
+ foreach (float f in output2.AsEnumerable())
+ {
+ output2Array.Add(f);
+ }
+
+ output.Add(output1.Name, output1Array);
+ output.Add(output2.Name, output2Array);
+
+ //Output is a dictionary of arrays, ex: { "output" : [0.1, 0.2, 0.3, 0.4, ...], "state_outs" : [0.5, ...]}
+ results.Dispose();
+ return output;
+ }
+ ///
+ public InferenceSession LoadModel(string Path)
+ {
+ using Godot.FileAccess file = FileAccess.Open(Path, Godot.FileAccess.ModeFlags.Read);
+ byte[] model = file.GetBuffer((int)file.GetLength());
+ //file.Close(); file.Dispose(); //Close the file, then dispose the reference.
+ return new InferenceSession(model, SessionOpt); //Load the model
+ }
+ public void FreeDisposables()
+ {
+ session.Dispose();
+ SessionOpt.Dispose();
+ }
+ }
+}
diff --git a/examples/PushBall/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs
new file mode 100644
index 0000000..ad7a41c
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/SessionConfigurator.cs
@@ -0,0 +1,131 @@
+using Godot;
+using Microsoft.ML.OnnxRuntime;
+
+namespace GodotONNX
+{
+ ///
+
+ public static class SessionConfigurator
+ {
+ public enum ComputeName
+ {
+ CUDA,
+ ROCm,
+ DirectML,
+ CoreML,
+ CPU
+ }
+
+ ///
+ public static SessionOptions MakeConfiguredSessionOptions()
+ {
+ SessionOptions sessionOptions = new();
+ SetOptions(sessionOptions);
+ return sessionOptions;
+ }
+
+ private static void SetOptions(SessionOptions sessionOptions)
+ {
+ sessionOptions.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_WARNING;
+ ApplySystemSpecificOptions(sessionOptions);
+ }
+
+ ///
+ static public void ApplySystemSpecificOptions(SessionOptions sessionOptions)
+ {
+ //Most code for this function is verbose only, the only reason it exists is to track
+ //implementation progress of the different compute APIs.
+
+ //December 2022: CUDA is not working.
+
+ string OSName = OS.GetName(); //Get OS Name
+
+ //ComputeName ComputeAPI = ComputeCheck(); //Get Compute API
+ // //TODO: Get CPU architecture
+
+ //Linux can use OpenVINO (C#) on x64 and ROCm on x86 (GDNative/C++)
+ //Windows can use OpenVINO (C#) on x64
+ //TODO: try TensorRT instead of CUDA
+ //TODO: Use OpenVINO for Intel Graphics
+
+ // Temporarily using CPU on all platforms to avoid errors detected with DML
+ ComputeName ComputeAPI = ComputeName.CPU;
+
+ //match OS and Compute API
+ GD.Print($"OS: {OSName} Compute API: {ComputeAPI}");
+
+ // CPU is set by default without appending necessary
+ // sessionOptions.AppendExecutionProvider_CPU(0);
+
+ /*
+ switch (OSName)
+ {
+ case "Windows": //Can use CUDA, DirectML
+ if (ComputeAPI is ComputeName.CUDA)
+ {
+ //CUDA
+ //sessionOptions.AppendExecutionProvider_CUDA(0);
+ //sessionOptions.AppendExecutionProvider_DML(0);
+ }
+ else if (ComputeAPI is ComputeName.DirectML)
+ {
+ //DirectML
+ //sessionOptions.AppendExecutionProvider_DML(0);
+ }
+ break;
+ case "X11": //Can use CUDA, ROCm
+ if (ComputeAPI is ComputeName.CUDA)
+ {
+ //CUDA
+ //sessionOptions.AppendExecutionProvider_CUDA(0);
+ }
+ if (ComputeAPI is ComputeName.ROCm)
+ {
+ //ROCm, only works on x86
+ //Research indicates that this has to be compiled as a GDNative plugin
+ //GD.Print("ROCm not supported yet, using CPU.");
+ //sessionOptions.AppendExecutionProvider_CPU(0);
+ }
+ break;
+ case "macOS": //Can use CoreML
+ if (ComputeAPI is ComputeName.CoreML)
+ { //CoreML
+ //TODO: Needs testing
+ //sessionOptions.AppendExecutionProvider_CoreML(0);
+ //CoreML on ARM64, out of the box, on x64 needs .tar file from GitHub
+ }
+ break;
+ default:
+ GD.Print("OS not Supported.");
+ break;
+ }
+ */
+ }
+
+
+ ///
+ public static ComputeName ComputeCheck()
+ {
+ string adapterName = Godot.RenderingServer.GetVideoAdapterName();
+ //string adapterVendor = Godot.RenderingServer.GetVideoAdapterVendor();
+ adapterName = adapterName.ToUpper(new System.Globalization.CultureInfo(""));
+ //TODO: GPU vendors for MacOS, what do they even use these days?
+
+ if (adapterName.Contains("INTEL"))
+ {
+ return ComputeName.DirectML;
+ }
+ if (adapterName.Contains("AMD") || adapterName.Contains("RADEON"))
+ {
+ return ComputeName.DirectML;
+ }
+ if (adapterName.Contains("NVIDIA"))
+ {
+ return ComputeName.CUDA;
+ }
+
+ GD.Print("Graphics Card not recognized."); //Should use CPU
+ return ComputeName.CPU;
+ }
+ }
+}
diff --git a/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml
new file mode 100644
index 0000000..91b07d6
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/ONNXInference.xml
@@ -0,0 +1,31 @@
+
+
+
+
+ The main ONNXInference Class that handles the inference process.
+
+
+
+
+ Starts the inference process.
+
+ Path to the ONNX model, expects a path inside resources.
+ How many observations will the model recieve.
+
+
+
+ Runs the given input through the model and returns the output.
+
+ Dictionary containing all observations.
+ How many different agents are creating these observations.
+ A Dictionary of arrays, containing instructions based on the observations.
+
+
+
+ Loads the given model into the inference process, using the best Execution provider available.
+
+ Path to the ONNX model, expects a path inside resources.
+ InferenceSession ready to run.
+
+
+
\ No newline at end of file
diff --git a/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml
new file mode 100644
index 0000000..f160c02
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/onnx/csharp/docs/SessionConfigurator.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ The main SessionConfigurator Class that handles the execution options and providers for the inference process.
+
+
+
+
+ Creates a SessionOptions with all available execution providers.
+
+ SessionOptions with all available execution providers.
+
+
+
+ Appends any execution provider available in the current system.
+
+
+ This function is mainly verbose for tracking implementation progress of different compute APIs.
+
+
+
+
+ Checks for available GPUs.
+
+ An integer identifier for each compute platform.
+
+
+
\ No newline at end of file
diff --git a/examples/PushBall/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd b/examples/PushBall/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd
new file mode 100644
index 0000000..e27f2c3
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/onnx/wrapper/ONNX_wrapper.gd
@@ -0,0 +1,51 @@
+extends Resource
+class_name ONNXModel
+var inferencer_script = load("res://addons/godot_rl_agents/onnx/csharp/ONNXInference.cs")
+
+var inferencer = null
+
+## How many action values the model outputs
+var action_output_size: int
+
+## Used to differentiate models
+## that only output continuous action mean (e.g. sb3, cleanrl export)
+## versus models that output mean and logstd (e.g. rllib export)
+var action_means_only: bool
+
+## Whether action_means_value has been set already for this model
+var action_means_only_set: bool
+
+# Must provide the path to the model and the batch size
+func _init(model_path, batch_size):
+ inferencer = inferencer_script.new()
+ action_output_size = inferencer.Initialize(model_path, batch_size)
+
+# This function is the one that will be called from the game,
+# requires the observation as an array and the state_ins as an int
+# returns an Array containing the action the model takes.
+func run_inference(obs: Array, state_ins: int) -> Dictionary:
+ if inferencer == null:
+ printerr("Inferencer not initialized")
+ return {}
+ return inferencer.RunInference(obs, state_ins)
+
+
+func _notification(what):
+ if what == NOTIFICATION_PREDELETE:
+ inferencer.FreeDisposables()
+ inferencer.free()
+
+# Check whether agent uses a continuous actions model with only action means or not
+func set_action_means_only(agent_action_space):
+ action_means_only_set = true
+ var continuous_only: bool = true
+ var continuous_actions: int
+ for action in agent_action_space:
+ if not agent_action_space[action]["action_type"] == "continuous":
+ continuous_only = false
+ break
+ else:
+ continuous_actions += agent_action_space[action]["size"]
+ if continuous_only:
+ if continuous_actions == action_output_size:
+ action_means_only = true
diff --git a/examples/PushBall/addons/godot_rl_agents/plugin.cfg b/examples/PushBall/addons/godot_rl_agents/plugin.cfg
new file mode 100644
index 0000000..b1bc988
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/plugin.cfg
@@ -0,0 +1,7 @@
+[plugin]
+
+name="GodotRLAgents"
+description="Custom nodes for the godot rl agents toolkit "
+author="Edward Beeching"
+version="0.1"
+script="godot_rl_agents.gd"
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn
new file mode 100644
index 0000000..5edb6c7
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ExampleRaycastSensor2D.tscn
@@ -0,0 +1,48 @@
+[gd_scene load_steps=5 format=3 uid="uid://ddeq7mn1ealyc"]
+
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd" id="1"]
+
+[sub_resource type="GDScript" id="2"]
+script/source = "extends Node2D
+
+
+
+func _physics_process(delta: float) -> void:
+ print(\"step start\")
+
+"
+
+[sub_resource type="GDScript" id="1"]
+script/source = "extends RayCast2D
+
+var steps = 1
+
+func _physics_process(delta: float) -> void:
+ print(\"processing raycast\")
+ steps += 1
+ if steps % 2:
+ force_raycast_update()
+
+ print(is_colliding())
+"
+
+[sub_resource type="CircleShape2D" id="3"]
+
+[node name="ExampleRaycastSensor2D" type="Node2D"]
+script = SubResource("2")
+
+[node name="ExampleAgent" type="Node2D" parent="."]
+position = Vector2(573, 314)
+rotation = 0.286234
+
+[node name="RaycastSensor2D" type="Node2D" parent="ExampleAgent"]
+script = ExtResource("1")
+
+[node name="TestRayCast2D" type="RayCast2D" parent="."]
+script = SubResource("1")
+
+[node name="StaticBody2D" type="StaticBody2D" parent="."]
+position = Vector2(1, 52)
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"]
+shape = SubResource("3")
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd
new file mode 100644
index 0000000..da170ba
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/GridSensor2D.gd
@@ -0,0 +1,235 @@
+@tool
+extends ISensor2D
+class_name GridSensor2D
+
+@export var debug_view := false:
+ get:
+ return debug_view
+ set(value):
+ debug_view = value
+ _update()
+
+@export_flags_2d_physics var detection_mask := 0:
+ get:
+ return detection_mask
+ set(value):
+ detection_mask = value
+ _update()
+
+@export var collide_with_areas := false:
+ get:
+ return collide_with_areas
+ set(value):
+ collide_with_areas = value
+ _update()
+
+@export var collide_with_bodies := true:
+ get:
+ return collide_with_bodies
+ set(value):
+ collide_with_bodies = value
+ _update()
+
+@export_range(1, 200, 0.1) var cell_width := 20.0:
+ get:
+ return cell_width
+ set(value):
+ cell_width = value
+ _update()
+
+@export_range(1, 200, 0.1) var cell_height := 20.0:
+ get:
+ return cell_height
+ set(value):
+ cell_height = value
+ _update()
+
+@export_range(1, 21, 2, "or_greater") var grid_size_x := 3:
+ get:
+ return grid_size_x
+ set(value):
+ grid_size_x = value
+ _update()
+
+@export_range(1, 21, 2, "or_greater") var grid_size_y := 3:
+ get:
+ return grid_size_y
+ set(value):
+ grid_size_y = value
+ _update()
+
+var _obs_buffer: PackedFloat64Array
+var _rectangle_shape: RectangleShape2D
+var _collision_mapping: Dictionary
+var _n_layers_per_cell: int
+
+var _highlighted_cell_color: Color
+var _standard_cell_color: Color
+
+
+func get_observation():
+ return _obs_buffer
+
+
+func _update():
+ if Engine.is_editor_hint():
+ if is_node_ready():
+ _spawn_nodes()
+
+
+func _ready() -> void:
+ _set_colors()
+
+ if Engine.is_editor_hint():
+ if get_child_count() == 0:
+ _spawn_nodes()
+ else:
+ _spawn_nodes()
+
+
+func _set_colors() -> void:
+ _standard_cell_color = Color(100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0)
+ _highlighted_cell_color = Color(255.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0)
+
+
+func _get_collision_mapping() -> Dictionary:
+ # defines which layer is mapped to which cell obs index
+ var total_bits = 0
+ var collision_mapping = {}
+ for i in 32:
+ var bit_mask = 2 ** i
+ if (detection_mask & bit_mask) > 0:
+ collision_mapping[i] = total_bits
+ total_bits += 1
+
+ return collision_mapping
+
+
+func _spawn_nodes():
+ for cell in get_children():
+ cell.name = "_%s" % cell.name # Otherwise naming below will fail
+ cell.queue_free()
+
+ _collision_mapping = _get_collision_mapping()
+ #prints("collision_mapping", _collision_mapping, len(_collision_mapping))
+ # allocate memory for the observations
+ _n_layers_per_cell = len(_collision_mapping)
+ _obs_buffer = PackedFloat64Array()
+ _obs_buffer.resize(grid_size_x * grid_size_y * _n_layers_per_cell)
+ _obs_buffer.fill(0)
+ #prints(len(_obs_buffer), _obs_buffer )
+
+ _rectangle_shape = RectangleShape2D.new()
+ _rectangle_shape.set_size(Vector2(cell_width, cell_height))
+
+ var shift := Vector2(
+ -(grid_size_x / 2) * cell_width,
+ -(grid_size_y / 2) * cell_height,
+ )
+
+ for i in grid_size_x:
+ for j in grid_size_y:
+ var cell_position = Vector2(i * cell_width, j * cell_height) + shift
+ _create_cell(i, j, cell_position)
+
+
+func _create_cell(i: int, j: int, position: Vector2):
+ var cell := Area2D.new()
+ cell.position = position
+ cell.name = "GridCell %s %s" % [i, j]
+ cell.modulate = _standard_cell_color
+
+ if collide_with_areas:
+ cell.area_entered.connect(_on_cell_area_entered.bind(i, j))
+ cell.area_exited.connect(_on_cell_area_exited.bind(i, j))
+
+ if collide_with_bodies:
+ cell.body_entered.connect(_on_cell_body_entered.bind(i, j))
+ cell.body_exited.connect(_on_cell_body_exited.bind(i, j))
+
+ cell.collision_layer = 0
+ cell.collision_mask = detection_mask
+ cell.monitorable = true
+ add_child(cell)
+ cell.set_owner(get_tree().edited_scene_root)
+
+ var col_shape := CollisionShape2D.new()
+ col_shape.shape = _rectangle_shape
+ col_shape.name = "CollisionShape2D"
+ cell.add_child(col_shape)
+ col_shape.set_owner(get_tree().edited_scene_root)
+
+ if debug_view:
+ var quad = MeshInstance2D.new()
+ quad.name = "MeshInstance2D"
+ var quad_mesh = QuadMesh.new()
+
+ quad_mesh.set_size(Vector2(cell_width, cell_height))
+
+ quad.mesh = quad_mesh
+ cell.add_child(quad)
+ quad.set_owner(get_tree().edited_scene_root)
+
+
+func _update_obs(cell_i: int, cell_j: int, collision_layer: int, entered: bool):
+ for key in _collision_mapping:
+ var bit_mask = 2 ** key
+ if (collision_layer & bit_mask) > 0:
+ var collison_map_index = _collision_mapping[key]
+
+ var obs_index = (
+ (cell_i * grid_size_x * _n_layers_per_cell)
+ + (cell_j * _n_layers_per_cell)
+ + collison_map_index
+ )
+ #prints(obs_index, cell_i, cell_j)
+ if entered:
+ _obs_buffer[obs_index] += 1
+ else:
+ _obs_buffer[obs_index] -= 1
+
+
+func _toggle_cell(cell_i: int, cell_j: int):
+ var cell = get_node_or_null("GridCell %s %s" % [cell_i, cell_j])
+
+ if cell == null:
+ print("cell not found, returning")
+
+ var n_hits = 0
+ var start_index = (cell_i * grid_size_x * _n_layers_per_cell) + (cell_j * _n_layers_per_cell)
+ for i in _n_layers_per_cell:
+ n_hits += _obs_buffer[start_index + i]
+
+ if n_hits > 0:
+ cell.modulate = _highlighted_cell_color
+ else:
+ cell.modulate = _standard_cell_color
+
+
+func _on_cell_area_entered(area: Area2D, cell_i: int, cell_j: int):
+ #prints("_on_cell_area_entered", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, area.collision_layer, true)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+ #print(_obs_buffer)
+
+
+func _on_cell_area_exited(area: Area2D, cell_i: int, cell_j: int):
+ #prints("_on_cell_area_exited", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, area.collision_layer, false)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+
+
+func _on_cell_body_entered(body: Node2D, cell_i: int, cell_j: int):
+ #prints("_on_cell_body_entered", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, body.collision_layer, true)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+
+
+func _on_cell_body_exited(body: Node2D, cell_i: int, cell_j: int):
+ #prints("_on_cell_body_exited", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, body.collision_layer, false)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd
new file mode 100644
index 0000000..67669a1
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/ISensor2D.gd
@@ -0,0 +1,25 @@
+extends Node2D
+class_name ISensor2D
+
+var _obs: Array = []
+var _active := false
+
+
+func get_observation():
+ pass
+
+
+func activate():
+ _active = true
+
+
+func deactivate():
+ _active = false
+
+
+func _update_observation():
+ pass
+
+
+func reset():
+ pass
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd
new file mode 100644
index 0000000..9bb54ed
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd
@@ -0,0 +1,118 @@
+@tool
+extends ISensor2D
+class_name RaycastSensor2D
+
+@export_flags_2d_physics var collision_mask := 1:
+ get:
+ return collision_mask
+ set(value):
+ collision_mask = value
+ _update()
+
+@export var collide_with_areas := false:
+ get:
+ return collide_with_areas
+ set(value):
+ collide_with_areas = value
+ _update()
+
+@export var collide_with_bodies := true:
+ get:
+ return collide_with_bodies
+ set(value):
+ collide_with_bodies = value
+ _update()
+
+@export var n_rays := 16.0:
+ get:
+ return n_rays
+ set(value):
+ n_rays = value
+ _update()
+
+@export_range(5, 3000, 5.0) var ray_length := 200:
+ get:
+ return ray_length
+ set(value):
+ ray_length = value
+ _update()
+@export_range(5, 360, 5.0) var cone_width := 360.0:
+ get:
+ return cone_width
+ set(value):
+ cone_width = value
+ _update()
+
+@export var debug_draw := true:
+ get:
+ return debug_draw
+ set(value):
+ debug_draw = value
+ _update()
+
+var _angles = []
+var rays := []
+
+
+func _update():
+ if Engine.is_editor_hint():
+ if debug_draw:
+ _spawn_nodes()
+ else:
+ for ray in get_children():
+ if ray is RayCast2D:
+ remove_child(ray)
+
+
+func _ready() -> void:
+ _spawn_nodes()
+
+
+func _spawn_nodes():
+ for ray in rays:
+ ray.queue_free()
+ rays = []
+
+ _angles = []
+ var step = cone_width / (n_rays)
+ var start = step / 2 - cone_width / 2
+
+ for i in n_rays:
+ var angle = start + i * step
+ var ray = RayCast2D.new()
+ ray.set_target_position(
+ Vector2(ray_length * cos(deg_to_rad(angle)), ray_length * sin(deg_to_rad(angle)))
+ )
+ ray.set_name("node_" + str(i))
+ ray.enabled = false
+ ray.collide_with_areas = collide_with_areas
+ ray.collide_with_bodies = collide_with_bodies
+ ray.collision_mask = collision_mask
+ add_child(ray)
+ rays.append(ray)
+
+ _angles.append(start + i * step)
+
+
+func get_observation() -> Array:
+ return self.calculate_raycasts()
+
+
+func calculate_raycasts() -> Array:
+ var result = []
+ for ray in rays:
+ ray.enabled = true
+ ray.force_raycast_update()
+ var distance = _get_raycast_distance(ray)
+ result.append(distance)
+ ray.enabled = false
+ return result
+
+
+func _get_raycast_distance(ray: RayCast2D) -> float:
+ if !ray.is_colliding():
+ return 0.0
+
+ var distance = (global_position - ray.get_collision_point()).length()
+ distance = clamp(distance, 0.0, ray_length)
+ return (ray_length - distance) / ray_length
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn
new file mode 100644
index 0000000..5ca402c
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.tscn
@@ -0,0 +1,7 @@
+[gd_scene load_steps=2 format=3 uid="uid://drvfihk5esgmv"]
+
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_2d/RaycastSensor2D.gd" id="1"]
+
+[node name="RaycastSensor2D" type="Node2D"]
+script = ExtResource("1")
+n_rays = 17.0
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn
new file mode 100644
index 0000000..a8057c7
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ExampleRaycastSensor3D.tscn
@@ -0,0 +1,6 @@
+[gd_scene format=3 uid="uid://biu787qh4woik"]
+
+[node name="ExampleRaycastSensor3D" type="Node3D"]
+
+[node name="Camera3D" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.804183, 0, 2.70146)
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd
new file mode 100644
index 0000000..24de9a4
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/GridSensor3D.gd
@@ -0,0 +1,258 @@
+@tool
+extends ISensor3D
+class_name GridSensor3D
+
+@export var debug_view := false:
+ get:
+ return debug_view
+ set(value):
+ debug_view = value
+ _update()
+
+@export_flags_3d_physics var detection_mask := 0:
+ get:
+ return detection_mask
+ set(value):
+ detection_mask = value
+ _update()
+
+@export var collide_with_areas := false:
+ get:
+ return collide_with_areas
+ set(value):
+ collide_with_areas = value
+ _update()
+
+@export var collide_with_bodies := false:
+ # NOTE! The sensor will not detect StaticBody3D, add an area to static bodies to detect them
+ get:
+ return collide_with_bodies
+ set(value):
+ collide_with_bodies = value
+ _update()
+
+@export_range(0.1, 2, 0.1) var cell_width := 1.0:
+ get:
+ return cell_width
+ set(value):
+ cell_width = value
+ _update()
+
+@export_range(0.1, 2, 0.1) var cell_height := 1.0:
+ get:
+ return cell_height
+ set(value):
+ cell_height = value
+ _update()
+
+@export_range(1, 21, 1, "or_greater") var grid_size_x := 3:
+ get:
+ return grid_size_x
+ set(value):
+ grid_size_x = value
+ _update()
+
+@export_range(1, 21, 1, "or_greater") var grid_size_z := 3:
+ get:
+ return grid_size_z
+ set(value):
+ grid_size_z = value
+ _update()
+
+var _obs_buffer: PackedFloat64Array
+var _box_shape: BoxShape3D
+var _collision_mapping: Dictionary
+var _n_layers_per_cell: int
+
+var _highlighted_box_material: StandardMaterial3D
+var _standard_box_material: StandardMaterial3D
+
+
+func get_observation():
+ return _obs_buffer
+
+
+func reset():
+ _obs_buffer.fill(0)
+
+
+func _update():
+ if Engine.is_editor_hint():
+ if is_node_ready():
+ _spawn_nodes()
+
+
+func _ready() -> void:
+ _make_materials()
+
+ if Engine.is_editor_hint():
+ if get_child_count() == 0:
+ _spawn_nodes()
+ else:
+ _spawn_nodes()
+
+
+func _make_materials() -> void:
+ if _highlighted_box_material != null and _standard_box_material != null:
+ return
+
+ _standard_box_material = StandardMaterial3D.new()
+ _standard_box_material.set_transparency(1) # ALPHA
+ _standard_box_material.albedo_color = Color(
+ 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0
+ )
+
+ _highlighted_box_material = StandardMaterial3D.new()
+ _highlighted_box_material.set_transparency(1) # ALPHA
+ _highlighted_box_material.albedo_color = Color(
+ 255.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0, 100.0 / 255.0
+ )
+
+
+func _get_collision_mapping() -> Dictionary:
+ # defines which layer is mapped to which cell obs index
+ var total_bits = 0
+ var collision_mapping = {}
+ for i in 32:
+ var bit_mask = 2 ** i
+ if (detection_mask & bit_mask) > 0:
+ collision_mapping[i] = total_bits
+ total_bits += 1
+
+ return collision_mapping
+
+
+func _spawn_nodes():
+ for cell in get_children():
+ cell.name = "_%s" % cell.name # Otherwise naming below will fail
+ cell.queue_free()
+
+ _collision_mapping = _get_collision_mapping()
+ #prints("collision_mapping", _collision_mapping, len(_collision_mapping))
+ # allocate memory for the observations
+ _n_layers_per_cell = len(_collision_mapping)
+ _obs_buffer = PackedFloat64Array()
+ _obs_buffer.resize(grid_size_x * grid_size_z * _n_layers_per_cell)
+ _obs_buffer.fill(0)
+ #prints(len(_obs_buffer), _obs_buffer )
+
+ _box_shape = BoxShape3D.new()
+ _box_shape.set_size(Vector3(cell_width, cell_height, cell_width))
+
+ var shift := Vector3(
+ -(grid_size_x / 2) * cell_width,
+ 0,
+ -(grid_size_z / 2) * cell_width,
+ )
+
+ for i in grid_size_x:
+ for j in grid_size_z:
+ var cell_position = Vector3(i * cell_width, 0.0, j * cell_width) + shift
+ _create_cell(i, j, cell_position)
+
+
+func _create_cell(i: int, j: int, position: Vector3):
+ var cell := Area3D.new()
+ cell.position = position
+ cell.name = "GridCell %s %s" % [i, j]
+
+ if collide_with_areas:
+ cell.area_entered.connect(_on_cell_area_entered.bind(i, j))
+ cell.area_exited.connect(_on_cell_area_exited.bind(i, j))
+
+ if collide_with_bodies:
+ cell.body_entered.connect(_on_cell_body_entered.bind(i, j))
+ cell.body_exited.connect(_on_cell_body_exited.bind(i, j))
+
+# cell.body_shape_entered.connect(_on_cell_body_shape_entered.bind(i, j))
+# cell.body_shape_exited.connect(_on_cell_body_shape_exited.bind(i, j))
+
+ cell.collision_layer = 0
+ cell.collision_mask = detection_mask
+ cell.monitorable = true
+ cell.input_ray_pickable = false
+ add_child(cell)
+ cell.set_owner(get_tree().edited_scene_root)
+
+ var col_shape := CollisionShape3D.new()
+ col_shape.shape = _box_shape
+ col_shape.name = "CollisionShape3D"
+ cell.add_child(col_shape)
+ col_shape.set_owner(get_tree().edited_scene_root)
+
+ if debug_view:
+ var box = MeshInstance3D.new()
+ box.name = "MeshInstance3D"
+ var box_mesh = BoxMesh.new()
+
+ box_mesh.set_size(Vector3(cell_width, cell_height, cell_width))
+ box_mesh.material = _standard_box_material
+
+ box.mesh = box_mesh
+ cell.add_child(box)
+ box.set_owner(get_tree().edited_scene_root)
+
+
+func _update_obs(cell_i: int, cell_j: int, collision_layer: int, entered: bool):
+ for key in _collision_mapping:
+ var bit_mask = 2 ** key
+ if (collision_layer & bit_mask) > 0:
+ var collison_map_index = _collision_mapping[key]
+
+ var obs_index = (
+ (cell_i * grid_size_z * _n_layers_per_cell)
+ + (cell_j * _n_layers_per_cell)
+ + collison_map_index
+ )
+ #prints(obs_index, cell_i, cell_j)
+ if entered:
+ _obs_buffer[obs_index] += 1
+ else:
+ _obs_buffer[obs_index] -= 1
+
+
+func _toggle_cell(cell_i: int, cell_j: int):
+ var cell = get_node_or_null("GridCell %s %s" % [cell_i, cell_j])
+
+ if cell == null:
+ print("cell not found, returning")
+
+ var n_hits = 0
+ var start_index = (cell_i * grid_size_z * _n_layers_per_cell) + (cell_j * _n_layers_per_cell)
+ for i in _n_layers_per_cell:
+ n_hits += _obs_buffer[start_index + i]
+
+ var cell_mesh = cell.get_node_or_null("MeshInstance3D")
+ if n_hits > 0:
+ cell_mesh.mesh.material = _highlighted_box_material
+ else:
+ cell_mesh.mesh.material = _standard_box_material
+
+
+func _on_cell_area_entered(area: Area3D, cell_i: int, cell_j: int):
+ #prints("_on_cell_area_entered", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, area.collision_layer, true)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+ #print(_obs_buffer)
+
+
+func _on_cell_area_exited(area: Area3D, cell_i: int, cell_j: int):
+ #prints("_on_cell_area_exited", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, area.collision_layer, false)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+
+
+func _on_cell_body_entered(body: Node3D, cell_i: int, cell_j: int):
+ #prints("_on_cell_body_entered", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, body.collision_layer, true)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
+
+
+func _on_cell_body_exited(body: Node3D, cell_i: int, cell_j: int):
+ #prints("_on_cell_body_exited", cell_i, cell_j)
+ _update_obs(cell_i, cell_j, body.collision_layer, false)
+ if debug_view:
+ _toggle_cell(cell_i, cell_j)
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd
new file mode 100644
index 0000000..aca3c2d
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/ISensor3D.gd
@@ -0,0 +1,25 @@
+extends Node3D
+class_name ISensor3D
+
+var _obs: Array = []
+var _active := false
+
+
+func get_observation():
+ pass
+
+
+func activate():
+ _active = true
+
+
+func deactivate():
+ _active = false
+
+
+func _update_observation():
+ pass
+
+
+func reset():
+ pass
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd
new file mode 100644
index 0000000..96dfb6a
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd
@@ -0,0 +1,63 @@
+extends Node3D
+class_name RGBCameraSensor3D
+var camera_pixels = null
+
+@onready var camera_texture := $Control/CameraTexture as Sprite2D
+@onready var processed_texture := $Control/ProcessedTexture as Sprite2D
+@onready var sub_viewport := $SubViewport as SubViewport
+@onready var displayed_image: ImageTexture
+
+@export var render_image_resolution := Vector2(36, 36)
+## Display size does not affect rendered or sent image resolution.
+## Scale is relative to either render image or downscale image resolution
+## depending on which mode is set.
+@export var displayed_image_scale_factor := Vector2(8, 8)
+
+@export_group("Downscale image options")
+## Enable to downscale the rendered image before sending the obs.
+@export var downscale_image: bool = false
+## If downscale_image is true, will display the downscaled image instead of rendered image.
+@export var display_downscaled_image: bool = true
+## This is the resolution of the image that will be sent after downscaling
+@export var resized_image_resolution := Vector2(36, 36)
+
+
+func _ready():
+ sub_viewport.size = render_image_resolution
+ camera_texture.scale = displayed_image_scale_factor
+
+ if downscale_image and display_downscaled_image:
+ camera_texture.visible = false
+ processed_texture.scale = displayed_image_scale_factor
+ else:
+ processed_texture.visible = false
+
+
+func get_camera_pixel_encoding():
+ var image := camera_texture.get_texture().get_image() as Image
+
+ if downscale_image:
+ image.resize(
+ resized_image_resolution.x, resized_image_resolution.y, Image.INTERPOLATE_NEAREST
+ )
+ if display_downscaled_image:
+ if not processed_texture.texture:
+ displayed_image = ImageTexture.create_from_image(image)
+ processed_texture.texture = displayed_image
+ else:
+ displayed_image.update(image)
+
+ return image.get_data().hex_encode()
+
+
+func get_camera_shape() -> Array:
+ var size = resized_image_resolution if downscale_image else render_image_resolution
+
+ assert(
+ size.x >= 36 and size.y >= 36,
+ "Camera sensor sent image resolution must be 36x36 or larger."
+ )
+ if sub_viewport.transparent_bg:
+ return [4, size.y, size.x]
+ else:
+ return [3, size.y, size.x]
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn
new file mode 100644
index 0000000..d58649c
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.tscn
@@ -0,0 +1,35 @@
+[gd_scene load_steps=3 format=3 uid="uid://baaywi3arsl2m"]
+
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_3d/RGBCameraSensor3D.gd" id="1"]
+
+[sub_resource type="ViewportTexture" id="ViewportTexture_y72s3"]
+viewport_path = NodePath("SubViewport")
+
+[node name="RGBCameraSensor3D" type="Node3D"]
+script = ExtResource("1")
+
+[node name="RemoteTransform" type="RemoteTransform3D" parent="."]
+remote_path = NodePath("../SubViewport/Camera")
+
+[node name="SubViewport" type="SubViewport" parent="."]
+size = Vector2i(36, 36)
+render_target_update_mode = 3
+
+[node name="Camera" type="Camera3D" parent="SubViewport"]
+near = 0.5
+
+[node name="Control" type="Control" parent="."]
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+metadata/_edit_use_anchors_ = true
+
+[node name="CameraTexture" type="Sprite2D" parent="Control"]
+texture = SubResource("ViewportTexture_y72s3")
+centered = false
+
+[node name="ProcessedTexture" type="Sprite2D" parent="Control"]
+centered = false
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd
new file mode 100644
index 0000000..1357529
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd
@@ -0,0 +1,185 @@
+@tool
+extends ISensor3D
+class_name RayCastSensor3D
+@export_flags_3d_physics var collision_mask = 1:
+ get:
+ return collision_mask
+ set(value):
+ collision_mask = value
+ _update()
+@export_flags_3d_physics var boolean_class_mask = 1:
+ get:
+ return boolean_class_mask
+ set(value):
+ boolean_class_mask = value
+ _update()
+
+@export var n_rays_width := 6.0:
+ get:
+ return n_rays_width
+ set(value):
+ n_rays_width = value
+ _update()
+
+@export var n_rays_height := 6.0:
+ get:
+ return n_rays_height
+ set(value):
+ n_rays_height = value
+ _update()
+
+@export var ray_length := 10.0:
+ get:
+ return ray_length
+ set(value):
+ ray_length = value
+ _update()
+
+@export var cone_width := 60.0:
+ get:
+ return cone_width
+ set(value):
+ cone_width = value
+ _update()
+
+@export var cone_height := 60.0:
+ get:
+ return cone_height
+ set(value):
+ cone_height = value
+ _update()
+
+@export var collide_with_areas := false:
+ get:
+ return collide_with_areas
+ set(value):
+ collide_with_areas = value
+ _update()
+
+@export var collide_with_bodies := true:
+ get:
+ return collide_with_bodies
+ set(value):
+ collide_with_bodies = value
+ _update()
+
+@export var class_sensor := false
+
+var rays := []
+var geo = null
+
+
+func _update():
+ if Engine.is_editor_hint():
+ if is_node_ready():
+ _spawn_nodes()
+
+
+func _ready() -> void:
+ if Engine.is_editor_hint():
+ if get_child_count() == 0:
+ _spawn_nodes()
+ else:
+ _spawn_nodes()
+
+
+func _spawn_nodes():
+ print("spawning nodes")
+ for ray in get_children():
+ ray.queue_free()
+ if geo:
+ geo.clear()
+ #$Lines.remove_points()
+ rays = []
+
+ var horizontal_step = cone_width / (n_rays_width)
+ var vertical_step = cone_height / (n_rays_height)
+
+ var horizontal_start = horizontal_step / 2 - cone_width / 2
+ var vertical_start = vertical_step / 2 - cone_height / 2
+
+ var points = []
+
+ for i in n_rays_width:
+ for j in n_rays_height:
+ var angle_w = horizontal_start + i * horizontal_step
+ var angle_h = vertical_start + j * vertical_step
+ #angle_h = 0.0
+ var ray = RayCast3D.new()
+ var cast_to = to_spherical_coords(ray_length, angle_w, angle_h)
+ ray.set_target_position(cast_to)
+
+ points.append(cast_to)
+
+ ray.set_name("node_" + str(i) + " " + str(j))
+ ray.enabled = true
+ ray.collide_with_bodies = collide_with_bodies
+ ray.collide_with_areas = collide_with_areas
+ ray.collision_mask = collision_mask
+ add_child(ray)
+ ray.set_owner(get_tree().edited_scene_root)
+ rays.append(ray)
+ ray.force_raycast_update()
+
+
+# if Engine.editor_hint:
+# _create_debug_lines(points)
+
+
+func _create_debug_lines(points):
+ if not geo:
+ geo = ImmediateMesh.new()
+ add_child(geo)
+
+ geo.clear()
+ geo.begin(Mesh.PRIMITIVE_LINES)
+ for point in points:
+ geo.set_color(Color.AQUA)
+ geo.add_vertex(Vector3.ZERO)
+ geo.add_vertex(point)
+ geo.end()
+
+
+func display():
+ if geo:
+ geo.display()
+
+
+func to_spherical_coords(r, inc, azimuth) -> Vector3:
+ return Vector3(
+ r * sin(deg_to_rad(inc)) * cos(deg_to_rad(azimuth)),
+ r * sin(deg_to_rad(azimuth)),
+ r * cos(deg_to_rad(inc)) * cos(deg_to_rad(azimuth))
+ )
+
+
+func get_observation() -> Array:
+ return self.calculate_raycasts()
+
+
+func calculate_raycasts() -> Array:
+ var result = []
+ for ray in rays:
+ ray.set_enabled(true)
+ ray.force_raycast_update()
+ var distance = _get_raycast_distance(ray)
+
+ result.append(distance)
+ if class_sensor:
+ var hit_class: float = 0
+ if ray.get_collider():
+ var hit_collision_layer = ray.get_collider().collision_layer
+ hit_collision_layer = hit_collision_layer & collision_mask
+ hit_class = (hit_collision_layer & boolean_class_mask) > 0
+ result.append(float(hit_class))
+ ray.set_enabled(false)
+ return result
+
+
+func _get_raycast_distance(ray: RayCast3D) -> float:
+ if !ray.is_colliding():
+ return 0.0
+
+ var distance = (global_transform.origin - ray.get_collision_point()).length()
+ distance = clamp(distance, 0.0, ray_length)
+ return (ray_length - distance) / ray_length
diff --git a/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn
new file mode 100644
index 0000000..35f9796
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.tscn
@@ -0,0 +1,27 @@
+[gd_scene load_steps=2 format=3 uid="uid://b803cbh1fmy66"]
+
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd" id="1"]
+
+[node name="RaycastSensor3D" type="Node3D"]
+script = ExtResource("1")
+n_rays_width = 4.0
+n_rays_height = 2.0
+ray_length = 11.0
+
+[node name="node_1 0" type="RayCast3D" parent="."]
+target_position = Vector3(-1.38686, -2.84701, 10.5343)
+
+[node name="node_1 1" type="RayCast3D" parent="."]
+target_position = Vector3(-1.38686, 2.84701, 10.5343)
+
+[node name="node_2 0" type="RayCast3D" parent="."]
+target_position = Vector3(1.38686, -2.84701, 10.5343)
+
+[node name="node_2 1" type="RayCast3D" parent="."]
+target_position = Vector3(1.38686, 2.84701, 10.5343)
+
+[node name="node_3 0" type="RayCast3D" parent="."]
+target_position = Vector3(4.06608, -2.84701, 9.81639)
+
+[node name="node_3 1" type="RayCast3D" parent="."]
+target_position = Vector3(4.06608, 2.84701, 9.81639)
diff --git a/examples/PushBall/addons/godot_rl_agents/sync.gd b/examples/PushBall/addons/godot_rl_agents/sync.gd
new file mode 100644
index 0000000..f47decb
--- /dev/null
+++ b/examples/PushBall/addons/godot_rl_agents/sync.gd
@@ -0,0 +1,598 @@
+extends Node
+class_name Sync
+
+# --fixed-fps 2000 --disable-render-loop
+
+enum ControlModes {
+ HUMAN, ## Test the environment manually
+ TRAINING, ## Train a model
+ ONNX_INFERENCE ## Load a pretrained model using an .onnx file
+}
+@export var control_mode: ControlModes = ControlModes.TRAINING
+## Action will be repeated for n frames (Godot physics steps).
+@export_range(1, 10, 1, "or_greater") var action_repeat := 8
+## Speeds up the physics in the environment to enable faster training.
+@export_range(0, 10, 0.1, "or_greater") var speed_up := 1.0
+## The path to a trained .onnx model file to use for inference (only needed for the 'Onnx Inference' control mode).
+@export var onnx_model_path := ""
+
+# Onnx model stored for each requested path
+var onnx_models: Dictionary
+
+@onready var start_time = Time.get_ticks_msec()
+
+const MAJOR_VERSION := "0"
+const MINOR_VERSION := "7"
+const DEFAULT_PORT := "11008"
+const DEFAULT_SEED := "1"
+var stream: StreamPeerTCP = null
+var connected = false
+var message_center
+var should_connect = true
+
+var all_agents: Array
+var agents_training: Array
+## Policy name of each agent, for use with multi-policy multi-agent RL cases
+var agents_training_policy_names: Array[String] = ["shared_policy"]
+var agents_inference: Array
+var agents_heuristic: Array
+
+## For recording expert demos
+var agent_demo_record: Node
+## File path for writing recorded trajectories
+var expert_demo_save_path: String
+## Stores recorded trajectories
+var demo_trajectories: Array
+## A trajectory includes obs: Array, acts: Array, terminal (set in Python env instead)
+var current_demo_trajectory: Array
+
+var need_to_send_obs = false
+var args = null
+var initialized = false
+var just_reset = false
+var onnx_model = null
+var n_action_steps = 0
+
+var _action_space_training: Array[Dictionary] = []
+var _action_space_inference: Array[Dictionary] = []
+var _obs_space_training: Array[Dictionary] = []
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+ await get_parent().ready
+ get_tree().set_pause(true)
+ _initialize()
+ await get_tree().create_timer(1.0).timeout
+ get_tree().set_pause(false)
+
+
+func _initialize():
+ _get_agents()
+ args = _get_args()
+ Engine.physics_ticks_per_second = _get_speedup() * 60 # Replace with function body.
+ Engine.time_scale = _get_speedup() * 1.0
+ prints(
+ "physics ticks",
+ Engine.physics_ticks_per_second,
+ Engine.time_scale,
+ _get_speedup(),
+ speed_up
+ )
+
+ _set_heuristic("human", all_agents)
+
+ _initialize_training_agents()
+ _initialize_inference_agents()
+ _initialize_demo_recording()
+
+ _set_seed()
+ _set_action_repeat()
+ initialized = true
+
+
+func _initialize_training_agents():
+ if agents_training.size() > 0:
+ _obs_space_training.resize(agents_training.size())
+ _action_space_training.resize(agents_training.size())
+ for agent_idx in range(0, agents_training.size()):
+ _obs_space_training[agent_idx] = agents_training[agent_idx].get_obs_space()
+ _action_space_training[agent_idx] = agents_training[agent_idx].get_action_space()
+ connected = connect_to_server()
+ if connected:
+ _set_heuristic("model", agents_training)
+ _handshake()
+ _send_env_info()
+ else:
+ push_warning(
+ "Couldn't connect to Python server, using human controls instead. ",
+ "Did you start the training server using e.g. `gdrl` from the console?"
+ )
+
+
+func _initialize_inference_agents():
+ if agents_inference.size() > 0:
+ if control_mode == ControlModes.ONNX_INFERENCE:
+ assert(
+ FileAccess.file_exists(onnx_model_path),
+ "Onnx Model Path set on Sync node does not exist: %s" % onnx_model_path
+ )
+ onnx_models[onnx_model_path] = ONNXModel.new(onnx_model_path, 1)
+
+ for agent in agents_inference:
+ var action_space = agent.get_action_space()
+ _action_space_inference.append(action_space)
+
+ var agent_onnx_model: ONNXModel
+ if agent.onnx_model_path.is_empty():
+ assert(
+ onnx_models.has(onnx_model_path),
+ (
+ "Node %s has no onnx model path set " % agent.get_path()
+ + "and sync node's control mode is not set to OnnxInference. "
+ + "Either add the path to the AIController, "
+ + "or if you want to use the path set on sync node instead, "
+ + "set control mode to OnnxInference."
+ )
+ )
+ prints(
+ "Info: AIController %s" % agent.get_path(),
+ "has no onnx model path set.",
+ "Using path set on the sync node instead."
+ )
+ agent_onnx_model = onnx_models[onnx_model_path]
+ else:
+ if not onnx_models.has(agent.onnx_model_path):
+ assert(
+ FileAccess.file_exists(agent.onnx_model_path),
+ (
+ "Onnx Model Path set on %s node does not exist: %s"
+ % [agent.get_path(), agent.onnx_model_path]
+ )
+ )
+ onnx_models[agent.onnx_model_path] = ONNXModel.new(agent.onnx_model_path, 1)
+ agent_onnx_model = onnx_models[agent.onnx_model_path]
+
+ agent.onnx_model = agent_onnx_model
+ if not agent_onnx_model.action_means_only_set:
+ agent_onnx_model.set_action_means_only(action_space)
+
+ _set_heuristic("model", agents_inference)
+
+
+func _initialize_demo_recording():
+ if agent_demo_record:
+ expert_demo_save_path = agent_demo_record.expert_demo_save_path
+ assert(
+ not expert_demo_save_path.is_empty(),
+ "Expert demo save path set in %s is empty." % agent_demo_record.get_path()
+ )
+
+ InputMap.add_action("RemoveLastDemoEpisode")
+ InputMap.action_add_event(
+ "RemoveLastDemoEpisode", agent_demo_record.remove_last_episode_key
+ )
+ current_demo_trajectory.resize(2)
+ current_demo_trajectory[0] = []
+ current_demo_trajectory[1] = []
+ agent_demo_record.heuristic = "demo_record"
+
+
+func _physics_process(_delta):
+ # two modes, human control, agent control
+ # pause tree, send obs, get actions, set actions, unpause tree
+
+ _demo_record_process()
+
+ if n_action_steps % action_repeat != 0:
+ n_action_steps += 1
+ return
+
+ n_action_steps += 1
+
+ _training_process()
+ _inference_process()
+ _heuristic_process()
+
+
+func _training_process():
+ if connected:
+ get_tree().set_pause(true)
+
+ var obs = _get_obs_from_agents(agents_training)
+ var info = _get_info_from_agents(agents_training)
+
+ if just_reset:
+ just_reset = false
+
+ var reply = {"type": "reset", "obs": obs, "info": info}
+ _send_dict_as_json_message(reply)
+ # this should go straight to getting the action and setting it checked the agent, no need to perform one phyics tick
+ get_tree().set_pause(false)
+ return
+
+ if need_to_send_obs:
+ need_to_send_obs = false
+ var reward = _get_reward_from_agents()
+ var done = _get_done_from_agents()
+ #_reset_agents_if_done() # this ensures the new observation is from the next env instance : NEEDS REFACTOR
+
+ var reply = {"type": "step", "obs": obs, "reward": reward, "done": done, "info": info}
+ _send_dict_as_json_message(reply)
+
+ var handled = handle_message()
+
+
+func _inference_process():
+ if agents_inference.size() > 0:
+ var obs: Array = _get_obs_from_agents(agents_inference)
+ var actions = []
+
+ for agent_id in range(0, agents_inference.size()):
+ var model: ONNXModel = agents_inference[agent_id].onnx_model
+ var action = model.run_inference(obs[agent_id]["obs"], 1.0)
+ var action_dict = _extract_action_dict(
+ action["output"], _action_space_inference[agent_id], model.action_means_only
+ )
+ actions.append(action_dict)
+
+ _set_agent_actions(actions, agents_inference)
+ _reset_agents_if_done(agents_inference)
+ get_tree().set_pause(false)
+
+
+func _demo_record_process():
+ if not agent_demo_record:
+ return
+
+ if Input.is_action_just_pressed("RemoveLastDemoEpisode"):
+ print("[Sync script][Demo recorder] Removing last recorded episode.")
+ demo_trajectories.remove_at(demo_trajectories.size() - 1)
+ print("Remaining episode count: %d" % demo_trajectories.size())
+
+ if n_action_steps % agent_demo_record.action_repeat != 0:
+ return
+
+ var obs_dict: Dictionary = agent_demo_record.get_obs()
+
+ # Get the current obs from the agent
+ assert(
+ obs_dict.has("obs"),
+ "Demo recorder needs an 'obs' key in get_obs() returned dictionary to record obs from."
+ )
+ current_demo_trajectory[0].append(obs_dict.obs)
+
+ # Get the action applied for the current obs from the agent
+ agent_demo_record.set_action()
+ var acts = agent_demo_record.get_action()
+
+ var terminal = agent_demo_record.get_done()
+ # Record actions only for non-terminal states
+ if terminal:
+ agent_demo_record.set_done_false()
+ else:
+ current_demo_trajectory[1].append(acts)
+
+ if terminal:
+ #current_demo_trajectory[2].append(true)
+ demo_trajectories.append(current_demo_trajectory.duplicate(true))
+ print("[Sync script][Demo recorder] Recorded episode count: %d" % demo_trajectories.size())
+ current_demo_trajectory[0].clear()
+ current_demo_trajectory[1].clear()
+
+
+func _heuristic_process():
+ for agent in agents_heuristic:
+ _reset_agents_if_done(agents_heuristic)
+
+
+func _extract_action_dict(action_array: Array, action_space: Dictionary, action_means_only: bool):
+ var index = 0
+ var result = {}
+ for key in action_space.keys():
+ var size = action_space[key]["size"]
+ var action_type = action_space[key]["action_type"]
+ if action_type == "discrete":
+ var largest_logit: float # Value of the largest logit for this action in the actions array
+ var largest_logit_idx: int # Index of the largest logit for this action in the actions array
+ for logit_idx in range(0, size):
+ var logit_value = action_array[index + logit_idx]
+ if logit_value > largest_logit:
+ largest_logit = logit_value
+ largest_logit_idx = logit_idx
+ result[key] = largest_logit_idx # Index of the largest logit is the discrete action value
+ index += size
+ elif action_type == "continuous":
+ # For continous actions, we only take the action mean values
+ result[key] = clamp_array(action_array.slice(index, index + size), -1.0, 1.0)
+ if action_means_only:
+ index += size # model only outputs action means, so we move index by size
+ else:
+ index += size * 2 # model outputs logstd after action mean, we skip the logstd part
+
+ else:
+ assert(
+ false,
+ (
+ 'Only "discrete" and "continuous" action types supported. Found: %s action type set.'
+ % action_type
+ )
+ )
+
+ return result
+
+
+## For AIControllers that inherit mode from sync, sets the correct mode.
+func _set_agent_mode(agent: Node):
+ var agent_inherits_mode: bool = agent.control_mode == agent.ControlModes.INHERIT_FROM_SYNC
+
+ if agent_inherits_mode:
+ match control_mode:
+ ControlModes.HUMAN:
+ agent.control_mode = agent.ControlModes.HUMAN
+ ControlModes.TRAINING:
+ agent.control_mode = agent.ControlModes.TRAINING
+ ControlModes.ONNX_INFERENCE:
+ agent.control_mode = agent.ControlModes.ONNX_INFERENCE
+
+
+func _get_agents():
+ all_agents = get_tree().get_nodes_in_group("AGENT")
+ for agent in all_agents:
+ _set_agent_mode(agent)
+
+ if agent.control_mode == agent.ControlModes.TRAINING:
+ agents_training.append(agent)
+ elif agent.control_mode == agent.ControlModes.ONNX_INFERENCE:
+ agents_inference.append(agent)
+ elif agent.control_mode == agent.ControlModes.HUMAN:
+ agents_heuristic.append(agent)
+ elif agent.control_mode == agent.ControlModes.RECORD_EXPERT_DEMOS:
+ assert(
+ not agent_demo_record,
+ "Currently only a single AIController can be used for recording expert demos."
+ )
+ agent_demo_record = agent
+
+ var training_agent_count = agents_training.size()
+ agents_training_policy_names.resize(training_agent_count)
+ for i in range(0, training_agent_count):
+ agents_training_policy_names[i] = agents_training[i].policy_name
+
+
+func _set_heuristic(heuristic, agents: Array):
+ for agent in agents:
+ agent.set_heuristic(heuristic)
+
+
+func _handshake():
+ print("performing handshake")
+
+ var json_dict = _get_dict_json_message()
+ assert(json_dict["type"] == "handshake")
+ var major_version = json_dict["major_version"]
+ var minor_version = json_dict["minor_version"]
+ if major_version != MAJOR_VERSION:
+ print("WARNING: major verison mismatch ", major_version, " ", MAJOR_VERSION)
+ if minor_version != MINOR_VERSION:
+ print("WARNING: minor verison mismatch ", minor_version, " ", MINOR_VERSION)
+
+ print("handshake complete")
+
+
+func _get_dict_json_message():
+ # returns a dictionary from of the most recent message
+ # this is not waiting
+ while stream.get_available_bytes() == 0:
+ stream.poll()
+ if stream.get_status() != 2:
+ print("server disconnected status, closing")
+ get_tree().quit()
+ return null
+
+ OS.delay_usec(10)
+
+ var message = stream.get_string()
+ var json_data = JSON.parse_string(message)
+
+ return json_data
+
+
+func _send_dict_as_json_message(dict):
+ stream.put_string(JSON.stringify(dict, "", false))
+
+
+func _send_env_info():
+ var json_dict = _get_dict_json_message()
+ assert(json_dict["type"] == "env_info")
+
+ var message = {
+ "type": "env_info",
+ "observation_space": _obs_space_training,
+ "action_space": _action_space_training,
+ "n_agents": len(agents_training),
+ "agent_policy_names": agents_training_policy_names
+ }
+ _send_dict_as_json_message(message)
+
+
+func connect_to_server():
+ print("Waiting for one second to allow server to start")
+ OS.delay_msec(1000)
+ print("trying to connect to server")
+ stream = StreamPeerTCP.new()
+
+ # "localhost" was not working on windows VM, had to use the IP
+ var ip = "127.0.0.1"
+ var port = _get_port()
+ var connect = stream.connect_to_host(ip, port)
+ stream.set_no_delay(true) # TODO check if this improves performance or not
+ stream.poll()
+ # Fetch the status until it is either connected (2) or failed to connect (3)
+ while stream.get_status() < 2:
+ stream.poll()
+ return stream.get_status() == 2
+
+
+func _get_args():
+ print("getting command line arguments")
+ var arguments = {}
+ for argument in OS.get_cmdline_args():
+ print(argument)
+ if argument.find("=") > -1:
+ var key_value = argument.split("=")
+ arguments[key_value[0].lstrip("--")] = key_value[1]
+ else:
+ # Options without an argument will be present in the dictionary,
+ # with the value set to an empty string.
+ arguments[argument.lstrip("--")] = ""
+
+ return arguments
+
+
+func _get_speedup():
+ print(args)
+ return args.get("speedup", str(speed_up)).to_float()
+
+
+func _get_port():
+ return args.get("port", DEFAULT_PORT).to_int()
+
+
+func _set_seed():
+ var _seed = args.get("env_seed", DEFAULT_SEED).to_int()
+ seed(_seed)
+
+
+func _set_action_repeat():
+ action_repeat = args.get("action_repeat", str(action_repeat)).to_int()
+
+
+func disconnect_from_server():
+ stream.disconnect_from_host()
+
+
+func handle_message() -> bool:
+ # get json message: reset, step, close
+ var message = _get_dict_json_message()
+ if message["type"] == "close":
+ print("received close message, closing game")
+ get_tree().quit()
+ get_tree().set_pause(false)
+ return true
+
+ if message["type"] == "reset":
+ print("resetting all agents")
+ _reset_agents()
+ just_reset = true
+ get_tree().set_pause(false)
+ #print("resetting forcing draw")
+# RenderingServer.force_draw()
+# var obs = _get_obs_from_agents()
+# print("obs ", obs)
+# var reply = {
+# "type": "reset",
+# "obs": obs
+# }
+# _send_dict_as_json_message(reply)
+ return true
+
+ if message["type"] == "call":
+ var method = message["method"]
+ var returns = _call_method_on_agents(method)
+ var reply = {"type": "call", "returns": returns}
+ print("calling method from Python")
+ _send_dict_as_json_message(reply)
+ return handle_message()
+
+ if message["type"] == "action":
+ var action = message["action"]
+ _set_agent_actions(action, agents_training)
+ need_to_send_obs = true
+ get_tree().set_pause(false)
+ return true
+
+ print("message was not handled")
+ return false
+
+
+func _call_method_on_agents(method):
+ var returns = []
+ for agent in all_agents:
+ returns.append(agent.call(method))
+
+ return returns
+
+
+func _reset_agents_if_done(agents = all_agents):
+ for agent in agents:
+ if agent.get_done():
+ agent.set_done_false()
+
+
+func _reset_agents(agents = all_agents):
+ for agent in agents:
+ agent.needs_reset = true
+ #agent.reset()
+
+
+func _get_obs_from_agents(agents: Array = all_agents):
+ var obs = []
+ for agent in agents:
+ obs.append(agent.get_obs())
+ return obs
+
+
+func _get_reward_from_agents(agents: Array = agents_training):
+ var rewards = []
+ for agent in agents:
+ rewards.append(agent.get_reward())
+ agent.zero_reward()
+ return rewards
+
+
+func _get_info_from_agents(agents: Array = all_agents):
+ var info = []
+ for agent in agents:
+ info.append(agent.get_info())
+ return info
+
+
+func _get_done_from_agents(agents: Array = agents_training):
+ var dones = []
+ for agent in agents:
+ var done = agent.get_done()
+ if done:
+ agent.set_done_false()
+ dones.append(done)
+ return dones
+
+
+func _set_agent_actions(actions, agents: Array = all_agents):
+ for i in range(len(actions)):
+ agents[i].set_action(actions[i])
+
+
+func clamp_array(arr: Array, min: float, max: float):
+ var output: Array = []
+ for a in arr:
+ output.append(clamp(a, min, max))
+ return output
+
+
+## Save recorded export demos on window exit (Close game window instead of "Stop" button in Godot Editor)
+func _notification(what):
+ if demo_trajectories.size() == 0 or expert_demo_save_path.is_empty():
+ return
+
+ if what == NOTIFICATION_PREDELETE:
+ var json_string = JSON.stringify(demo_trajectories, "", false)
+ var file = FileAccess.open(expert_demo_save_path, FileAccess.WRITE)
+
+ if not file:
+ var error: Error = FileAccess.get_open_error()
+ assert(not error, "There was an error opening the file: %d" % error)
+
+ file.store_line(json_string)
+ var error = file.get_error()
+ assert(not error, "There was an error after trying to write to the file: %d" % error)
diff --git a/examples/PushBall/assets/goal.glb b/examples/PushBall/assets/goal.glb
new file mode 100644
index 0000000..c283f3d
Binary files /dev/null and b/examples/PushBall/assets/goal.glb differ
diff --git a/examples/PushBall/assets/license.md b/examples/PushBall/assets/license.md
new file mode 100644
index 0000000..3ce90a3
--- /dev/null
+++ b/examples/PushBall/assets/license.md
@@ -0,0 +1,3 @@
+The following license is only for the graphical assets in the folder "assets", including subfolders, specifically .glb and .png files:
+Author: Ivan Dodic (https://github.com/Ivan-267),
+License: https://creativecommons.org/licenses/by/4.0/
\ No newline at end of file
diff --git a/examples/PushBall/assets/robot.glb b/examples/PushBall/assets/robot.glb
new file mode 100644
index 0000000..f14e0b7
Binary files /dev/null and b/examples/PushBall/assets/robot.glb differ
diff --git a/examples/PushBall/assets/tiles/grass.glb b/examples/PushBall/assets/tiles/grass.glb
new file mode 100644
index 0000000..0b7d721
Binary files /dev/null and b/examples/PushBall/assets/tiles/grass.glb differ
diff --git a/examples/PushBall/assets/tiles/grass_grass.png b/examples/PushBall/assets/tiles/grass_grass.png
new file mode 100644
index 0000000..0776d27
Binary files /dev/null and b/examples/PushBall/assets/tiles/grass_grass.png differ
diff --git a/examples/PushBall/assets/tiles/gray.glb b/examples/PushBall/assets/tiles/gray.glb
new file mode 100644
index 0000000..b492e88
Binary files /dev/null and b/examples/PushBall/assets/tiles/gray.glb differ
diff --git a/examples/PushBall/assets/tiles/green.glb b/examples/PushBall/assets/tiles/green.glb
new file mode 100644
index 0000000..5b60982
Binary files /dev/null and b/examples/PushBall/assets/tiles/green.glb differ
diff --git a/examples/PushBall/assets/tiles/platform.glb b/examples/PushBall/assets/tiles/platform.glb
new file mode 100644
index 0000000..53ca706
Binary files /dev/null and b/examples/PushBall/assets/tiles/platform.glb differ
diff --git a/examples/PushBall/assets/tiles/tree.glb b/examples/PushBall/assets/tiles/tree.glb
new file mode 100644
index 0000000..cd75810
Binary files /dev/null and b/examples/PushBall/assets/tiles/tree.glb differ
diff --git a/examples/PushBall/assets/tiles/wooden_fence.glb b/examples/PushBall/assets/tiles/wooden_fence.glb
new file mode 100644
index 0000000..ae0b32a
Binary files /dev/null and b/examples/PushBall/assets/tiles/wooden_fence.glb differ
diff --git a/examples/PushBall/ground_sensor.tscn b/examples/PushBall/ground_sensor.tscn
new file mode 100644
index 0000000..b0ecdd8
--- /dev/null
+++ b/examples/PushBall/ground_sensor.tscn
@@ -0,0 +1,106 @@
+[gd_scene load_steps=2 format=3 uid="uid://cs4v3usqu455o"]
+
+[ext_resource type="Script" path="res://scenes/robot/RayGridSensor.gd" id="1_e1dtn"]
+
+[node name="GroundSensor" type="Node3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.25, 0, -3.2)
+script = ExtResource("1_e1dtn")
+n_rays_height = 4.0
+ray_length = 2.025
+grid_width = 3.0
+grid_height = 5.0
+
+[node name="node_0 0" type="RayCast3D" parent="."]
+target_position = Vector3(0, -2.025, 0)
+
+[node name="_RayCast3D_22425" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_0 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_0 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_1 0" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 0)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="_RayCast3D_22426" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_1 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_1 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="_RayCast3D_22427" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="_RayCast3D_22428" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_2 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_2 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_3 0" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, 0)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_3 1" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_3 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_3 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_4 0" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 0)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_4 1" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_4 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_4 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_5 0" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, 0)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_5 1" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, 1.25)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_5 2" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, 2.5)
+target_position = Vector3(0, -2.025, 0)
+
+[node name="node_5 3" type="RayCast3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.5, 0, 3.75)
+target_position = Vector3(0, -2.025, 0)
diff --git a/examples/PushBall/icon.svg b/examples/PushBall/icon.svg
new file mode 100644
index 0000000..3fe4f4a
--- /dev/null
+++ b/examples/PushBall/icon.svg
@@ -0,0 +1 @@
+
diff --git a/examples/PushBall/model.onnx b/examples/PushBall/model.onnx
new file mode 100644
index 0000000..7d1b3a5
Binary files /dev/null and b/examples/PushBall/model.onnx differ
diff --git a/examples/PushBall/project.godot b/examples/PushBall/project.godot
new file mode 100644
index 0000000..f1a3052
--- /dev/null
+++ b/examples/PushBall/project.godot
@@ -0,0 +1,61 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=5
+
+[application]
+
+config/name="PushTheBall"
+run/main_scene="res://scenes/training_scene.tscn"
+config/features=PackedStringArray("4.3", "C#", "Forward Plus")
+config/icon="res://icon.svg"
+
+[dotnet]
+
+project/assembly_name="PushBall"
+
+[editor_plugins]
+
+enabled=PackedStringArray("res://addons/godot_rl_agents/plugin.cfg")
+
+[input]
+
+move_left={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
+move_right={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
+move_up={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
+move_down={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
+push={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
+]
+}
+
+[physics]
+
+common/max_physics_steps_per_frame=32
diff --git a/examples/PushBall/readme.md b/examples/PushBall/readme.md
new file mode 100644
index 0000000..4be8dd6
--- /dev/null
+++ b/examples/PushBall/readme.md
@@ -0,0 +1,130 @@
+# Push Ball
+A ball-pushing robot environment.
+
+https://github.com/user-attachments/assets/71cf8787-db48-4c9f-a6da-dbbbbaa52211
+
+# Goal:
+The robot needs to push the ball into the goal.
+
+# Observations:
+```gdscript
+func get_obs() -> Dictionary:
+ var observations: Array[float] = []
+ for raycast_sensor in raycast_sensors:
+ var obs = raycast_sensor.get_observation()
+ observations.append_array(obs)
+
+ var player_to_goal := player.to_local(player.goal.global_position)
+ var player_to_goal_dir := player_to_goal.normalized()
+ var player_to_goal_dist := clampf(player_to_goal.length() / 5.0, 0, 1.0)
+
+ var player_to_ball := player.to_local(player.ball.global_position)
+ var player_to_ball_dir := player_to_ball.normalized()
+ var player_to_ball_dist := clampf(player_to_ball.length() / 10.0, 0, 1.0)
+
+ var player_velocity = player.linear_velocity
+ player_velocity = player.global_basis.inverse() * player_velocity
+ player_velocity = player_velocity.limit_length(4) / 4
+
+ var ball_velocity = player.ball.linear_velocity
+ ball_velocity = player.global_basis.inverse() * ball_velocity
+ ball_velocity = ball_velocity.limit_length(4) / 4
+
+ (
+ observations
+ . append_array(
+ [
+ player_to_goal_dir.x,
+ player_to_goal_dir.z,
+ player_to_goal_dist,
+ player_to_ball_dir.x,
+ player_to_ball_dir.z,
+ player_to_ball_dist,
+ player_velocity.x,
+ player_velocity.z,
+ ball_velocity.x,
+ ball_velocity.z,
+ n_steps / float(reset_after),
+ ]
+ )
+ )
+
+ return {"obs": observations}
+```
+
+# Action space:
+
+There are 2 continuous actions used by the agent, for moving and turning:
+
+```gdscript
+func get_action_space() -> Dictionary:
+ return {
+ "move": {"size": 1, "action_type": "continuous"},
+ "turn": {"size": 1, "action_type": "continuous"}
+ }
+
+```
+
+To incentivize forward movement, the backward action is clamped in `set_action` (so moving backward is slower):
+
+```gdscript
+ player.requested_movement = clampf(action.move[0], -1.0, 0.2)
+ player.requested_turn = clampf(action.turn[0], -1.0, 1.0)
+```
+
+# Rewards and episode end condition:
+Reward is given when:
+- The ball approaches the goal (best distance based)
+- The robot approaches the ball (best distance based)
+- The robot falls down or the episode times out (negative rewards in these cases)
+
+Episode ends when:
+- The ball reaches the goal
+- Either the player or ball fall down
+- Episode times out after a certain amount of steps (adjustable in AIController)
+
+
+# Training:
+
+These are the training settings used to train the included onnx file:
+
+[SB3 example script](https://github.com/edbeeching/godot_rl_agents/blob/main/examples/stable_baselines3_example.py) was used for training, with the following changes:
+
+```python
+ learning_rate = 0.0001 if not args.linear_lr_schedule else linear_schedule(0.0003)
+ model: PPO = PPO(
+ "MlpPolicy",
+ env,
+ n_steps=256,
+ batch_size=256 * env.num_envs,
+ clip_range=0.1,
+ target_kl=0.01,
+ learning_rate=learning_rate,
+ n_epochs=50,
+ ent_coef=0.0065,
+ tensorboard_log=args.experiment_dir,
+ verbose=2,
+ )
+```
+
+Note: Additional changes not detailed above are needed to use the MlpPolicy (`SBGSingleObsEnv` should be used), but you should be able to use the `MultiInput` policy instead.
+
+SB3 example script cmd arguments:
+
+```python
+--n_parallel=4
+--onnx_export_path=model.onnx
+--timesteps=100_000_000
+--save_model_path=model.zip
+--speedup=20
+```
+
+Notes:
+- Training was manually stopped at around 21m steps.
+- `--env_path` also needs to be set to the exported executable.
+
+This environment was made by [Ivan267.](https://github.com/Ivan-267)
+
+
+# Testing the trained onnx:
+A trained onnx file is included. To test it, open the environment, then open the `res://scenes/onnx_test_scene.tscn` scene, then press `F6`.
diff --git a/examples/PushBall/scenes/ball/ball.gd b/examples/PushBall/scenes/ball/ball.gd
new file mode 100644
index 0000000..99034f5
--- /dev/null
+++ b/examples/PushBall/scenes/ball/ball.gd
@@ -0,0 +1,10 @@
+extends RigidBody3D
+class_name Ball
+
+@export var spawn_position_manager: SpawnPositionManager
+
+
+func reset():
+ global_transform = spawn_position_manager.get_spawn_position()
+ linear_velocity = Vector3.ZERO
+ angular_velocity = Vector3.ZERO
diff --git a/examples/PushBall/scenes/ball/ball.tscn b/examples/PushBall/scenes/ball/ball.tscn
new file mode 100644
index 0000000..c43773c
--- /dev/null
+++ b/examples/PushBall/scenes/ball/ball.tscn
@@ -0,0 +1,64 @@
+[gd_scene load_steps=10 format=3 uid="uid://i2xan4njr6b3"]
+
+[ext_resource type="Script" path="res://scenes/ball/ball.gd" id="1_ctddt"]
+[ext_resource type="PackedScene" uid="uid://bmc018ke831mi" path="res://scenes/spawn_position_manager/spawn_positions.tscn" id="2_r851m"]
+
+[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_o5xow"]
+friction = 0.5
+bounce = 0.5
+
+[sub_resource type="SphereShape3D" id="SphereShape3D_7ksrn"]
+
+[sub_resource type="FastNoiseLite" id="FastNoiseLite_bwtfo"]
+noise_type = 5
+
+[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_1w6s6"]
+in_3d_space = true
+seamless = true
+seamless_blend_skirt = 1.0
+noise = SubResource("FastNoiseLite_bwtfo")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4qk56"]
+render_priority = -1
+cull_mode = 1
+shading_mode = 0
+albedo_color = Color(0, 0, 0, 1)
+disable_receive_shadows = true
+grow = true
+grow_amount = 0.04
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_25ryc"]
+next_pass = SubResource("StandardMaterial3D_4qk56")
+albedo_color = Color(0.2494, 0.86, 0.82947, 1)
+albedo_texture = SubResource("NoiseTexture2D_1w6s6")
+metallic_specular = 1.0
+roughness = 0.0
+uv1_triplanar = true
+texture_filter = 0
+
+[sub_resource type="SphereMesh" id="SphereMesh_tah8n"]
+material = SubResource("StandardMaterial3D_25ryc")
+radial_segments = 32
+rings = 16
+
+[node name="Ball" type="RigidBody3D" node_paths=PackedStringArray("spawn_position_manager")]
+collision_layer = 8388608
+collision_mask = 513
+mass = 0.1
+physics_material_override = SubResource("PhysicsMaterial_o5xow")
+gravity_scale = 4.0
+continuous_cd = true
+linear_damp_mode = 1
+linear_damp = 4.0
+angular_damp_mode = 1
+angular_damp = 10.0
+script = ExtResource("1_ctddt")
+spawn_position_manager = NodePath("SpawnPositions")
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
+shape = SubResource("SphereShape3D_7ksrn")
+
+[node name="SpawnPositions" parent="." instance=ExtResource("2_r851m")]
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+mesh = SubResource("SphereMesh_tah8n")
diff --git a/examples/PushBall/scenes/goal/goal.gd b/examples/PushBall/scenes/goal/goal.gd
new file mode 100644
index 0000000..63616bb
--- /dev/null
+++ b/examples/PushBall/scenes/goal/goal.gd
@@ -0,0 +1,13 @@
+extends Area3D
+
+@export var spawn_position_manager: SpawnPositionManager
+@onready var initial_transform := transform
+@onready var pointer := $goal/GoalPointer
+
+
+func _physics_process(delta: float) -> void:
+ pointer.rotate_y(delta * 2)
+
+
+func reset():
+ global_transform = spawn_position_manager.get_spawn_position()
diff --git a/examples/PushBall/scenes/goal/goal.tscn b/examples/PushBall/scenes/goal/goal.tscn
new file mode 100644
index 0000000..4bb0e06
--- /dev/null
+++ b/examples/PushBall/scenes/goal/goal.tscn
@@ -0,0 +1,35 @@
+[gd_scene load_steps=7 format=3 uid="uid://b44vhh42y4dsq"]
+
+[ext_resource type="Script" path="res://scenes/goal/goal.gd" id="1_3bxxn"]
+[ext_resource type="PackedScene" uid="uid://8cvhxosmcq6" path="res://assets/goal.glb" id="2_dhf6t"]
+[ext_resource type="PackedScene" uid="uid://bmc018ke831mi" path="res://scenes/spawn_position_manager/spawn_positions.tscn" id="2_mxo1m"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_fw6v3"]
+transparency = 1
+albedo_color = Color(1, 1, 0, 0.670588)
+
+[sub_resource type="BoxMesh" id="BoxMesh_kg8u1"]
+material = SubResource("StandardMaterial3D_fw6v3")
+size = Vector3(2, 1, 2)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_ntota"]
+size = Vector3(2, 1, 2)
+
+[node name="Goal" type="Area3D" node_paths=PackedStringArray("spawn_position_manager")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, -4.814)
+collision_layer = 129
+collision_mask = 8388609
+script = ExtResource("1_3bxxn")
+spawn_position_manager = NodePath("SpawnPositions")
+
+[node name="goal" parent="." instance=ExtResource("2_dhf6t")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.015, 0)
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+visible = false
+mesh = SubResource("BoxMesh_kg8u1")
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
+shape = SubResource("BoxShape3D_ntota")
+
+[node name="SpawnPositions" parent="." instance=ExtResource("2_mxo1m")]
diff --git a/examples/PushBall/scenes/levels/all_levels.tscn b/examples/PushBall/scenes/levels/all_levels.tscn
new file mode 100644
index 0000000..747bbd0
--- /dev/null
+++ b/examples/PushBall/scenes/levels/all_levels.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=5 format=3 uid="uid://cck7kpuva1vvs"]
+
+[ext_resource type="PackedScene" uid="uid://d32ntbmtrnc2q" path="res://scenes/levels/game_scene4.tscn" id="2_ow08o"]
+[ext_resource type="PackedScene" uid="uid://c53ucq8gavhuw" path="res://scenes/levels/game_scene3.tscn" id="3_gjead"]
+[ext_resource type="PackedScene" uid="uid://b0x45hi2a0acs" path="res://scenes/levels/game_scene5.tscn" id="4_8wn7o"]
+[ext_resource type="PackedScene" uid="uid://bhcgcxco45ugn" path="res://scenes/levels/game_scene.tscn" id="5_sko1o"]
+
+[node name="AllLevels" type="Node3D"]
+
+[node name="Camera3D" type="Camera3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 0.515038, 0.857167, 0, -0.857167, 0.515038, 40, 16.555, 14.165)
+
+[node name="GameScene" parent="." instance=ExtResource("5_sko1o")]
+
+[node name="GameScene3" parent="." instance=ExtResource("3_gjead")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 40, 0, -2)
+
+[node name="GameScene4" parent="." instance=ExtResource("2_ow08o")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 80, 0, 0)
+
+[node name="GameScene5" parent="." instance=ExtResource("4_8wn7o")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 120, 0, 0)
diff --git a/examples/PushBall/scenes/levels/game_scene.tscn b/examples/PushBall/scenes/levels/game_scene.tscn
new file mode 100644
index 0000000..c9df679
--- /dev/null
+++ b/examples/PushBall/scenes/levels/game_scene.tscn
@@ -0,0 +1,65 @@
+[gd_scene load_steps=7 format=3 uid="uid://bhcgcxco45ugn"]
+
+[ext_resource type="Script" path="res://scenes/levels/level_manager.gd" id="1_7koww"]
+[ext_resource type="PackedScene" uid="uid://dj6uaupgnjtgm" path="res://scenes/robot/robot.tscn" id="2_5xkem"]
+[ext_resource type="PackedScene" uid="uid://i2xan4njr6b3" path="res://scenes/ball/ball.tscn" id="4_0fucp"]
+[ext_resource type="MeshLibrary" uid="uid://dd25bvxh87k52" path="res://scenes/tiles/mesh_library.tres" id="4_f0s4p"]
+[ext_resource type="PackedScene" uid="uid://b44vhh42y4dsq" path="res://scenes/goal/goal.tscn" id="5_wf7cw"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_e2xuh"]
+size = Vector3(8, 2, 18)
+
+[node name="GameScene" type="Node3D" node_paths=PackedStringArray("nodes_to_reset")]
+script = ExtResource("1_7koww")
+nodes_to_reset = [NodePath("Ball"), NodePath("Goal")]
+
+[node name="Robot" parent="." instance=ExtResource("2_5xkem")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
+
+[node name="Map" type="Node3D" parent="."]
+
+[node name="GridMap" type="GridMap" parent="Map"]
+mesh_library = ExtResource("4_f0s4p")
+data = {
+"cells": PackedInt32Array(5, 65535, 5, 5, 0, 5, 0, 2, 1, 65535, 2, 1, 65534, 2, 1, 1, 2, 1, 1, 1, 1, 1, 0, 1, 1, 65535, 1, 1, 65534, 1, 1, 65533, 1, 65534, 65533, 1, 65534, 65534, 1, 65534, 65535, 1, 65534, 1, 1, 65534, 0, 1, 65535, 1, 1, 0, 1, 1, 0, 0, 1, 0, 65535, 1, 0, 65534, 1, 0, 65533, 1, 65535, 65533, 1, 65535, 65534, 1, 65535, 65535, 1, 65535, 0, 1, 65534, 3, 1, 65535, 3, 1, 0, 3, 1, 1, 3, 1, 1, 65532, 1, 65535, 65532, 1, 65534, 65532, 1, 65537, 65532, 1441796, 65538, 65532, 1048580, 65538, 65533, 1048580, 65538, 65534, 1048580, 65538, 65535, 1048580, 65538, 0, 1048580, 65538, 1, 1048580, 65538, 3, 1048580, 131069, 65532, 1441796, 131069, 65533, 1441796, 131069, 65534, 1441796, 131069, 65535, 1441796, 131069, 0, 1441796, 131069, 1, 1441796, 131069, 2, 1441796, 131069, 3, 1441796, 131070, 4, 4, 131071, 4, 4, 65536, 4, 4, 65537, 4, 4, 65538, 2, 1048580, 1, 65531, 0, 0, 65531, 0, 65533, 65531, 3, 65534, 65531, 0, 65535, 65531, 0, 1, 4, 0, 0, 4, 0, 65535, 4, 0, 65534, 4, 0, 65533, 4, 3, 65533, 3, 0, 65533, 2, 0, 65533, 1, 3, 65533, 0, 0, 65533, 65535, 0, 65533, 65534, 3, 65533, 65533, 0, 65533, 65532, 0, 2, 65532, 0, 2, 0, 0, 2, 65535, 0, 2, 3, 0, 2, 4, 3, 2, 1, 3, 2, 2, 0, 2, 65534, 3, 2, 65533, 0, 2, 65531, 3, 0, 65532, 1, 65537, 65531, 655364, 65536, 65531, 655364, 131071, 65531, 655364, 131070, 65531, 655364)
+}
+metadata/_editor_floor_ = Vector3(0, 1, 0)
+
+[node name="FloorCollider" type="StaticBody3D" parent="Map"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1)
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="Map/FloorCollider"]
+shape = SubResource("BoxShape3D_e2xuh")
+
+[node name="Ball" parent="." instance=ExtResource("4_0fucp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
+
+[node name="Node3D" type="Node3D" parent="Ball/SpawnPositions" index="0"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, -1)
+
+[node name="Node3D2" type="Node3D" parent="Ball/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, -1)
+
+[node name="Node3D3" type="Node3D" parent="Ball/SpawnPositions" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1)
+
+[node name="Node3D4" type="Node3D" parent="Ball/SpawnPositions" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, 1)
+
+[node name="Goal" parent="." instance=ExtResource("5_wf7cw")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 2, -7)
+
+[node name="Node3D" type="Node3D" parent="Goal/SpawnPositions" index="0"]
+
+[node name="Node3D2" type="Node3D" parent="Goal/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, 0)
+
+[node name="Node3D3" type="Node3D" parent="Goal/SpawnPositions" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 14)
+
+[node name="Node3D4" type="Node3D" parent="Goal/SpawnPositions" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 0, 14)
+
+[editable path="Ball"]
+[editable path="Goal"]
+[editable path="Goal/SpawnPositions"]
diff --git a/examples/PushBall/scenes/levels/game_scene3.tscn b/examples/PushBall/scenes/levels/game_scene3.tscn
new file mode 100644
index 0000000..910fb37
--- /dev/null
+++ b/examples/PushBall/scenes/levels/game_scene3.tscn
@@ -0,0 +1,69 @@
+[gd_scene load_steps=9 format=3 uid="uid://c53ucq8gavhuw"]
+
+[ext_resource type="Script" path="res://scenes/levels/level_manager.gd" id="1_rqk3a"]
+[ext_resource type="PackedScene" uid="uid://dj6uaupgnjtgm" path="res://scenes/robot/robot.tscn" id="2_he2qg"]
+[ext_resource type="MeshLibrary" uid="uid://dd25bvxh87k52" path="res://scenes/tiles/mesh_library.tres" id="3_3vxpv"]
+[ext_resource type="PackedScene" uid="uid://i2xan4njr6b3" path="res://scenes/ball/ball.tscn" id="4_2f4cs"]
+[ext_resource type="PackedScene" uid="uid://b44vhh42y4dsq" path="res://scenes/goal/goal.tscn" id="5_3guq0"]
+[ext_resource type="PackedScene" uid="uid://ddlyhy8ad7r6h" path="res://scenes/levels/platform.tscn" id="5_qgr7p"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_eqybw"]
+size = Vector3(6, 2, 8)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_ok4dv"]
+size = Vector3(6, 2, 8)
+
+[node name="GameScene3" type="Node3D" node_paths=PackedStringArray("nodes_to_reset")]
+script = ExtResource("1_rqk3a")
+nodes_to_reset = [NodePath("Ball"), NodePath("Goal"), NodePath("Platform")]
+
+[node name="Robot" parent="." instance=ExtResource("2_he2qg")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 9.5)
+
+[node name="Map" type="Node3D" parent="."]
+
+[node name="GridMap" type="GridMap" parent="Map"]
+mesh_library = ExtResource("3_3vxpv")
+data = {
+"cells": PackedInt32Array(65534, 3, 1048579, 65534, 4, 1048576, 65534, 5, 1048579, 65535, 3, 1048577, 65535, 4, 1048577, 65535, 5, 1048576, 0, 3, 1048577, 0, 4, 1048577, 0, 5, 1048576, 1, 3, 1048579, 1, 4, 1048576, 1, 5, 1048579, 65536, 5, 4, 131071, 5, 4, 131070, 4, 1441796, 131070, 3, 1441796, 65537, 3, 1048580, 65537, 4, 1048580, 65534, 65533, 655363, 65534, 65534, 0, 65534, 65535, 655363, 65535, 65533, 0, 65535, 65534, 1, 65535, 65535, 1, 0, 65533, 0, 0, 65534, 1, 0, 65535, 1, 1, 65533, 655363, 1, 65534, 0, 1, 65535, 655363, 131070, 65534, 1441796, 131070, 65535, 1441796, 131071, 65533, 655364, 65536, 65533, 655364, 65537, 65534, 1048580, 65537, 65535, 1048580)
+}
+metadata/_editor_floor_ = Vector3(0, 1, 0)
+
+[node name="FloorCollider" type="StaticBody3D" parent="Map"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1)
+
+[node name="CollisionShape3D8" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -1.6292e-07, 0, 8)
+shape = SubResource("BoxShape3D_eqybw")
+
+[node name="CollisionShape3D9" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -2.06632e-07, 0, -4)
+shape = SubResource("BoxShape3D_ok4dv")
+
+[node name="Ball" parent="." instance=ExtResource("4_2f4cs")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 7)
+
+[node name="SpawnPositions" parent="Ball" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
+
+[node name="Node3D" type="Node3D" parent="Ball/SpawnPositions" index="0"]
+
+[node name="Goal" parent="." instance=ExtResource("5_3guq0")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2, -3)
+
+[node name="Node3D" type="Node3D" parent="Goal/SpawnPositions" index="0"]
+
+[node name="Node3D2" type="Node3D" parent="Goal/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, 0)
+
+[node name="Platform" parent="." instance=ExtResource("5_qgr7p")]
+transform = Transform3D(1, 0, -1.74846e-07, 0, 1, 0, 1.74846e-07, 0, 1, -1, 0, 3)
+
+[node name="Node3D" type="Node3D" parent="Platform/SpawnPositions" index="0"]
+
+[node name="Node3D2" type="Node3D" parent="Platform/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0, -4.76837e-07)
+
+[editable path="Ball"]
+[editable path="Goal"]
+[editable path="Platform"]
diff --git a/examples/PushBall/scenes/levels/game_scene4.tscn b/examples/PushBall/scenes/levels/game_scene4.tscn
new file mode 100644
index 0000000..d08d676
--- /dev/null
+++ b/examples/PushBall/scenes/levels/game_scene4.tscn
@@ -0,0 +1,89 @@
+[gd_scene load_steps=8 format=3 uid="uid://d32ntbmtrnc2q"]
+
+[ext_resource type="Script" path="res://scenes/levels/level_manager.gd" id="1_flvlp"]
+[ext_resource type="PackedScene" uid="uid://dj6uaupgnjtgm" path="res://scenes/robot/robot.tscn" id="2_h11iq"]
+[ext_resource type="MeshLibrary" uid="uid://dd25bvxh87k52" path="res://scenes/tiles/mesh_library.tres" id="3_dhg3i"]
+[ext_resource type="PackedScene" uid="uid://i2xan4njr6b3" path="res://scenes/ball/ball.tscn" id="4_pwn6m"]
+[ext_resource type="PackedScene" uid="uid://b44vhh42y4dsq" path="res://scenes/goal/goal.tscn" id="5_bvys5"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_mlj80"]
+size = Vector3(2, 2, 22)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_4nr14"]
+size = Vector3(2, 2, 18)
+
+[node name="GameScene4" type="Node3D" node_paths=PackedStringArray("nodes_to_reset")]
+script = ExtResource("1_flvlp")
+nodes_to_reset = [NodePath("Ball"), NodePath("Goal")]
+
+[node name="Robot" parent="." instance=ExtResource("2_h11iq")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2.5, 1)
+level_id = [0, 0, 1, 0]
+
+[node name="Map" type="Node3D" parent="."]
+
+[node name="GridMap" type="GridMap" parent="Map"]
+mesh_library = ExtResource("3_dhg3i")
+data = {
+"cells": PackedInt32Array(65530, 65531, 655360, 65530, 65532, 655360, 65530, 65533, 655360, 65530, 65534, 655360, 65530, 0, 655360, 65530, 1, 655360, 65530, 2, 655360, 65531, 65531, 655361, 65531, 65532, 655361, 65531, 65533, 655361, 65531, 65534, 655361, 65531, 65535, 655361, 65531, 0, 655361, 65531, 1, 655361, 65531, 2, 655361, 65531, 3, 655361, 65532, 65535, 655361, 65533, 65535, 655361, 65534, 65535, 655361, 65535, 65531, 655361, 65535, 65532, 655361, 65535, 65533, 655361, 65535, 65534, 655361, 65535, 65535, 655361, 65535, 0, 655361, 65535, 1, 655361, 65535, 2, 655361, 65535, 3, 655361, 0, 65535, 655361, 1, 65535, 655361, 2, 65535, 655361, 3, 65531, 1, 3, 65532, 655361, 3, 65533, 655361, 3, 65534, 655361, 3, 65535, 655361, 3, 0, 655361, 3, 1, 655361, 3, 2, 655361, 3, 3, 655361, 4, 65531, 655360, 4, 65532, 655360, 4, 65533, 655360, 4, 65534, 655360, 4, 0, 655360, 4, 1, 655360, 4, 2, 655360, 4, 3, 655360, 131066, 3, 1441796, 131066, 2, 1441796, 131066, 1, 1441796, 131066, 0, 1441796, 131066, 65535, 1441796, 131066, 65534, 1441796, 131066, 65533, 1441796, 131066, 65531, 1441796, 131066, 65532, 1441796, 65540, 65531, 1048580, 65540, 65532, 1048580, 65540, 65533, 1048580, 65540, 65534, 1048580, 65540, 65535, 1048580, 65540, 0, 1048580, 65540, 1, 1048580, 65540, 2, 1048580, 65540, 3, 1048580, 0, 3, 1, 1, 3, 1, 2, 3, 1, 65534, 3, 1, 65533, 3, 1, 65532, 3, 1, 65532, 65531, 1, 65533, 65531, 1, 65534, 65531, 1, 0, 65531, 1, 1, 65531, 1, 2, 65531, 1, 4, 4, 655363, 3, 4, 0, 2, 4, 655360, 1, 4, 0, 0, 4, 0, 65535, 4, 655363, 65534, 4, 655360, 65533, 4, 655360, 65532, 4, 655360, 65531, 4, 0, 65530, 65530, 655363, 65531, 65530, 0, 65532, 65530, 655360, 65533, 65530, 655360, 65534, 65530, 655360, 65535, 65530, 655363, 0, 65530, 655360, 1, 65530, 655360, 2, 65530, 655360, 3, 65530, 0, 4, 65530, 655363, 131067, 4, 4, 131068, 4, 4, 131069, 4, 4, 131070, 4, 4, 131071, 4, 4, 65536, 4, 4, 65537, 4, 4, 65538, 4, 4, 65539, 4, 4, 65539, 65530, 655364, 65538, 65530, 655364, 65537, 65530, 655364, 65536, 65530, 655364, 131069, 65530, 655364, 131068, 65530, 655364, 131067, 65530, 655364, 131070, 65530, 655364, 131071, 65530, 655364, 65530, 4, 655363, 65530, 3, 655360, 65530, 65535, 655363, 4, 65535, 655363)
+}
+metadata/_editor_floor_ = Vector3(0, 0, 0)
+
+[node name="FloorCollider" type="StaticBody3D" parent="Map"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1)
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9, 0, -2)
+shape = SubResource("BoxShape3D_mlj80")
+
+[node name="CollisionShape3D5" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 0, -2)
+shape = SubResource("BoxShape3D_mlj80")
+
+[node name="CollisionShape3D2" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 0, -2)
+shape = SubResource("BoxShape3D_mlj80")
+
+[node name="CollisionShape3D3" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -1, 0, -10)
+shape = SubResource("BoxShape3D_4nr14")
+
+[node name="CollisionShape3D6" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -1, 0, -2)
+shape = SubResource("BoxShape3D_4nr14")
+
+[node name="CollisionShape3D4" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -1, 0, 6)
+shape = SubResource("BoxShape3D_4nr14")
+
+[node name="Ball" parent="." instance=ExtResource("4_pwn6m")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9, 2.5, -9)
+
+[node name="Node3D" type="Node3D" parent="Ball/SpawnPositions" index="0"]
+
+[node name="Node3D2" type="Node3D" parent="Ball/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0, 0)
+
+[node name="Node3D3" type="Node3D" parent="Ball/SpawnPositions" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16, 0, 0)
+
+[node name="Node3D4" type="Node3D" parent="Ball/SpawnPositions" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16, 0, 8)
+
+[node name="Node3D5" type="Node3D" parent="Ball/SpawnPositions" index="4"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 16, 0, 16)
+
+[node name="Node3D6" type="Node3D" parent="Ball/SpawnPositions" index="5"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8, 0, 16)
+
+[node name="Node3D7" type="Node3D" parent="Ball/SpawnPositions" index="6"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 16)
+
+[node name="Goal" parent="." instance=ExtResource("5_bvys5")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 2, -1)
+
+[node name="Node3D" type="Node3D" parent="Goal/SpawnPositions" index="0"]
+
+[editable path="Ball"]
+[editable path="Goal"]
+[editable path="Goal/SpawnPositions"]
diff --git a/examples/PushBall/scenes/levels/game_scene5.tscn b/examples/PushBall/scenes/levels/game_scene5.tscn
new file mode 100644
index 0000000..6fe3a47
--- /dev/null
+++ b/examples/PushBall/scenes/levels/game_scene5.tscn
@@ -0,0 +1,66 @@
+[gd_scene load_steps=7 format=3 uid="uid://b0x45hi2a0acs"]
+
+[ext_resource type="Script" path="res://scenes/levels/level_manager.gd" id="1_wdfa4"]
+[ext_resource type="PackedScene" uid="uid://dj6uaupgnjtgm" path="res://scenes/robot/robot.tscn" id="2_7h777"]
+[ext_resource type="MeshLibrary" uid="uid://dd25bvxh87k52" path="res://scenes/tiles/mesh_library.tres" id="3_0fuqq"]
+[ext_resource type="PackedScene" uid="uid://i2xan4njr6b3" path="res://scenes/ball/ball.tscn" id="4_g3ck8"]
+[ext_resource type="PackedScene" uid="uid://b44vhh42y4dsq" path="res://scenes/goal/goal.tscn" id="5_xykhe"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_arno1"]
+size = Vector3(12, 2, 16)
+
+[node name="GameScene5" type="Node3D" node_paths=PackedStringArray("nodes_to_reset")]
+script = ExtResource("1_wdfa4")
+nodes_to_reset = [NodePath("Ball"), NodePath("Goal")]
+
+[node name="Robot" parent="." instance=ExtResource("2_7h777")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
+
+[node name="Map" type="Node3D" parent="."]
+
+[node name="GridMap" type="GridMap" parent="Map"]
+mesh_library = ExtResource("3_0fuqq")
+data = {
+"cells": PackedInt32Array(65535, 65535, 1441793, 0, 65535, 1441793, 1, 65535, 1441793, 2, 65535, 1441793, 2, 65534, 1441793, 2, 65533, 1441793, 65534, 3, 1, 65535, 3, 1, 0, 3, 1441793, 1, 3, 1441793, 2, 3, 1441793, 2, 2, 1441793, 2, 1, 1441793, 2, 0, 1441793, 1, 0, 1441793, 0, 0, 1441793, 65535, 0, 1441793, 65534, 0, 1441793, 65534, 65535, 1441793, 1, 65533, 1441795, 1, 65534, 655363, 0, 65534, 1441792, 65535, 65534, 1441792, 65534, 65534, 655363, 65534, 65533, 1441795, 65535, 65533, 1441792, 0, 65533, 1441792, 1, 1, 655363, 1, 2, 1441795, 0, 2, 1441792, 65535, 2, 1441792, 65534, 2, 1441795, 65534, 1, 655363, 65535, 1, 1441792, 0, 1, 1441792, 3, 2, 1441792, 3, 0, 1441792, 65533, 3, 1, 65533, 2, 1441793, 65533, 1, 1441793, 65533, 0, 1441793, 65533, 65535, 1441793, 65533, 65534, 1441793, 65533, 65533, 1441793, 65532, 3, 1441792, 65532, 2, 1441792, 65532, 1, 1441792, 65532, 0, 1441792, 65532, 65535, 1441792, 65532, 65534, 1441792, 65532, 65533, 1441792, 65532, 65532, 1441792, 65532, 65531, 1441792, 65533, 65531, 1441792, 65534, 65531, 1441792, 65535, 65531, 1441792, 0, 65531, 1441792, 1, 65531, 1441792, 65533, 65532, 1441793, 65534, 65532, 1441793, 65535, 65532, 1441793, 0, 65532, 1441793, 1, 65532, 1441793, 2, 65532, 1441793, 2, 65531, 1441792, 3, 65531, 1441792, 3, 65533, 1441792, 3, 65532, 1441792, 3, 65534, 1441792, 3, 65535, 1441792, 3, 1, 1441792, 3, 3, 1441792, 65539, 3, 1048580, 65539, 2, 1048580, 65539, 1, 1048580, 65539, 0, 1048580, 65539, 65535, 1048580, 65539, 65534, 1048580, 65539, 65533, 1048580, 65539, 65532, 1048580, 131068, 65532, 1441796, 131068, 65533, 1441796, 131068, 65534, 1441796, 131068, 65535, 1441796, 131068, 0, 1441796, 131068, 1, 1441796, 131068, 2, 1441796, 131068, 3, 1441796, 131069, 65531, 655364, 131070, 65531, 655364, 131071, 65531, 655364, 65536, 65531, 655364, 65537, 65531, 655364, 65538, 65531, 655364, 131070, 0, 655364, 131071, 0, 655364, 65536, 0, 655364, 65537, 0, 655364, 65537, 65535, 4, 65536, 65535, 4, 131071, 65535, 4, 131070, 65535, 4, 131069, 1, 1441796, 131069, 2, 1441796, 131070, 3, 4, 131071, 3, 4, 65536, 3, 4, 65537, 3, 4, 65538, 1, 1048580, 65538, 2, 1048580, 65538, 65533, 1048580, 65538, 65534, 1048580, 131069, 65534, 1441796, 131069, 65533, 1441796, 131070, 65532, 655364, 131071, 65532, 655364, 65536, 65532, 655364, 65537, 65532, 655364, 3, 4, 1441792, 2, 4, 1441792, 1, 4, 1441792, 0, 4, 1441792, 65535, 4, 1441792, 65532, 4, 1441792, 65533, 4, 1441792, 65534, 4, 1441792, 65538, 4, 4, 65537, 4, 4, 65536, 4, 4, 131071, 4, 4, 131070, 4, 4, 131069, 4, 4)
+}
+metadata/_editor_floor_ = Vector3(0, 0, 0)
+
+[node name="FloorCollider" type="StaticBody3D" parent="Map"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1)
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="Map/FloorCollider"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1)
+shape = SubResource("BoxShape3D_arno1")
+
+[node name="Ball" parent="." instance=ExtResource("4_g3ck8")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 1)
+
+[node name="Node3D" type="Node3D" parent="Ball/SpawnPositions" index="0"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, 0)
+
+[node name="Node3D4" type="Node3D" parent="Ball/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 0)
+
+[node name="Node3D5" type="Node3D" parent="Ball/SpawnPositions" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, -2)
+
+[node name="Node3D8" type="Node3D" parent="Ball/SpawnPositions" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, -2)
+
+[node name="Goal" parent="." instance=ExtResource("5_xykhe")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 2, -7)
+
+[node name="Node3D" type="Node3D" parent="Goal/SpawnPositions" index="0"]
+
+[node name="Node3D2" type="Node3D" parent="Goal/SpawnPositions" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 0, 0)
+
+[node name="Node3D3" type="Node3D" parent="Goal/SpawnPositions" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 10, 0, 14)
+
+[node name="Node3D4" type="Node3D" parent="Goal/SpawnPositions" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 14)
+
+[editable path="Ball"]
+[editable path="Goal"]
+[editable path="Goal/SpawnPositions"]
diff --git a/examples/PushBall/scenes/levels/level_manager.gd b/examples/PushBall/scenes/levels/level_manager.gd
new file mode 100644
index 0000000..9361fb4
--- /dev/null
+++ b/examples/PushBall/scenes/levels/level_manager.gd
@@ -0,0 +1,22 @@
+extends Node3D
+class_name LevelManager
+
+## Nodes to reset, must implement reset() method
+@export var nodes_to_reset: Array[Node]
+
+@onready var player := $Robot
+@onready var ball := $Ball
+@onready var goal := $Goal
+
+
+func _ready():
+ reset_all_resetables()
+ player.level_manager = self
+ player.ball = ball
+ player.goal = goal
+ goal.connect("body_entered", player._on_goal_body_entered)
+
+
+func reset_all_resetables():
+ for node in nodes_to_reset:
+ node.reset()
diff --git a/examples/PushBall/scenes/levels/platform.gd b/examples/PushBall/scenes/levels/platform.gd
new file mode 100644
index 0000000..c3e245e
--- /dev/null
+++ b/examples/PushBall/scenes/levels/platform.gd
@@ -0,0 +1,7 @@
+extends AnimatableBody3D
+
+@export var spawn_position_manager: SpawnPositionManager
+
+
+func reset() -> void:
+ global_transform = spawn_position_manager.get_spawn_position()
diff --git a/examples/PushBall/scenes/levels/platform.tscn b/examples/PushBall/scenes/levels/platform.tscn
new file mode 100644
index 0000000..729cbc9
--- /dev/null
+++ b/examples/PushBall/scenes/levels/platform.tscn
@@ -0,0 +1,32 @@
+[gd_scene load_steps=6 format=3 uid="uid://ddlyhy8ad7r6h"]
+
+[ext_resource type="Script" path="res://scenes/levels/platform.gd" id="1_kygys"]
+[ext_resource type="PackedScene" uid="uid://s1bbjv46d7pu" path="res://assets/tiles/platform.glb" id="1_nridm"]
+[ext_resource type="PackedScene" uid="uid://bmc018ke831mi" path="res://scenes/spawn_position_manager/spawn_positions.tscn" id="2_h5deu"]
+
+[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_t6ebn"]
+rough = true
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_nq455"]
+size = Vector3(2, 0.2, 6)
+
+[node name="Platform" type="AnimatableBody3D" node_paths=PackedStringArray("spawn_position_manager")]
+transform = Transform3D(1, 0, -1.74846e-07, 0, 1, 0, 1.74846e-07, 0, 1, 0, 0, 3)
+physics_material_override = SubResource("PhysicsMaterial_t6ebn")
+script = ExtResource("1_kygys")
+spawn_position_manager = NodePath("SpawnPositions")
+
+[node name="platform" parent="." instance=ExtResource("1_nridm")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
+
+[node name="platform3" parent="." instance=ExtResource("1_nridm")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.49692e-07, 2, -2)
+
+[node name="platform2" parent="." instance=ExtResource("1_nridm")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 2)
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9, 0)
+shape = SubResource("BoxShape3D_nq455")
+
+[node name="SpawnPositions" parent="." instance=ExtResource("2_h5deu")]
diff --git a/examples/PushBall/scenes/onnx_test_scene.tscn b/examples/PushBall/scenes/onnx_test_scene.tscn
new file mode 100644
index 0000000..ba301de
--- /dev/null
+++ b/examples/PushBall/scenes/onnx_test_scene.tscn
@@ -0,0 +1,88 @@
+[gd_scene load_steps=9 format=3 uid="uid://dx5rplq74i3ja"]
+
+[ext_resource type="PackedScene" uid="uid://cck7kpuva1vvs" path="res://scenes/levels/all_levels.tscn" id="1_4mept"]
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sync.gd" id="2_8d7lx"]
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_7p42g"]
+ground_bottom_color = Color(0, 0, 0, 1)
+
+[sub_resource type="Sky" id="Sky_o1jv5"]
+sky_material = SubResource("ProceduralSkyMaterial_7p42g")
+
+[sub_resource type="Environment" id="Environment_mom6d"]
+background_mode = 2
+sky = SubResource("Sky_o1jv5")
+tonemap_mode = 2
+ssao_radius = 2.85
+sdfgi_enabled = true
+glow_enabled = true
+
+[sub_resource type="Animation" id="Animation_7vl40"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:position")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 17.854, 10.898)]
+}
+
+[sub_resource type="Animation" id="Animation_vose7"]
+resource_name = "new_animation"
+length = 40.0
+loop_mode = 2
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath(".:position")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 8, 10, 18, 20.1, 28, 30),
+"transitions": PackedFloat32Array(1, 0.5, 1, 0.5, 1, 0.5, 1),
+"update": 0,
+"values": [Vector3(0, 17.854, 10.898), Vector3(0, 17.854, 10.898), Vector3(40, 17.854, 10.898), Vector3(40, 17.854, 10.898), Vector3(78.9, 17.854, 10.898), Vector3(78.9, 17.854, 10.898), Vector3(120, 17.854, 10.898)]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_fuhyb"]
+_data = {
+"RESET": SubResource("Animation_7vl40"),
+"new_animation": SubResource("Animation_vose7")
+}
+
+[node name="OnnxInferenceScene" type="Node3D"]
+
+[node name="AllLevels" parent="." instance=ExtResource("1_4mept")]
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_mom6d")
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
+shadow_enabled = true
+
+[node name="Node3D" type="Node3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 0.743145, 0.669131, 0, -0.669131, 0.743145, 0, -3.7, 23.76)
+
+[node name="Camera3D" type="Camera3D" parent="Node3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17.854, 10.898)
+current = true
+fov = 45.0
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="Node3D/Camera3D"]
+libraries = {
+"": SubResource("AnimationLibrary_fuhyb")
+}
+autoplay = "new_animation"
+speed_scale = 0.5
+
+[node name="Sync" type="Node" parent="."]
+script = ExtResource("2_8d7lx")
+control_mode = 2
+speed_up = 1.5
+onnx_model_path = "model.onnx"
diff --git a/examples/PushBall/scenes/robot/robot.gd b/examples/PushBall/scenes/robot/robot.gd
new file mode 100644
index 0000000..175b0b4
--- /dev/null
+++ b/examples/PushBall/scenes/robot/robot.gd
@@ -0,0 +1,125 @@
+extends RigidBody3D
+class_name Player
+
+#region Set by LevelManager
+@onready var ball: Ball
+@onready var goal: Area3D
+#endregion
+
+## Reward given when the robot or ball falls
+## (affects training behavior only)
+var fall_reward = -2.0
+
+## Node with player animations
+@export var animation_player: AnimationPlayer
+## Movement speed of the robot
+@export var movement_speed := 2.0
+## Rotation speed of the robot
+@export var rotation_speed := 12.0
+
+@onready var _ai_controller := $AIController3D
+@onready var _initial_transform = transform
+@onready var level_manager := get_parent() as LevelManager
+@onready var visual_robot: Node3D = $robot
+@onready var floor_sensor := $FloorSensor
+
+var closest_goal_dist
+var closest_ball_dist
+
+#region Set by AIController
+var requested_movement: float
+var requested_turn: float
+#endregion
+
+
+func _physics_process(_delta):
+ # Set to true by the sync node when reset is requested from Python (starting training, evaluation, etc.)
+ if _ai_controller.needs_reset:
+ reset()
+ _ai_controller.reset()
+
+ _process_movement()
+ _process_rotation()
+
+ _process_fell_down_check()
+ _process_distance_rewards()
+
+
+## Gives positive rewards when:
+## - Ball approaches the goal position
+## - Player approaches the ball position
+
+
+func _process_distance_rewards():
+#region Reward for the ball approaching the goal
+ var current_dist = get_goal_dist()
+ if not closest_goal_dist:
+ closest_goal_dist = current_dist
+
+ if current_dist < closest_goal_dist:
+ _ai_controller.reward += (closest_goal_dist - current_dist)
+ closest_goal_dist = current_dist
+#endregion
+
+#region Reward for the robot approaching the ball
+ var current_ball_dist = global_position.distance_to(ball.global_position)
+ if not closest_ball_dist:
+ closest_ball_dist = current_ball_dist
+
+ if current_ball_dist < closest_ball_dist:
+ _ai_controller.reward += (closest_ball_dist - current_ball_dist)
+ closest_ball_dist = current_ball_dist
+#endregion
+
+
+## Ensures that the player (or ball) did not fall down
+## otherwise, restarts the episode with fall_reward
+func _process_fell_down_check():
+ if ball.global_position.y < 0 or global_position.y < 0:
+ game_over(fall_reward)
+
+
+func _process_rotation():
+ if not floor_sensor.is_colliding():
+ return
+ if requested_turn:
+ apply_torque(Vector3.UP * requested_turn * rotation_speed)
+
+
+func _process_movement():
+ if not floor_sensor.is_colliding():
+ return
+ if requested_movement:
+ apply_central_force(global_basis.z * (requested_movement * movement_speed))
+
+ animation_player.play("walking")
+ else:
+ animation_player.play("idle")
+
+
+func game_over(reward = 0.0, success := false):
+ reset()
+ _ai_controller.reset()
+ _ai_controller.reward += reward
+ _ai_controller.done = true
+ _ai_controller.is_success = success
+
+
+## Returns the ball's distance to the goal
+func get_goal_dist():
+ return ball.global_position.distance_to(goal.global_position)
+
+
+func reset():
+ level_manager.reset_all_resetables()
+ linear_velocity = Vector3.ZERO
+ angular_velocity = Vector3.ZERO
+ transform = _initial_transform
+ await get_tree().physics_frame
+ closest_goal_dist = null
+ closest_ball_dist = null
+
+
+func _on_goal_body_entered(body: Node3D) -> void:
+ if body is Ball:
+ game_over(10.0, true)
diff --git a/examples/PushBall/scenes/robot/robot.tscn b/examples/PushBall/scenes/robot/robot.tscn
new file mode 100644
index 0000000..5576a7d
--- /dev/null
+++ b/examples/PushBall/scenes/robot/robot.tscn
@@ -0,0 +1,346 @@
+[gd_scene load_steps=14 format=3 uid="uid://dj6uaupgnjtgm"]
+
+[ext_resource type="PackedScene" uid="uid://bb2je1c8jc1qr" path="res://assets/robot.glb" id="1_n7jto"]
+[ext_resource type="Script" path="res://scenes/robot/robot.gd" id="1_vywkg"]
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sensors/sensors_3d/RaycastSensor3D.gd" id="2_0pavx"]
+[ext_resource type="Script" path="res://scenes/robot/robot_ai_controller.gd" id="5_sx7mj"]
+
+[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_mfev2"]
+
+[sub_resource type="Animation" id="Animation_2kfmf"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Robot/Arm:rotation")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 0, 0)]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("Robot/Arm_001:rotation")
+tracks/1/interp = 1
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 0, 0)]
+}
+tracks/2/type = "value"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Robot/Torso:position")
+tracks/2/interp = 1
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 0, 0)]
+}
+tracks/3/type = "value"
+tracks/3/imported = false
+tracks/3/enabled = true
+tracks/3/path = NodePath("Robot/Head:position")
+tracks/3/interp = 1
+tracks/3/loop_wrap = true
+tracks/3/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 0, 0)]
+}
+tracks/4/type = "value"
+tracks/4/imported = false
+tracks/4/enabled = true
+tracks/4/path = NodePath("Robot/Head:rotation")
+tracks/4/interp = 1
+tracks/4/loop_wrap = true
+tracks/4/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 0,
+"values": [Vector3(0, 0, 0)]
+}
+
+[sub_resource type="Animation" id="Animation_ly00x"]
+resource_name = "idle"
+length = 4.0
+loop_mode = 1
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Robot/Arm:rotation")
+tracks/0/interp = 2
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 2),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0.349066, 0, 0.0610865)]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("Robot/Arm_001:rotation")
+tracks/1/interp = 2
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0, 2),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(-0.349066, 0, -0.148353)]
+}
+tracks/2/type = "value"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Robot/Head:rotation")
+tracks/2/interp = 2
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(0, 1, 2, 3),
+"transitions": PackedFloat32Array(1, 1, 1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0, 0.162316, 0.0488692), Vector3(0, 0, 0), Vector3(0.139626, -0.178024, 0.0226893)]
+}
+
+[sub_resource type="Animation" id="Animation_6jb0l"]
+resource_name = "idle"
+loop_mode = 1
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Robot/Arm:rotation")
+tracks/0/interp = 2
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.5),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0, -0.174533, 0)]
+}
+tracks/1/type = "value"
+tracks/1/imported = false
+tracks/1/enabled = true
+tracks/1/path = NodePath("Robot/Arm_001:rotation")
+tracks/1/interp = 2
+tracks/1/loop_wrap = true
+tracks/1/keys = {
+"times": PackedFloat32Array(0, 0.5),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0, 0.174533, 0)]
+}
+tracks/2/type = "value"
+tracks/2/imported = false
+tracks/2/enabled = true
+tracks/2/path = NodePath("Robot/Torso:position")
+tracks/2/interp = 2
+tracks/2/loop_wrap = true
+tracks/2/keys = {
+"times": PackedFloat32Array(0, 0.25, 0.5),
+"transitions": PackedFloat32Array(1, 1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0, -0.01, 0), Vector3(0, 0, 0)]
+}
+tracks/3/type = "value"
+tracks/3/imported = false
+tracks/3/enabled = true
+tracks/3/path = NodePath("Robot/Head:position")
+tracks/3/interp = 1
+tracks/3/loop_wrap = true
+tracks/3/keys = {
+"times": PackedFloat32Array(0, 0.5),
+"transitions": PackedFloat32Array(1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(0, -0.02, 0)]
+}
+tracks/4/type = "value"
+tracks/4/imported = false
+tracks/4/enabled = true
+tracks/4/path = NodePath("Robot/Head:rotation")
+tracks/4/interp = 1
+tracks/4/loop_wrap = true
+tracks/4/keys = {
+"times": PackedFloat32Array(0, 0.25, 0.5),
+"transitions": PackedFloat32Array(1, 1, 1),
+"update": 0,
+"values": [Vector3(0, 0, 0), Vector3(-0.0349066, 0, 0), Vector3(0, 0, 0)]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_g7kmm"]
+_data = {
+"RESET": SubResource("Animation_2kfmf"),
+"idle": SubResource("Animation_ly00x"),
+"walking": SubResource("Animation_6jb0l")
+}
+
+[sub_resource type="InputEventKey" id="InputEventKey_25ja1"]
+device = -1
+keycode = 82
+unicode = 114
+
+[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_e2j88"]
+radius = 0.279
+height = 1.0
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_6w8t5"]
+size = Vector3(0.6, 0.5, 0.6)
+
+[sub_resource type="SphereShape3D" id="SphereShape3D_yuuhn"]
+radius = 0.279
+
+[node name="Robot" type="RigidBody3D" node_paths=PackedStringArray("animation_player") groups=["resetable"]]
+collision_layer = 512
+collision_mask = 8388609
+axis_lock_angular_x = true
+axis_lock_angular_z = true
+mass = 10.0
+physics_material_override = SubResource("PhysicsMaterial_mfev2")
+gravity_scale = 4.0
+continuous_cd = true
+contact_monitor = true
+max_contacts_reported = 3
+linear_damp_mode = 1
+linear_damp = 10.0
+angular_damp_mode = 1
+angular_damp = 10.0
+script = ExtResource("1_vywkg")
+animation_player = NodePath("robot/AnimationPlayer")
+movement_speed = 650.0
+rotation_speed = 30.0
+
+[node name="RaycastSensors" type="Node3D" parent="."]
+
+[node name="360Sensor" type="Node3D" parent="RaycastSensors"]
+script = ExtResource("2_0pavx")
+n_rays_width = 8.0
+n_rays_height = 1.0
+cone_width = 360.0
+cone_height = 1.0
+
+[node name="@RayCast3D@75028" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(-3.82683, 0, -9.2388)
+
+[node name="@RayCast3D@75029" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(-9.2388, 0, -3.82683)
+
+[node name="@RayCast3D@75030" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(-9.2388, 0, 3.82683)
+
+[node name="@RayCast3D@75031" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(-3.82683, 0, 9.2388)
+
+[node name="@RayCast3D@75032" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(3.82683, 0, 9.2388)
+
+[node name="@RayCast3D@75033" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(9.2388, 0, 3.82683)
+
+[node name="@RayCast3D@75034" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(9.2388, 0, -3.82683)
+
+[node name="@RayCast3D@75035" type="RayCast3D" parent="RaycastSensors/360Sensor"]
+target_position = Vector3(3.82683, 0, -9.2388)
+
+[node name="GroundSensor" type="Node3D" parent="RaycastSensors"]
+transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 1.36046, 0)
+script = ExtResource("2_0pavx")
+n_rays_width = 4.0
+n_rays_height = 4.0
+ray_length = 6.0
+cone_width = 120.0
+cone_height = 120.0
+
+[node name="node_0 0" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-3, -4.24264, 3)
+
+[node name="node_0 1" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-4.09808, -1.55291, 4.09808)
+
+[node name="node_0 2" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-4.09808, 1.55291, 4.09808)
+
+[node name="node_0 3" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-3, 4.24264, 3)
+
+[node name="node_1 0" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-1.09808, -4.24264, 4.09808)
+
+[node name="node_1 1" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-1.5, -1.55291, 5.59808)
+
+[node name="node_1 2" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-1.5, 1.55291, 5.59808)
+
+[node name="node_1 3" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(-1.09808, 4.24264, 4.09808)
+
+[node name="node_2 0" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(1.09808, -4.24264, 4.09808)
+
+[node name="node_2 1" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(1.5, -1.55291, 5.59808)
+
+[node name="node_2 2" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(1.5, 1.55291, 5.59808)
+
+[node name="node_2 3" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(1.09808, 4.24264, 4.09808)
+
+[node name="@RayCast3D@63805" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(3, -4.24264, 3)
+
+[node name="@RayCast3D@63806" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(4.09808, -1.55291, 4.09808)
+
+[node name="@RayCast3D@63807" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(4.09808, 1.55291, 4.09808)
+
+[node name="node_3 3" type="RayCast3D" parent="RaycastSensors/GroundSensor"]
+target_position = Vector3(3, 4.24264, 3)
+
+[node name="robot" parent="." instance=ExtResource("1_n7jto")]
+transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 0, -0.3, 0)
+
+[node name="Robot" parent="robot" index="0"]
+transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0, 0)
+
+[node name="Arm_001" parent="robot/Robot" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00394951, 0, -0.18)
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="robot"]
+libraries = {
+"": SubResource("AnimationLibrary_g7kmm")
+}
+autoplay = "idle"
+
+[node name="AIController3D" type="Node3D" parent="." node_paths=PackedStringArray("raycast_sensors")]
+script = ExtResource("5_sx7mj")
+raycast_sensors = [NodePath("../RaycastSensors/360Sensor"), NodePath("../RaycastSensors/GroundSensor")]
+reset_after = 3500
+expert_demo_save_path = "demo.json"
+remove_last_episode_key = SubResource("InputEventKey_25ja1")
+action_repeat = 4
+
+[node name="CollisionShape3D4" type="CollisionShape3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0502479, -0.00153814)
+shape = SubResource("CapsuleShape3D_e2j88")
+
+[node name="CollisionShape3D5" type="CollisionShape3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.155767, -0.00153814)
+shape = SubResource("BoxShape3D_6w8t5")
+
+[node name="FloorSensor" type="ShapeCast3D" parent="."]
+shape = SubResource("SphereShape3D_yuuhn")
+target_position = Vector3(0, -0.5, 0)
+max_results = 1
+
+[editable path="robot"]
diff --git a/examples/PushBall/scenes/robot/robot_ai_controller.gd b/examples/PushBall/scenes/robot/robot_ai_controller.gd
new file mode 100644
index 0000000..c23a4f0
--- /dev/null
+++ b/examples/PushBall/scenes/robot/robot_ai_controller.gd
@@ -0,0 +1,94 @@
+extends AIController3D
+class_name RobotAIController
+
+@export var raycast_sensors: Array[Node3D]
+@onready var player = get_parent() as Player
+var is_success: bool = false
+
+
+func get_obs() -> Dictionary:
+ var observations: Array[float] = []
+ for raycast_sensor in raycast_sensors:
+ var obs = raycast_sensor.get_observation()
+ observations.append_array(obs)
+
+ var player_to_goal := player.to_local(player.goal.global_position)
+ var player_to_goal_dir := player_to_goal.normalized()
+ var player_to_goal_dist := clampf(player_to_goal.length() / 5.0, 0, 1.0)
+
+ var player_to_ball := player.to_local(player.ball.global_position)
+ var player_to_ball_dir := player_to_ball.normalized()
+ var player_to_ball_dist := clampf(player_to_ball.length() / 10.0, 0, 1.0)
+
+ var player_velocity = player.linear_velocity
+ player_velocity = player.global_basis.inverse() * player_velocity
+ player_velocity = player_velocity.limit_length(4) / 4
+
+ var ball_velocity = player.ball.linear_velocity
+ ball_velocity = player.global_basis.inverse() * ball_velocity
+ ball_velocity = ball_velocity.limit_length(4) / 4
+
+ (
+ observations
+ . append_array(
+ [
+ player_to_goal_dir.x,
+ player_to_goal_dir.z,
+ player_to_goal_dist,
+ player_to_ball_dir.x,
+ player_to_ball_dir.z,
+ player_to_ball_dist,
+ player_velocity.x,
+ player_velocity.z,
+ ball_velocity.x,
+ ball_velocity.z,
+ n_steps / float(reset_after),
+ ]
+ )
+ )
+
+ return {"obs": observations}
+
+
+func get_info() -> Dictionary:
+ return {"is_success": is_success}
+
+
+func get_reward() -> float:
+ return reward
+
+
+func _physics_process(_delta: float) -> void:
+ # Reset on timeout, this is implemented in parent class to set needs_reset to true,
+ # we are re-implementing here to call player.game_over() that handles the game reset.
+ n_steps += 1
+ if n_steps > reset_after:
+ n_steps = 0
+ player.game_over(-10, false)
+
+ # In training or onnx inference modes, this method will be called by sync node with actions provided,
+ # For human control mode the method will not be called, so we call it here without any actions provided.
+ if control_mode == ControlModes.HUMAN:
+ set_action()
+
+
+func get_action_space() -> Dictionary:
+ return {
+ "move": {"size": 1, "action_type": "continuous"},
+ "turn": {"size": 1, "action_type": "continuous"}
+ }
+
+
+func get_action() -> Array:
+ return [player.requested_movement, player.requested_turn, player.requested_ball_kick]
+
+
+func set_action(action = null) -> void:
+ # If there's no action provided, it means that AI is not controlling the robot (human control)
+ if not action:
+ var input = Input.get_vector("move_left", "move_right", "move_up", "move_down")
+ player.requested_movement = input.y
+ player.requested_turn = -input.x
+ else:
+ player.requested_movement = clampf(action.move[0], -1.0, 0.2)
+ player.requested_turn = clampf(action.turn[0], -1.0, 1.0)
diff --git a/examples/PushBall/scenes/spawn_position_manager/spawn_positions.gd b/examples/PushBall/scenes/spawn_position_manager/spawn_positions.gd
new file mode 100644
index 0000000..6f769c4
--- /dev/null
+++ b/examples/PushBall/scenes/spawn_position_manager/spawn_positions.gd
@@ -0,0 +1,14 @@
+extends Node3D
+class_name SpawnPositionManager
+
+@onready var position_nodes = get_children()
+var spawn_transforms: Array[Transform3D]
+
+
+func _ready() -> void:
+ for position_node in position_nodes:
+ spawn_transforms.append(position_node.global_transform)
+
+
+func get_spawn_position() -> Transform3D:
+ return spawn_transforms.pick_random()
diff --git a/examples/PushBall/scenes/spawn_position_manager/spawn_positions.tscn b/examples/PushBall/scenes/spawn_position_manager/spawn_positions.tscn
new file mode 100644
index 0000000..5d23e45
--- /dev/null
+++ b/examples/PushBall/scenes/spawn_position_manager/spawn_positions.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://bmc018ke831mi"]
+
+[ext_resource type="Script" path="res://scenes/spawn_position_manager/spawn_positions.gd" id="1_3q5jt"]
+
+[node name="SpawnPositions" type="Node3D"]
+script = ExtResource("1_3q5jt")
diff --git a/examples/PushBall/scenes/tiles/mesh_library.tres b/examples/PushBall/scenes/tiles/mesh_library.tres
new file mode 100644
index 0000000..5085258
--- /dev/null
+++ b/examples/PushBall/scenes/tiles/mesh_library.tres
@@ -0,0 +1,465 @@
+[gd_resource type="MeshLibrary" load_steps=35 format=4 uid="uid://dd25bvxh87k52"]
+
+[ext_resource type="Texture2D" uid="uid://n5cpgvg4uorg" path="res://assets/tiles/grass_grass.png" id="1_j1v2u"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5tm3b"]
+resource_name = "grass.004"
+transparency = 4
+cull_mode = 2
+albedo_texture = ExtResource("1_j1v2u")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_oxje1"]
+resource_name = "grass"
+cull_mode = 2
+albedo_color = Color(0.146383, 0.792724, 0, 1)
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_0c4lr"]
+_surfaces = [{
+"aabb": AABB(-0.663943, 0.810673, -0.730111, 1.17936, 0.597767, 1.45198),
+"format": 34896613377,
+"index_count": 24,
+"index_data": PackedByteArray("AAADAAEAAAACAAMABAAHAAUABAAGAAcACAALAAkACAAKAAsADAAPAA0ADAAOAA8A"),
+"name": "grass.004",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 16,
+"vertex_data": PackedByteArray("AAA8/1T7AAAYCtMa/vsAAMYYPP/jAgAA3yLTGo0DAABr9mnkYe4AAP//AAC06wAAnJJp5KwCAAAwnAAAAAAAAKw8//8T/gAAhUaVG///AABThP//tQsAACyOlRuhDQAALn1p5JXrAADAhgAASO4AAMPhaeQZAAAAVesAAMsCAAA=")
+}, {
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"format": 34896613377,
+"index_count": 60,
+"index_data": PackedByteArray("CgAEAAYACgAIAAQAAwAJAAsAAwACAAkAAAAHAAUAAAABAAcAAQACAAMAAQAAAAIAAQALAAcAAQADAAsABAAHAAYABAAFAAcABgALAAoABgAHAAsACgAJAAgACgALAAkACAAFAAQACAAJAAUAAgAFAAkAAgAAAAUA"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("AAAAAP//AAAAAAAAAAAAAP7/AAD//wAA//8AAAAAAAC4A///RvwAAAAARvz//wAAuAP//7gDAAAAAEb8AAAAAEb8//9G/AAA/v9G/P//AABG/P//uAMAAP//RvwAAAAA")
+}]
+blend_shape_mode = 0
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_455vr"]
+resource_name = "grass_Plane_001"
+_surfaces = [{
+"aabb": AABB(-0.663943, 0.810673, -0.730111, 1.17936, 0.597767, 1.45198),
+"attribute_data": PackedByteArray("/3//f/9///////9////+//9//3//f///////f////v//f/9//3///////3////7//3//f/9///////9////+/w=="),
+"format": 34896613399,
+"index_count": 24,
+"index_data": PackedByteArray("AAADAAEAAAACAAMABAAHAAUABAAGAAcACAALAAkACAAKAAsADAAPAA0ADAAOAA8A"),
+"material": SubResource("StandardMaterial3D_5tm3b"),
+"name": "grass.004",
+"primitive": 3,
+"uv_scale": Vector4(2, 1.75, 0, 0),
+"vertex_count": 16,
+"vertex_data": PackedByteArray("AAA8/1T7yrwYCtMa/vvKvMYYPP/jAsq83yLTGo0Dyrxr9mnkYe6Mzf//AAC064zNnJJp5KwCjM0wnAAAAACMzaw8//8T/n62hUaVG///frZThP//tQt+tiyOlRuhDX62Ln1p5JXrgLLAhgAASO6AssPhaeQZAICyVesAAMsCgLKuio4FroqOBa6KjgWuio4F6Yi2A+mItgPpiLYD6Yi2A4mLdAaJi3QGiYt0BomLdAYrjBwHK4wcByuMHAcrjBwH")
+}, {
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"attribute_data": PackedByteArray("/18AAP8f/z//X////1//v/8f/3//X/+//1//P/9f/z//X/8//1//f/9f/3//X/9/Ed/tQBHf7UAR3+1AEZ8AAP/f/z//3/8/EZ///xHfEX8R3xF/Ed8RfxGf/7//3/9//9//fxGf/7/toO1A7aDtQO2g7UARn/8//5//PxGf/z8Rn/8/7aARf+2gEX/toBF/EZ//f/+f/38Rn/9/EZ//fw=="),
+"format": 34896613399,
+"index_count": 60,
+"index_data": PackedByteArray("IgANABQAIgAbAA0ACwAgACcACwAIACAAAgAZABIAAgAFABkABAAHAAoABAABAAcAAwAkABYAAwAJACQADgAYABUADgARABgAEwAlACEAEwAXACUAIwAfABwAIwAmAB8AGgAQAAwAGgAeABAABgAPAB0ABgAAAA8A"),
+"material": SubResource("StandardMaterial3D_oxje1"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 40,
+"vertex_data": PackedByteArray("AAAAAP///78AAAAA////vwAAAAD//1TVAAAAAAAA//8AAAAAAAD/vwAAAAAAAFTV/v8AAP///7/+/wAA////v/7/AAD//1TV//8AAAAA/////wAAAAD/v///AAAAAFTVuAP//0b8//+4A///Rvz//7gD//9G/KrpAABG/P///78AAEb8/////wAARvz//6rpAABG/P//VNW4A///uAP//7gD//+4A///uAP//7gDqukAAEb8AAD//wAARvwAAP//AABG/AAAqukAAEb8AABU1Ub8//9G/P//Rvz//0b8//9G/P//Rvyr6f7/Rvz///+//v9G/P/////+/0b8//+r6f7/Rvz//1TVRvz//7gD//9G/P//uAP//0b8//+4A6rp//9G/AAA/////0b8AAD/////RvwAAKrp//9G/AAAVNX/////AAD/f1TVVNX/v/+/AAD/f1TVVNX/////AAD/f6oqqir/v/+/AAD/f6oqqir/f3yl/3//vwlqBLX//////398pQlqBLVU1VTV/3+B2v9//78JagS1/7//v/9/gdoJagS1VNVU1f9/fKX/f/+/BDX2Ff//////f3ylBDX2Faoqqir/f4Ha/3//vwQ19RX/v/+//3+B2gQ19RWqKqoq")
+}]
+blend_shape_mode = 0
+shadow_mesh = SubResource("ArrayMesh_0c4lr")
+
+[sub_resource type="Image" id="Image_tet6u"]
+data = {
+"data": PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgMCDAEBAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwUDEQEBAQYCAwIJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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ML0f/zC+H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zG/H/8xwB//McAg/zHAIP8xwCD/McAg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvR//ML0f/zC9H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xvx//McAg/zHAIP8xwCD/McAg/zHAIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML0f/zC9H/8wvh//ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8xvx//McAf/zHAIP8xwCD/McAg/zHAIP8xwCD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC9H/8wvR//ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//Mb8f/zHAH/8xwCD/McAg/zHAIP8xwCD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvR//ML4f/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAg/zHAIP8xwCD/McAg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML0f/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zG/H/8xwB//McAf/zHAIP8xwCD/McAg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAIP8xwCD/McAg/zHAIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwCD/McAg/zHAIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//Mb8f/zHAH/8xwB//McAg/zHAIP8xwCD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAf/zHAIP8xwCD/McEg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAIP8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwB//McAg/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAg/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAf/zHAIP8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/McIg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwB//McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/McIg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/ML8f/zC/H/8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/McIg/zHCIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHAH/8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwB//McEg/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McAf/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wwB//MMAf/zHAH/8xwB//McAf/zHBH/8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHAH/8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwR//McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zDAH/8xwB//McAf/zHAH/8xwB//McEf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wwB//McAf/zHAH/8xwB//McEf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wwB//MMAf/zHAH/8xwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/MMAf/zHAH/8xwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zDAH/8xwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8xwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="),
+"format": "RGBA8",
+"height": 64,
+"mipmaps": false,
+"width": 64
+}
+
+[sub_resource type="ImageTexture" id="ImageTexture_5xgod"]
+image = SubResource("Image_tet6u")
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_snubt"]
+size = Vector3(2, 5, 2)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_mkc52"]
+resource_name = "concrete"
+cull_mode = 2
+albedo_color = Color(0.199087, 0.199087, 0.199087, 1)
+roughness = 0.5
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_ejvnk"]
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"format": 34896613377,
+"index_count": 60,
+"index_data": PackedByteArray("CgAEAAYACgAIAAQAAwAJAAsAAwACAAkAAAAHAAUAAAABAAcAAQACAAMAAQAAAAIAAQALAAcAAQADAAsABAAHAAYABAAFAAcABgALAAoABgAHAAsACgAJAAgACgALAAkACAAFAAQACAAJAAUAAgAFAAkAAgAAAAUA"),
+"name": "concrete",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("AAAAAP//AAAAAAAAAAAAAP//AAD//wAA//8AAAAAAAC4A///RvwAAAAARvz//wAAuAP//7gDAAAAAEb8AAAAAEb8//9G/AAA//9G/P//AABG/P//uAMAAP//RvwAAAAA")
+}]
+blend_shape_mode = 0
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_2e2w7"]
+resource_name = "gray_Cube_002"
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"attribute_data": PackedByteArray("/18AAP8f/z//X////1//v/8f/3//X/+//1//P/9f/z//X/8//1//f/9f/3//X/9/Ed/tQBHf7UAR3+1AEZ8AAP/f/z//3/8/EZ///xHfEX8R3xF/Ed8RfxGf/7//3/9//9//fxGf/7/toO1A7aDtQO2g7UARn/8//5//PxGf/z8Rn/8/7aARf+2gEX/toBF/EZ//f/+f/38Rn/9/EZ//fw=="),
+"format": 34896613399,
+"index_count": 60,
+"index_data": PackedByteArray("IgANABQAIgAbAA0ACwAgACcACwAIACAAAgAZABIAAgAFABkABAAHAAoABAABAAcAAwAkABYAAwAJACQADgAYABUADgARABgAEwAlACEAEwAXACUAIwAfABwAIwAmAB8AGgAQAAwAGgAeABAABgAPAB0ABgAAAA8A"),
+"material": SubResource("StandardMaterial3D_mkc52"),
+"name": "concrete",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 40,
+"vertex_data": PackedByteArray("AAAAAP///78AAAAA////vwAAAAD//1TVAAAAAAAA//8AAAAAAAD/vwAAAAAAAFTV//8AAP///7///wAA////v///AAD//1TV//8AAAAA/////wAAAAD/v///AAAAAFTVuAP//0b8//+4A///Rvz//7gD//9G/KrpAABG/P///78AAEb8/////wAARvz//6rpAABG/P//VNW4A///uAP//7gD//+4A///uAP//7gDqukAAEb8AAD//wAARvwAAP//AABG/AAAqukAAEb8AABU1Ub8//9G/P//Rvz//0b8//9G/P//Rvyq6f//Rvz///+///9G/P///////0b8//+q6f//Rvz//1TVRvz//7gD//9G/P//uAP//0b8//+4A6rp//9G/AAA/////0b8AAD/////RvwAAKrp//9G/AAAVNX/////AAD/f1TVVNX/v/+/AAD/f1TVVNX/////AAD/f6oqqir/v/+/AAD/f6oqqir/f3yl/3//vwlqBLX//////398pQlqBLVU1VTV/3+B2v9//78JagS1/7//v/9/gdoJagS1VNVU1f9/fKX/f/+/BDX2Ff//////f3ylBDX2Faoqqir/f4Ha/3//vwQ19RX/v/+//3+B2gQ19RWqKqoq")
+}]
+blend_shape_mode = 0
+shadow_mesh = SubResource("ArrayMesh_ejvnk")
+
+[sub_resource type="Image" id="Image_jmsqj"]
+data = {
+"data": PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAISEh/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/SkpK/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/SkpK/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/S0tL/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEhIf80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/S0tL/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/S0tL/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/S0tL/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9LS0v/S0tL/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9MTEz/TExM/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs7O/87Ozv/PDw8/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9MTEz/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/PDw8/zw8PP89PT3/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9MTEz/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/z09Pf89PT3/PT09/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9MTEz/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8+Pj7/Pj4+/z4+Pv80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP9NTU3/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/z8/P/8/Pz//Pz8//zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/01NTf9NTU3/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/9AQED/QEBA/0BAQP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/05OTv9NTU3/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/0FBQf9BQUH/QkJC/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/05OTv8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/9CQkL/QkJC/0NDQ/80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/05OTv8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/0NDQ/9ERET/RERE/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/09PT/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/9FRUX/RUVF/0VFRf80NDT/NDQ0/09PT/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/0ZGRv8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoa/xoaGv8aGhr/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Gxsb/xsbG/8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/MTEx/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/zExMf8xMTH/MTEx/zExMf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8xMTH/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/MTEx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaGhr/Ghoa/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="),
+"format": "RGBA8",
+"height": 64,
+"mipmaps": false,
+"width": 64
+}
+
+[sub_resource type="ImageTexture" id="ImageTexture_op0o1"]
+image = SubResource("Image_jmsqj")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_phtkf"]
+resource_name = "grass"
+cull_mode = 2
+albedo_color = Color(0.146383, 0.792724, 0, 1)
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_f4oji"]
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"format": 34896613377,
+"index_count": 60,
+"index_data": PackedByteArray("CgAEAAYACgAIAAQAAwAJAAsAAwACAAkAAAAHAAUAAAABAAcAAQACAAMAAQAAAAIAAQALAAcAAQADAAsABAAHAAYABAAFAAcABgALAAoABgAHAAsACgAJAAgACgALAAkACAAFAAQACAAJAAUAAgAFAAkAAgAAAAUA"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("AAAAAP//AAAAAAAAAAAAAP//AAD//wAA//8AAAAAAAC4A///RvwAAAAARvz//wAAuAP//7gDAAAAAEb8AAAAAEb8//9G/AAA//9G/P//AABG/P//uAMAAP//RvwAAAAA")
+}]
+blend_shape_mode = 0
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_1mtgn"]
+resource_name = "green_Cube_004"
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"attribute_data": PackedByteArray("/18AAP8f/z//X////1//v/8f/3//X/+//1//P/9f/z//X/8//1//f/9f/3//X/9/Ed/tQBHf7UAR3+1AEZ8AAP/f/z//3/8/EZ///xHfEX8R3xF/Ed8RfxGf/7//3/9//9//fxGf/7/toO1A7aDtQO2g7UARn/8//5//PxGf/z8Rn/8/7aARf+2gEX/toBF/EZ//f/+f/38Rn/9/EZ//fw=="),
+"format": 34896613399,
+"index_count": 60,
+"index_data": PackedByteArray("IgANABQAIgAbAA0ACwAgACcACwAIACAAAgAZABIAAgAFABkABAAHAAoABAABAAcAAwAkABYAAwAJACQADgAYABUADgARABgAEwAlACEAEwAXACUAIwAfABwAIwAmAB8AGgAQAAwAGgAeABAABgAPAB0ABgAAAA8A"),
+"material": SubResource("StandardMaterial3D_phtkf"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 40,
+"vertex_data": PackedByteArray("AAAAAP///78AAAAA////vwAAAAD//1TVAAAAAAAA//8AAAAAAAD/vwAAAAAAAFTV//8AAP///7///wAA////v///AAD//1TV//8AAAAA/////wAAAAD/v///AAAAAFTVuAP//0b8//+4A///Rvz//7gD//9G/KrpAABG/P///78AAEb8/////wAARvz//6rpAABG/P//VNW4A///uAP//7gD//+4A///uAP//7gDqukAAEb8AAD//wAARvwAAP//AABG/AAAqukAAEb8AABU1Ub8//9G/P//Rvz//0b8//9G/P//Rvyq6f//Rvz///+///9G/P///////0b8//+q6f//Rvz//1TVRvz//7gD//9G/P//uAP//0b8//+4A6rp//9G/AAA/////0b8AAD/////RvwAAKrp//9G/AAAVNX/////AAD/f1TVVNX/v/+/AAD/f1TVVNX/////AAD/f6oqqir/v/+/AAD/f6oqqir/f3yl/3//vwlqBLX//////398pQlqBLVU1VTV/3+B2v9//78JagS1/7//v/9/gdoJagS1VNVU1f9/fKX/f/+/BDX2Ff//////f3ylBDX2Faoqqir/f4Ha/3//vwQ19RX/v/+//3+B2gQ19RWqKqoq")
+}]
+blend_shape_mode = 0
+shadow_mesh = SubResource("ArrayMesh_f4oji")
+
+[sub_resource type="Image" id="Image_fsj22"]
+data = {
+"data": PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ6QY/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANs0k/zbNJP82zST/Nswk/zbMJP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbMJP82zCT/Nswk/zbLJP82yyT/Nssk/zbLJP82yyT/Nssk/zbLJP82yyT/Nssk/zbLJP82yyT/Nssk/zbLJP82yyT/Nssk/zbLJP82yyT/Nssk/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1zCT/Ncwk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/ON0k/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/ON0j/zG/IP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1yyT/Ncsk/zXLJP81yyT/Ncsk/zXLJP81yyT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/ON0j/zG/IP8xvyD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACekGP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/ON0j/zG/IP8xvyD/Mb8g/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/Ncok/zXKJP81yiT/ON0j/zC/H/8xvyD/Mb8g/zG/IP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81ySP/Nckk/zXJJP81yST/Nckk/zXJJP81yST/ON0j/zC/H/8wvx//Mb8g/zG/IP8xvyD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/843CP/ONwj/zC/H/8wvx//Mb8f/zG/IP8xvyD/Mb8g/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Ncoj/zXKI/81yiP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/Nckj/zXJI/81ySP/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ML0f/zC+H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xvx//McAf/zHAIP8xwCD/McAg/zHAIP8xwCD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML0f/zC9H/8wvh//ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//Mb8f/zHAH/8xwCD/McAg/zHAIP8xwCD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC9H/8wvR//ML4f/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//Mb8f/zHAH/8xwCD/McAg/zHAIP8xwCD/McAg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvR//ML4f/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zG/H/8xwB//McAg/zHAIP8xwCD/McAg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML0f/zC+H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAIP8xwCD/McAg/zHAIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xvx//McAf/zHAH/8xwCD/McAg/zHAIP8xwCD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//Mb8f/zHAH/8xwCD/McAg/zHAIP8xwCD/McEg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAg/zHAIP8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zG/H/8xwB//McAf/zHAIP8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwCD/McAg/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwCD/McAg/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwB//McAg/zHAIP8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAf/zHAIP8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/McIg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/GXQN/xl0Df8ZdA3/ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/McIg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/xl0Df8ZdA3/GXQN/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwCD/McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/McIg/zHCIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8ZdA3/GXQN/xl0Df8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McAg/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8xwiD/McIg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8ZdA3/ML8f/zC/H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwB//McAf/zHAIP8xwSD/McEg/zHBIP8xwSD/McEg/zHCIP8xwiD/McIg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/GXQN/zC/H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAf/zHAH/8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8wvx//ML8f/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwCD/McEg/zHBIP8xwSD/McEg/zHBIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwB//McAg/zHBIP8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McAf/zHBIP8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHAIP8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHAH/8xwSD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwB//McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwB//McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McAf/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wwB//MMAf/zHAH/8xwB//McAf/zHBH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//MMAf/zHAH/8xwB//McAf/zHAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/MMAf/zDAH/8xwB//McAf/zHAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zDAH/8xwB//McAf/zHAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/MMAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="),
+"format": "RGBA8",
+"height": 64,
+"mipmaps": false,
+"width": 64
+}
+
+[sub_resource type="ImageTexture" id="ImageTexture_613u0"]
+image = SubResource("Image_fsj22")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ijvmk"]
+resource_name = "grass"
+cull_mode = 2
+albedo_color = Color(0.146383, 0.792724, 0, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ufxyo"]
+resource_name = "Material.011"
+cull_mode = 2
+albedo_color = Color(0.906392, 0.554774, 0, 1)
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_5esuj"]
+resource_name = "Material.012"
+cull_mode = 2
+albedo_color = Color(0.214332, 0.0889574, 0.0230044, 1)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yf47a"]
+resource_name = "Material.004"
+cull_mode = 2
+albedo_color = Color(0.685558, 0.363767, 0.110521, 1)
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_u8d04"]
+resource_name = "Material.005"
+cull_mode = 2
+albedo_color = Color(0.204015, 0.906473, 0, 1)
+roughness = 0.5
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_iscf7"]
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"format": 34896613377,
+"index_count": 60,
+"index_data": PackedByteArray("CgAEAAYACgAIAAQAAwAJAAsAAwACAAkAAAAHAAUAAAABAAcAAQACAAMAAQAAAAIAAQALAAcAAQADAAsABAAHAAYABAAFAAcABgALAAoABgAHAAsACgAJAAgACgALAAkACAAFAAQACAAJAAUAAgAFAAkAAgAAAAUA"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("AAAAAP//AAAAAAAAAAAAAP//AAD//wAA//8AAAAAAAC4A///RvwAAAAARvz//wAAuAP//7gDAAAAAEb8AAAAAEb8//9G/AAA//9G/P//AABG/P//uAMAAP//RvwAAAAA")
+}, {
+"aabb": AABB(-0.911349, 1.00623, -0.911349, 1.8227, 0.127916, 1.8227),
+"format": 34896613377,
+"index_count": 144,
+"index_data": PackedByteArray("AAAEAAMAAAABAAQAAQAFAAQAAQACAAUAAwAHAAYAAwAEAAcABAAIAAcABAAFAAgABgAKAAkABgAHAAoABwALAAoABwAIAAsACQANAAwACQAKAA0ACgAOAA0ACgALAA4ADAAQAA8ADAANABAADQARABAADQAOABEADwATABIADwAQABMAEAAUABMAEAARABQAEgAWABUAEgATABYAEwAXABYAEwAUABcAFQAZABgAFQAWABkAFgAaABkAFgAXABoAGAAcABsAGAAZABwAGQAdABwAGQAaAB0AGwAfAB4AGwAcAB8AHAAgAB8AHAAdACAAHgAiACEAHgAfACIAHwAjACIAHwAgACMAIQABAAAAIQAiAAEAIgACAAEAIgAjAAIA"),
+"name": "Material.011",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 36,
+"vertex_data": PackedByteArray("//8AAP9/AAAq+P///38AAH7rNp7/fwAA2O4AAP8/AAAQ6P//6kMAABfdNp4/SgAA/78AACYRAAAUvP//7hcAAL+1Np7nIgAA/38AAAAAAAD/f///1AcAAP9/Np6AFAAA/z8AACYRAADqQ///7hcAAD9KNp7nIgAAJhEAAP8/AADuF///6kMAAOciNp4/SgAAAAAAAP9/AADUB////38AAIAUNp7/fwAAJhEAAP+/AADuF///FLwAAOciNp6/tQAA/z8AANjuAADqQ///EOgAAD9KNp4X3QAA/38AAP//AAD/f///KvgAAP9/Np5+6wAA/78AANjuAAAUvP//EOgAAL+1Np4X3QAA2O4AAP+/AAAQ6P//FLwAABfdNp6/tQAA")
+}, {
+"aabb": AABB(-0.911349, 1.00623, -0.911349, 1.8227, 1e-05, 1.8227),
+"format": 34896613377,
+"index_count": 30,
+"index_data": PackedByteArray("AQALAAAACwAJAAoACQAHAAgABwAFAAYABQADAAQAAwABAAIAAQAJAAsACQAFAAcABQABAAMACQABAAUA"),
+"name": "Material.012",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("//8AAP9/AADY7gAA/z8AAP+/AAAmEQAA/38AAAAAAAD/PwAAJhEAACYRAAD/PwAAAAAAAP9/AAAmEQAA/78AAP8/AADY7gAA/38AAP//AAD/vwAA2O4AANjuAAD/vwAA")
+}, {
+"aabb": AABB(-0.248464, 0.846295, -0.256822, 0.44153, 1.51265, 0.449862),
+"format": 34896613377,
+"index_count": 99,
+"index_data": PackedByteArray("BAABAAAAAQADAAIAAQAEAAMABAAFABMABAAAAAUAEwAGABIAEwAFAAYAEgAHABEAEgAGAAcAAwATABAAAwAEABMAEAASAA8AEAATABIADwARAA4ADwASABEAAgAQAA0AAgADABAADQAPAAwADQAQAA8ADAAOAAsADAAPAA4AAQANAAoAAQACAA0ACgAMAAkACgANAAwACQALAAgACQAMAAsAAAAKAAUAAAABAAoABQAJAAYABQAKAAkABgAIAAcABgAJAAgA"),
+"lods": [0.0193507, PackedByteArray("BAABAAAAAQAEAAMAAQADAAIABAAFABMABAAAAAUAEwAFAAcAEwAHABEAAwATABAAAwAEABMAEAATABEAEAARAA4AAgAQAA0AAgADABAADQAQAA4ADQAOAAsAAQANAAoAAQACAA0ACgANAAsACgALAAgAAAAKAAUAAAABAAoABQAKAAgABQAIAAcA")],
+"name": "Material.004",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 20,
+"vertex_data": PackedByteArray("//8AAErAAACXawAA//8AAAAAAAAniQAA6VEAAAAAAAAg8AAAEyIAAK/XY28ZqQAAPcgrqDGgAAC7yf//CaEAAA95kf4TxQAAn3mjqL7BAACadWNvNNMAAFo+Wf8+gwAAAEEpqeqCAAB/LmNvqYQAAAVr/v7iNwAAHmwNqaQ6AACiZGNvAyoAAJjBdv/wSgAAur9yqGxMAAAyzWNviUAAAA==")
+}, {
+"aabb": AABB(-0.718427, 2.05751, -0.753282, 1.36393, 1.3161, 1.33542),
+"format": 34896613377,
+"index_count": 240,
+"index_data": PackedByteArray("AAAMAA0AAQAPAA0AAAARAAwAAAATABEAAAAQABMAAQAWAA8AAgAYAA4AAwAaABIABAAcABQABQAeABUAAQAZABYAAgAbABgAAwAdABoABAAfABwABQAXAB4ABgAlACAABwAnACEACAAoACIACQApACMACgAmACQAJgALACkAJgApACQAJAApAAkAKQALACgAKQAoACMAIwAoAAgAKAALACcAKAAnACIAIgAnAAcAJwALACUAJwAlACEAIQAlAAYAJQALACYAJQAmACAAIAAmAAoAFwAKACQAFwAkAB4AHgAkAAkAHwAJACMAHwAjABwAHAAjAAgAHQAIACIAHQAiABoAGgAiAAcAGwAHACEAGwAhABgAGAAhAAYAGQAGACAAGQAgABYAFgAgAAoAHgAJAB8AHgAfABUAFQAfAAQAHAAIAB0AHAAdABQAFAAdAAMAGgAHABsAGgAbABIAEgAbAAIAGAAGABkAGAAZAA4ADgAZAAEAFgAKABcAFgAXAA8ADwAXAAUAEAAFABUAEAAVABMAEwAVAAQAEwAEABQAEwAUABEAEQAUAAMAEQADABIAEQASAAwADAASAAIADwAFABAADwAQAA0ADQAQAAAADAACAA4ADAAOAA0ADQAOAAEA"),
+"lods": [0.229579, PackedByteArray("AAAbAA0AGwABAA0AGwAlAAYAGwAGAAEAAQAGABYABgAgABYABgAlACAAJQAmACAAJQALACYAAQAWAAUAAQAFAA0ABQAQAA0ADQAQAAAAFgAKAAUAFgAgAAoAIAAmAAoAEAAFABUAEAAVABMAAAAQABMAEwAVAAQABQAKABUACgAJABUAFQAJAAQACgAmAAkAJgApAAkAJgALACkAKQAoAAkAKQALACgACQAoAAgABAAJAAgACAAdAAQABAAdAAMAEQAEAAMAEwAEABEAAAATABEAAwAdABoAAwAaABEAGgAbABEAAAARABsAHQAIACIAHQAiABoACAAoACIAKAAbACIAGgAiABsAKAALABsAGwALACUA")],
+"name": "Material.005",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 42,
+"vertex_data": PackedByteArray("uogAAB2KAAAKIT1UwrIAAH8uKE8+LwAAHb9TUOMnAACZ6ktWr54AAAuPbU3//wAAbBXlxiFvAACgewDAmBwAAMLjh78KXwAASsnPuo3XAACaV/69I+QAAJyG//+DjAAAXVviGwdYAAC1RxkbeKIAAL8qvk6JcwAA80pSRTbsAABAh2MjMccAANilYCdwTwAA/HtTSQQeAABHxbwWHZUAAGPhqkR+YQAAncwGOp/fAAD8JbqFtOEAAD5tkIwA+QAA1hfAiktGAAAAAAqMVpUAAECeGIQAAAAA7UhyiiUSAAD//zaK0HwAAD/ZkoapOAAA+rIKiSb9AAAO6+yDVsMAAHUYu9XktgAAMjZ51A8zAAC1sS3H0jAAAF/lbsdynAAAfpLpwZftAADHQdP8RnsAAAJiRPwOyQAAWH7A7NRHAACQwG/3tW4AAAau7/N4ugAA")
+}]
+blend_shape_mode = 0
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_emgrj"]
+resource_name = "tree_Cube_005"
+_surfaces = [{
+"aabb": AABB(-1, -1, -1, 2, 2, 2),
+"attribute_data": PackedByteArray("/18AAP8f/z//X////1//v/8f/3//X/+//1//P/9f/z//X/8//1//f/9f/3//X/9/Ed/tQBHf7UAR3+1AEZ8AAP/f/z//3/8/EZ///xHfEX8R3xF/Ed8RfxGf/7//3/9//9//fxGf/7/toO1A7aDtQO2g7UARn/8//5//PxGf/z8Rn/8/7aARf+2gEX/toBF/EZ//f/+f/38Rn/9/EZ//fw=="),
+"format": 34896613399,
+"index_count": 60,
+"index_data": PackedByteArray("IgANABQAIgAbAA0ACwAgACcACwAIACAAAgAZABIAAgAFABkABAAHAAoABAABAAcAAwAkABYAAwAJACQADgAYABUADgARABgAEwAlACEAEwAXACUAIwAfABwAIwAmAB8AGgAQAAwAGgAeABAABgAPAB0ABgAAAA8A"),
+"material": SubResource("StandardMaterial3D_ijvmk"),
+"name": "grass",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 40,
+"vertex_data": PackedByteArray("AAAAAP///78AAAAA////vwAAAAD//1TVAAAAAAAA//8AAAAAAAD/vwAAAAAAAFTV//8AAP///7///wAA////v///AAD//1TV//8AAAAA/////wAAAAD/v///AAAAAFTVuAP//0b8//+4A///Rvz//7gD//9G/KrpAABG/P///78AAEb8/////wAARvz//6rpAABG/P//VNW4A///uAP//7gD//+4A///uAP//7gDqukAAEb8AAD//wAARvwAAP//AABG/AAAqukAAEb8AABU1Ub8//9G/P//Rvz//0b8//9G/P//Rvyq6f//Rvz///+///9G/P///////0b8//+q6f//Rvz//1TVRvz//7gD//9G/P//uAP//0b8//+4A6rp//9G/AAA/////0b8AAD/////RvwAAKrp//9G/AAAVNX/////AAD/f1TVVNX/v/+/AAD/f1TVVNX/////AAD/f6oqqir/v/+/AAD/f6oqqir/f3yl/3//vwlqBLX//////398pQlqBLVU1VTV/3+B2v9//78JagS1/7//v/9/gdoJagS1VNVU1f9/fKX/f/+/BDX2Ff//////f3ylBDX2Faoqqir/f4Ha/3//vwQ19RX/v/+//3+B2gQ19RWqKqoq")
+}, {
+"aabb": AABB(-0.911349, 1.00623, -0.911349, 1.8227, 0.127916, 1.8227),
+"attribute_data": PackedByteArray("/39lZv9/ZWb/fzIz/38yM/9/MjP/fzIz/38AAP9/AABUlWVmVJVlZlSVMjNUlTIzVJUyM1SVMjNUlQAAVJUAAKqqZWaqqmVmqqoyM6qqMjOqqjIzqqoyM6qqAACqqgAA/79lZv+/ZWb/vzIz/78yM/+/MjP/vzIz/78AAP+/AABU1WVmVNVlZlTVMjNU1TIzVNUyM1TVMjNU1QAAVNUAAKnqZWap6mVmqeoyM6nqMjOp6jIzqeoyM6nqAACp6gAAAABlZv//ZWb//zIzAAAyMwAAMjMAADIz//8yM///AAAAAAAAVRVlZlUVZWZVFTIzVRUyM1UVMjNVFTIzVRUAAFUVAABVFQAAqiplZqoqZWaqKjIzqioyM6oqMjOqKjIzqioAAKoqAAD/P2Vm/z9lZv8/MjP/PzIz/z8yM/8/MjP/PwAA/z8AAFVVZWZVVWVmVVUyM1VVMjNVVTIzVVUyM1VVAABVVQAAqmplZqpqZWaqajIzqmoyM6pqMjOqajIzqmoAAKpqAAA="),
+"format": 34896613399,
+"index_count": 144,
+"index_data": PackedByteArray("AQALAAkAAQADAAsABAAPAA0ABAAGAA8ACAATABEACAAKABMADAAXABUADAAOABcAEAAbABgAEAASABsAFAAfABwAFAAWAB8AGQAkACAAGQAdACQAGgAmACIAGgAeACYAIQAsACgAIQAlACwAIwAuACoAIwAnAC4AKQA2ADEAKQAtADYAKwA3ADIAKwAvADcAMAA+ADoAMAA1AD4AMwBAADwANAA4AEEAOQBHAEMAOQA9AEcAOwBJAEUAOwA/AEkAQgBPAEsAQgBGAE8ARABQAEwARABIAFAASgBUAFIASgBNAFQATgBYAFYATgBRAFgAUwBcAFoAUwBVAFwAVwBgAF4AVwBZAGAAWwACAAAAWwBdAAIAXwAHAAUAXwBhAAcA"),
+"material": SubResource("StandardMaterial3D_ufxyo"),
+"name": "Material.011",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 98,
+"vertex_data": PackedByteArray("//8AAP9/Zrf//wAA/3/kyyr4////f2a3Kvj///9/5Msq+P///3+C5ir4////f1/efus2nv9/guZ+6zae/39f3tjuAAD/P6ng2O4AAP8/5MsQ6P//6kOp4BDo///qQ+TLEOj//+pDIvAQ6P//6kOC5hfdNp4/SiLwF902nj9Kgub/vwAAJhGK9f+/AAAmEangFLz//+4XivUUvP//7hep4BS8///uF536FLz//+4XIvC/tTae5yKd+r+1Np7nIiLw/38AAAAAivX/fwAAAACK9f9////UB536/3///9QHivX/f///1Aed+v9////UB4r1/382noAUnfr/fzaegBSd+v8/AAAmEYr1/z8AACYRqeDqQ///7hed+upD///uFyLw6kP//+4XivXqQ///7hep4D9KNp7nIp36P0o2nuciIvAmEQAA/z+p4CYRAAD/P+TL7hf//+pDIvDuF///6kOC5u4X///qQ6ng7hf//+pD5MvnIjaeP0oi8OciNp4/SoLmAAAAAP9/ZrcAAAAA/3/ky9QH////f4Lm1Af///9/X97UB////39g3tQH////f2a31Af///9/5MuAFDae/3+C5oAUNp7/f2DeJhEAAP+/sKMmEQAA/79mt+4X//8UvGfY7hf//xS8X97uF///FLywo+4X//8UvGa35yI2nr+1Z9jnIjaev7Vf3uciNp6/tWDe/z8AANjuYpP/PwAA2O6wo+pD//8Q6DnV6kP//xDoZ9jqQ///EOhik+pD//8Q6LCjP0o2nhfdOdU/SjaeF91n2P9/AAD//2KT/38AAP//YpP/f///Kvg51f9///8q+GKT/3///yr4OdX/f///Kvhik/9/Np5+6znV/382nn7rOdX/vwAA2O5ik/+/AADY7rCjFLz//xDoYpMUvP//EOiwoxS8//8Q6DnVFLz//xDoZ9i/tTaeF9051b+1Np4X3WfY2O4AAP+/sKPY7gAA/79mtxDo//8UvLCjEOj//xS8ZrcQ6P//FLxn2BDo//8UvF/eF902nr+1Z9gX3Taev7Vf3qGo/RapoZ0Ooaj9FqmhnQ4h4L0pCua9OSHgvSkK5r05bZxTCKmhnQ5tnFMIqaGdDoHaghoh4L0pgdqCGiHgvSnOl8UCbZxTCM6XxQJtnFMIVtTQCYHaghpW1NAJgdqCGs6XxQLEgjDoz4mnq86XxQJW1NAJxIIw6M+Jp6tW1NAJxIIw6FOIkOPPiaergZp9pcSCMOhTiJDjz4mnq4GafaVTiJDjnY5U3oGafaW8qdyfU4iQ452OVN6Bmn2lvKncn/2WXdedjlTevKncn7y585m9ufOZ/ZZd152OVN68qdyfvbnzme6kw8v9ll3XQM2+kry585nupMPL/ZZd10DNvpK8ufOZvbnzmcPHyK7upMPL4+kpiEDNvpLDx8iu7qTDy+PpKYhAzb6SNtHDR8PHyK7j6SmINtHDR9T342nDx8iu4+kpiNT342k20cNHOrTuJDbRw0c6tO4k1PfjaUDtQE3U9+NpQO1ATTq07iShqP0WOrTuJKGo/RZA7UBNCua9OUDtQE0K5r05")
+}, {
+"aabb": AABB(-0.911349, 1.00623, -0.911349, 1.8227, 1e-05, 1.8227),
+"attribute_data": PackedByteArray("/39lZlSVZWaqqmVm/79lZlTVZWap6mVmAABlZlUVZWaqKmVm/z9lZlVVZWaqamVm"),
+"format": 34896613399,
+"index_count": 30,
+"index_data": PackedByteArray("AQALAAAACwAJAAoACQAHAAgABwAFAAYABQADAAQAAwABAAIAAQAJAAsACQAFAAcABQABAAMACQABAAUA"),
+"material": SubResource("StandardMaterial3D_5esuj"),
+"name": "Material.012",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 12,
+"vertex_data": PackedByteArray("//8AAP9//7/Y7gAA/z//v/+/AAAmEf+//38AAAAA/7//PwAAJhH/vyYRAAD/P/+/AAAAAP9//78mEQAA/7//v/8/AADY7v+//38AAP///7//vwAA2O7/v9juAAD/v/+/AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/")
+}, {
+"aabb": AABB(-0.248464, 0.846295, -0.256822, 0.44153, 1.51265, 0.449862),
+"attribute_data": PackedByteArray("/7+Ogv///38AAP9/bfoCrczM/3/MzP9/mZn/fxzks/GZmf9/Zmb/f+Kbs/FmZv9/kIUCrTMz/38zM/9/////X////1////9fAAD/XwAA/1////8/////PwAA/z8AAP8/AAD/P////x8AAP8fzMz/H8zM/x/LzP8/y8z/P8vM/z/LzP8/y8z/P8vM/1/LzP9fy8z/X8vM/1/LzP9fmZn/H5mZ/x+Zmf8/mZn/P5mZ/z+Zmf8/mZn/P5mZ/1+Zmf9fmZn/X5mZ/1+Zmf9fZmb/H2Zm/x9mZv8/Zmb/P2Zm/z9mZv8/Zmb/P2Zm/19mZv9fZmb/X2Zm/19mZv9fMzP/HzMz/x8zM/8/MzP/PzMz/z8zM/8/MzP/PzMz/18zM/9fMzP/XzMz/18zM/9f"),
+"format": 34896613399,
+"index_count": 99,
+"index_data": PackedByteArray("DAADAAAAAwAKAAcAAwAMAAoADQASAEYADQACABIARwAXAEIASAATABgAQQAaAD8AQQAWABoACwBJADwACwAOAEkAPQBDADgAPgBKAEQAOQBAADQAOQBFAEAABgA6AC4ABgAJADoAMAA2ACkALwA7ADUAKgAzACcAKgA3ADMABQAxACQABQAIADEAJQArACAAJgAyACwAIQAoABwAIQAtACgAAQAiAA8AAQAEACIAEAAeABUAEQAjAB8AFAAbABkAFAAdABsA"),
+"lods": [0.0193507, PackedByteArray("DAADAAAAAwAMAAoAAwAKAAcADQASAEYADQACABIARgASABoARgAaAD8ACwBJADwACwAOAEkAPABJAEAAPABAADQABgA6AC4ABgAJADoALgA6ADMALgAzACcABQAxACQABQAIADEAJAAxACgAJAAoABwAAQAiAA8AAQAEACIADwAiABsADwAbABkA")],
+"material": SubResource("StandardMaterial3D_yf47a"),
+"name": "Material.004",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 75,
+"vertex_data": PackedByteArray("//8AAErARR3//wAASsBEkf//AABKwBXEl2sAAP//RR2XawAA//9EkZdrAAD//56iAAAAACeJp9UAAAAAJ4lFHQAAAAAniZ6i6VEAAAAAp9XpUQAAAABFHelRAAAAADT3IPAAABMiRR0g8AAAEyIVxCDwAAATIjT3r9djbxmpRJGv12NvGakKka/XY28ZqRGRr9djbxmpFcSv12NvGakLxD3IK6gxoBGRPcgrqDGgCpE9yCuoMaDmwz3IK6gxoBXEPcgrqDGgC8S7yf//CaE0kbvJ//8JoejDD3mR/hPFJpEPeZH+E8Wgop95o6i+wRaRn3mjqL7BCpGfeaOovsERkZ95o6i+wZKin3mjqL7BnqKadWNvNNNEkZp1Y2800xGRmnVjbzTTnqKadWNvNNOSopp1Y28004qiWj5Z/z6DhdVaPln/PoOfogBBKanqgp7VAEEpqeqChNUAQSmp6oKSogBBKanqgoqiAEEpqeqCnqJ/LmNvqYSn1X8uY2+phKHVfy5jb6mEntV/LmNvqYSeon8uY2+phIqiBWv+/uI3hNUFa/7+4jco9x5sDamkOqHVHmwNqaQ6ntUebA2ppDqE1R5sDamkOkL3HmwNqaQ6KPeiZGNvAyqn1aJkY28DKqHVomRjbwMqNPeiZGNvAypC96JkY28DKjf3mMF2//BK6MOYwXb/8Eon97q/cqhsTObDur9yqGxMFcS6v3KobExC97q/cqhsTDf3ur9yqGxMJvcyzWNviUAVxDLNY2+JQBXEMs1jb4lAC8QyzWNviUA09zLNY2+JQDf3vzF+43GchhcEiz0FvzF+43GchhckjGTuXIPD9r8xfuMkjGTuXIPD9r8xfuOlhqYAvzF+4wSLPQWlhqYAcZyGFySU8xTBltISBIs9BXaIBgQwfqgDJJTzFLR+BQFviGEDdogGBFZt3gSfgNgB3HBNBA99h/kSf6oGJJTzFMGW0hJNiMbweX3k+nGchhfBltISJIxk7k2IxvCYiRbyjoFp/yZ91fnkgqr40YDi/02IxvCYiRbykn02+1yDw/afgsj45IKq+CSMZO6YiRbyZIGE/xSBrAGfgsj45IKq+KWA/v88ev0A5n50AVyDw/afgsj4pYamADx6/QAghYAA+YCEApmAJAFVf7kAb4hhAzx6/QAghYAAan7hAQSLPQVviGEDdogGBKWGpgAghYAA")
+}, {
+"aabb": AABB(-0.718427, 2.05751, -0.753282, 1.36393, 1.3161, 1.33542),
+"attribute_data": PackedByteArray("iy7//6KL//8WXf//uej//y26///RRa/X0UWv19FFr9fRRa/X0UWv10UXr9dFF6/XRRev1///r9f//6/Xc9Gv13PRr9dz0a/Xc9Gv13PRr9fooq/X6KKv1+iir9fooq/X6KKv11x0r9dcdK/XXHSv11x0r9dcdK/Xiy5gr4suYK+LLmCviy5gr4suYK8AAGCvAABgr7noYK+56GCvuehgry26YK8tumCvLbpgry26YK8tumCvootgr6KLYK+ii2Cvootgr6KLYK8WXWCvFl1grxZdYK8WXWCvFl1gr9FFEYdcdBGH6KIRh3PREYdFFxGH6CLX6+gi1+voItfrXPTX61z01+tc9NfrLjrX6y461+suOtfrdFHX63RR1+t0Udfriy6v14sur9eLLq/Xiy6v14sur9eLLq/XFl2v1xZdr9cWXa/XFl2v1xZdr9cWXa/X/3/X6/9/1+v/f9fruWjX67lo1+u5aNfrFt3X69DF1+sW3dfr0MXX69DF1+sW3dfrueiv17nor9e56K/Xueiv17nor9e56K/XRZfX60WX1+tFl9friq7X64qu1+uKrtfrLbqv1y26r9ctuq/XLbqv1y26r9ctuq/Xoouv16KLr9eii6/Xoouv16KLr9eii6/XdFGIw3RRiMN0UYjDdFGIw3RRiMN0UYjDuWiIw7loiMO5aIjDuWiIw7loiMO5aIjD6CKIw+giiMPoIojD6CKIw+giiMPoIojDLjqIwy46iMMuOojDLjqIwy46iMMuOojDFt2IwxbdiMMW3YjDFt2IwxbdiMMW3YjDoguIw6ILiMNc9IjDXPSIw6ILiMNc9IjDiq6Iw4quiMOKrojDiq6Iw4quiMOKrojD0MWIw9DFiMPQxYjD0MWIw9DFiMPQxYjD/3+Iw/9/iMP/f4jD/3+Iw/9/iMP/f4jDRZeIw0WXiMNFl4jDRZeIw0WXiMNFl4jD0UVgr9FFYK/RRWCv0UVgr9FFYK/RRWCvRRdgr0UXYK9FF2CvRRdgr0UXYK9FF2Cvc9Fgr3PRYK9z0WCvc9Fgr3PRYK9z0WCv6KJgr+iiYK/oomCv6KJgr+iiYK/oomCvXHRgr1x0YK9cdGCvXHRgr1x0YK9cdGCvLjo5m+giOZsuOjmbLjo5m+giOZvoIjmbdFE5m7loOZt0UTmbuWg5m7loOZt0UTmbFt05m6ILOZuiCzmbogs5mxbdOZsW3Tmbiq45m4quOZvQxTmbiq45m9DFOZvQxTmbRZc5m/9/OZv/fzmb/385m0WXOZtFlzmb0UWv13PRr9fooq/XXHSv11x0r9eLLmCviy5gry26YK+ii2Cvootgry461+tFl9friq7X66KLr9eii6/XdFGIwxbdiMMW3YjDoguIw6ILiMOiC4jDXPSIw9FFYK9z0WCvLjo5m+giOZu5aDmbiq45m9DFOZtFlzmb/385mw=="),
+"format": 34896613399,
+"index_count": 240,
+"index_data": PackedByteArray("AAA8AEIABwBQAEcAAwBaAEAABABqAFsAAQBVAGcACQB5AFEACwCHAE0AEQCSAGUAGACeAG0AGwCrAHUACACOAHgADACXAIkAEwCnAJUAFQCzAJ0AHAB/AK0AIQDUALQAIwDhAL4AKgDpAMIALQDqAMYAMgDcAM8A2QA4AOsA2wDtAM4AzADsAC8A7gA5AOQA7wDlAMgAygDnACgA5gA6AN4A6ADiAMAAwQDjACUA3wA7ANYA4ADXAL0AuwDTAB8A0gA3ANgA1QDaALUAuADdADQAgAAzANEAfgDQAKwAqgDNADAAsAAxAMcAsgDJAJwAnwDLACkApQAsAMQApgDFAJQAkwDDACcAmgAkAL8AlgC8AIgAhAC6AB4AjQAiALYAjwC3AHoAewC5ADUAqAAuAK4AqQCvAHIAdgCxABQAoQArAKMAoACiAHAAcQCkABIAkQAmAJsAkACZAGQAYwCYAA4AhgAgAIsAhQCKAEkATACMAAYAfAA2AIEAfQCDAFMAUgCCAB0AVgAZAHQAVABzAGYAaAB3ABYAaQAXAGwAawBuAF0AXgBvAA8AXwAQAGIAXABhAEEAPwBgAA0ATwAaAFkATgBYAEYARQBXAAIAPgAKAEoAPQBIAEMARABLAAUA"),
+"lods": [0.229579, PackedByteArray("AAACAfoABAHwAPoABAHTAPYABAH1APAA8AD1AP8A9QC0AP8A9gAIAbQACAHYALQACAE3ANgA8AD/APMA8ADzAEUA8wBXAEUARQBXAAIA/wAyAPMA/wC5ADIABgHdADIAVADzAHMAVABzAPsAAQBUAPsA+wD+APIA9AAyAP0AMgD4AP0A/QD4APIAMgAKAfkACgEOAfkACgE4AA4BDQELAfgADQE5AAsB+AALAfcA8gD4APcA9wCiAPIA8gCiAPEAWwDyAPEA/ADyAFsABAD8AFsA8QCiAAAB8QAAAVoAAAGYAFoAAwBaAJgAogD3AAcBogAHAZQA9wAMAQcBDAEFAQcBAQEHAQUBDAE6AAUBAwE7AAkB")],
+"material": SubResource("StandardMaterial3D_u8d04"),
+"name": "Material.005",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 271,
+"vertex_data": PackedByteArray("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")
+}]
+blend_shape_mode = 0
+shadow_mesh = SubResource("ArrayMesh_iscf7")
+
+[sub_resource type="Image" id="Image_ep661"]
+data = {
+"data": PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Df8orhb/Ntsh/zC+H/8wvh//ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwCD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQN/xl0Df8wvh//ML4f/zC/H/8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwCD/McAg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA3/ML4f/zC+H/8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwB//McAg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC+H/8wvx//ML8f/zC/H/8wvx//ML8f/zHAH/8xwB//McAf/zHAIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvh//ML8f/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wvx//ML8f/zC/H/8xwB//McAf/zHAH/8xwCD/McEg/zHBIP8xwSD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McEg/zHBIP8xwSD/McEg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zC/H/8wvx//McAf/zHAH/8xwB//McAf/zHBIP8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wvx//MMAf/zHAH/8xwB//McAf/zHBIP8xwSD/McEg/zHBIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwSD/McEg/zHBIP8xwSD/McIg/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//ML8f/zDAH/8xwB//McAf/zHAH/8xwR//McEg/zHBIP8xwSD/McIg/zHCIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/ML8f/zC/H/8wwB//McAf/zHAH/8xwB//McEg/zHBIP8xwSD/McEg/zHCIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zC/H/8wwB//McAf/zHAH/8xwB//McEf/zHBIP8xwSD/McEg/zHCIP8xwiD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wvx//MMAf/zHAH/8xwB//McAf/zHBH/8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/MMAf/zDAH/8xwB//McAf/zHBH/8xwSD/McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGnUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zDAH/8xwB//McAf/zHAH/8xwR//McEg/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8wwB//McAf/zHAH/8xwR//McEf/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXQO/xl0Dv8ZdA7/GXQO/xl0Dv8ZdA7/McAf/zHAH/8xwB//McEf/zHBIP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl1Dv8ZdA7/GXQO/xl0Dv8ZdA7/GXQO/zHAH/8xwB//McEf/zHBH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/GXQO/xl0Dv8xwB//McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGXUO/xl1Dv8ZdQ7/GXUO/xl0Dv8ZdA7/McAf/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZdQ7/GXQO/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="),
+"format": "RGBA8",
+"height": 64,
+"mipmaps": false,
+"width": 64
+}
+
+[sub_resource type="ImageTexture" id="ImageTexture_3fakq"]
+image = SubResource("Image_ep661")
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ksx03"]
+resource_name = "Wood"
+cull_mode = 2
+albedo_color = Color(0.90643, 0.669319, 0.0971488, 1)
+roughness = 0.5
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a4lxw"]
+resource_name = "metal"
+cull_mode = 2
+albedo_color = Color(0.369313, 0.369313, 0.369313, 1)
+metallic = 0.512
+roughness = 0.524
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_wl7qe"]
+_surfaces = [{
+"aabb": AABB(-1.00116, -1.12542, -1.05409, 2.00487, 0.972221, 0.113565),
+"format": 34896613377,
+"index_count": 144,
+"index_data": PackedByteArray("AAADAAEAAAACAAMAAgAHAAMAAgAGAAcABgAFAAcABgAEAAUABAABAAUABAAAAAEAAgAEAAYAAgAAAAQABwABAAMABwAFAAEACAALAAkACAAKAAsACgAPAAsACgAOAA8ADgANAA8ADgAMAA0ADAAJAA0ADAAIAAkACgAMAA4ACgAIAAwADwAJAAsADwANAAkAEAATABEAEAASABMAEgAXABMAEgAWABcAFgAVABcAFgAUABUAFAARABUAFAAQABEAEgAUABYAEgAQABQAFwARABMAFwAVABEAGAAbABkAGAAaABsAGgAfABsAGgAeAB8AHgAdAB8AHgAcAB0AHAAZAB0AHAAYABkAGgAcAB4AGgAYABwAHwAZABsAHwAdABkA"),
+"name": "Wood",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 32,
+"vertex_data": PackedByteArray("nLH//7HaAACezv//sdoAAJyx//8mFQAAns7//yYVAACcsQAAsdoAAJ7OAACx2gAAnLEAACYVAACezgAAJhUAAOwx//+x2gAA7k7//7HaAADsMf//JhUAAO5O//8mFQAA7DEAALHaAADuTgAAsdoAAOwxAAAmFQAA7k4AACYVAACMAJlhE8wAAI0Aa53IygAAnwCKYYoGAACgAFydPwUAAOr/jGGY6gAA6/9enU3pAAD+/31hDyUAAP//T53EIwAAwwCQtmHsAADpAITy//8AABwBz7V2MwAAAADl8UoaAABT/0m0WL8AAGX/cfLozAAAZP+Ws04AAADU/wHxAAAAAA==")
+}, {
+"aabb": AABB(-0.543871, -0.692006, -1.0571, 1.11774, 0.409166, 0.126927),
+"format": 34896613377,
+"index_count": 144,
+"index_data": PackedByteArray("AAADAAEAAAACAAMAAgAFAAMAAgAEAAUAAwAHAAEAAwAFAAcABAAHAAUABAAGAAcABgABAAcABgAAAAEAAAAEAAIAAAAGAAQACAALAAkACAAKAAsACgANAAsACgAMAA0ACwAPAAkACwANAA8ADAAPAA0ADAAOAA8ADgAJAA8ADgAIAAkACAAMAAoACAAOAAwAEAATABEAEAASABMAEgAVABMAEgAUABUAEwAXABEAEwAVABcAFAAXABUAFAAWABcAFgARABcAFgAQABEAEAAUABIAEAAWABQAGAAbABkAGAAaABsAGgAdABsAGgAcAB0AGwAfABkAGwAdAB8AHAAfAB0AHAAeAB8AHgAZAB8AHgAYABkAGAAcABoAGAAeABwA"),
+"name": "metal",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 32,
+"vertex_data": PackedByteArray("W+0MPQAAAABb7Qw9//8AAAn7XiUAAAAACfteJf//AABe8gAAAAAAAF7yAAD//wAAsOStFwAAAACw5K0X//8AANcL//8AAAAA1wv/////AABLF7bgAAAAAEsXtuD//wAA1wtuwQAAAADXC27B//8AAGQAtuAAAAAAZAC24P//AACL9P7/AAAAAIv0/v///wAA//+24AAAAAD//7bg//8AAIv0bsEAAAAAi/Ruwf//AAAX6bbgAAAAABfptuD//wAAHgcdPAAAAAAeBx08//8AAKoVqygAAAAAqhWrKP//AACMDu4AAAAAAIwO7gD//wAAAABgFAAAAAAAAGAU//8AAA==")
+}]
+blend_shape_mode = 0
+
+[sub_resource type="ArrayMesh" id="ArrayMesh_ysymx"]
+resource_name = "wooden_fence_Cube_006"
+_surfaces = [{
+"aabb": AABB(-1.00116, -1.12542, -1.05409, 2.00487, 0.972221, 0.113565),
+"attribute_data": PackedByteArray("/18AAP9f////H/8//58AAP+f////3/8//1//v/9f/7//H/9//5//v/+f/7//3/9//1//P/9f/z//X/8//5//P/+f/z//n/8//1//f/9f/3//X/9//5//f/+f/3//n/9//18AAP9f////H/8//58AAP+f////3/8//1//v/9f/7//H/9//5//v/+f/7//3/9//1//P/9f/z//X/8//5//P/+f/z//n/8//1//f/9f/3//X/9//5//f/+f/3//n/9//x//P/9fAAD/X////9//P/+fAAD/n////1//v/8f/3//X/+//9//f/+f/7//n/+//1//P/9f/z//X/8//5//P/+f/z//n/8//1//f/9f/3//X/9//5//f/+f/3//n/9//18AAP8f/z//X////9//P/+fAAD/n////x//f/9f/7//X/+//9//f/+f/7//n/+//1//P/9f/z//X/8//5//P/+f/z//n/8//1//f/9f/3//X/9//5//f/+f/3//n/9/"),
+"format": 34896613399,
+"index_count": 144,
+"index_data": PackedByteArray("AQAKAAQAAQAHAAoABgAVAAkABgASABUAEwAQABYAEwANABAADAADAA8ADAAAAAMACAAOABQACAACAA4AFwAFAAsAFwARAAUAGQAiABwAGQAfACIAHgAtACEAHgAqAC0AKwAoAC4AKwAlACgAJAAbACcAJAAYABsAIAAmACwAIAAaACYALwAdACMALwApAB0AMgA7ADUAMgA4ADsANgBGADoANgBCAEYAQwBAAEcAQwA8AEAAPgA0AEEAPgAxADQANwA9AEQANwAwAD0ARQAzADkARQA/ADMASgBTAE0ASgBQAFMATwBfAFIATwBcAF8AWgBZAF4AWgBVAFkAVABMAFgAVABIAEwATgBWAFsATgBJAFYAXQBLAFEAXQBXAEsA"),
+"material": SubResource("StandardMaterial3D_ksx03"),
+"name": "Wood",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 96,
+"vertex_data": PackedByteArray("nLH//7HaAICcsf//sdr/v5yx//+x2lTVns7//7HaAICezv//sdr/v57O//+x2lTVnLH//yYV//+csf//JhX/v5yx//8mFVTVns7//yYV//+ezv//JhX/v57O//8mFVTVnLEAALHaAICcsQAAsdr/v5yxAACx2lTVns4AALHaAICezgAAsdr/v57OAACx2lTVnLEAACYV//+csQAAJhX/v5yxAAAmFVTVns4AACYV//+ezgAAJhX/v57OAAAmFVTV7DH//7HaAIDsMf//sdr/v+wx//+x2lTV7k7//7HaAIDuTv//sdr/v+5O//+x2lTV7DH//yYV///sMf//JhX/v+wx//8mFVTV7k7//yYV///uTv//JhX/v+5O//8mFVTV7DEAALHaAIDsMQAAsdr/v+wxAACx2lTV7k4AALHaAIDuTgAAsdr/v+5OAACx2lTV7DEAACYV///sMQAAJhX/v+wxAAAmFVTV7k4AACYV///uTgAAJhX/v+5OAAAmFVTVjACZYRPM5b+MAJlhE8z+v4wAmWETzIzVjQBrncjKzP+NAGudyMr+v40Aa53IyozVnwCKYYoGuv+fAIphigblv58AimGKBozVoABcnT8FzP+gAFydPwW6/6AAXJ0/BYzV6v+MYZjqG9Xq/4xhmOrlv+r/jGGY6v6/6/9enU3pzP/r/16dTekb1ev/Xp1N6f6//v99YQ8luv/+/31hDyUb1f7/fWEPJeW///9PncQjzP///0+dxCO6////T53EIxvVwwCQtmHszr/DAJC2YeynvsMAkLZh7MjV6QCE8v//1//pAITy///Qv+kAhPL//zjUHAHPtXYzp74cAc+1djON/xwBz7V2M1fWAADl8Uoa2P8AAOXxShqO/wAA5fFKGrDUU/9JtFi/6L9T/0m0WL8y1VP/SbRYv6e+Zf9x8ujMsf9l/3Hy6Mzrv2X/cfLozLbUZP+Ws04ADNVk/5azTgCnvmT/lrNOAIf/1P8B8QAAsv/U/wHxAACR1NT/AfEAAIj//3///////39UVaqq/3///////3+qKqoq////f////39UVaqq////f////3+qKqoq/3///wAA/39UVaqq/3///wAA/3+qKqoq////fwAA/39UVaqq////fwAA/3+qKqoq/3///////39UVaqq/3///////3+qKqoq////f////39UVaqq////f////3+qKqoq/3///wAA/39UVaqq/3///wAA/3+qKqoq////fwAA/39UVaqq////fwAA/3+qKqoqbwDcgLn/Z/9O1THVBsA2ALn/Z/9O1THV7T/vP28A3IBO1THVBsA2AO0/7z9O1THVoyqJKm8A3IC5/2f/BsA2AKMqiSq5/2f/7T/vP6MqiSpvANyABsA2AO0/7z+jKokqTwFb/UwBnH8w1sXVNoAuwU8BW/1a1LHWTgGbf5xBdD/V1nLVNYAvwbtBVT/p1GnWUAFc/X0p8ip4AYZ/YoAYwVABXP0RKqkqqincKnkBhn8PQP1AYYAZwTwqlCovQN5A")
+}, {
+"aabb": AABB(-0.543871, -0.692006, -1.0571, 1.11774, 0.409166, 0.126927),
+"attribute_data": PackedByteArray("/7+Ogv///38AAP9//z+Ogv//AAAAAAAAb/3/v/+//3//v/9/cH3/v/+/AAD/vwAA/79v/f9//3//f/9//z9v/f9/AAD/fwAAjoL/v/8//3//P/9/jwL/v/8/AAD/PwAA/7+Ogv///38AAP9//z+Ogv//AAAAAAAAb/3/v/+//3//v/9/cH3/v/+/AAD/vwAA/79v/f9//3//f/9//z9v/f9/AAD/fwAAjoL/v/8//3//P/9/jwL/v/8/AAD/PwAA/7+Ogv///38AAP9//z+Ogv//AAAAAAAAb/3/v/+//3//v/9/cH3/v/+/AAD/vwAA/79v/f9//3//f/9//z9v/f9/AAD/fwAAjoL/v/8//3//P/9/jwL/v/8/AAD/PwAA/7+Ogv///38AAP9//z+Ogv//AAAAAAAAb/3/v/+//3//v/9/cH3/v/+/AAD/vwAA/79v/f9//3//f/9//z9v/f9/AAD/fwAAjoL/v/8//3//P/9/jwL/v/8/AAD/PwAA"),
+"format": 34896613399,
+"index_count": 144,
+"index_data": PackedByteArray("AQAKAAQAAQAHAAoACAAQAAsACAANABAACQAVAAMACQAPABUADgAWABEADgATABYAFAAFABcAFAACAAUAAAAMAAYAAAASAAwAGQAiABwAGQAfACIAIAAoACMAIAAlACgAIQAtABsAIQAnAC0AJgAvACkAJgAsAC8AKwAdAC4AKwAaAB0AGAAkAB4AGAAqACQAMQA6ADQAMQA3ADoAOABAADsAOAA9AEAAOQBFADMAOQA/AEUAPgBHAEEAPgBEAEcAQwA1AEYAQwAyADUAMAA8ADYAMABCADwASQBSAEwASQBPAFIAUABYAFMAUABVAFgAUQBdAEsAUQBXAF0AVgBeAFkAVgBbAF4AXABNAF8AXABKAE0ASABUAE4ASABaAFQA"),
+"material": SubResource("StandardMaterial3D_a4lxw"),
+"name": "metal",
+"primitive": 3,
+"uv_scale": Vector4(0, 0, 0, 0),
+"vertex_count": 96,
+"vertex_data": PackedByteArray("W+0MPQAAAABb7Qw9AADV71vtDD0AAKbjW+0MPf///Ihb7Qw9///V71vtDD3//6bjCfteJQAAAAAJ+14lAADV7wn7XiUAAI3JCfteJf///IgJ+14l///V7wn7XiX//43JXvIAAAAAAABe8gAAAACNyV7yAAAAACnDXvIAAP///Ihe8gAA//+NyV7yAAD//ynDsOStFwAAAACw5K0XAAApw7DkrRcAAKbjsOStF////Iiw5K0X//8pw7DkrRf//6bj1wv//wAAAADXC///AACq6dcL//8AAKrp1wv/////AIDXC/////+q6dcL/////6rpSxe24AAAAABLF7bgAACq6UsXtuAAAPzFSxe24P//AIBLF7bg//+q6UsXtuD///zF1wtuwQAAAADXC27BAAD8xdcLbsEAAPzF1wtuwf//AIDXC27B///8xdcLbsH///zFZAC24AAAAABkALbgAACq6WQAtuAAAPzFZAC24P//AIBkALbg//+q6WQAtuD///zFi/T+/wAAAACL9P7/AACq6Yv0/v8AAKrpi/T+////AICL9P7///+q6Yv0/v///6rp//+24AAAAAD//7bgAACq6f//tuAAAPzF//+24P//AID//7bg//+q6f//tuD///zFi/RuwQAAAACL9G7BAAD8xYv0bsEAAPzFi/Ruwf//AICL9G7B///8xYv0bsH///zFF+m24AAAAAAX6bbgAACq6RfptuAAAPzFF+m24P//AIAX6bbg//+q6RfptuD///zFHgcdPAAAAAAeBx08AADx8h4HHTwAALvgHgcdPP//dY0eBx08///x8h4HHTz//7vgqhWrKAAAAACqFasoAADx8qoVqygAAJHLqhWrKP//dY2qFaso///x8qoVqyj//5HLjA7uAAAAAACMDu4AAACRy4wO7gAAABLCjA7uAP//dY2MDu4A//+Ry4wO7gD//xLCAABgFAAAAAAAAGAUAAASwgAAYBQAALvgAABgFP//dY0AAGAU//8SwgAAYBT//7vgO/PDjOQ3NxBhZDCy/////+Q3NxBhZDCyO/PDjOQ3NxCHIfA8/////+Q3NxCHIfA8O/PDjIch8DwAL3+X/////4ch8DwAL3+XO/PDjAAvf5dhZDCy/////wAvf5dhZDCy////fwQ19hUJagS1/3///wQ19hUJagS1/v//fwQ19hX/HAFG/3///wQ19hX/HAFG////f/8cAUb+Of6c/3////8cAUb+Of6c/v//fwlqBLX+Of6c/3///wlqBLX+Of6c////fwQ19hUJagS1/3///wQ19hUJagS1/v//fwQ19hX/HAFG/3///wQ19hX/HAFG////f/8cAUb+Of6c/3////8cAUb+Of6c/v//fwlqBLX+Of6c/3///wlqBLX+Of6cte1Jkls5Rw2PYcew/////1s5Rw2PYcewte1Jkls5Rw2HI/A4/////1s5Rw2HI/A4te1Jkocj8DiDKEGU/////4cj8DiDKEGUte1JkoMoQZSPYcew/////4MoQZSPYcew")
+}]
+blend_shape_mode = 0
+shadow_mesh = SubResource("ArrayMesh_wl7qe")
+
+[sub_resource type="Image" id="Image_gnm4j"]
+data = {
+"data": PackedByteArray("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgpR7/4KUe/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOClHv/gpR7/4KUe/+ClHv/gpR7/4KUe/+ClHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCXw3/gl8N/4JfDf+CXw3/36Ue/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/wAAAAAAAAAA36Ue/9+lHv/fpR7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/4RgDv/fpR7/36Ue/9+lHv/fpR7/36Ue/9+lHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/36Ue/9+lHv+EYA3/hGAN/4RgDv+EYA7/36Ue/9+lHv/fpR7/0Zoe/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/9+lHv+EYA3/hGAN/4RgDf+EYA7/hGAO/9GaHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/36Ue/4RgDf/fpR7/36Ue/9+lHv/fpR7/36Ue/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/9+lHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/36Ue/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf8lJSX/JSUl/2tra/+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf/fpR7/36Ue/9+lHv/fpR7/36Ue/9+lHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADfpR7/36Ue/9+lHv/fpR7/AAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/yUlJf8lJSX/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/36Ue/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGEN/9+lHv/fpR7/36Ue/9+lHv/fpR7/36Ue/wAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf/fpR7/36Ue/9+lHv/fpR7/36Ue/9+lHv8AAAAAAAAAAN+kHv/fpB7/36Qe/96kHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRhDf+EYQ3/hGEN/4RhDf/fpR7/36Ue/9+lHv/fpR7/36Ue/9+lHv/fpR7/AAAAAIRgDf+EYA3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/36Ue/9+lHv/fpR7/36Ue/4RgDv+EYA7/3qQe/96kHv/epB7/3qQe/96kHv/epB7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYQ3/hGEN/4RhDf+EYQ3/hGEN/4RhDf+EYQ3/hGEN/9+kHv/fpB7/36Qe/9+kHv+EYA3/hGAN/4RgDf+EYA3/hGAN/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+EYA7/hGAO/4RgDv+EYA7/hGAO/96kHv/epB7/3qQe/9GbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGEN/4RhDf+EYQ3/hGEN/4RhDf+EYQ3/hGAN/4RgDf+EYA3/hGAN/4RgDf/fpB7/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9GaHf8AAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+EYA7/hGAO/4RgDv+EYA7/hGAO/9GbHf/Rmx3/36Ue/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRhDf+EYQ3/hGEN/4RhDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Rmh3/3qQe/wAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4RgDv+EYA7/hGAO/4RgDv+EYA7/hGAO/4RgDv/Rmx3/36Ue/9+lHv/fpR7/36Ue/9+lHv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYQ3/hGEN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv8AAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+EYA3/hGAN/4RgDv+EYA7/hGAO/4RgDv+EYA7/gl8N/4JfDf+CXw3/36Qe/9+kHv/fpB7/36Qe/9+kHv/fpB7/36Qe/wAAAAAAAAAAAAAAAAAAAAAAAAAAhGEN/4RhDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv/epB7/3qQe/wAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/hGAN/4RgDf+EYA3/hGAN/2lpaf+EYA7/hGAO/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf/epB7/3qQe/96kHv/epB7/3qQe/96kHv8AAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/JSUl/1RUVP+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/epB7/3qQe/96kHv/epB7/3qQe/96kHv8AAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4RgDf+EYA3/hGAN/yUlJf8lJSX/hGAN/4RgDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/96kHv/epB7/0Jod/wAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/JSUl/yUlJf8lJSX/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv/epB7/AAAAAAAAAAAAAAAAAAAAAIJfDf+CXw3/gl8N/4JfDf+EYA3/hGAN/4RgDf8lJSX/JSUl/2lpaf+EYA3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/0Jod/9CaHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf8lJSX/MjIy/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/epB7/3qQe/96kHv/epB7/3qQe/96kHv8AAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/9CaHf/Rmh3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv/epB7/AAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf/Rmh3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/96kHv/epB7/3qQe/96kHv+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/0Zod/9GaHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAIJfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/4JfDf+CXw3/gl8N/9GaHf/Rmh3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Rmh3/AAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/96kHv+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAgl8N/4JfDf+CXw3/gl8N/4JfDf/Rmh3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv/epB7/AAAAAAAAAAAAAAAAAAAAAIJfDf+CXw3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9GaHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/96kHv/epB7/3qQe/96kHv/epB7/3qQe/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Rmh3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/yUlJf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/3qQe/96kHv/epB7/3qQe/96kHv/epB7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/yUlJf8lJSX/JSUl/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/96kHv/epB7/3qQe/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9GaHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/JSUl/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Rmh3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0Zod/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0psd/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9GaHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Rmh3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0psd/9KbHf8AAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0psd/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0psd/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIRgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/hGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/0psd/9KbHf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf+EYA3/hGAN/9KbHf/Smx3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhGAN/4RgDf+EYA3/hGAN/4RgDf/Smx3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEYA3/0psd/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="),
+"format": "RGBA8",
+"height": 64,
+"mipmaps": false,
+"width": 64
+}
+
+[sub_resource type="ImageTexture" id="ImageTexture_sxfgn"]
+image = SubResource("Image_gnm4j")
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_0fe72"]
+size = Vector3(2, 4, 0.265)
+
+[resource]
+item/0/name = "Grass"
+item/0/mesh = SubResource("ArrayMesh_455vr")
+item/0/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/0/shapes = [SubResource("BoxShape3D_snubt"), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)]
+item/0/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/0/navigation_layers = 1
+item/0/preview = SubResource("ImageTexture_5xgod")
+item/1/name = "Gray"
+item/1/mesh = SubResource("ArrayMesh_2e2w7")
+item/1/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/1/shapes = []
+item/1/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/1/navigation_layers = 1
+item/1/preview = SubResource("ImageTexture_op0o1")
+item/2/name = "Green"
+item/2/mesh = SubResource("ArrayMesh_1mtgn")
+item/2/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/2/shapes = [SubResource("BoxShape3D_snubt"), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)]
+item/2/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/2/navigation_layers = 1
+item/2/preview = SubResource("ImageTexture_613u0")
+item/3/name = "Tree"
+item/3/mesh = SubResource("ArrayMesh_emgrj")
+item/3/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/3/shapes = [SubResource("BoxShape3D_snubt"), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)]
+item/3/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/3/navigation_layers = 1
+item/3/preview = SubResource("ImageTexture_3fakq")
+item/4/name = "WoodFence"
+item/4/mesh = SubResource("ArrayMesh_ysymx")
+item/4/mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/4/shapes = [SubResource("BoxShape3D_0fe72"), Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.872101, -1)]
+item/4/navigation_mesh_transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
+item/4/navigation_layers = 1
+item/4/preview = SubResource("ImageTexture_sxfgn")
diff --git a/examples/PushBall/scenes/tiles/tiles.tscn b/examples/PushBall/scenes/tiles/tiles.tscn
new file mode 100644
index 0000000..1e9b427
--- /dev/null
+++ b/examples/PushBall/scenes/tiles/tiles.tscn
@@ -0,0 +1,59 @@
+[gd_scene load_steps=8 format=3 uid="uid://48qkk328vkwu"]
+
+[ext_resource type="PackedScene" uid="uid://8kbips6v0udq" path="res://assets/tiles/grass.glb" id="1_mnvew"]
+[ext_resource type="PackedScene" uid="uid://bujd1vfmbe5ba" path="res://assets/tiles/gray.glb" id="2_ttdf0"]
+[ext_resource type="PackedScene" uid="uid://42ejkug73b60" path="res://assets/tiles/green.glb" id="3_ktywo"]
+[ext_resource type="PackedScene" uid="uid://dtbi6bkhvj2vn" path="res://assets/tiles/tree.glb" id="4_80i4m"]
+[ext_resource type="PackedScene" uid="uid://dj56ae4k54bna" path="res://assets/tiles/wooden_fence.glb" id="5_d1kmr"]
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_snubt"]
+size = Vector3(2, 5, 2)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_0fe72"]
+size = Vector3(2, 4, 0.265)
+
+[node name="Tiles" type="Node3D"]
+
+[node name="grass" parent="." instance=ExtResource("1_mnvew")]
+visible = false
+
+[node name="StaticBody3D" type="StaticBody3D" parent="grass/Grass" index="0"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="grass/Grass/StaticBody3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
+shape = SubResource("BoxShape3D_snubt")
+
+[node name="gray" parent="." instance=ExtResource("2_ttdf0")]
+visible = false
+
+[node name="green" parent="." instance=ExtResource("3_ktywo")]
+visible = false
+
+[node name="StaticBody3D" type="StaticBody3D" parent="green/Green" index="0"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="green/Green/StaticBody3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
+shape = SubResource("BoxShape3D_snubt")
+
+[node name="tree" parent="." instance=ExtResource("4_80i4m")]
+visible = false
+
+[node name="StaticBody3D" type="StaticBody3D" parent="tree/Tree" index="0"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="tree/Tree/StaticBody3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
+shape = SubResource("BoxShape3D_snubt")
+
+[node name="wooden_fence" parent="." instance=ExtResource("5_d1kmr")]
+visible = false
+
+[node name="StaticBody3D" type="StaticBody3D" parent="wooden_fence/WoodFence" index="0"]
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="wooden_fence/WoodFence/StaticBody3D"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.872101, -1)
+shape = SubResource("BoxShape3D_0fe72")
+
+[editable path="grass"]
+[editable path="green"]
+[editable path="tree"]
+[editable path="wooden_fence"]
diff --git a/examples/PushBall/scenes/training_scene.tscn b/examples/PushBall/scenes/training_scene.tscn
new file mode 100644
index 0000000..d7c59cf
--- /dev/null
+++ b/examples/PushBall/scenes/training_scene.tscn
@@ -0,0 +1,57 @@
+[gd_scene load_steps=6 format=3 uid="uid://csfbca4jihdku"]
+
+[ext_resource type="Script" path="res://addons/godot_rl_agents/sync.gd" id="2_4sdps"]
+[ext_resource type="PackedScene" uid="uid://cck7kpuva1vvs" path="res://scenes/levels/all_levels.tscn" id="2_n4cfp"]
+
+[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_cojh0"]
+sky_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
+ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
+
+[sub_resource type="Sky" id="Sky_ddj2e"]
+sky_material = SubResource("ProceduralSkyMaterial_cojh0")
+
+[sub_resource type="Environment" id="Environment_evcys"]
+background_mode = 2
+sky = SubResource("Sky_ddj2e")
+tonemap_mode = 2
+glow_enabled = true
+
+[node name="TrainingScene" type="Node3D"]
+
+[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
+environment = SubResource("Environment_evcys")
+
+[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
+transform = Transform3D(-0.866025, -0.433013, 0.25, 0, 0.5, 0.866025, -0.5, 0.75, -0.433013, 0, 0, 0)
+
+[node name="AllLevels" parent="." instance=ExtResource("2_n4cfp")]
+
+[node name="AllLevels2" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -100)
+
+[node name="AllLevels3" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -200)
+
+[node name="AllLevels4" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -300)
+
+[node name="AllLevels5" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -400)
+
+[node name="AllLevels6" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -500)
+
+[node name="AllLevels7" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -600)
+
+[node name="AllLevels8" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -700)
+
+[node name="AllLevels9" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -800)
+
+[node name="AllLevels10" parent="." instance=ExtResource("2_n4cfp")]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -900)
+
+[node name="Sync" type="Node" parent="."]
+script = ExtResource("2_4sdps")